Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| abfe25d051 | |||
| 574b230b26 | |||
| b31c0f30c5 |
@@ -47,7 +47,7 @@ android {
|
|||||||
applicationIdSuffix = ".debug"
|
applicationIdSuffix = ".debug"
|
||||||
}
|
}
|
||||||
named("release") {
|
named("release") {
|
||||||
signingConfig = signingConfigs.getByName("release")
|
signingConfig = signingConfigs.getByName("debugSigning")
|
||||||
|
|
||||||
isMinifyEnabled = true
|
isMinifyEnabled = true
|
||||||
isShrinkResources = true
|
isShrinkResources = true
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
|
|||||||
compileSdk = getVersionInt("compileSdk")
|
compileSdk = getVersionInt("compileSdk")
|
||||||
targetSdk = getVersionInt("targetSdk")
|
targetSdk = getVersionInt("targetSdk")
|
||||||
}
|
}
|
||||||
|
lint {
|
||||||
|
abortOnError = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import com.android.build.api.dsl.LibraryExtension
|
|||||||
import com.android.build.api.variant.LibraryAndroidComponentsExtension
|
import com.android.build.api.variant.LibraryAndroidComponentsExtension
|
||||||
import dev.meloda.fast.configureKotlinAndroid
|
import dev.meloda.fast.configureKotlinAndroid
|
||||||
import dev.meloda.fast.disableUnnecessaryAndroidTests
|
import dev.meloda.fast.disableUnnecessaryAndroidTests
|
||||||
|
import dev.meloda.fast.getVersionInt
|
||||||
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
|
||||||
@@ -20,7 +21,13 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
|
|||||||
extensions.configure<LibraryExtension> {
|
extensions.configure<LibraryExtension> {
|
||||||
configureKotlinAndroid(this)
|
configureKotlinAndroid(this)
|
||||||
androidResources.enable = false
|
androidResources.enable = false
|
||||||
defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
defaultConfig {
|
||||||
|
minSdk = getVersionInt("minSdk")
|
||||||
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
lint {
|
||||||
|
abortOnError = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
extensions.configure<LibraryAndroidComponentsExtension> {
|
extensions.configure<LibraryAndroidComponentsExtension> {
|
||||||
disableUnnecessaryAndroidTests(target)
|
disableUnnecessaryAndroidTests(target)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ object AppConstants {
|
|||||||
|
|
||||||
const val INSTALL_APP_MIME_TYPE = "application/vnd.android.package-archive"
|
const val INSTALL_APP_MIME_TYPE = "application/vnd.android.package-archive"
|
||||||
|
|
||||||
const val API_VERSION = "5.238"
|
const val API_VERSION = "5.263"
|
||||||
const val URL_OAUTH = "https://oauth.vk.ru"
|
const val URL_OAUTH = "https://oauth.vk.ru"
|
||||||
const val URL_API = "https://api.vk.ru/method"
|
const val URL_API = "https://api.vk.ru/method"
|
||||||
|
|
||||||
|
|||||||
@@ -598,6 +598,7 @@ private fun getAttachmentIconByType(attachmentType: AttachmentType): UiImage? {
|
|||||||
AttachmentType.VIDEO_MESSAGE -> null
|
AttachmentType.VIDEO_MESSAGE -> null
|
||||||
AttachmentType.GROUP_CHAT_STICKER -> R.drawable.ic_sticker_fill_round_24
|
AttachmentType.GROUP_CHAT_STICKER -> R.drawable.ic_sticker_fill_round_24
|
||||||
AttachmentType.STICKER_PACK_PREVIEW -> null
|
AttachmentType.STICKER_PACK_PREVIEW -> null
|
||||||
|
AttachmentType.CHANNEL_MESSAGE -> null
|
||||||
}?.let(UiImage::Resource)
|
}?.let(UiImage::Resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,6 +688,7 @@ fun getAttachmentUiText(
|
|||||||
AttachmentType.VIDEO_MESSAGE -> R.string.message_attachments_video_message
|
AttachmentType.VIDEO_MESSAGE -> R.string.message_attachments_video_message
|
||||||
AttachmentType.GROUP_CHAT_STICKER -> R.string.message_attachments_group_sticker
|
AttachmentType.GROUP_CHAT_STICKER -> R.string.message_attachments_group_sticker
|
||||||
AttachmentType.STICKER_PACK_PREVIEW -> R.string.message_attachments_sticker_pack_preview
|
AttachmentType.STICKER_PACK_PREVIEW -> R.string.message_attachments_sticker_pack_preview
|
||||||
|
AttachmentType.CHANNEL_MESSAGE -> R.string.message_attachments_channel_message
|
||||||
}.let(UiText::Resource)
|
}.let(UiText::Resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ enum class AttachmentType(var value: String) {
|
|||||||
ARTICLE("article"),
|
ARTICLE("article"),
|
||||||
VIDEO_MESSAGE("video_message"),
|
VIDEO_MESSAGE("video_message"),
|
||||||
GROUP_CHAT_STICKER("ugc_sticker"),
|
GROUP_CHAT_STICKER("ugc_sticker"),
|
||||||
STICKER_PACK_PREVIEW("sticker_pack_preview")
|
STICKER_PACK_PREVIEW("sticker_pack_preview"),
|
||||||
|
CHANNEL_MESSAGE("channel_message")
|
||||||
;
|
;
|
||||||
|
|
||||||
fun isMultiple(): Boolean = this in listOf(PHOTO, VIDEO, AUDIO, FILE)
|
fun isMultiple(): Boolean = this in listOf(PHOTO, VIDEO, AUDIO, FILE)
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ data class VkAttachmentItemData(
|
|||||||
@Json(name = "article") val article: VkArticleData?,
|
@Json(name = "article") val article: VkArticleData?,
|
||||||
@Json(name = "video_message") val videoMessage: VkVideoMessageData?,
|
@Json(name = "video_message") val videoMessage: VkVideoMessageData?,
|
||||||
@Json(name = "ugc_sticker") val groupSticker: VkGroupStickerData?,
|
@Json(name = "ugc_sticker") val groupSticker: VkGroupStickerData?,
|
||||||
@Json(name = "sticker_pack_preview") val stickerPackPreview: VkStickerPackPreviewData?
|
@Json(name = "sticker_pack_preview") val stickerPackPreview: VkStickerPackPreviewData?,
|
||||||
|
@Json(name = "channel_message") val channelMessageData: VkChannelMessageData?
|
||||||
) {
|
) {
|
||||||
fun toDomain(): VkAttachment = when (AttachmentType.parse(type)) {
|
fun toDomain(): VkAttachment = when (AttachmentType.parse(type)) {
|
||||||
AttachmentType.UNKNOWN -> VkUnknownAttachment
|
AttachmentType.UNKNOWN -> VkUnknownAttachment
|
||||||
@@ -66,5 +67,6 @@ data class VkAttachmentItemData(
|
|||||||
AttachmentType.VIDEO_MESSAGE -> videoMessage?.toDomain()
|
AttachmentType.VIDEO_MESSAGE -> videoMessage?.toDomain()
|
||||||
AttachmentType.GROUP_CHAT_STICKER -> groupSticker?.toDomain()
|
AttachmentType.GROUP_CHAT_STICKER -> groupSticker?.toDomain()
|
||||||
AttachmentType.STICKER_PACK_PREVIEW -> stickerPackPreview?.toDomain()
|
AttachmentType.STICKER_PACK_PREVIEW -> stickerPackPreview?.toDomain()
|
||||||
|
AttachmentType.CHANNEL_MESSAGE -> channelMessageData?.toDomain()
|
||||||
} ?: VkUnknownAttachment
|
} ?: VkUnknownAttachment
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package dev.meloda.fast.model.api.data
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
import dev.meloda.fast.model.api.domain.VkChannelMessage
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class VkChannelMessageData(
|
||||||
|
@Json(name = "channel_id") val channelId: Long,
|
||||||
|
@Json(name = "cmid") val cmId: Long,
|
||||||
|
@Json(name = "author_id") val authorId: Long,
|
||||||
|
@Json(name = "channel_info") val channelInfo: ChannelInfo,
|
||||||
|
@Json(name = "channel_type") val channelType: String,
|
||||||
|
@Json(name = "guid") val guid: String,
|
||||||
|
@Json(name = "text") val text: String?,
|
||||||
|
@Json(name = "time") val time: Long,
|
||||||
|
@Json(name = "attachments") val attachments: List<VkAttachmentItemData> = emptyList(),
|
||||||
|
) : VkAttachmentData {
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class ChannelInfo(
|
||||||
|
@Json(name = "photo_base") val photoBase: String?,
|
||||||
|
@Json(name = "title") val title: String
|
||||||
|
)
|
||||||
|
|
||||||
|
fun toDomain(): VkChannelMessage = VkChannelMessage(
|
||||||
|
channelId = channelId,
|
||||||
|
cmId = cmId,
|
||||||
|
authorId = authorId,
|
||||||
|
channelInfo = VkChannelMessage.ChannelInfo(
|
||||||
|
title = channelInfo.title,
|
||||||
|
photoBase = channelInfo.photoBase
|
||||||
|
),
|
||||||
|
channelType = channelType,
|
||||||
|
guid = guid,
|
||||||
|
text = text,
|
||||||
|
time = time,
|
||||||
|
attachments = attachments.map(VkAttachmentItemData::toDomain),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package dev.meloda.fast.model.api.domain
|
||||||
|
|
||||||
|
import dev.meloda.fast.model.api.data.AttachmentType
|
||||||
|
|
||||||
|
data class VkChannelMessage(
|
||||||
|
val channelId: Long,
|
||||||
|
val cmId: Long,
|
||||||
|
val authorId: Long,
|
||||||
|
val channelInfo: ChannelInfo,
|
||||||
|
val channelType: String,
|
||||||
|
val guid: String,
|
||||||
|
val text: String?,
|
||||||
|
val time: Long,
|
||||||
|
val attachments: List<VkAttachment>?,
|
||||||
|
) : VkAttachment {
|
||||||
|
|
||||||
|
data class ChannelInfo(
|
||||||
|
val title: String,
|
||||||
|
val photoBase: String?
|
||||||
|
)
|
||||||
|
|
||||||
|
override val type: AttachmentType = AttachmentType.CHANNEL_MESSAGE
|
||||||
|
}
|
||||||
@@ -58,7 +58,7 @@ fun AppTheme(
|
|||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
val colorScheme: ColorScheme = when {
|
val colorScheme: ColorScheme = predefinedColorScheme ?: when {
|
||||||
useDynamicColors && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
useDynamicColors && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||||
if (useDarkTheme) dynamicDarkColorScheme(context)
|
if (useDarkTheme) dynamicDarkColorScheme(context)
|
||||||
else dynamicLightColorScheme(context)
|
else dynamicLightColorScheme(context)
|
||||||
@@ -82,10 +82,6 @@ fun AppTheme(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val colorPrimary by animateColorAsState(colorScheme.primary)
|
|
||||||
val colorSurface by animateColorAsState(colorScheme.surface)
|
|
||||||
val colorBackground by animateColorAsState(colorScheme.background)
|
|
||||||
|
|
||||||
val typography = if (useSystemFont) {
|
val typography = if (useSystemFont) {
|
||||||
MaterialTheme.typography
|
MaterialTheme.typography
|
||||||
} else {
|
} else {
|
||||||
@@ -118,12 +114,7 @@ fun AppTheme(
|
|||||||
}
|
}
|
||||||
|
|
||||||
MaterialExpressiveTheme(
|
MaterialExpressiveTheme(
|
||||||
colorScheme = (predefinedColorScheme ?: colorScheme)
|
colorScheme = colorScheme,
|
||||||
.copy(
|
|
||||||
primary = colorPrimary,
|
|
||||||
background = colorBackground,
|
|
||||||
surface = colorSurface
|
|
||||||
),
|
|
||||||
typography = typography,
|
typography = typography,
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import androidx.compose.ui.graphics.luminance
|
|||||||
import androidx.compose.ui.graphics.painter.Painter
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
import androidx.compose.ui.graphics.toArgb
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.input.key.onKeyEvent
|
import androidx.compose.ui.input.key.onKeyEvent
|
||||||
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.colorResource
|
import androidx.compose.ui.res.colorResource
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
@@ -113,11 +114,12 @@ fun LazyListState.isScrollingUp(): Boolean {
|
|||||||
@Composable
|
@Composable
|
||||||
fun isNeedToEnableDarkMode(darkMode: DarkMode): Boolean {
|
fun isNeedToEnableDarkMode(darkMode: DarkMode): Boolean {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
val configuration = LocalConfiguration.current
|
||||||
|
|
||||||
val appForceDarkMode = darkMode == DarkMode.ENABLED
|
val appForceDarkMode = darkMode == DarkMode.ENABLED
|
||||||
val appBatterySaver = darkMode == DarkMode.AUTO_BATTERY
|
val appBatterySaver = darkMode == DarkMode.AUTO_BATTERY
|
||||||
|
|
||||||
val systemUiNightMode = context.resources.configuration.uiMode
|
val systemUiNightMode = configuration.uiMode
|
||||||
|
|
||||||
val isSystemBatterySaver = context.getSystemService<PowerManager>()?.isPowerSaveMode == true
|
val isSystemBatterySaver = context.getSystemService<PowerManager>()?.isPowerSaveMode == true
|
||||||
val isSystemUsingDarkTheme =
|
val isSystemUsingDarkTheme =
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
<string name="message_attachments_video_message">Video message</string>
|
<string name="message_attachments_video_message">Video message</string>
|
||||||
<string name="message_attachments_group_sticker">Group sticker</string>
|
<string name="message_attachments_group_sticker">Group sticker</string>
|
||||||
<string name="message_attachments_sticker_pack_preview">Sticker pack preview</string>
|
<string name="message_attachments_sticker_pack_preview">Sticker pack preview</string>
|
||||||
|
<string name="message_attachments_channel_message">Channel message</string>
|
||||||
|
|
||||||
<string name="chat_interaction_uploading_file">Uploading file</string>
|
<string name="chat_interaction_uploading_file">Uploading file</string>
|
||||||
<string name="chat_interaction_uploading_photo">Uploading photo</string>
|
<string name="chat_interaction_uploading_photo">Uploading photo</string>
|
||||||
|
|||||||
@@ -100,7 +100,13 @@ class LoginViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onBackPressed() {
|
fun onBackPressed() {
|
||||||
_screenState.setValue { old -> old.copy(showLogo = true) }
|
_screenState.setValue { old ->
|
||||||
|
old.copy(
|
||||||
|
showLogo = true,
|
||||||
|
loginError = false,
|
||||||
|
passwordError = false
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onPasswordVisibilityButtonClicked() {
|
fun onPasswordVisibilityButtonClicked() {
|
||||||
|
|||||||
+27
-12
@@ -31,9 +31,13 @@ import androidx.compose.material3.ScaffoldDefaults
|
|||||||
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.TextField
|
||||||
|
import androidx.compose.material3.lightColorScheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
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.autofill.ContentType
|
import androidx.compose.ui.autofill.ContentType
|
||||||
@@ -58,7 +62,6 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import dev.meloda.fast.auth.login.LoginViewModel
|
import dev.meloda.fast.auth.login.LoginViewModel
|
||||||
import dev.meloda.fast.auth.login.model.CaptchaArguments
|
|
||||||
import dev.meloda.fast.auth.login.model.LoginDialog
|
import dev.meloda.fast.auth.login.model.LoginDialog
|
||||||
import dev.meloda.fast.auth.login.model.LoginScreenState
|
import dev.meloda.fast.auth.login.model.LoginScreenState
|
||||||
import dev.meloda.fast.auth.login.model.LoginUserBannedArguments
|
import dev.meloda.fast.auth.login.model.LoginUserBannedArguments
|
||||||
@@ -67,6 +70,8 @@ import dev.meloda.fast.ui.R
|
|||||||
import dev.meloda.fast.ui.common.LocalSizeConfig
|
import dev.meloda.fast.ui.common.LocalSizeConfig
|
||||||
import dev.meloda.fast.ui.components.MaterialDialog
|
import dev.meloda.fast.ui.components.MaterialDialog
|
||||||
import dev.meloda.fast.ui.components.TextFieldErrorText
|
import dev.meloda.fast.ui.components.TextFieldErrorText
|
||||||
|
import dev.meloda.fast.ui.theme.AppTheme
|
||||||
|
import dev.meloda.fast.ui.theme.ClassicColorScheme
|
||||||
import dev.meloda.fast.ui.util.handleEnterKey
|
import dev.meloda.fast.ui.util.handleEnterKey
|
||||||
import dev.meloda.fast.ui.util.handleTabKey
|
import dev.meloda.fast.ui.util.handleTabKey
|
||||||
import org.koin.androidx.compose.koinViewModel
|
import org.koin.androidx.compose.koinViewModel
|
||||||
@@ -114,17 +119,27 @@ fun LoginRoute(
|
|||||||
viewModel.onValidationCodeReceived(validationCode)
|
viewModel.onValidationCodeReceived(validationCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
LoginScreen(
|
var useClassic by rememberSaveable { mutableStateOf(true) }
|
||||||
screenState = screenState,
|
|
||||||
onLoginInputChanged = viewModel::onLoginInputChanged,
|
AppTheme(
|
||||||
onPasswordInputChanged = viewModel::onPasswordInputChanged,
|
predefinedColorScheme = if (useClassic) ClassicColorScheme.lightScheme
|
||||||
onPasswordFieldEnterKeyClicked = viewModel::onSignInButtonClicked,
|
else lightColorScheme(),
|
||||||
onPasswordVisibilityButtonClicked = viewModel::onPasswordVisibilityButtonClicked,
|
) {
|
||||||
onPasswordFieldGoAction = viewModel::onSignInButtonClicked,
|
LoginScreen(
|
||||||
onSignInButtonClicked = viewModel::onSignInButtonClicked,
|
screenState = screenState,
|
||||||
onLogoClicked = viewModel::onLogoClicked,
|
onLoginInputChanged = viewModel::onLoginInputChanged,
|
||||||
onLogoLongClicked = onNavigateToSettings
|
onPasswordInputChanged = viewModel::onPasswordInputChanged,
|
||||||
)
|
onPasswordFieldEnterKeyClicked = viewModel::onSignInButtonClicked,
|
||||||
|
onPasswordVisibilityButtonClicked = viewModel::onPasswordVisibilityButtonClicked,
|
||||||
|
onPasswordFieldGoAction = viewModel::onSignInButtonClicked,
|
||||||
|
onSignInButtonClicked = viewModel::onSignInButtonClicked,
|
||||||
|
onLogoClicked = {
|
||||||
|
viewModel.onLogoClicked()
|
||||||
|
useClassic = !useClassic
|
||||||
|
},
|
||||||
|
onLogoLongClicked = onNavigateToSettings
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
HandleDialogs(
|
HandleDialogs(
|
||||||
loginDialog = loginDialog,
|
loginDialog = loginDialog,
|
||||||
|
|||||||
+5
-2
@@ -119,12 +119,15 @@ fun Attachments(
|
|||||||
|
|
||||||
AttachmentType.STICKER -> {
|
AttachmentType.STICKER -> {
|
||||||
Sticker(
|
Sticker(
|
||||||
item = attachment as VkStickerDomain
|
url = (attachment as VkStickerDomain).getUrl(
|
||||||
|
width = 256,
|
||||||
|
withBackground = false
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
AttachmentType.GIFT -> {
|
AttachmentType.GIFT -> {
|
||||||
Gift(item = attachment as VkGiftDomain)
|
Gift(url = (attachment as VkGiftDomain).getDefaultThumbSizeOrLess())
|
||||||
}
|
}
|
||||||
|
|
||||||
AttachmentType.VIDEO_MESSAGE -> {
|
AttachmentType.VIDEO_MESSAGE -> {
|
||||||
|
|||||||
+6
-7
@@ -21,25 +21,24 @@ import androidx.compose.ui.res.vectorResource
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import dev.meloda.fast.model.api.domain.VkGiftDomain
|
|
||||||
import dev.meloda.fast.ui.R
|
import dev.meloda.fast.ui.R
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Gift(
|
fun Gift(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
item: VkGiftDomain
|
url: String
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier.width(192.dp),
|
modifier = modifier
|
||||||
|
.width(208.dp)
|
||||||
|
.padding(8.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
) {
|
) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = item.getDefaultThumbSizeOrLess(),
|
model = url,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
modifier = Modifier
|
modifier = Modifier.size(192.dp)
|
||||||
.padding(8.dp)
|
|
||||||
.fillMaxWidth()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
|
|||||||
+6
-10
@@ -10,27 +10,23 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import dev.meloda.fast.model.api.domain.VkStickerDomain
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Sticker(
|
fun Sticker(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
item: VkStickerDomain
|
url: String?
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier.size(192.dp),
|
modifier = modifier
|
||||||
|
.size(208.dp)
|
||||||
|
.padding(8.dp),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = item.getUrl(
|
model = url,
|
||||||
width = 256,
|
|
||||||
withBackground = false
|
|
||||||
),
|
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
modifier = Modifier
|
modifier = Modifier.fillMaxSize()
|
||||||
.padding(8.dp)
|
|
||||||
.fillMaxSize()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ kotlin = "2.3.21"
|
|||||||
ksp = "2.3.7"
|
ksp = "2.3.7"
|
||||||
moduleGraph = "2.9.1"
|
moduleGraph = "2.9.1"
|
||||||
versions = "0.54.0"
|
versions = "0.54.0"
|
||||||
stability-analyzer = "0.7.4"
|
stability-analyzer = "0.7.5"
|
||||||
|
|
||||||
compose-bom = "2026.04.01"
|
compose-bom = "2026.04.01"
|
||||||
koin = "4.2.1"
|
koin = "4.2.1"
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
+2
@@ -2,6 +2,8 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
|
retries=0
|
||||||
|
retryBackOffMs=500
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright © 2015-2021 the original authors.
|
# Copyright © 2015 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -86,8 +86,7 @@ done
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||||
' "$PWD" ) || exit
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
@@ -115,7 +114,6 @@ case "$( uname )" in #(
|
|||||||
NONSTOP* ) nonstop=true ;;
|
NONSTOP* ) nonstop=true ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
@@ -173,7 +171,6 @@ fi
|
|||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
if "$cygwin" || "$msys" ; then
|
if "$cygwin" || "$msys" ; then
|
||||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
|
||||||
|
|
||||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
@@ -206,15 +203,14 @@ fi
|
|||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Collect all arguments for the java command:
|
# Collect all arguments for the java command:
|
||||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
# and any embedded shellness will be escaped.
|
# and any embedded shellness will be escaped.
|
||||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
# treated as '${Hostname}' itself on the command line.
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
set -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
-classpath "$CLASSPATH" \
|
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||||
org.gradle.wrapper.GradleWrapperMain \
|
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
# Stop when "xargs" is not available.
|
# Stop when "xargs" is not available.
|
||||||
|
|||||||
Vendored
+10
-22
@@ -23,8 +23,8 @@
|
|||||||
@rem
|
@rem
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
|
|
||||||
@rem Set local scope for the variables with windows NT shell
|
@rem Set local scope for the variables, and ensure extensions are enabled
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
setlocal EnableExtensions
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%"=="" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
@@ -51,7 +51,7 @@ echo. 1>&2
|
|||||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
"%COMSPEC%" /c exit 1
|
||||||
|
|
||||||
:findJavaFromJavaHome
|
:findJavaFromJavaHome
|
||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
@@ -65,30 +65,18 @@ echo. 1>&2
|
|||||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
"%COMSPEC%" /c exit 1
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
@rem Execute Gradle
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
|
||||||
|
@rem which allows us to clear the local environment before executing the java command
|
||||||
|
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
|
||||||
|
|
||||||
:end
|
:exitWithErrorLevel
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
|
||||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
"%COMSPEC%" /c exit %ERRORLEVEL%
|
||||||
|
|
||||||
:fail
|
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
|
||||||
rem the _cmd.exe /c_ return code!
|
|
||||||
set EXIT_CODE=%ERRORLEVEL%
|
|
||||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
|
||||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
|
||||||
exit /b %EXIT_CODE%
|
|
||||||
|
|
||||||
:mainEnd
|
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
|
||||||
|
|
||||||
:omega
|
|
||||||
|
|||||||
Reference in New Issue
Block a user