9 Commits

Author SHA1 Message Date
melod1n 155a3666ad bump app version code and name (#251) 2026-02-16 16:32:10 +03:00
melod1n ce375c902c Refactor: Improve reply component layout and styling
This commit refactors the `Reply` composable for better layout consistency and simplifies its implementation.

The `Reply` component no longer uses a fixed height, allowing it to dynamically resize based on its content. The layout has been updated from a `Box` to a `Row` to properly align the side indicator bar with the height of the text content. Padding and corner rounding logic has been simplified and centralized within the `Reply` composable itself, removing redundant parameters from the `MessageBubble`.

Key changes:
- `Reply` composable now uses `Row` for its root layout instead of `Box`.
- Removed the fixed `48.dp` height to allow dynamic content sizing.
- The side indicator bar's height now matches the text content's height.
- Simplified padding and shape logic in `MessageBubble` by removing conditional parameters passed to `Reply`.
- Adjusted padding inside `MessageBubble` to accommodate the new `Reply` layout.
2026-02-06 22:58:03 +03:00
melod1n 96b4fc8539 ui: improve Compose stability and message UI
- Add minute/second abbreviations and kotlin.time-based relative time formatter
- Introduce FastPreview and update previews to use AppTheme with dark/dynamic colors
- Refactor attachments preview grid & waveform to use ImmutableList and reduce recompositions
- Tweak message bubble reply styling and swipe-to-reply animation/haptics
- Add Compose Stability Analyzer plugin and enable it in debug builds
- Cache shared images by sha256 and improve share intent/chooser text
- Minor UX polish (e.g., “No views”) and immutability annotations
2026-02-06 22:14:01 +03:00
melod1n e3e9157dd5 Style: Update icons for message status and actions
This commit updates the icons used to indicate a message's status and within the message context menu. The outlined "star" and "edit" icons have been replaced with their filled variants for better visual distinction.

Key changes:
- Replaced `ic_star_round_24` with `ic_star_fill_round_24` for "important" messages in `DateStatus` and the "Mark as Important" action.
- Replaced `ic_edit_round_24` with `ic_edit_fill_round_24` for "edited" messages in `DateStatus`.
- Added the new `ic_edit_fill_round_24` drawable resource.
- In `MessageBubble`, the `derivedStateOf` for `shouldFill` is now wrapped in a `remember` block to prevent unnecessary recompositions.
2026-01-24 21:58:11 +03:00
melod1n 5aa28066d7 add icons to dialog in messages history
change icons fill color from @android:color/white to #ffffff
2026-01-24 21:49:28 +03:00
melod1n 1638d70ef2 update and refresh icons to Material Symbols;
update MaterialDialog style
2026-01-24 21:36:41 +03:00
melod1n 8c13d9e7e1 update some icons 2026-01-24 16:02:02 +03:00
melod1n 5dd829b6f6 change @android:color/white to #ffffff in icons 2026-01-24 15:28:13 +03:00
melod1n 2a238fa1bf Refactor: Upgrade Gradle and streamline build logic
This commit upgrades the project's build system and refactors the build logic for better maintainability and alignment with modern practices.

The Gradle version has been updated from 8.14.2 to 9.3.0, and the Android Gradle Plugin (AGP) has been upgraded to version 9.0.0. This required migrating the build logic to use the new `com.android.build.api.dsl` interfaces instead of the deprecated `com.android.build.gradle` ones.

Key changes:
- Upgraded Gradle to `9.3.0`.
- Upgraded Android Gradle Plugin to `9.0.0`.
- Updated various dependencies including Kotlin, Compose BOM, Chucker, and serialization.
- Removed the explicit `kotlin-android` plugin application, as it's now handled by AGP.
- Migrated build convention plugins to use the new AGP DSL APIs.
- Commented out the custom APK naming logic in `app/build.gradle.kts`.
- Added new `gradle.properties` flags for build configuration.
- Corrected the namespace in `core/model` from `datastore` to `model`.
2026-01-24 14:58:04 +03:00
221 changed files with 1486 additions and 1295 deletions
+13 -13
View File
@@ -13,8 +13,8 @@ android {
defaultConfig { defaultConfig {
applicationId = "dev.meloda.fastvk" applicationId = "dev.meloda.fastvk"
versionCode = 10 versionCode = 11
versionName = "0.2.2" versionName = "0.2.3"
} }
signingConfigs { signingConfigs {
@@ -59,17 +59,17 @@ android {
} }
} }
applicationVariants.all { // applicationVariants.all {
outputs.all { // outputs.all {
val date = System.currentTimeMillis() / 1000 // val date = System.currentTimeMillis() / 1000
val buildType = buildType.name // val buildType = buildType.name
val appVersion = versionName // val appVersion = versionName
val appVersionCode = versionCode // val appVersionCode = versionCode
//
val newApkName = "app-$buildType-v$appVersion($appVersionCode)-$date.apk" // val newApkName = "app-$buildType-v$appVersion($appVersionCode)-$date.apk"
(this as? BaseVariantOutputImpl)?.outputFileName = newApkName // (this as? BaseVariantOutputImpl)?.outputFileName = newApkName
} // }
} // }
packaging { packaging {
resources { resources {
@@ -4,6 +4,8 @@ import android.app.Application
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import coil.ImageLoader import coil.ImageLoader
import coil.ImageLoaderFactory import coil.ImageLoaderFactory
import com.skydoves.compose.stability.runtime.ComposeStabilityAnalyzer
import dev.meloda.fast.auth.BuildConfig
import dev.meloda.fast.common.di.applicationModule import dev.meloda.fast.common.di.applicationModule
import dev.meloda.fast.datastore.AppSettings import dev.meloda.fast.datastore.AppSettings
import org.koin.android.ext.android.get import org.koin.android.ext.android.get
@@ -20,6 +22,8 @@ class AppGlobal : Application(), ImageLoaderFactory {
AppSettings.init(preferences) AppSettings.init(preferences)
initKoin() initKoin()
ComposeStabilityAnalyzer.setEnabled(BuildConfig.DEBUG)
} }
private fun initKoin() { private fun initKoin() {
@@ -29,20 +29,20 @@ fun NavGraphBuilder.mainScreen(
val navigationItems = ImmutableList.of( val navigationItems = ImmutableList.of(
BottomNavigationItem( BottomNavigationItem(
titleResId = R.string.title_friends, titleResId = R.string.title_friends,
selectedIconResId = R.drawable.baseline_people_alt_24, selectedIconResId = R.drawable.ic_group_fill_round_24,
unselectedIconResId = R.drawable.outline_people_alt_24, unselectedIconResId = R.drawable.ic_group_round_24,
route = Friends, route = Friends,
), ),
BottomNavigationItem( BottomNavigationItem(
titleResId = R.string.title_convos, titleResId = R.string.title_convos,
selectedIconResId = R.drawable.baseline_chat_24, selectedIconResId = R.drawable.ic_mail_fill_round_24,
unselectedIconResId = R.drawable.outline_chat_24, unselectedIconResId = R.drawable.ic_mail_round_24,
route = ConvoGraph route = ConvoGraph
), ),
BottomNavigationItem( BottomNavigationItem(
titleResId = R.string.title_profile, titleResId = R.string.title_profile,
selectedIconResId = R.drawable.baseline_account_circle_24, selectedIconResId = R.drawable.ic_account_circle_fill_round_24,
unselectedIconResId = R.drawable.outline_account_circle_24, unselectedIconResId = R.drawable.ic_account_circle_round_24,
route = Profile route = Profile
) )
) )
@@ -69,9 +69,7 @@ import dev.meloda.fast.ui.theme.LocalNavController
import dev.meloda.fast.ui.theme.LocalNavRootController import dev.meloda.fast.ui.theme.LocalNavRootController
import dev.meloda.fast.ui.theme.LocalThemeConfig import dev.meloda.fast.ui.theme.LocalThemeConfig
import dev.meloda.fast.ui.theme.LocalUser import dev.meloda.fast.ui.theme.LocalUser
import dev.meloda.fast.ui.util.ImmutableList
import dev.meloda.fast.ui.util.ImmutableList.Companion.toImmutableList import dev.meloda.fast.ui.util.ImmutableList.Companion.toImmutableList
import dev.meloda.fast.ui.util.immutableListOf
import dev.meloda.fast.ui.util.isNeedToEnableDarkMode import dev.meloda.fast.ui.util.isNeedToEnableDarkMode
import org.koin.androidx.compose.koinViewModel import org.koin.androidx.compose.koinViewModel
import org.koin.compose.koinInject import org.koin.compose.koinInject
@@ -309,7 +307,7 @@ fun RootScreen(
LocalNavController provides navController LocalNavController provides navController
) { ) {
var photoViewerInfo by rememberSaveable { var photoViewerInfo by rememberSaveable {
mutableStateOf<Pair<ImmutableList<String>, Int?>?>(null) mutableStateOf<Pair<List<String>, Int?>?>(null)
} }
Box(modifier = Modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) {
@@ -333,7 +331,7 @@ fun RootScreen(
onSettingsButtonClicked = navController::navigateToSettings, onSettingsButtonClicked = navController::navigateToSettings,
onNavigateToMessagesHistory = navController::navigateToMessagesHistory, onNavigateToMessagesHistory = navController::navigateToMessagesHistory,
onPhotoClicked = { url -> onPhotoClicked = { url ->
photoViewerInfo = immutableListOf(url) to null photoViewerInfo = listOf(url) to null
}, },
onMessageClicked = navController::navigateToMessagesHistory, onMessageClicked = navController::navigateToMessagesHistory,
onNavigateToCreateChat = navController::navigateToCreateChat onNavigateToCreateChat = navController::navigateToCreateChat
@@ -344,13 +342,13 @@ fun RootScreen(
onBack = navController::navigateUp, onBack = navController::navigateUp,
onNavigateToChatMaterials = navController::navigateToChatMaterials, onNavigateToChatMaterials = navController::navigateToChatMaterials,
onNavigateToPhotoViewer = { photos, index -> onNavigateToPhotoViewer = { photos, index ->
photoViewerInfo = photos.toImmutableList() to index photoViewerInfo = photos to index
} }
) )
chatMaterialsScreen( chatMaterialsScreen(
onBack = navController::navigateUp, onBack = navController::navigateUp,
onPhotoClicked = { url -> onPhotoClicked = { url ->
photoViewerInfo = immutableListOf(url) to null photoViewerInfo = listOf(url) to null
} }
) )
createChatScreen( createChatScreen(
@@ -378,7 +376,9 @@ fun RootScreen(
} }
PhotoViewDialog( PhotoViewDialog(
photoViewerInfo = photoViewerInfo, photoViewerInfo = photoViewerInfo?.let { info ->
info.first.toImmutableList() to info.second
},
onDismiss = { photoViewerInfo = null } onDismiss = { photoViewerInfo = null }
) )
} }
@@ -10,6 +10,7 @@ class AndroidApplicationComposeConventionPlugin : Plugin<Project> {
with(target) { with(target) {
apply(plugin = "com.android.application") apply(plugin = "com.android.application")
apply(plugin = "org.jetbrains.kotlin.plugin.compose") apply(plugin = "org.jetbrains.kotlin.plugin.compose")
apply(plugin = "com.github.skydoves.compose.stability.analyzer")
val extension = extensions.getByType<ApplicationExtension>() val extension = extensions.getByType<ApplicationExtension>()
configureAndroidCompose(extension) configureAndroidCompose(extension)
@@ -1,6 +1,5 @@
import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.ApplicationExtension
import dev.meloda.fast.configureKotlinAndroid import dev.meloda.fast.configureKotlinAndroid
import dev.meloda.fast.libs
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.configure
@@ -10,12 +9,15 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
with(target) { with(target) {
with(pluginManager) { with(pluginManager) {
apply("com.android.application") apply("com.android.application")
apply("org.jetbrains.kotlin.android")
} }
extensions.configure<ApplicationExtension> { extensions.configure<ApplicationExtension> {
configureKotlinAndroid(this) configureKotlinAndroid(this)
defaultConfig.targetSdk = 36 defaultConfig {
targetSdk = 36
compileSdk = 36
minSdk = 23
}
} }
} }
} }
@@ -1,4 +1,4 @@
import com.android.build.gradle.LibraryExtension import com.android.build.api.dsl.LibraryExtension
import dev.meloda.fast.configureAndroidCompose import dev.meloda.fast.configureAndroidCompose
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
@@ -10,6 +10,7 @@ class AndroidLibraryComposeConventionPlugin : Plugin<Project> {
with(target) { with(target) {
apply(plugin = "com.android.library") apply(plugin = "com.android.library")
apply(plugin = "org.jetbrains.kotlin.plugin.compose") apply(plugin = "org.jetbrains.kotlin.plugin.compose")
apply(plugin = "com.github.skydoves.compose.stability.analyzer")
val extension = extensions.getByType<LibraryExtension>() val extension = extensions.getByType<LibraryExtension>()
extension.androidResources.enable = false extension.androidResources.enable = false
@@ -1,5 +1,5 @@
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.variant.LibraryAndroidComponentsExtension import com.android.build.api.variant.LibraryAndroidComponentsExtension
import com.android.build.gradle.LibraryExtension
import dev.meloda.fast.configureKotlinAndroid import dev.meloda.fast.configureKotlinAndroid
import dev.meloda.fast.disableUnnecessaryAndroidTests import dev.meloda.fast.disableUnnecessaryAndroidTests
import org.gradle.api.Plugin import org.gradle.api.Plugin
@@ -13,7 +13,6 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
with(target) { with(target) {
with(pluginManager) { with(pluginManager) {
apply("com.android.library") apply("com.android.library")
apply("org.jetbrains.kotlin.android")
apply("org.jetbrains.kotlin.plugin.parcelize") apply("org.jetbrains.kotlin.plugin.parcelize")
apply("org.jetbrains.kotlin.plugin.serialization") apply("org.jetbrains.kotlin.plugin.serialization")
} }
@@ -21,7 +20,6 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
extensions.configure<LibraryExtension> { extensions.configure<LibraryExtension> {
configureKotlinAndroid(this) configureKotlinAndroid(this)
androidResources.enable = false androidResources.enable = false
defaultConfig.targetSdk = 36
defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
extensions.configure<LibraryAndroidComponentsExtension> { extensions.configure<LibraryAndroidComponentsExtension> {
@@ -1,6 +1,5 @@
import com.android.build.gradle.TestExtension import com.android.build.api.dsl.TestExtension
import dev.meloda.fast.configureKotlinAndroid import dev.meloda.fast.configureKotlinAndroid
import dev.meloda.fast.libs
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.configure
@@ -10,7 +9,6 @@ class AndroidTestConventionPlugin : Plugin<Project> {
with(target) { with(target) {
with(pluginManager) { with(pluginManager) {
apply("com.android.test") apply("com.android.test")
apply("org.jetbrains.kotlin.android")
} }
extensions.configure<TestExtension> { extensions.configure<TestExtension> {
@@ -5,12 +5,10 @@ import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.dependencies
internal fun Project.configureAndroidCompose( internal fun Project.configureAndroidCompose(
commonExtension: CommonExtension<*, *, *, *, *, *>, commonExtension: CommonExtension,
) { ) {
commonExtension.apply { commonExtension.apply {
buildFeatures { buildFeatures.compose = true
compose = true
}
dependencies { dependencies {
val bom = libs.findLibrary("compose-bom").get() val bom = libs.findLibrary("compose-bom").get()
@@ -1,6 +1,9 @@
package dev.meloda.fast package dev.meloda.fast
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.CommonExtension import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.CompileOptions
import com.android.build.api.dsl.LibraryExtension
import org.gradle.api.JavaVersion import org.gradle.api.JavaVersion
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.plugins.JavaPluginExtension
@@ -13,24 +16,25 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinBaseExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
internal fun Project.configureKotlinAndroid( internal fun Project.configureKotlinAndroid(
commonExtension: CommonExtension<*, *, *, *, *, *>, commonExtension: CommonExtension,
) { ) {
when (commonExtension) {
is ApplicationExtension -> commonExtension.compileOptions(buildCompileOptions())
is LibraryExtension -> commonExtension.compileOptions(buildCompileOptions())
}
commonExtension.apply { commonExtension.apply {
compileSdk = 36 compileSdk = 36
defaultConfig {
minSdk = 23
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
} }
configureKotlin<KotlinAndroidProjectExtension>() configureKotlin<KotlinAndroidProjectExtension>()
} }
private fun buildCompileOptions(): CompileOptions.() -> Unit = {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
internal fun Project.configureKotlinJvm() { internal fun Project.configureKotlinJvm() {
extensions.configure<JavaPluginExtension> { extensions.configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_21 sourceCompatibility = JavaVersion.VERSION_21
+2 -1
View File
@@ -1,7 +1,6 @@
plugins { plugins {
alias(libs.plugins.android.application) apply false alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false alias(libs.plugins.android.library) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.parcelize) apply false alias(libs.plugins.kotlin.parcelize) apply false
alias(libs.plugins.kotlin.serialization) apply false alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.kotlin.jvm) apply false alias(libs.plugins.kotlin.jvm) apply false
@@ -9,4 +8,6 @@ plugins {
alias(libs.plugins.room) apply false alias(libs.plugins.room) apply false
alias(libs.plugins.ksp) apply false alias(libs.plugins.ksp) apply false
alias(libs.plugins.module.graph) apply true alias(libs.plugins.module.graph) apply true
alias(libs.plugins.versions) apply true
alias(libs.plugins.stability.analyzer) apply false
} }
@@ -1,7 +1,6 @@
package dev.meloda.fast.common.util package dev.meloda.fast.common.util
import com.conena.nanokt.jvm.util.dayOfMonth import com.conena.nanokt.jvm.util.dayOfMonth
import com.conena.nanokt.jvm.util.hour
import com.conena.nanokt.jvm.util.hourOfDay import com.conena.nanokt.jvm.util.hourOfDay
import com.conena.nanokt.jvm.util.millisecond import com.conena.nanokt.jvm.util.millisecond
import com.conena.nanokt.jvm.util.minute import com.conena.nanokt.jvm.util.minute
@@ -12,6 +11,12 @@ import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import kotlin.time.Clock
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
import kotlin.time.Instant
object TimeUtils { object TimeUtils {
@@ -56,37 +61,23 @@ object TimeUtils {
monthShort: () -> String, monthShort: () -> String,
weekShort: () -> String, weekShort: () -> String,
dayShort: () -> String, dayShort: () -> String,
minuteShort: () -> String,
secondShort: () -> String,
now: () -> String now: () -> String
): String { ): String {
val now = Calendar.getInstance() val now = Clock.System.now()
val then = Calendar.getInstance().also { it.timeInMillis = date } val then = Instant.fromEpochMilliseconds(date)
val diff = now - then
return when { return when {
now.year != then.year -> { diff > 365.days -> "${diff.inWholeDays / 365}${yearShort().lowercase()}"
"${now.year - then.year}${yearShort().lowercase()}" diff > 30.days -> "${diff.inWholeDays / 30}${monthShort().lowercase()}"
} diff > 7.days -> "${diff.inWholeDays / 7}${weekShort().lowercase()}"
diff > 1.days -> "${diff.inWholeDays}${dayShort().lowercase()}"
now.month != then.month -> { diff > 1.hours -> "${diff.inWholeHours}h"
"${now.month - then.month}${monthShort().lowercase()}" diff > 1.minutes -> "${diff.inWholeMinutes}${minuteShort().lowercase()}"
} diff > 1.seconds -> "${diff.inWholeSeconds}${secondShort().lowercase()}"
else -> now().lowercase()
now.dayOfMonth != then.dayOfMonth -> {
val change = now.dayOfMonth - then.dayOfMonth
if (change % 7 == 0) {
"${change / 7}${weekShort().lowercase()}"
} else {
"$change${dayShort().lowercase()}"
}
}
now.hour == then.hour && now.minute == then.minute -> {
now().lowercase()
}
else -> {
SimpleDateFormat("HH:mm", Locale.getDefault()).format(date)
}
} }
} }
} }
@@ -1,7 +1,17 @@
package dev.meloda.fast.common.util package dev.meloda.fast.common.util
import java.net.URLEncoder import java.net.URLEncoder
import java.security.MessageDigest
fun String.urlEncode(encoding: String = "utf-8"): String { fun String.urlEncode(encoding: String = "utf-8"): String {
return URLEncoder.encode(this, encoding) return URLEncoder.encode(this, encoding)
} }
fun String.sha256() = this.hashString("SHA-256")
fun String.hashString(algorithm: String): String {
return MessageDigest
.getInstance(algorithm)
.digest(this.toByteArray())
.fold("") { str, it -> str + "%02x".format(it) }
}
+1
View File
@@ -18,5 +18,6 @@ dependencies {
implementation(libs.bundles.nanokt) implementation(libs.bundles.nanokt)
implementation(platform(libs.compose.bom))
implementation(libs.compose.ui) implementation(libs.compose.ui)
} }
@@ -6,10 +6,7 @@ import dev.meloda.fast.model.database.AccountEntity
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
class GetCurrentAccountUseCase( class GetCurrentAccountUseCase(private val accountsRepository: AccountsRepository) {
private val accountsRepository: AccountsRepository
) {
suspend operator fun invoke(): AccountEntity? = withContext(Dispatchers.IO) { suspend operator fun invoke(): AccountEntity? = withContext(Dispatchers.IO) {
accountsRepository.getAccountById(UserConfig.currentUserId) accountsRepository.getAccountById(UserConfig.currentUserId)
} }
@@ -40,7 +40,7 @@ fun VkConvo.extractAvatar(): UiImage = when (peerType) {
PeerType.CHAT -> { PeerType.CHAT -> {
photo200 photo200
} }
}?.let(UiImage::Url) ?: UiImage.Resource(R.drawable.ic_account_circle_cut) }?.let(UiImage::Url) ?: UiImage.Resource(R.drawable.ic_account_circle_fill_round_24)
fun VkConvo.extractTitle( fun VkConvo.extractTitle(
useContactName: Boolean, useContactName: Boolean,
@@ -470,16 +470,25 @@ fun extractActionText(
} }
} }
private fun extractAttachmentIcon( fun extractAttachmentIcon(
lastMessage: VkMessage? lastMessage: VkMessage?
): UiImage? = when { ): UiImage? = when {
lastMessage == null -> null lastMessage == null -> null
lastMessage.text == null -> null lastMessage.text == null -> null
lastMessage.geoType != null -> {
val geoType = lastMessage.geoType
if (geoType == "point") {
UiImage.Resource(R.drawable.ic_pin_drop_fill_round_24)
} else {
UiImage.Resource(R.drawable.ic_map_fill_round_24)
}
}
!lastMessage.forwards.isNullOrEmpty() -> { !lastMessage.forwards.isNullOrEmpty() -> {
if (lastMessage.forwards.orEmpty().size == 1) { if (lastMessage.forwards.orEmpty().size == 1) {
UiImage.Resource(R.drawable.ic_attachment_forwarded_message) UiImage.Resource(R.drawable.ic_reply_round_24)
} else { } else {
UiImage.Resource(R.drawable.ic_attachment_forwarded_messages) UiImage.Resource(R.drawable.ic_reply_all_round_24)
} }
} }
@@ -487,13 +496,9 @@ private fun extractAttachmentIcon(
lastMessage.attachments?.let { attachments -> lastMessage.attachments?.let { attachments ->
if (attachments.isEmpty()) return null if (attachments.isEmpty()) return null
if (attachments.size == 1 || isAttachmentsHaveOneType(attachments)) { if (attachments.size == 1 || isAttachmentsHaveOneType(attachments)) {
lastMessage.geoType?.let {
return UiImage.Resource(R.drawable.ic_map_marker)
}
getAttachmentIconByType(attachments.first().type) getAttachmentIconByType(attachments.first().type)
} else { } else {
UiImage.Resource(R.drawable.ic_baseline_attach_file_24) UiImage.Resource(R.drawable.ic_attach_file_round_24)
} }
} }
} }
@@ -565,22 +570,22 @@ fun extractAttachmentText(
private fun getAttachmentIconByType(attachmentType: AttachmentType): UiImage? { private fun getAttachmentIconByType(attachmentType: AttachmentType): UiImage? {
return when (attachmentType) { return when (attachmentType) {
AttachmentType.PHOTO -> R.drawable.ic_attachment_photo AttachmentType.PHOTO -> R.drawable.ic_image_fill_round_24
AttachmentType.VIDEO -> R.drawable.ic_attachment_video AttachmentType.VIDEO -> R.drawable.ic_video_fill_round_24
AttachmentType.AUDIO -> R.drawable.ic_attachment_audio AttachmentType.AUDIO -> R.drawable.ic_music_note_round_24
AttachmentType.FILE -> R.drawable.ic_attachment_file AttachmentType.FILE -> R.drawable.ic_draft_fill_round_24
AttachmentType.LINK -> R.drawable.ic_attachment_link AttachmentType.LINK -> R.drawable.ic_language_round_24
AttachmentType.AUDIO_MESSAGE -> R.drawable.ic_attachment_voice AttachmentType.AUDIO_MESSAGE -> R.drawable.ic_mic_fill_round_24
AttachmentType.MINI_APP -> R.drawable.ic_attachment_mini_app AttachmentType.MINI_APP -> R.drawable.ic_widgets_fill_round_24
AttachmentType.STICKER -> R.drawable.ic_attachment_sticker AttachmentType.STICKER -> R.drawable.ic_sticker_fill_round_24
AttachmentType.GIFT -> R.drawable.ic_attachment_gift AttachmentType.GIFT -> R.drawable.ic_attachment_gift_old
AttachmentType.WALL -> R.drawable.ic_attachment_wall AttachmentType.WALL -> R.drawable.ic_brick_fill_round_24
AttachmentType.GRAFFITI -> R.drawable.ic_attachment_graffiti AttachmentType.GRAFFITI -> R.drawable.ic_fragrance_fill_round_24
AttachmentType.POLL -> R.drawable.ic_attachment_poll AttachmentType.POLL -> R.drawable.ic_insert_chart_fill_round_24
AttachmentType.WALL_REPLY -> R.drawable.ic_attachment_wall_reply AttachmentType.WALL_REPLY -> R.drawable.ic_comment_fill_round_24
AttachmentType.CALL -> R.drawable.ic_attachment_call AttachmentType.CALL -> R.drawable.ic_call_round_24
AttachmentType.GROUP_CALL_IN_PROGRESS -> R.drawable.ic_attachment_group_call AttachmentType.GROUP_CALL_IN_PROGRESS -> R.drawable.ic_perm_phone_msg_fill_round_24
AttachmentType.STORY -> R.drawable.ic_attachment_story AttachmentType.STORY -> R.drawable.ic_history_toggle_off_round_24
AttachmentType.UNKNOWN -> null AttachmentType.UNKNOWN -> null
AttachmentType.CURATOR -> null AttachmentType.CURATOR -> null
AttachmentType.EVENT -> null AttachmentType.EVENT -> null
@@ -591,7 +596,7 @@ private fun getAttachmentIconByType(attachmentType: AttachmentType): UiImage? {
AttachmentType.NARRATIVE -> null AttachmentType.NARRATIVE -> null
AttachmentType.ARTICLE -> null AttachmentType.ARTICLE -> null
AttachmentType.VIDEO_MESSAGE -> null AttachmentType.VIDEO_MESSAGE -> null
AttachmentType.GROUP_CHAT_STICKER -> R.drawable.ic_attachment_sticker AttachmentType.GROUP_CHAT_STICKER -> R.drawable.ic_sticker_fill_round_24
AttachmentType.STICKER_PACK_PREVIEW -> null AttachmentType.STICKER_PACK_PREVIEW -> null
}?.let(UiImage::Resource) }?.let(UiImage::Resource)
} }
@@ -685,20 +690,6 @@ fun getAttachmentUiText(
}.let(UiText::Resource) }.let(UiText::Resource)
} }
fun getAttachmentConvoIcon(message: VkMessage?): UiImage? {
return message?.attachments?.let { attachments ->
if (attachments.isEmpty()) return null
if (attachments.size == 1 || isAttachmentsHaveOneType(attachments)) {
message.geoType?.let {
return UiImage.Resource(R.drawable.ic_map_marker)
}
getAttachmentIconByType(attachments.first().type)
} else {
UiImage.Resource(R.drawable.ic_baseline_attach_file_24)
}
}
}
fun extractBirthday(convo: VkConvo): Boolean { fun extractBirthday(convo: VkConvo): Boolean {
val birthday = convo.user?.birthday ?: return false val birthday = convo.user?.birthday ?: return false
val splitBirthday = birthday.split(".").mapNotNull(String::toIntOrNull) val splitBirthday = birthday.split(".").mapNotNull(String::toIntOrNull)
@@ -27,11 +27,13 @@ fun VkConvo.asPresentation(
monthShort = { resources.getString(R.string.month_short) }, monthShort = { resources.getString(R.string.month_short) },
weekShort = { resources.getString(R.string.week_short) }, weekShort = { resources.getString(R.string.week_short) },
dayShort = { resources.getString(R.string.day_short) }, dayShort = { resources.getString(R.string.day_short) },
minuteShort = { resources.getString(R.string.minute_short) },
secondShort = { resources.getString(R.string.second_short) },
now = { resources.getString(R.string.time_now) }, now = { resources.getString(R.string.time_now) },
), ),
message = extractMessage(resources, lastMessage, id, peerType), message = extractMessage(resources, lastMessage, id, peerType),
attachmentImage = if (lastMessage?.text == null) null attachmentImage = if (lastMessage?.text == null) null
else getAttachmentConvoIcon(lastMessage), else extractAttachmentIcon(lastMessage),
isPinned = majorId > 0, isPinned = majorId > 0,
actionImageId = ActionState.parse(isPhantom, isCallInProgress).getResourceId(), actionImageId = ActionState.parse(isPhantom, isCallInProgress).getResourceId(),
isBirthday = extractBirthday(this), isBirthday = extractBirthday(this),
@@ -27,7 +27,7 @@ fun VkMessage.extractAvatar() = when {
} }
else -> null else -> null
}?.let(UiImage::Url) ?: UiImage.Resource(R.drawable.ic_account_circle_cut) }?.let(UiImage::Url) ?: UiImage.Resource(R.drawable.ic_account_circle_fill_round_24)
fun VkMessage.extractDate(): String = fun VkMessage.extractDate(): String =
SimpleDateFormat("HH:mm", Locale.getDefault()).format(date * 1000L) SimpleDateFormat("HH:mm", Locale.getDefault()).format(date * 1000L)
+2 -2
View File
@@ -4,7 +4,7 @@ plugins {
} }
android { android {
namespace = "dev.meloda.fast.datastore" namespace = "dev.meloda.fast.model"
} }
dependencies { dependencies {
@@ -12,7 +12,7 @@ dependencies {
ksp(libs.moshi.kotlin.codegen) ksp(libs.moshi.kotlin.codegen)
implementation(platform(libs.compose.bom)) implementation(platform(libs.compose.bom))
implementation(libs.bundles.compose) implementation(libs.compose.ui)
implementation(libs.room.ktx) implementation(libs.room.ktx)
implementation(libs.room.runtime) implementation(libs.room.runtime)
@@ -1,7 +1,9 @@
package dev.meloda.fast.model.api.domain package dev.meloda.fast.model.api.domain
import androidx.compose.runtime.Immutable
import dev.meloda.fast.model.api.data.AttachmentType import dev.meloda.fast.model.api.data.AttachmentType
@Immutable
interface VkAttachment { interface VkAttachment {
val type: AttachmentType val type: AttachmentType
} }
@@ -0,0 +1,48 @@
package dev.meloda.fast.ui.common
import androidx.compose.ui.tooling.preview.AndroidUiModes.UI_MODE_NIGHT_YES
import androidx.compose.ui.tooling.preview.AndroidUiModes.UI_MODE_TYPE_NORMAL
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.Wallpapers.BLUE_DOMINATED_EXAMPLE
import androidx.compose.ui.tooling.preview.Wallpapers.GREEN_DOMINATED_EXAMPLE
import androidx.compose.ui.tooling.preview.Wallpapers.RED_DOMINATED_EXAMPLE
import androidx.compose.ui.tooling.preview.Wallpapers.YELLOW_DOMINATED_EXAMPLE
@Preview(name = "70%", fontScale = 0.70f)
@Preview(name = "85%", fontScale = 0.85f)
@Preview(name = "100%", fontScale = 1.0f)
@Preview(name = "115%", fontScale = 1.15f)
@Preview(name = "130%", fontScale = 1.3f)
@Preview(name = "150%", fontScale = 1.5f)
@Preview(name = "180%", fontScale = 1.8f)
@Preview(name = "200%", fontScale = 2f)
@Preview(name = "Light")
@Preview(name = "Red", wallpaper = RED_DOMINATED_EXAMPLE)
@Preview(name = "Blue", wallpaper = BLUE_DOMINATED_EXAMPLE)
@Preview(name = "Green", wallpaper = GREEN_DOMINATED_EXAMPLE)
@Preview(name = "Yellow", wallpaper = YELLOW_DOMINATED_EXAMPLE)
@Preview(name = "Dark", uiMode = UI_MODE_NIGHT_YES or UI_MODE_TYPE_NORMAL)
@Preview(
name = "Dark Red",
uiMode = UI_MODE_NIGHT_YES or UI_MODE_TYPE_NORMAL,
wallpaper = RED_DOMINATED_EXAMPLE
)
@Preview(
name = "Dark Blue",
uiMode = UI_MODE_NIGHT_YES or UI_MODE_TYPE_NORMAL,
wallpaper = BLUE_DOMINATED_EXAMPLE
)
@Preview(
name = "Dark Green",
uiMode = UI_MODE_NIGHT_YES or UI_MODE_TYPE_NORMAL,
wallpaper = GREEN_DOMINATED_EXAMPLE
)
@Preview(
name = "Dark Yellow",
uiMode = UI_MODE_NIGHT_YES or UI_MODE_TYPE_NORMAL,
wallpaper = YELLOW_DOMINATED_EXAMPLE
)
annotation class FastPreview
@@ -25,7 +25,7 @@ import dev.meloda.fast.ui.R
@Composable @Composable
fun ErrorView( fun ErrorView(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
iconResId: Int? = R.drawable.round_error_24, iconResId: Int? = R.drawable.ic_error_fill_round_24,
text: String, text: String,
buttonText: String? = null, buttonText: String? = null,
onButtonClick: (() -> Unit)? = null, onButtonClick: (() -> Unit)? = null,
@@ -2,6 +2,8 @@ package dev.meloda.fast.ui.components
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@@ -9,19 +11,27 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialogDefaults import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Checkbox import androidx.compose.material3.Checkbox
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.RadioButton import androidx.compose.material3.RadioButton
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.material3.TextField
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@@ -30,9 +40,22 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.onPlaced import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewDynamicColors
import androidx.compose.ui.tooling.preview.PreviewFontScale
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewScreenSizes
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import dev.meloda.fast.ui.R
import dev.meloda.fast.ui.common.FastPreview
import dev.meloda.fast.ui.theme.AppTheme
import dev.meloda.fast.ui.util.ImmutableList import dev.meloda.fast.ui.util.ImmutableList
import dev.meloda.fast.ui.util.ImmutableList.Companion.toImmutableList import dev.meloda.fast.ui.util.ImmutableList.Companion.toImmutableList
@@ -41,23 +64,31 @@ import dev.meloda.fast.ui.util.ImmutableList.Companion.toImmutableList
fun MaterialDialog( fun MaterialDialog(
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
confirmText: String? = null, icon: ImageVector? = null,
confirmAction: (() -> Unit)? = null, iconTint: Color = MaterialTheme.colorScheme.primary,
cancelText: String? = null,
cancelAction: (() -> Unit)? = null,
neutralText: String? = null,
neutralAction: (() -> Unit)? = null,
title: String? = null, title: String? = null,
text: String? = null, text: String? = null,
selectionType: SelectionType = SelectionType.None, selectionType: SelectionType = SelectionType.None,
items: ImmutableList<String> = ImmutableList.empty(), items: ImmutableList<String> = ImmutableList.empty(),
preSelectedItems: ImmutableList<Int> = ImmutableList.empty(), preSelectedItems: ImmutableList<Int> = ImmutableList.empty(),
onItemClick: ((index: Int) -> Unit)? = null, onItemClick: ((index: Int) -> Unit)? = null,
confirmText: String? = null,
confirmAction: (() -> Unit)? = null,
confirmContainerColor: Color = MaterialTheme.colorScheme.primary,
confirmContentColor: Color = MaterialTheme.colorScheme.contentColorFor(confirmContainerColor),
cancelText: String? = null,
cancelAction: (() -> Unit)? = null,
cancelContainerColor: Color = Color.Transparent,
cancelContentColor: Color = MaterialTheme.colorScheme.contentColorFor(cancelContainerColor),
neutralText: String? = null,
neutralAction: (() -> Unit)? = null,
neutralContainerColor: Color = Color.Transparent,
neutralContentColor: Color = MaterialTheme.colorScheme.contentColorFor(neutralContainerColor),
properties: DialogProperties = DialogProperties(), properties: DialogProperties = DialogProperties(),
actionInvokeDismiss: ActionInvokeDismiss = ActionInvokeDismiss.IfNoAction, actionInvokeDismiss: ActionInvokeDismiss = ActionInvokeDismiss.IfNoAction,
customContent: (@Composable ColumnScope.() -> Unit)? = null customContent: (@Composable ColumnScope.() -> Unit)? = null
) { ) {
var alertItems by remember { var alertItems by remember(items, preSelectedItems) {
mutableStateOf( mutableStateOf(
items.mapIndexed { index, title -> items.mapIndexed { index, title ->
DialogItem( DialogItem(
@@ -77,6 +108,13 @@ fun MaterialDialog(
val scrollState = rememberScrollState() val scrollState = rememberScrollState()
val canScrollBackward by remember { derivedStateOf { scrollState.value > 0 } } val canScrollBackward by remember { derivedStateOf { scrollState.value > 0 } }
val canScrollForward by remember { derivedStateOf { scrollState.value < scrollState.maxValue } } val canScrollForward by remember { derivedStateOf { scrollState.value < scrollState.maxValue } }
val shouldAddVerticalPadding = remember(
icon, title, text, items,
confirmText, cancelText, neutralText
) {
icon != null || title != null || text != null || items.isNotEmpty() ||
confirmText != null || cancelText != null || neutralText != null
}
Surface( Surface(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@@ -84,19 +122,33 @@ fun MaterialDialog(
shape = AlertDialogDefaults.shape, shape = AlertDialogDefaults.shape,
tonalElevation = AlertDialogDefaults.TonalElevation tonalElevation = AlertDialogDefaults.TonalElevation
) { ) {
Column(modifier = Modifier.padding(bottom = 10.dp)) { Column(
if (title != null) { horizontalAlignment = Alignment.CenterHorizontally
Spacer(modifier = Modifier.height(20.dp)) ) {
if (shouldAddVerticalPadding) {
Spacer(modifier = Modifier.height(24.dp))
}
Row { if (icon != null) {
Spacer(modifier = Modifier.width(24.dp)) Icon(
Text( imageVector = icon,
modifier = Modifier.weight(1f), contentDescription = null,
text = title, tint = iconTint,
style = MaterialTheme.typography.headlineSmall modifier = Modifier.size(30.dp)
) )
Spacer(modifier = Modifier.width(20.dp)) Spacer(modifier = Modifier.height(16.dp))
} }
if (title != null) {
Text(
modifier = Modifier
.padding(horizontal = 24.dp)
.fillMaxWidth(),
text = title,
style = MaterialTheme.typography.headlineSmall,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(4.dp))
} }
AnimatedVisibility(isPlaced && canScrollBackward) { AnimatedVisibility(isPlaced && canScrollBackward) {
@@ -110,25 +162,22 @@ fun MaterialDialog(
.verticalScroll(scrollState) .verticalScroll(scrollState)
.onPlaced { isPlaced = true } .onPlaced { isPlaced = true }
) { ) {
if (text != null && title == null) {
Spacer(modifier = Modifier.height(20.dp))
}
if (text != null) { if (text != null) {
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(10.dp))
Row { Row(modifier = Modifier.padding(horizontal = 24.dp)) {
Spacer(modifier = Modifier.width(24.dp))
Text( Text(
modifier = Modifier.weight(1f), modifier = Modifier.fillMaxWidth(),
text = text, text = text,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center
) )
Spacer(modifier = Modifier.width(20.dp))
} }
} }
Spacer(modifier = Modifier.height(8.dp)) if (text != null || title != null) {
Spacer(modifier = Modifier.height(8.dp))
}
if (alertItems.isNotEmpty()) { if (alertItems.isNotEmpty()) {
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
@@ -158,7 +207,7 @@ fun MaterialDialog(
alertItems = newItems.toImmutableList() alertItems = newItems.toImmutableList()
} }
) )
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(4.dp))
} else { } else {
customContent?.invoke(this) customContent?.invoke(this)
} }
@@ -168,67 +217,77 @@ fun MaterialDialog(
HorizontalDivider() HorizontalDivider()
} }
Row { if (confirmText != null || cancelText != null || neutralText != null) {
Spacer(modifier = Modifier.width(20.dp)) Column(
if (neutralText != null) { modifier = Modifier
TextButton( .padding(horizontal = 24.dp)
onClick = { .padding(top = 10.dp),
neutralAction?.invoke() ?: kotlin.run { verticalArrangement = Arrangement.spacedBy(4.dp)
if (actionInvokeDismiss == ActionInvokeDismiss.IfNoAction) { ) {
if (confirmText != null) {
Button(
modifier = Modifier.fillMaxWidth(),
onClick = {
val hadAction = confirmAction != null
confirmAction?.invoke()
if (actionInvokeDismiss == ActionInvokeDismiss.Always || (actionInvokeDismiss == ActionInvokeDismiss.IfNoAction && !hadAction)) {
onDismissRequest() onDismissRequest()
} }
} },
colors = ButtonDefaults.buttonColors(
if (actionInvokeDismiss == ActionInvokeDismiss.Always) { containerColor = confirmContainerColor,
onDismissRequest() contentColor = confirmContentColor
} )
) {
Text(text = confirmText)
} }
) {
Text(text = neutralText)
} }
}
Spacer(modifier = Modifier.weight(1f)) if (cancelText != null) {
OutlinedButton(
modifier = Modifier.fillMaxWidth(),
onClick = {
val hadAction = cancelAction != null
cancelAction?.invoke()
if (cancelText != null) { if (actionInvokeDismiss == ActionInvokeDismiss.Always || (actionInvokeDismiss == ActionInvokeDismiss.IfNoAction && !hadAction)) {
TextButton(
onClick = {
cancelAction?.invoke() ?: kotlin.run {
if (actionInvokeDismiss == ActionInvokeDismiss.IfNoAction) {
onDismissRequest() onDismissRequest()
} }
} },
colors = ButtonDefaults.outlinedButtonColors(
if (actionInvokeDismiss == ActionInvokeDismiss.Always) { containerColor = cancelContainerColor,
onDismissRequest() contentColor = cancelContentColor
} )
) {
Text(text = cancelText)
} }
) {
Text(text = cancelText)
} }
}
Spacer(modifier = Modifier.width(2.dp)) if (neutralText != null) {
TextButton(
modifier = Modifier.fillMaxWidth(),
onClick = {
val hadAction = neutralAction != null
neutralAction?.invoke()
if (confirmText != null) { if (actionInvokeDismiss == ActionInvokeDismiss.Always || (actionInvokeDismiss == ActionInvokeDismiss.IfNoAction && !hadAction)) {
TextButton(
onClick = {
confirmAction?.invoke() ?: kotlin.run {
if (actionInvokeDismiss == ActionInvokeDismiss.IfNoAction) {
onDismissRequest() onDismissRequest()
} }
} },
colors = ButtonDefaults.textButtonColors(
if (actionInvokeDismiss == ActionInvokeDismiss.Always) { containerColor = neutralContainerColor,
onDismissRequest() contentColor = neutralContentColor
} )
) {
Text(text = neutralText)
} }
) {
Text(text = confirmText)
} }
} }
}
Spacer(modifier = Modifier.width(20.dp)) if (shouldAddVerticalPadding) {
Spacer(modifier = Modifier.height(24.dp))
} }
} }
} }
@@ -253,41 +312,40 @@ fun AlertItems(
} else { } else {
onItemClick?.invoke(index) onItemClick?.invoke(index)
} }
}, }
.padding(horizontal = 10.dp),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
when (selectionType) { when (selectionType) {
SelectionType.Multi -> { SelectionType.Multi -> {
Spacer(modifier = Modifier.width(10.dp))
Checkbox( Checkbox(
checked = item.isSelected, checked = item.isSelected,
onCheckedChange = { onCheckedChange = {
onItemCheckedChanged?.invoke(index) onItemCheckedChanged?.invoke(index)
} }
) )
Spacer(modifier = Modifier.width(16.dp))
} }
SelectionType.Single -> { SelectionType.Single -> {
Spacer(modifier = Modifier.width(10.dp))
RadioButton( RadioButton(
selected = item.isSelected, selected = item.isSelected,
onClick = { onClick = {
onItemClick?.invoke(index) onItemClick?.invoke(index)
} }
) )
Spacer(modifier = Modifier.width(16.dp))
} }
SelectionType.None -> { SelectionType.None -> {
Spacer(modifier = Modifier.width(26.dp)) Spacer(modifier = Modifier.width(16.dp))
} }
} }
Spacer(modifier = Modifier.width(4.dp))
Text( Text(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
text = item.title, text = item.title,
style = MaterialTheme.typography.bodyLarge style = MaterialTheme.typography.bodyLarge
) )
Spacer(modifier = Modifier.width(20.dp))
} }
} }
} }
@@ -308,3 +366,93 @@ sealed class SelectionType {
data object Multi : SelectionType() data object Multi : SelectionType()
data object None : SelectionType() data object None : SelectionType()
} }
@FastPreview
@Composable
private fun MaterialDialogPreview() {
AppTheme(useDarkTheme = isSystemInDarkTheme(), useDynamicColors = true) {
MaterialDialog(
onDismissRequest = {},
title = "Material Dialog",
text = "This is a preview of a Material dialog.",
confirmText = "Confirm",
cancelText = "Cancel",
icon = ImageVector.vectorResource(R.drawable.ic_info_round_24)
)
}
}
@FastPreview
@Composable
private fun MaterialDialogWithListPreview() {
AppTheme(useDarkTheme = isSystemInDarkTheme(), useDynamicColors = true) {
MaterialDialog(
onDismissRequest = {},
title = "Material Dialog",
text = "This is a preview of a Material dialog.",
confirmText = "Confirm",
cancelText = "Cancel",
items = listOf("Item 1", "Item 2", "Item 3").toImmutableList(),
selectionType = SelectionType.Single,
icon = ImageVector.vectorResource(R.drawable.ic_info_round_24)
)
}
}
@FastPreview
@Composable
private fun MaterialDialogWithCustomContent() {
AppTheme(useDarkTheme = isSystemInDarkTheme(), useDynamicColors = true) {
MaterialDialog(
onDismissRequest = {},
title = "Material Dialog",
confirmText = "Confirm",
cancelText = "Cancel",
icon = ImageVector.vectorResource(R.drawable.ic_info_round_24)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp)
) {
TextField(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(10.dp))
.weight(1f),
value = "",
onValueChange = {},
label = { Text(text = "Text") },
placeholder = { Text(text = "Text") },
shape = RoundedCornerShape(10.dp),
)
}
}
}
}
@FastPreview
@Composable
private fun MaterialDialogWithOnlyCustomContent() {
AppTheme(useDarkTheme = isSystemInDarkTheme(), useDynamicColors = true) {
MaterialDialog(onDismissRequest = {}) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp)
) {
TextField(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(10.dp))
.weight(1f),
value = "",
onValueChange = {},
label = { Text(text = "Text") },
placeholder = { Text(text = "Text") },
shape = RoundedCornerShape(10.dp),
)
}
}
}
}
@@ -1,5 +1,6 @@
package dev.meloda.fast.ui.components package dev.meloda.fast.ui.components
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
@@ -8,15 +9,17 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import dev.meloda.fast.ui.R import dev.meloda.fast.ui.R
import dev.meloda.fast.ui.common.FastPreview
import dev.meloda.fast.ui.theme.AppTheme
@Composable @Composable
fun NoItemsView( fun NoItemsView(
@@ -49,11 +52,15 @@ fun NoItemsView(
} }
} }
@Preview @FastPreview
@Composable @Composable
private fun NoItemsViewPreview() { private fun NoItemsViewPreview() {
NoItemsView( AppTheme(useDarkTheme = isSystemInDarkTheme(), useDynamicColors = true) {
customText = "Nothing here...", Surface {
buttonText = "Refresh" NoItemsView(
) customText = "Nothing here...",
buttonText = "Refresh"
)
}
}
} }
@@ -2,8 +2,14 @@ package dev.meloda.fast.ui.extensions
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.ui.Modifier
@Composable @Composable
fun <T> ProvidableCompositionLocal<T?>.getOrThrow(): T { fun <T> ProvidableCompositionLocal<T?>.getOrThrow(): T {
return requireNotNull(current) return requireNotNull(current)
} }
inline fun Modifier.ifTrue(
condition: Boolean,
block: Modifier.() -> Modifier
): Modifier = if (condition) block() else this
@@ -9,6 +9,7 @@ import org.koin.androidx.compose.koinViewModel
import org.koin.core.parameter.ParametersDefinition import org.koin.core.parameter.ParametersDefinition
import org.koin.core.qualifier.Qualifier import org.koin.core.qualifier.Qualifier
@Suppress("ParamsComparedByRef")
@Composable @Composable
inline fun <reified T : ViewModel> NavBackStackEntry.sharedViewModel( inline fun <reified T : ViewModel> NavBackStackEntry.sharedViewModel(
navController: NavController, navController: NavController,
@@ -11,31 +11,31 @@ sealed class ConvoOption(
data object MarkAsRead : ConvoOption( data object MarkAsRead : ConvoOption(
title = UiText.Resource(R.string.action_mark_as_read), title = UiText.Resource(R.string.action_mark_as_read),
icon = UiImage.Resource(R.drawable.round_done_all_24) icon = UiImage.Resource(R.drawable.ic_done_all_round_24)
) )
data object Pin : ConvoOption( data object Pin : ConvoOption(
title = UiText.Resource(R.string.action_pin), title = UiText.Resource(R.string.action_pin),
icon = UiImage.Resource(R.drawable.pin_outline_24) icon = UiImage.Resource(R.drawable.ic_keep_round_24)
) )
data object Unpin : ConvoOption( data object Unpin : ConvoOption(
title = UiText.Resource(R.string.action_unpin), title = UiText.Resource(R.string.action_unpin),
icon = UiImage.Resource(R.drawable.pin_off_outline_24) icon = UiImage.Resource(R.drawable.ic_keep_off_round_24)
) )
data object Delete : ConvoOption( data object Delete : ConvoOption(
title = UiText.Resource(R.string.action_delete), title = UiText.Resource(R.string.action_delete),
icon = UiImage.Resource(R.drawable.round_delete_outline_24) icon = UiImage.Resource(R.drawable.ic_delete_round_24)
) )
data object Archive : ConvoOption( data object Archive : ConvoOption(
title = UiText.Resource(R.string.convo_context_action_archive), title = UiText.Resource(R.string.convo_context_action_archive),
icon = UiImage.Resource(R.drawable.outline_archive_24) icon = UiImage.Resource(R.drawable.ic_archive_round_24)
) )
data object Unarchive : ConvoOption( data object Unarchive : ConvoOption(
title = UiText.Resource(R.string.convo_context_action_unarchive), title = UiText.Resource(R.string.convo_context_action_unarchive),
icon = UiImage.Resource(R.drawable.outline_unarchive_24) icon = UiImage.Resource(R.drawable.ic_unarchive_round_24)
) )
} }
@@ -9,10 +9,6 @@ class ImmutableList<T>(val values: List<T>) : Collection<T> {
operator fun get(index: Int): T = values[index] operator fun get(index: Int): T = values[index]
inline fun forEach(action: (T) -> Unit) {
for (element in values) action(element)
}
inline fun <R> map(transform: (T) -> R): ImmutableList<R> { inline fun <R> map(transform: (T) -> R): ImmutableList<R> {
return values.map(transform).toImmutableList() return values.map(transform).toImmutableList()
} }
@@ -49,13 +45,15 @@ class ImmutableList<T>(val values: List<T>) : Collection<T> {
if (elements.isNotEmpty()) copyOf(elements.asList()) else empty() if (elements.isNotEmpty()) copyOf(elements.asList()) else empty()
fun <T> of(element: T) = ImmutableList(listOf(element)) fun <T> of(element: T) = ImmutableList(listOf(element))
fun <T> ImmutableList<T>?.orEmpty(): ImmutableList<T> = this ?: emptyImmutableList()
} }
override fun iterator(): Iterator<T> = values.listIterator() override fun iterator(): Iterator<T> = values.listIterator()
val lastIndex: Int get() = this.size - 1
} }
fun <T> emptyImmutableList(): ImmutableList<T> = ImmutableList(emptyList()) fun <T> emptyImmutableList(): ImmutableList<T> = ImmutableList(emptyList())
fun <T> immutableListOf(vararg elements: T) = ImmutableList(listOf(elements = elements)) fun <T> immutableListOf(vararg elements: T) = ImmutableList(listOf(elements = elements))
fun <T> ImmutableList<T>?.orEmpty(): ImmutableList<T> = this ?: emptyImmutableList()
@@ -1,11 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,6c1.93,0 3.5,1.57 3.5,3.5S13.93,13 12,13s-3.5,-1.57 -3.5,-3.5S10.07,6 12,6zM12,20c-2.03,0 -4.43,-0.82 -6.14,-2.88C7.55,15.8 9.68,15 12,15s4.45,0.8 6.14,2.12C16.43,19.18 14.03,20 12,20z" />
</vector>
@@ -1,12 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM6,9h12v2L6,11L6,9zM14,14L6,14v-2h8v2zM18,8L6,8L6,6h12v2z" />
</vector>
@@ -1,27 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:fillType="evenOdd"
android:pathData="M16.67,13.13C18.04,14.06 19,15.32 19,17v3h4v-3C23,14.82 19.43,13.53 16.67,13.13z" />
<path
android:fillColor="#ffffff"
android:fillType="evenOdd"
android:pathData="M9,8m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0" />
<path
android:fillColor="#ffffff"
android:fillType="evenOdd"
android:pathData="M15,12c2.21,0 4,-1.79 4,-4c0,-2.21 -1.79,-4 -4,-4c-0.47,0 -0.91,0.1 -1.33,0.24C14.5,5.27 15,6.58 15,8s-0.5,2.73 -1.33,3.76C14.09,11.9 14.53,12 15,12z" />
<path
android:fillColor="#ffffff"
android:fillType="evenOdd"
android:pathData="M9,13c-2.67,0 -8,1.34 -8,4v3h16v-3C17,14.34 11.67,13 9,13z" />
</vector>
@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="48"
android:viewportHeight="48">
<path
android:fillColor="#ffffff"
android:fillType="evenOdd"
android:pathData="M24,0C10.7452,0 0,10.7452 0,24C0,37.2548 10.7452,48 24,48C37.2548,48 48,37.2548 48,24C48,10.7452 37.2548,0 24,0ZM32.25,13.8152C32.25,9.4191 28.7383,6 24.5,6C20.2617,6 16.75,9.4191 16.75,13.8152C16.75,18.0891 20.2617,21.6304 24.5,21.6304C28.7383,21.6304 32.25,18.0891 32.25,13.8152ZM9,34.5743C12.3906,39.5809 18.082,43 24.5,43C30.918,43 36.6094,39.5809 40,34.5743C39.8789,29.3234 29.5859,26.5149 24.5,26.5149C19.293,26.5149 9.1211,29.3234 9,34.5743Z" />
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M234,684Q285,645 348,622.5Q411,600 480,600Q549,600 612,622.5Q675,645 726,684Q761,643 780.5,591Q800,539 800,480Q800,347 706.5,253.5Q613,160 480,160Q347,160 253.5,253.5Q160,347 160,480Q160,539 179.5,591Q199,643 234,684ZM480,520Q421,520 380.5,479.5Q340,439 340,380Q340,321 380.5,280.5Q421,240 480,240Q539,240 579.5,280.5Q620,321 620,380Q620,439 579.5,479.5Q539,520 480,520ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880Z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="#ffffff"
android:pathData="M234,684Q285,645 348,622.5Q411,600 480,600Q549,600 612,622.5Q675,645 726,684Q761,643 780.5,591Q800,539 800,480Q800,347 706.5,253.5Q613,160 480,160Q347,160 253.5,253.5Q160,347 160,480Q160,539 179.5,591Q199,643 234,684ZM480,520Q421,520 380.5,479.5Q340,439 340,380Q340,321 380.5,280.5Q421,240 480,240Q539,240 579.5,280.5Q620,321 620,380Q620,439 579.5,479.5Q539,520 480,520ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM480,800Q533,800 580,784.5Q627,769 666,740Q627,711 580,695.5Q533,680 480,680Q427,680 380,695.5Q333,711 294,740Q333,769 380,784.5Q427,800 480,800ZM480,440Q506,440 523,423Q540,406 540,380Q540,354 523,337Q506,320 480,320Q454,320 437,337Q420,354 420,380Q420,406 437,423Q454,440 480,440ZM480,380Q480,380 480,380Q480,380 480,380Q480,380 480,380Q480,380 480,380Q480,380 480,380Q480,380 480,380Q480,380 480,380Q480,380 480,380ZM480,740Q480,740 480,740Q480,740 480,740Q480,740 480,740Q480,740 480,740Q480,740 480,740Q480,740 480,740Q480,740 480,740Q480,740 480,740Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M200,840Q167,840 143.5,816.5Q120,793 120,760L120,261Q120,247 124.5,234Q129,221 138,210L188,149Q199,135 215.5,127.5Q232,120 250,120L710,120Q728,120 744.5,127.5Q761,135 772,149L822,210Q831,221 835.5,234Q840,247 840,261L840,760Q840,793 816.5,816.5Q793,840 760,840L200,840ZM216,240L744,240L710,200Q710,200 710,200Q710,200 710,200L250,200Q250,200 250,200Q250,200 250,200L216,240ZM480,400Q463,400 451.5,411.5Q440,423 440,440L440,568L404,532Q393,521 376,521Q359,521 348,532Q337,543 337,560Q337,577 348,588L452,692Q464,704 480,704Q496,704 508,692L612,588Q623,577 623,560Q623,543 612,532Q601,521 584,521Q567,521 556,532L520,568L520,440Q520,423 508.5,411.5Q497,400 480,400Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M480,400Q463,400 451.5,411.5Q440,423 440,440L440,568L404,532Q393,521 376,521Q359,521 348,532Q337,543 337,560Q337,577 348,588L452,692Q464,704 480,704Q496,704 508,692L612,588Q623,577 623,560Q623,543 612,532Q601,521 584,521Q567,521 556,532L520,568L520,440Q520,423 508.5,411.5Q497,400 480,400ZM200,320L200,760Q200,760 200,760Q200,760 200,760L760,760Q760,760 760,760Q760,760 760,760L760,320L200,320ZM200,840Q167,840 143.5,816.5Q120,793 120,760L120,261Q120,247 124.5,234Q129,221 138,210L188,149Q199,135 215.5,127.5Q232,120 250,120L710,120Q728,120 744.5,127.5Q761,135 772,149L822,210Q831,221 835.5,234Q840,247 840,261L840,760Q840,793 816.5,816.5Q793,840 760,840L200,840ZM216,240L744,240L710,200Q710,200 710,200Q710,200 710,200L250,200Q250,200 250,200Q250,200 250,200L216,240ZM480,540L480,540L480,540Q480,540 480,540Q480,540 480,540L480,540Q480,540 480,540Q480,540 480,540Z"/>
</vector>
@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:autoMirrored="true"
android:viewportWidth="960" android:viewportWidth="960"
android:viewportHeight="960"> android:viewportHeight="960"
android:autoMirrored="true">
<path <path
android:fillColor="#ffffff" android:fillColor="#ffffff"
android:pathData="M313,520L509,716Q521,728 520.5,744Q520,760 508,772Q496,783 480,783.5Q464,784 452,772L188,508Q182,502 179.5,495Q177,488 177,480Q177,472 179.5,465Q182,458 188,452L452,188Q463,177 479.5,177Q496,177 508,188Q520,200 520,216.5Q520,233 508,245L313,440L760,440Q777,440 788.5,451.5Q800,463 800,480Q800,497 788.5,508.5Q777,520 760,520L313,520Z" /> android:pathData="M313,520L509,716Q521,728 520.5,744Q520,760 508,772Q496,783 480,783.5Q464,784 452,772L188,508Q182,502 179.5,495Q177,488 177,480Q177,472 179.5,465Q182,458 188,452L452,188Q463,177 479.5,177Q496,177 508,188Q520,200 520,216.5Q520,233 508,245L313,440L760,440Q777,440 788.5,451.5Q800,463 800,480Q800,497 788.5,508.5Q777,520 760,520L313,520Z"/>
</vector> </vector>
@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M5,13L16.17,13l-4.88,4.88a1.008,1.008 0,0 0,-0 1.42,1 1,0 0,0 1.41,-0L19.29,12.71a1,1 0,0 0,-0 -1.41l-6.59,-6.59a1,1 0,0 0,-1.41 1.41L16.17,11L5,11a1,1 0,0 0,-0 2Z"
android:fillColor="#ffffff"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:autoMirrored="true">
<path
android:fillColor="#ffffff"
android:pathData="M647,520L200,520Q183,520 171.5,508.5Q160,497 160,480Q160,463 171.5,451.5Q183,440 200,440L647,440L451,244Q439,232 439.5,216Q440,200 452,188Q464,177 480,176.5Q496,176 508,188L772,452Q778,458 780.5,465Q783,472 783,480Q783,488 780.5,495Q778,502 772,508L508,772Q497,783 480.5,783Q464,783 452,772Q440,760 440,743.5Q440,727 452,715L647,520Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M720,630Q720,734 647,807Q574,880 470,880Q366,880 293,807Q220,734 220,630L220,260Q220,185 272.5,132.5Q325,80 400,80Q475,80 527.5,132.5Q580,185 580,260L580,610Q580,656 548,688Q516,720 470,720Q424,720 392,688Q360,656 360,610L360,280Q360,263 371.5,251.5Q383,240 400,240Q417,240 428.5,251.5Q440,263 440,280L440,610Q440,623 448.5,631.5Q457,640 470,640Q483,640 491.5,631.5Q500,623 500,610L500,260Q499,218 470.5,189Q442,160 400,160Q358,160 329,189Q300,218 300,260L300,630Q299,701 349,750.5Q399,800 470,800Q540,800 589,750.5Q638,701 640,630L640,280Q640,263 651.5,251.5Q663,240 680,240Q697,240 708.5,251.5Q720,263 720,280L720,630Z"/>
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M12 3V13.55C11.41 13.21 10.73 13 10 13C7.79 13 6 14.79 6 17S7.79 21 10 21 14 19.21 14 17V7H18V3H12Z" />
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M6.62,10.79C8.06,13.62 10.38,15.94 13.21,17.38L15.41,15.18C15.69,14.9 16.08,14.82 16.43,14.93C17.55,15.3 18.75,15.5 20,15.5A1,1 0 0,1 21,16.5V20A1,1 0 0,1 20,21A17,17 0 0,1 3,4A1,1 0 0,1 4,3H7.5A1,1 0 0,1 8.5,4C8.5,5.25 8.7,6.45 9.07,7.57C9.18,7.92 9.1,8.31 8.82,8.59L6.62,10.79Z" />
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M13,9V3.5L18.5,9M6,2C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6Z" />
</vector>
@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M10,9V5l-7,7 7,7v-4.1c5,0 8.5,1.6 11,5.1 -1,-5 -4,-10 -11,-11z" />
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M13,9V5L6,12L13,19V14.9C18,14.9 21.5,16.5 24,20C23,15 20,10 13,9M7,8V5L0,12L7,19V16L3,12L7,8Z" />
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M10,4H12V6H10V4M7,3H9V5H7V3M7,6H9V8H7V6M6,8V10H4V8H6M6,5V7H4V5H6M6,2V4H4V2H6M13,22A2,2 0 0,1 11,20V10A2,2 0 0,1 13,8V7H14V4H17V7H18V8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H13M13,10V20H18V10H13Z" />
</vector>
@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M20 15.5C18.75 15.5 17.55 15.3 16.43 14.93C16.08 14.82 15.69 14.9 15.41 15.17L13.21 17.37C10.38 15.93 8.06 13.62 6.62 10.79L8.82 8.58C9.1 8.31 9.18 7.92 9.07 7.57C8.7 6.45 8.5 5.25 8.5 4C8.5 3.45 8.05 3 7.5 3H4C3.45 3 3 3.45 3 4C3 13.39 10.61 21 20 21C20.55 21 21 20.55 21 20V16.5C21 15.95 20.55 15.5 20 15.5M12 3V13L15 10H21V3H12Z" />
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M16.36,14C16.44,13.34 16.5,12.68 16.5,12C16.5,11.32 16.44,10.66 16.36,10H19.74C19.9,10.64 20,11.31 20,12C20,12.69 19.9,13.36 19.74,14M14.59,19.56C15.19,18.45 15.65,17.25 15.97,16H18.92C17.96,17.65 16.43,18.93 14.59,19.56M14.34,14H9.66C9.56,13.34 9.5,12.68 9.5,12C9.5,11.32 9.56,10.65 9.66,10H14.34C14.43,10.65 14.5,11.32 14.5,12C14.5,12.68 14.43,13.34 14.34,14M12,19.96C11.17,18.76 10.5,17.43 10.09,16H13.91C13.5,17.43 12.83,18.76 12,19.96M8,8H5.08C6.03,6.34 7.57,5.06 9.4,4.44C8.8,5.55 8.35,6.75 8,8M5.08,16H8C8.35,17.25 8.8,18.45 9.4,19.56C7.57,18.93 6.03,17.65 5.08,16M4.26,14C4.1,13.36 4,12.69 4,12C4,11.31 4.1,10.64 4.26,10H7.64C7.56,10.66 7.5,11.32 7.5,12C7.5,12.68 7.56,13.34 7.64,14M12,4.03C12.83,5.23 13.5,6.57 13.91,8H10.09C10.5,6.57 11.17,5.23 12,4.03M18.92,8H15.97C15.65,6.75 15.19,5.55 14.59,4.44C16.43,5.07 17.96,6.34 18.92,8M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" />
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M5,3H19A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21H5A2,2 0 0,1 3,19V5A2,2 0 0,1 5,3M7,7V9H9V7H7M11,7V9H13V7H11M15,7V9H17V7H15M7,11V13H9V11H7M11,11V13H13V11H11M15,11V13H17V11H15M7,15V17H9V15H7M11,15V17H13V15H11M15,15V17H17V15H15Z" />
</vector>
@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" />
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3M9 17H7V10H9V17M13 17H11V7H13V17M17 17H15V13H17V17Z" />
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M5.5,2C3.56,2 2,3.56 2,5.5V18.5C2,20.44 3.56,22 5.5,22H16L22,16V5.5C22,3.56 20.44,2 18.5,2H5.5M5.75,4H18.25A1.75,1.75 0 0,1 20,5.75V15H18.5C16.56,15 15,16.56 15,18.5V20H5.75A1.75,1.75 0 0,1 4,18.25V5.75A1.75,1.75 0 0,1 5.75,4M14.44,6.77C14.28,6.77 14.12,6.79 13.97,6.83C13.03,7.09 12.5,8.05 12.74,9C12.79,9.15 12.86,9.3 12.95,9.44L16.18,8.56C16.18,8.39 16.16,8.22 16.12,8.05C15.91,7.3 15.22,6.77 14.44,6.77M8.17,8.5C8,8.5 7.85,8.5 7.7,8.55C6.77,8.81 6.22,9.77 6.47,10.7C6.5,10.86 6.59,11 6.68,11.16L9.91,10.28C9.91,10.11 9.89,9.94 9.85,9.78C9.64,9 8.95,8.5 8.17,8.5M16.72,11.26L7.59,13.77C8.91,15.3 11,15.94 12.95,15.41C14.9,14.87 16.36,13.25 16.72,11.26Z" />
</vector>
@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M15.1,19.37l1,1.74c-0.96,0.44 -2.01,0.73 -3.1,0.84v-2.02C13.74,19.84 14.44,19.65 15.1,19.37zM4.07,13H2.05c0.11,1.1 0.4,2.14 0.84,3.1l1.74,-1C4.35,14.44 4.16,13.74 4.07,13zM15.1,4.63l1,-1.74C15.14,2.45 14.1,2.16 13,2.05v2.02C13.74,4.16 14.44,4.35 15.1,4.63zM19.93,11h2.02c-0.11,-1.1 -0.4,-2.14 -0.84,-3.1l-1.74,1C19.65,9.56 19.84,10.26 19.93,11zM8.9,19.37l-1,1.74c0.96,0.44 2.01,0.73 3.1,0.84v-2.02C10.26,19.84 9.56,19.65 8.9,19.37zM11,4.07V2.05c-1.1,0.11 -2.14,0.4 -3.1,0.84l1,1.74C9.56,4.35 10.26,4.16 11,4.07zM18.36,7.17l1.74,-1.01c-0.63,-0.87 -1.4,-1.64 -2.27,-2.27l-1.01,1.74C17.41,6.08 17.92,6.59 18.36,7.17zM4.63,8.9l-1.74,-1C2.45,8.86 2.16,9.9 2.05,11h2.02C4.16,10.26 4.35,9.56 4.63,8.9zM19.93,13c-0.09,0.74 -0.28,1.44 -0.56,2.1l1.74,1c0.44,-0.96 0.73,-2.01 0.84,-3.1H19.93zM16.83,18.36l1.01,1.74c0.87,-0.63 1.64,-1.4 2.27,-2.27l-1.74,-1.01C17.92,17.41 17.41,17.92 16.83,18.36zM7.17,5.64L6.17,3.89C5.29,4.53 4.53,5.29 3.9,6.17l1.74,1.01C6.08,6.59 6.59,6.08 7.17,5.64zM5.64,16.83L3.9,17.83c0.63,0.87 1.4,1.64 2.27,2.27l1.01,-1.74C6.59,17.92 6.08,17.41 5.64,16.83zM13,7h-2v5.41l4.29,4.29l1.41,-1.41L13,11.59V7z" />
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M19 3C20.1 3 21 3.9 21 5V19C21 20.1 20.1 21 19 21H5C3.9 21 3 20.1 3 19V5C3 3.9 3.9 3 5 3H19M7 18V16H5V18H7M7 13V11H5V13H7M7 8V6H5V8H7M19 18V16H17V18H19M19 13V11H17V13H19M19 8V6H17V8H19Z" />
</vector>
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#ffffff" android:pathData="M12,2A3,3 0 0,1 15,5V11A3,3 0 0,1 12,14A3,3 0 0,1 9,11V5A3,3 0 0,1 12,2M19,11C19,14.53 16.39,17.44 13,17.93V21H11V17.93C7.61,17.44 5,14.53 5,11H7A5,5 0 0,0 12,16A5,5 0 0,0 17,11H19Z" />
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M3,16H12V21H3V16M2,10H8V15H2V10M9,10H15V15H9V10M16,10H22V15H16V10M13,16H21V21H13V16M3,4H11V9H3V4M12,4H21V9H12V4Z" />
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M21.99,4c0,-1.1 -0.89,-2 -1.99,-2L4,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h14l4,4 -0.01,-18zM18,14L6,14v-2h12v2zM18,11L6,11L6,9h12v2zM18,8L6,8L6,6h12v2z" />
</vector>
@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M16.5,6v11.5c0,2.21 -1.79,4 -4,4s-4,-1.79 -4,-4V5c0,-1.38 1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5v10.5c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1V6H10v9.5c0,1.38 1.12,2.5 2.5,2.5s2.5,-1.12 2.5,-2.5V5c0,-2.21 -1.79,-4 -4,-4S7,2.79 7,5v12.5c0,3.04 2.46,5.5 5.5,5.5s5.5,-2.46 5.5,-5.5V6h-1.5z" />
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M480,720L312,792Q272,809 236,785.5Q200,762 200,719L200,200Q200,167 223.5,143.5Q247,120 280,120L680,120Q713,120 736.5,143.5Q760,167 760,200L760,719Q760,762 724,785.5Q688,809 648,792L480,720ZM480,632L680,718Q680,718 680,718Q680,718 680,718L680,200Q680,200 680,200Q680,200 680,200L280,200Q280,200 280,200Q280,200 280,200L280,718Q280,718 280,718Q280,718 280,718L480,632ZM480,200L280,200Q280,200 280,200Q280,200 280,200L280,200Q280,200 280,200Q280,200 280,200L680,200Q680,200 680,200Q680,200 680,200L680,200Q680,200 680,200Q680,200 680,200L480,200Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M80,740L80,380Q80,355 97.5,337.5Q115,320 140,320L200,320L200,220Q200,195 217.5,177.5Q235,160 260,160L380,160Q405,160 422.5,177.5Q440,195 440,220L440,320L520,320L520,220Q520,195 537.5,177.5Q555,160 580,160L700,160Q725,160 742.5,177.5Q760,195 760,220L760,320L820,320Q845,320 862.5,337.5Q880,355 880,380L880,740Q880,765 862.5,782.5Q845,800 820,800L140,800Q115,800 97.5,782.5Q80,765 80,740Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M160,880Q143,880 131.5,868.5Q120,857 120,840L120,680Q120,647 143.5,623.5Q167,600 200,600L760,600Q793,600 816.5,623.5Q840,647 840,680L840,840Q840,857 828.5,868.5Q817,880 800,880L160,880ZM200,520L200,400Q200,367 223.5,343.5Q247,320 280,320L440,320L440,262Q422,250 411,233Q400,216 400,192Q400,177 406,162.5Q412,148 424,136L466,94Q468,92 480,88Q482,88 494,94L536,136Q548,148 554,162.5Q560,177 560,192Q560,216 549,233Q538,250 520,262L520,320L680,320Q713,320 736.5,343.5Q760,367 760,400L760,520L200,520Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M798,840Q673,840 551,785.5Q429,731 329,631Q229,531 174.5,409Q120,287 120,162Q120,144 132,132Q144,120 162,120L324,120Q338,120 349,129.5Q360,139 362,152L388,292Q390,308 387,319Q384,330 376,338L279,436Q299,473 326.5,507.5Q354,542 387,574Q418,605 452,631.5Q486,658 524,680L618,586Q627,577 641.5,572.5Q656,568 670,570L808,598Q822,602 831,612.5Q840,623 840,636L840,798Q840,816 828,828Q816,840 798,840Z"/>
</vector>
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:autoMirrored="true">
<path
android:fillColor="#ffffff"
android:pathData="M280,560L680,560Q697,560 708.5,548.5Q720,537 720,520Q720,503 708.5,491.5Q697,480 680,480L280,480Q263,480 251.5,491.5Q240,503 240,520Q240,537 251.5,548.5Q263,560 280,560ZM280,440L680,440Q697,440 708.5,428.5Q720,417 720,400Q720,383 708.5,371.5Q697,360 680,360L280,360Q263,360 251.5,371.5Q240,383 240,400Q240,417 251.5,428.5Q263,440 280,440ZM280,320L680,320Q697,320 708.5,308.5Q720,297 720,280Q720,263 708.5,251.5Q697,240 680,240L280,240Q263,240 251.5,251.5Q240,263 240,280Q240,297 251.5,308.5Q263,320 280,320ZM160,720Q127,720 103.5,696.5Q80,673 80,640L80,160Q80,127 103.5,103.5Q127,80 160,80L800,80Q833,80 856.5,103.5Q880,127 880,160L880,783Q880,810 855.5,820.5Q831,831 812,812L720,720L160,720Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M360,720Q327,720 303.5,696.5Q280,673 280,640L280,160Q280,127 303.5,103.5Q327,80 360,80L720,80Q753,80 776.5,103.5Q800,127 800,160L800,640Q800,673 776.5,696.5Q753,720 720,720L360,720ZM360,640L720,640Q720,640 720,640Q720,640 720,640L720,160Q720,160 720,160Q720,160 720,160L360,160Q360,160 360,160Q360,160 360,160L360,640Q360,640 360,640Q360,640 360,640ZM200,880Q167,880 143.5,856.5Q120,833 120,800L120,280Q120,263 131.5,251.5Q143,240 160,240Q177,240 188.5,251.5Q200,263 200,280L200,800Q200,800 200,800Q200,800 200,800L600,800Q617,800 628.5,811.5Q640,823 640,840Q640,857 628.5,868.5Q617,880 600,880L200,880ZM360,640Q360,640 360,640Q360,640 360,640L360,160Q360,160 360,160Q360,160 360,160L360,160Q360,160 360,160Q360,160 360,160L360,640Q360,640 360,640Q360,640 360,640Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M280,840Q247,840 223.5,816.5Q200,793 200,760L200,240L200,240Q183,240 171.5,228.5Q160,217 160,200Q160,183 171.5,171.5Q183,160 200,160L360,160L360,160Q360,143 371.5,131.5Q383,120 400,120L560,120Q577,120 588.5,131.5Q600,143 600,160L600,160L760,160Q777,160 788.5,171.5Q800,183 800,200Q800,217 788.5,228.5Q777,240 760,240L760,240L760,760Q760,793 736.5,816.5Q713,840 680,840L280,840ZM400,680Q417,680 428.5,668.5Q440,657 440,640L440,360Q440,343 428.5,331.5Q417,320 400,320Q383,320 371.5,331.5Q360,343 360,360L360,640Q360,657 371.5,668.5Q383,680 400,680ZM560,680Q577,680 588.5,668.5Q600,657 600,640L600,360Q600,343 588.5,331.5Q577,320 560,320Q543,320 531.5,331.5Q520,343 520,360L520,640Q520,657 531.5,668.5Q543,680 560,680Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M280,840Q247,840 223.5,816.5Q200,793 200,760L200,240L200,240Q183,240 171.5,228.5Q160,217 160,200Q160,183 171.5,171.5Q183,160 200,160L360,160L360,160Q360,143 371.5,131.5Q383,120 400,120L560,120Q577,120 588.5,131.5Q600,143 600,160L600,160L760,160Q777,160 788.5,171.5Q800,183 800,200Q800,217 788.5,228.5Q777,240 760,240L760,240L760,760Q760,793 736.5,816.5Q713,840 680,840L280,840ZM680,240L280,240L280,760Q280,760 280,760Q280,760 280,760L680,760Q680,760 680,760Q680,760 680,760L680,240ZM400,680Q417,680 428.5,668.5Q440,657 440,640L440,360Q440,343 428.5,331.5Q417,320 400,320Q383,320 371.5,331.5Q360,343 360,360L360,640Q360,657 371.5,668.5Q383,680 400,680ZM560,680Q577,680 588.5,668.5Q600,657 600,640L600,360Q600,343 588.5,331.5Q577,320 560,320Q543,320 531.5,331.5Q520,343 520,360L520,640Q520,657 531.5,668.5Q543,680 560,680ZM280,240L280,240L280,760Q280,760 280,760Q280,760 280,760L280,760Q280,760 280,760Q280,760 280,760L280,240Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M70,522Q58,510 58.5,494Q59,478 71,466Q83,455 99,454.5Q115,454 127,466L269,608L269,608Q276,615 283,622Q290,629 297,636Q309,648 308.5,664Q308,680 296,692L296,692Q284,703 268,703.5Q252,704 240,692L70,522ZM494,607L834,267Q846,255 862,255.5Q878,256 890,268Q901,280 901.5,296Q902,312 890,324L522,692Q510,704 494,704Q478,704 466,692L296,522Q285,511 285,494.5Q285,478 296,466Q308,454 324.5,454Q341,454 353,466L494,607ZM663,325L522,466Q511,477 494.5,477Q478,477 466,466Q454,454 454,437.5Q454,421 466,409L607,268Q618,257 634.5,257Q651,257 663,268Q675,280 675,296.5Q675,313 663,325Z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:autoMirrored="true">
<path
android:fillColor="#ffffff"
android:pathData="M240,880Q207,880 183.5,856.5Q160,833 160,800L160,160Q160,127 183.5,103.5Q207,80 240,80L527,80Q543,80 557.5,86Q572,92 583,103L777,297Q788,308 794,322.5Q800,337 800,353L800,800Q800,833 776.5,856.5Q753,880 720,880L240,880ZM520,320Q520,337 531.5,348.5Q543,360 560,360L720,360L520,160L520,320Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M160,840Q143,840 131.5,828.5Q120,817 120,800L120,703Q120,687 126,672.5Q132,658 143,647L648,143Q660,132 674.5,126Q689,120 705,120Q721,120 736,126Q751,132 762,144L817,200Q829,211 834.5,226Q840,241 840,256Q840,272 834.5,286.5Q829,301 817,313L313,817Q302,828 287.5,834Q273,840 257,840L160,840ZM704,312L760,256L704,200L648,256L704,312Z"/>
</vector>
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
@@ -8,4 +7,3 @@
android:fillColor="#ffffff" android:fillColor="#ffffff"
android:pathData="M200,760L257,760L648,369L591,312L200,703L200,760ZM160,840Q143,840 131.5,828.5Q120,817 120,800L120,703Q120,687 126,672.5Q132,658 143,647L648,143Q660,132 674.5,126Q689,120 705,120Q721,120 736,126Q751,132 762,144L817,200Q829,211 834.5,226Q840,241 840,256Q840,272 834.5,286.5Q829,301 817,313L313,817Q302,828 287.5,834Q273,840 257,840L160,840ZM760,256L760,256L704,200L704,200L760,256ZM619,341L591,312L591,312L648,369L648,369L619,341Z"/> android:pathData="M200,760L257,760L648,369L591,312L200,703L200,760ZM160,840Q143,840 131.5,828.5Q120,817 120,800L120,703Q120,687 126,672.5Q132,658 143,647L648,143Q660,132 674.5,126Q689,120 705,120Q721,120 736,126Q751,132 762,144L817,200Q829,211 834.5,226Q840,241 840,256Q840,272 834.5,286.5Q829,301 817,313L313,817Q302,828 287.5,834Q273,840 257,840L160,840ZM760,256L760,256L704,200L704,200L760,256ZM619,341L591,312L591,312L648,369L648,369L619,341Z"/>
</vector> </vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M480,680Q497,680 508.5,668.5Q520,657 520,640Q520,623 508.5,611.5Q497,600 480,600Q463,600 451.5,611.5Q440,623 440,640Q440,657 451.5,668.5Q463,680 480,680ZM480,520Q497,520 508.5,508.5Q520,497 520,480L520,320Q520,303 508.5,291.5Q497,280 480,280Q463,280 451.5,291.5Q440,303 440,320L440,480Q440,497 451.5,508.5Q463,520 480,520ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M480,680Q497,680 508.5,668.5Q520,657 520,640Q520,623 508.5,611.5Q497,600 480,600Q463,600 451.5,611.5Q440,623 440,640Q440,657 451.5,668.5Q463,680 480,680ZM480,520Q497,520 508.5,508.5Q520,497 520,480L520,320Q520,303 508.5,291.5Q497,280 480,280Q463,280 451.5,291.5Q440,303 440,320L440,480Q440,497 451.5,508.5Q463,520 480,520ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM480,800Q614,800 707,707Q800,614 800,480Q800,346 707,253Q614,160 480,160Q346,160 253,253Q160,346 160,480Q160,614 253,707Q346,800 480,800ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M440,720Q423,720 411.5,708.5Q400,697 400,680Q400,663 411.5,651.5Q423,640 440,640L520,640Q537,640 548.5,651.5Q560,663 560,680Q560,697 548.5,708.5Q537,720 520,720L440,720ZM280,520Q263,520 251.5,508.5Q240,497 240,480Q240,463 251.5,451.5Q263,440 280,440L680,440Q697,440 708.5,451.5Q720,463 720,480Q720,497 708.5,508.5Q697,520 680,520L280,520ZM160,320Q143,320 131.5,308.5Q120,297 120,280Q120,263 131.5,251.5Q143,240 160,240L800,240Q817,240 828.5,251.5Q840,263 840,280Q840,297 828.5,308.5Q817,320 800,320L160,320Z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:autoMirrored="true">
<path
android:fillColor="#ffffff"
android:pathData="M767,440L612,285Q600,273 600,256.5Q600,240 612,228Q624,217 640.5,217Q657,217 668,228L852,412Q858,418 860.5,425Q863,432 863,440Q863,448 860.5,455Q858,462 852,468L668,652Q656,664 640,663.5Q624,663 612,652Q600,640 599.5,624Q599,608 611,596L767,440ZM527,480L280,480Q230,480 195,515Q160,550 160,600L160,720Q160,737 148.5,748.5Q137,760 120,760Q103,760 91.5,748.5Q80,737 80,720L80,600Q80,517 138.5,458.5Q197,400 280,400L527,400L412,285Q400,273 400,256.5Q400,240 412,228Q424,217 440.5,217Q457,217 468,228L652,412Q658,418 660.5,425Q663,432 663,440Q663,448 660.5,455Q658,462 652,468L468,652Q456,664 440,663.5Q424,663 412,652Q400,640 399.5,624Q399,608 411,596L527,480Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M560,320Q543,320 531.5,308.5Q520,297 520,280Q520,263 531.5,251.5Q543,240 560,240Q577,240 588.5,251.5Q600,263 600,280Q600,297 588.5,308.5Q577,320 560,320ZM800,320Q783,320 771.5,308.5Q760,297 760,280Q760,263 771.5,251.5Q783,240 800,240Q817,240 828.5,251.5Q840,263 840,280Q840,297 828.5,308.5Q817,320 800,320ZM680,240Q663,240 651.5,228.5Q640,217 640,200Q640,183 651.5,171.5Q663,160 680,160Q697,160 708.5,171.5Q720,183 720,200Q720,217 708.5,228.5Q697,240 680,240ZM800,160Q783,160 771.5,148.5Q760,137 760,120Q760,103 771.5,91.5Q783,80 800,80Q817,80 828.5,91.5Q840,103 840,120Q840,137 828.5,148.5Q817,160 800,160ZM680,400Q663,400 651.5,388.5Q640,377 640,360Q640,343 651.5,331.5Q663,320 680,320Q697,320 708.5,331.5Q720,343 720,360Q720,377 708.5,388.5Q697,400 680,400ZM800,480Q783,480 771.5,468.5Q760,457 760,440Q760,423 771.5,411.5Q783,400 800,400Q817,400 828.5,411.5Q840,423 840,440Q840,457 828.5,468.5Q817,480 800,480ZM200,840Q167,840 143.5,816.5Q120,793 120,760L120,480Q120,447 143.5,423.5Q167,400 200,400L440,400Q473,400 496.5,423.5Q520,447 520,480L520,760Q520,793 496.5,816.5Q473,840 440,840L200,840ZM200,340L200,200Q200,167 223.5,143.5Q247,120 280,120L400,120Q417,120 428.5,131.5Q440,143 440,160L440,340L200,340Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M40,688Q40,654 57.5,625.5Q75,597 104,582Q166,551 230,535.5Q294,520 360,520Q426,520 490,535.5Q554,551 616,582Q645,597 662.5,625.5Q680,654 680,688L680,720Q680,753 656.5,776.5Q633,800 600,800L120,800Q87,800 63.5,776.5Q40,753 40,720L40,688ZM738,800Q749,782 754.5,761.5Q760,741 760,720L760,680Q760,636 735.5,595.5Q711,555 666,526Q717,532 762,546.5Q807,561 846,582Q882,602 901,626.5Q920,651 920,680L920,720Q920,753 896.5,776.5Q873,800 840,800L738,800ZM360,480Q294,480 247,433Q200,386 200,320Q200,254 247,207Q294,160 360,160Q426,160 473,207Q520,254 520,320Q520,386 473,433Q426,480 360,480ZM760,320Q760,386 713,433Q666,480 600,480Q589,480 572,477.5Q555,475 544,472Q571,440 585.5,401Q600,362 600,320Q600,278 585.5,239Q571,200 544,168Q558,163 572,161.5Q586,160 600,160Q666,160 713,207Q760,254 760,320Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M40,688Q40,654 57.5,625.5Q75,597 104,582Q166,551 230,535.5Q294,520 360,520Q426,520 490,535.5Q554,551 616,582Q645,597 662.5,625.5Q680,654 680,688L680,720Q680,753 656.5,776.5Q633,800 600,800L120,800Q87,800 63.5,776.5Q40,753 40,720L40,688ZM840,800L738,800Q749,782 754.5,761.5Q760,741 760,720L760,680Q760,636 735.5,595.5Q711,555 666,526Q717,532 762,546.5Q807,561 846,582Q882,602 901,626.5Q920,651 920,680L920,720Q920,753 896.5,776.5Q873,800 840,800ZM360,480Q294,480 247,433Q200,386 200,320Q200,254 247,207Q294,160 360,160Q426,160 473,207Q520,254 520,320Q520,386 473,433Q426,480 360,480ZM760,320Q760,386 713,433Q666,480 600,480Q589,480 572,477.5Q555,475 544,472Q571,440 585.5,401Q600,362 600,320Q600,278 585.5,239Q571,200 544,168Q558,163 572,161.5Q586,160 600,160Q666,160 713,207Q760,254 760,320ZM120,720L600,720L600,688Q600,677 594.5,668Q589,659 580,654Q526,627 471,613.5Q416,600 360,600Q304,600 249,613.5Q194,627 140,654Q131,659 125.5,668Q120,677 120,688L120,720ZM360,400Q393,400 416.5,376.5Q440,353 440,320Q440,287 416.5,263.5Q393,240 360,240Q327,240 303.5,263.5Q280,287 280,320Q280,353 303.5,376.5Q327,400 360,400ZM360,720L360,720L360,720Q360,720 360,720Q360,720 360,720Q360,720 360,720Q360,720 360,720Q360,720 360,720Q360,720 360,720Q360,720 360,720Q360,720 360,720ZM360,320Q360,320 360,320Q360,320 360,320Q360,320 360,320Q360,320 360,320Q360,320 360,320Q360,320 360,320Q360,320 360,320Q360,320 360,320Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M225,266Q208,266 196.5,254Q185,242 185,225Q185,208 196.5,196.5Q208,185 225,185Q242,185 254,196.5Q266,208 266,225Q266,242 254,254Q242,266 225,266ZM387,173Q370,173 358,161Q346,149 346,132Q346,115 358,103.5Q370,92 387,92Q404,92 415.5,103.5Q427,115 427,132Q427,149 415.5,161Q404,173 387,173ZM573,173Q556,173 544.5,161Q533,149 533,132Q533,115 544.5,103.5Q556,92 573,92Q590,92 602,103.5Q614,115 614,132Q614,149 602,161Q590,173 573,173ZM735,266Q718,266 706,254Q694,242 694,225Q694,208 706,196Q718,184 735,184Q752,184 763.5,196Q775,208 775,225Q775,242 763.5,254Q752,266 735,266ZM828,427Q811,427 799,415.5Q787,404 787,387Q787,370 799,358.5Q811,347 828,347Q845,347 856.5,358.5Q868,370 868,387Q868,404 856.5,415.5Q845,427 828,427ZM828,614Q811,614 799,602Q787,590 787,573Q787,556 799,544.5Q811,533 828,533Q845,533 856.5,544.5Q868,556 868,573Q868,590 856.5,602Q845,614 828,614ZM735,775Q718,775 706,763.5Q694,752 694,735Q694,718 706,706Q718,694 735,694Q752,694 763.5,706Q775,718 775,735Q775,752 763.5,763.5Q752,775 735,775ZM573,868Q556,868 544.5,856.5Q533,845 533,828Q533,811 544.5,799Q556,787 573,787Q590,787 602,799Q614,811 614,828Q614,845 602,856.5Q590,868 573,868ZM387,868Q370,868 358,856.5Q346,845 346,828Q346,811 358,799Q370,787 387,787Q404,787 415.5,799Q427,811 427,828Q427,845 415.5,856.5Q404,868 387,868ZM225,774Q208,774 196.5,762.5Q185,751 185,734Q185,717 196.5,705.5Q208,694 225,694Q242,694 253.5,705.5Q265,717 265,734Q265,751 253.5,762.5Q242,774 225,774ZM132,613Q115,613 103.5,601Q92,589 92,572Q92,555 103.5,543.5Q115,532 132,532Q149,532 161,543.5Q173,555 173,572Q173,589 161,601Q149,613 132,613ZM132,427Q115,427 103.5,415.5Q92,404 92,387Q92,370 103.5,358Q115,346 132,346Q149,346 161,358Q173,370 173,387Q173,404 161,415.5Q149,427 132,427ZM520,464L640,584Q651,595 651,612Q651,629 640,640Q629,651 612,651Q595,651 584,640L452,508Q446,502 443,494.5Q440,487 440,479L440,320Q440,303 451.5,291.5Q463,280 480,280Q497,280 508.5,291.5Q520,303 520,320L520,464Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M200,840Q167,840 143.5,816.5Q120,793 120,760L120,200Q120,167 143.5,143.5Q167,120 200,120L760,120Q793,120 816.5,143.5Q840,167 840,200L840,760Q840,793 816.5,816.5Q793,840 760,840L200,840ZM280,680L680,680Q692,680 698,669Q704,658 696,648L586,501Q580,493 570,493Q560,493 554,501L450,640L376,541Q370,533 360,533Q350,533 344,541L264,648Q256,658 262,669Q268,680 280,680Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M440,680L520,680L520,440L440,440L440,680ZM480,360Q497,360 508.5,348.5Q520,337 520,320Q520,303 508.5,291.5Q497,280 480,280Q463,280 451.5,291.5Q440,303 440,320Q440,337 451.5,348.5Q463,360 480,360ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM480,800Q614,800 707,707Q800,614 800,480Q800,346 707,253Q614,160 480,160Q346,160 253,253Q160,346 160,480Q160,614 253,707Q346,800 480,800ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M200,840Q167,840 143.5,816.5Q120,793 120,760L120,200Q120,167 143.5,143.5Q167,120 200,120L760,120Q793,120 816.5,143.5Q840,167 840,200L840,760Q840,793 816.5,816.5Q793,840 760,840L200,840ZM320,400Q303,400 291.5,411.5Q280,423 280,440L280,640Q280,657 291.5,668.5Q303,680 320,680Q337,680 348.5,668.5Q360,657 360,640L360,440Q360,423 348.5,411.5Q337,400 320,400ZM480,280Q463,280 451.5,291.5Q440,303 440,320L440,640Q440,657 451.5,668.5Q463,680 480,680Q497,680 508.5,668.5Q520,657 520,640L520,320Q520,303 508.5,291.5Q497,280 480,280ZM640,520Q623,520 611.5,531.5Q600,543 600,560L600,640Q600,657 611.5,668.5Q623,680 640,680Q657,680 668.5,668.5Q680,657 680,640L680,560Q680,543 668.5,531.5Q657,520 640,520Z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M640,200L640,480L708,548Q714,554 717,561.5Q720,569 720,577L720,600Q720,617 708.5,628.5Q697,640 680,640L520,640L520,874Q520,891 508.5,902.5Q497,914 480,914Q463,914 451.5,902.5Q440,891 440,874L440,640L280,640Q263,640 251.5,628.5Q240,617 240,600L240,577Q240,569 243,561.5Q246,554 252,548L320,480L320,200L320,200Q303,200 291.5,188.5Q280,177 280,160Q280,143 291.5,131.5Q303,120 320,120L640,120Q657,120 668.5,131.5Q680,143 680,160Q680,177 668.5,188.5Q657,200 640,200Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M572,459L290,177Q285,172 282.5,166Q280,160 280,154Q280,141 289,130.5Q298,120 313,120L640,120Q657,120 668.5,131.5Q680,143 680,160Q680,176 665.5,182.5Q651,189 640,200L640,200L640,430Q640,457 615.5,467.5Q591,478 572,459ZM440,880L440,640L296,640Q271,640 256,622.5Q241,605 241,583Q241,572 245.5,561Q250,550 260,540L320,480L320,434L84,196Q73,185 72.5,168.5Q72,152 84,140Q95,129 112,129Q129,129 140,140L819,819Q831,831 830.5,847.5Q830,864 818,876Q806,887 790,887.5Q774,888 762,876L526,640L520,640L520,880Q520,897 508.5,908.5Q497,920 480,920Q463,920 451.5,908.5Q440,897 440,880Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M560,200L400,200L400,287L290,177Q285,172 282.5,166Q280,160 280,154Q280,141 289,130.5Q298,120 313,120L640,120Q657,120 668.5,131.5Q680,143 680,160Q680,176 665.5,182.5Q651,189 640,200L640,200L640,440Q640,457 628.5,468.5Q617,480 600,480Q583,480 571.5,468.5Q560,457 560,440L560,200ZM440,880L440,640L296,640Q271,640 256,622.5Q241,605 241,583Q241,572 245.5,561Q250,550 260,540L320,480L320,434L84,196Q73,185 72.5,168.5Q72,152 84,140Q95,129 112,129Q129,129 140,140L819,819Q831,831 830.5,847.5Q830,864 818,876Q806,887 790,887.5Q774,888 762,876L526,640L520,640L520,880Q520,897 508.5,908.5Q497,920 480,920Q463,920 451.5,908.5Q440,897 440,880ZM354,560L446,560L402,516L400,514L354,560ZM480,367L480,367L480,367L480,367ZM402,516L402,516L402,516L402,516Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M640,200L640,480L708,548Q714,554 717,561.5Q720,569 720,577L720,600Q720,617 708.5,628.5Q697,640 680,640L520,640L520,874Q520,891 508.5,902.5Q497,914 480,914Q463,914 451.5,902.5Q440,891 440,874L440,640L280,640Q263,640 251.5,628.5Q240,617 240,600L240,577Q240,569 243,561.5Q246,554 252,548L320,480L320,200L320,200Q303,200 291.5,188.5Q280,177 280,160Q280,143 291.5,131.5Q303,120 320,120L640,120Q657,120 668.5,131.5Q680,143 680,160Q680,177 668.5,188.5Q657,200 640,200ZM354,560L606,560L560,514L560,200L400,200L400,514L354,560ZM480,560L480,560L480,560L480,560L480,560L480,560Z"/>
</vector>
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M480,880Q398,880 325,848.5Q252,817 197.5,762.5Q143,708 111.5,635Q80,562 80,480Q80,397 111.5,324.5Q143,252 197.5,197.5Q252,143 325,111.5Q398,80 480,80Q563,80 635.5,111.5Q708,143 762.5,197.5Q817,252 848.5,324.5Q880,397 880,480Q880,562 848.5,635Q817,708 762.5,762.5Q708,817 635.5,848.5Q563,880 480,880ZM480,798Q506,762 525,723Q544,684 556,640L404,640Q416,684 435,723Q454,762 480,798ZM376,782Q358,749 344.5,713.5Q331,678 322,640L204,640Q233,690 276.5,727Q320,764 376,782ZM584,782Q640,764 683.5,727Q727,690 756,640L638,640Q629,678 615.5,713.5Q602,749 584,782ZM170,560L306,560Q303,540 301.5,520.5Q300,501 300,480Q300,459 301.5,439.5Q303,420 306,400L170,400Q165,420 162.5,439.5Q160,459 160,480Q160,501 162.5,520.5Q165,540 170,560ZM386,560L574,560Q577,540 578.5,520.5Q580,501 580,480Q580,459 578.5,439.5Q577,420 574,400L386,400Q383,420 381.5,439.5Q380,459 380,480Q380,501 381.5,520.5Q383,540 386,560ZM654,560L790,560Q795,540 797.5,520.5Q800,501 800,480Q800,459 797.5,439.5Q795,420 790,400L654,400Q657,420 658.5,439.5Q660,459 660,480Q660,501 658.5,520.5Q657,540 654,560ZM638,320L756,320Q727,270 683.5,233Q640,196 584,178Q602,211 615.5,246.5Q629,282 638,320ZM404,320L556,320Q544,276 525,237Q506,198 480,162Q454,198 435,237Q416,276 404,320ZM204,320L322,320Q331,282 344.5,246.5Q358,211 376,178Q320,196 276.5,233Q233,270 204,320Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M160,800Q127,800 103.5,776.5Q80,753 80,720L80,240Q80,207 103.5,183.5Q127,160 160,160L800,160Q833,160 856.5,183.5Q880,207 880,240L880,720Q880,753 856.5,776.5Q833,800 800,800L160,800ZM480,513Q485,513 490.5,511.5Q496,510 501,507L784,330Q792,325 796,317.5Q800,310 800,301Q800,281 783,271Q766,261 748,272L480,440L212,272Q194,261 177,271.5Q160,282 160,301Q160,311 164,318.5Q168,326 176,330L459,507Q464,510 469.5,511.5Q475,513 480,513Z"/>
</vector>
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M574,831L360,756L174,828Q164,832 154.5,830.5Q145,829 137,824Q129,819 124.5,810.5Q120,802 120,791L120,230Q120,217 127.5,207Q135,197 148,192L334,129Q340,127 346.5,126Q353,125 360,125Q367,125 373.5,126Q380,127 386,129L600,204L786,132Q796,128 805.5,129.5Q815,131 823,136Q831,141 835.5,149.5Q840,158 840,169L840,730Q840,743 832.5,753Q825,763 812,768L626,831Q620,833 613.5,834Q607,835 600,835Q593,835 586.5,834Q580,833 574,831ZM560,742L560,274L400,218L400,686L560,742Z"/>
</vector>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z" />
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M480,560Q430,560 395,525Q360,490 360,440L360,200Q360,150 395,115Q430,80 480,80Q530,80 565,115Q600,150 600,200L600,440Q600,490 565,525Q530,560 480,560ZM440,800L440,717Q348,704 282.5,639Q217,574 203,481Q201,464 212,452Q223,440 240,440Q257,440 268.5,451.5Q280,463 284,480Q298,550 353.5,595Q409,640 480,640Q552,640 607,594.5Q662,549 676,480Q680,463 691.5,451.5Q703,440 720,440Q737,440 748,452Q759,464 757,481Q743,572 678,638Q613,704 520,717L520,800Q520,817 508.5,828.5Q497,840 480,840Q463,840 451.5,828.5Q440,817 440,800Z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M480,560Q430,560 395,525Q360,490 360,440L360,200Q360,150 395,115Q430,80 480,80Q530,80 565,115Q600,150 600,200L600,440Q600,490 565,525Q530,560 480,560ZM480,320Q480,320 480,320Q480,320 480,320L480,320Q480,320 480,320Q480,320 480,320Q480,320 480,320Q480,320 480,320L480,320Q480,320 480,320Q480,320 480,320ZM440,800L440,717Q348,704 282.5,639Q217,574 203,481Q201,464 212,452Q223,440 240,440Q257,440 268.5,451.5Q280,463 284,480Q298,550 353.5,595Q409,640 480,640Q552,640 607,594.5Q662,549 676,480Q680,463 691.5,451.5Q703,440 720,440Q737,440 748,452Q759,464 757,481Q743,572 678,638Q613,704 520,717L520,800Q520,817 508.5,828.5Q497,840 480,840Q463,840 451.5,828.5Q440,817 440,800ZM480,480Q497,480 508.5,468.5Q520,457 520,440L520,200Q520,183 508.5,171.5Q497,160 480,160Q463,160 451.5,171.5Q440,183 440,200L440,440Q440,457 451.5,468.5Q463,480 480,480Z"/>
</vector>
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#ffffff"
android:pathData="M400,840Q334,840 287,793Q240,746 240,680Q240,614 287,567Q334,520 400,520Q423,520 442.5,525.5Q462,531 480,542L480,160Q480,143 491.5,131.5Q503,120 520,120L680,120Q697,120 708.5,131.5Q720,143 720,160L720,240Q720,257 708.5,268.5Q697,280 680,280L560,280L560,680Q560,746 513,793Q466,840 400,840Z"/>
</vector>
@@ -1,18 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M15.5,9.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0" />
<path
android:fillColor="@android:color/white"
android:pathData="M8.5,9.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0" />
<path
android:fillColor="@android:color/white"
android:pathData="M12,18c2.28,0 4.22,-1.66 5,-4H7C7.78,16.34 9.72,18 12,18z" />
<path
android:fillColor="@android:color/white"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12c0,5.52 4.47,10 9.99,10C17.52,22 22,17.52 22,12C22,6.48 17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8c0,-4.42 3.58,-8 8,-8s8,3.58 8,8C20,16.42 16.42,20 12,20z" />
</vector>

Some files were not shown because too many files have changed in this diff Show More