diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 483dbee..6f303bc 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -31,6 +31,11 @@
+
+
+
+
+
= Build.VERSION_CODES.TIRAMISU) {
- intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
- } else {
- intent.getParcelableExtra(Intent.EXTRA_STREAM)
+ val stickers: MutableList = when (intent?.action) {
+ Intent.ACTION_SEND -> {
+ val data = mutableListOf()
+ if (intent.type?.startsWith("image/") == true) {
+ val uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
+ } else {
+ intent.getParcelableExtra(Intent.EXTRA_STREAM)
+ }
+ if (uri != null) {
+ data.add(UriWithStickerUuidBean(uri = uri))
+ }
+ data
+ } else data
+ }
+
+ Intent.ACTION_SEND_MULTIPLE -> {
+ val data = mutableListOf()
+ if (intent.type?.startsWith("image/") == true) {
+ val uris = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)
+ } else {
+ intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM)
+ }?.map { UriWithStickerUuidBean(uri = it) }
+ if (uris != null) {
+ data.addAll(uris)
+ }
+ data
+ } else data
}
- } else {
- null
- } ?: return
- navController.navigate(
- ADD_SCREEN_ROUTE,
- Bundle().apply { putParcelable("sticker", sticker) }
+ else -> mutableListOf()
+ }
+
+ if (stickers.isEmpty()) return
+
+ openAddScreen(
+ navController = navController,
+ stickers = stickers,
+ isEdit = false,
)
}
}
diff --git a/app/src/main/java/com/skyd/rays/ui/screen/add/AddScreen.kt b/app/src/main/java/com/skyd/rays/ui/screen/add/AddScreen.kt
index b7228d4..d589188 100644
--- a/app/src/main/java/com/skyd/rays/ui/screen/add/AddScreen.kt
+++ b/app/src/main/java/com/skyd/rays/ui/screen/add/AddScreen.kt
@@ -1,6 +1,7 @@
package com.skyd.rays.ui.screen.add
import android.net.Uri
+import android.os.Bundle
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
@@ -70,19 +71,23 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.navigation.NavHostController
import com.skyd.rays.R
import com.skyd.rays.appContext
import com.skyd.rays.base.LoadUiIntent
import com.skyd.rays.config.refreshStickerData
import com.skyd.rays.ext.addAllDistinctly
import com.skyd.rays.ext.addIfAny
+import com.skyd.rays.ext.navigate
import com.skyd.rays.ext.plus
import com.skyd.rays.ext.popBackStackWithLifecycle
import com.skyd.rays.ext.showSnackbar
import com.skyd.rays.ext.showSnackbarWithLaunchedEffect
+import com.skyd.rays.model.bean.EmptyUriWithStickerUuidBean
import com.skyd.rays.model.bean.StickerBean
import com.skyd.rays.model.bean.StickerWithTags
import com.skyd.rays.model.bean.TagBean
+import com.skyd.rays.model.bean.UriWithStickerUuidBean
import com.skyd.rays.ui.component.AnimatedPlaceholder
import com.skyd.rays.ui.component.RaysCard
import com.skyd.rays.ui.component.RaysImage
@@ -94,9 +99,28 @@ import com.skyd.rays.util.stickerUuidToUri
const val ADD_SCREEN_ROUTE = "addScreen"
+fun openAddScreen(
+ navController: NavHostController,
+ stickers: MutableList,
+ isEdit: Boolean
+) {
+ navController.navigate(
+ ADD_SCREEN_ROUTE,
+ Bundle().apply {
+ putBoolean("isEdit", isEdit)
+ putParcelableArrayList("stickers", ArrayList(stickers))
+ }
+ )
+}
+
@Composable
-fun AddScreen(initStickerUuid: String, sticker: Uri?, viewModel: AddViewModel = hiltViewModel()) {
+fun AddScreen(
+ initStickers: MutableList,
+ isEdit: Boolean,
+ viewModel: AddViewModel = hiltViewModel()
+) {
var openDialog by remember { mutableStateOf(false) }
+ var openDuplicateDialog by remember { mutableStateOf(false) }
val keyboardController = LocalSoftwareKeyboardController.current
val context = LocalContext.current
val focusManager = LocalFocusManager.current
@@ -106,20 +130,21 @@ fun AddScreen(initStickerUuid: String, sticker: Uri?, viewModel: AddViewModel =
val navController = LocalNavController.current
var titleText by rememberSaveable { mutableStateOf("") }
var currentTagText by rememberSaveable { mutableStateOf("") }
- var stickerUri by remember { mutableStateOf(null) }
var stickerCreateTime by remember { mutableLongStateOf(System.currentTimeMillis()) }
val tags = remember { mutableStateListOf() }
- var stickerUuid by remember { mutableStateOf(initStickerUuid) }
+ var currentSticker by remember { mutableStateOf(EmptyUriWithStickerUuidBean) }
+ val stickersWaitingList = remember { mutableStateListOf() }
val suggestedTags = remember { mutableStateListOf() }
val loadUiIntent by viewModel.loadUiIntentFlow.collectAsStateWithLifecycle(initialValue = null)
val uiEvent by viewModel.uiEventFlow.collectAsStateWithLifecycle(initialValue = null)
- val uriWaitingList = remember { mutableStateListOf() }
LaunchedEffect(Unit) {
- if (initStickerUuid.isNotBlank()) {
- viewModel.sendUiIntent(AddIntent.GetStickerWithTags(initStickerUuid))
- } else if (sticker != null) {
- stickerUri = sticker
+ initStickers.firstOrNull()?.let { firstSticker ->
+ currentSticker = firstSticker
+ stickersWaitingList.addAll(initStickers.subList(1, initStickers.size))
+ if (firstSticker.stickerUuid.isNotBlank()) {
+ viewModel.sendUiIntent(AddIntent.GetStickerWithTags(firstSticker.stickerUuid))
+ }
}
}
@@ -134,21 +159,20 @@ fun AddScreen(initStickerUuid: String, sticker: Uri?, viewModel: AddViewModel =
title = {
Text(
text = stringResource(
- if (stickerUuid.isBlank()) R.string.add_screen_name
- else R.string.add_screen_name_edit
+ if (isEdit) R.string.add_screen_name_edit else R.string.add_screen_name
)
)
},
actions = {
TopBarIcon(
- imageVector = if (uriWaitingList.isEmpty()) {
+ imageVector = if (stickersWaitingList.isEmpty()) {
Icons.Default.Done
} else {
Icons.AutoMirrored.Default.ArrowForwardIos
},
contentDescription = stringResource(R.string.add_screen_add),
onClick = {
- if (stickerUri == null) {
+ if (currentSticker.isEmpty()) {
snackbarHostState.showSnackbar(
scope = scope,
message = appContext.getString(R.string.add_screen_sticker_is_not_set),
@@ -160,11 +184,14 @@ fun AddScreen(initStickerUuid: String, sticker: Uri?, viewModel: AddViewModel =
sticker = StickerBean(
title = titleText,
createTime = stickerCreateTime
- ).apply { uuid = stickerUuid },
+ ).apply { uuid = currentSticker.stickerUuid },
tags = tags.distinct()
)
viewModel.sendUiIntent(
- AddIntent.AddNewStickerWithTags(stickerWithTags, stickerUri!!)
+ AddIntent.AddNewStickerWithTags(
+ stickerWithTags,
+ currentSticker.uri!!
+ )
)
}
}
@@ -176,30 +203,31 @@ fun AddScreen(initStickerUuid: String, sticker: Uri?, viewModel: AddViewModel =
val pickStickerLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.GetContent()
) { result ->
- if (result != null) stickerUri = result
+ if (result != null) currentSticker = UriWithStickerUuidBean(uri = result)
}
val pickStickersLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.GetMultipleContents()
) { result ->
if (result.isEmpty()) return@rememberLauncherForActivityResult
- if (stickerUri == null) {
- stickerUri = result.first()
- uriWaitingList.addAllDistinctly(result.subList(1, result.size))
+ if (currentSticker.isEmpty()) {
+ currentSticker = UriWithStickerUuidBean(uri = result.first())
+ stickersWaitingList.addAllDistinctly(result.subList(1, result.size)
+ .map { UriWithStickerUuidBean(uri = it) })
} else {
- uriWaitingList.addAllDistinctly(result)
- uriWaitingList.removeIf { it == stickerUri }
+ stickersWaitingList.addAllDistinctly(result.map { UriWithStickerUuidBean(uri = it) })
+ stickersWaitingList.removeIf { it.uri == currentSticker.uri }
}
}
LazyColumn(contentPadding = paddingValues + PaddingValues(horizontal = 16.dp)) {
item {
AnimatedVisibility(
- visible = uriWaitingList.isNotEmpty(),
+ visible = stickersWaitingList.isNotEmpty(),
enter = expandVertically(),
exit = shrinkVertically(),
) {
WaitingRow(
- uris = uriWaitingList,
- onStickerDeleted = { uriWaitingList.remove(it) },
+ uris = stickersWaitingList,
+ onStickerDeleted = { stickersWaitingList.remove(it) },
)
}
}
@@ -259,12 +287,8 @@ fun AddScreen(initStickerUuid: String, sticker: Uri?, viewModel: AddViewModel =
}
item {
StickerCard(
- stickerUri = stickerUri,
- pickLauncher = if (initStickerUuid.isBlank()) {
- pickStickersLauncher
- } else {
- pickStickerLauncher
- }
+ stickerUri = currentSticker.uri,
+ pickLauncher = if (isEdit) pickStickerLauncher else pickStickersLauncher
)
}
}
@@ -275,14 +299,14 @@ fun AddScreen(initStickerUuid: String, sticker: Uri?, viewModel: AddViewModel =
text = { Text(text = stringResource(R.string.add_screen_success)) },
onDismissRequest = {
openDialog = false
- if (uriWaitingList.isEmpty() && stickerUri == null) {
+ if (stickersWaitingList.isEmpty() && currentSticker.isEmpty()) {
navController.popBackStackWithLifecycle()
}
},
confirmButton = {
TextButton(onClick = {
openDialog = false
- if (uriWaitingList.isEmpty() && stickerUri == null) {
+ if (stickersWaitingList.isEmpty() && currentSticker.isEmpty()) {
navController.popBackStackWithLifecycle()
}
}) {
@@ -290,21 +314,32 @@ fun AddScreen(initStickerUuid: String, sticker: Uri?, viewModel: AddViewModel =
}
}
)
+
+ RaysDialog(
+ visible = openDuplicateDialog,
+ title = { Text(text = stringResource(R.string.dialog_tip)) },
+ text = { Text(text = stringResource(R.string.add_screen_sticker_duplicate)) },
+ onDismissRequest = { openDuplicateDialog = false },
+ confirmButton = {
+ TextButton(onClick = { openDuplicateDialog = false }) {
+ Text(text = stringResource(id = R.string.dialog_ok))
+ }
+ }
+ )
}
// 添加/修改完成后重设页面数据
fun resetStickerData() {
- stickerUuid = initStickerUuid
titleText = ""
currentTagText = ""
stickerCreateTime = System.currentTimeMillis()
suggestedTags.clear()
tags.clear()
- if (uriWaitingList.isEmpty()) {
- stickerUri = null
+ if (stickersWaitingList.isEmpty()) {
+ currentSticker = EmptyUriWithStickerUuidBean
} else {
- stickerUri = uriWaitingList.first()
- uriWaitingList.removeAt(0)
+ currentSticker = stickersWaitingList.first()
+ stickersWaitingList.removeAt(0)
}
}
@@ -312,9 +347,11 @@ fun AddScreen(initStickerUuid: String, sticker: Uri?, viewModel: AddViewModel =
when (getStickersWithTagsUiEvent) {
is GetStickersWithTagsUiEvent.Success -> {
val stickerBean = getStickersWithTagsUiEvent.stickerWithTags.sticker
- stickerUuid = stickerBean.uuid
+ currentSticker = currentSticker.copy(
+ uri = stickerUuidToUri(stickerBean.uuid),
+ stickerUuid = stickerBean.uuid
+ )
titleText = stickerBean.title
- stickerUri = stickerUuidToUri(stickerBean.uuid)
stickerCreateTime = stickerBean.createTime
tags.clear()
tags.addAll(getStickersWithTagsUiEvent.stickerWithTags.tags.distinct())
@@ -326,12 +363,7 @@ fun AddScreen(initStickerUuid: String, sticker: Uri?, viewModel: AddViewModel =
}
when (addStickersResultUiEvent) {
- AddStickersResultUiEvent.Duplicate -> {
- snackbarHostState.showSnackbarWithLaunchedEffect(
- context.getString(R.string.add_screen_sticker_duplicate),
- key2 = addStickersResultUiEvent,
- )
- }
+ AddStickersResultUiEvent.Duplicate -> openDuplicateDialog = true
is AddStickersResultUiEvent.Success -> {
refreshStickerData.tryEmit(Unit)
@@ -368,7 +400,10 @@ fun AddScreen(initStickerUuid: String, sticker: Uri?, viewModel: AddViewModel =
}
@Composable
-private fun WaitingRow(uris: List, onStickerDeleted: (Uri) -> Unit) {
+private fun WaitingRow(
+ uris: List,
+ onStickerDeleted: (UriWithStickerUuidBean) -> Unit
+) {
Column {
Spacer(modifier = Modifier.height(10.dp))
Text(
@@ -383,7 +418,7 @@ private fun WaitingRow(uris: List, onStickerDeleted: (Uri) -> Unit) {
items(uris) { uri ->
RaysCard(onClick = { onStickerDeleted(uri) }) {
RaysImage(
- model = uri,
+ model = uri.uri,
modifier = Modifier
.fillMaxHeight()
.aspectRatio(1f),
diff --git a/app/src/main/java/com/skyd/rays/ui/screen/home/HomeScreen.kt b/app/src/main/java/com/skyd/rays/ui/screen/home/HomeScreen.kt
index 35ec4e7..df2420e 100644
--- a/app/src/main/java/com/skyd/rays/ui/screen/home/HomeScreen.kt
+++ b/app/src/main/java/com/skyd/rays/ui/screen/home/HomeScreen.kt
@@ -76,6 +76,7 @@ import com.skyd.rays.ext.inBottomOrNotLarge
import com.skyd.rays.ext.isCompact
import com.skyd.rays.ext.showSnackbarWithLaunchedEffect
import com.skyd.rays.model.bean.StickerWithTags
+import com.skyd.rays.model.bean.UriWithStickerUuidBean
import com.skyd.rays.model.preference.StickerScalePreference
import com.skyd.rays.model.preference.search.QueryPreference
import com.skyd.rays.ui.component.AnimatedPlaceholder
@@ -90,9 +91,10 @@ import com.skyd.rays.ui.local.LocalNavController
import com.skyd.rays.ui.local.LocalQuery
import com.skyd.rays.ui.local.LocalStickerScale
import com.skyd.rays.ui.local.LocalWindowSizeClass
-import com.skyd.rays.ui.screen.add.ADD_SCREEN_ROUTE
+import com.skyd.rays.ui.screen.add.openAddScreen
import com.skyd.rays.ui.screen.home.searchbar.RaysSearchBar
import com.skyd.rays.util.sendStickerByUuid
+import com.skyd.rays.util.stickerUuidToUri
@Composable
@@ -139,7 +141,13 @@ fun HomeScreen(viewModel: HomeViewModel = hiltViewModel()) {
visible = fabVisibility,
text = { Text(text = stringResource(R.string.home_screen_add)) },
icon = { Icon(imageVector = Icons.Default.Add, contentDescription = null) },
- onClick = { navController.navigate(ADD_SCREEN_ROUTE) },
+ onClick = {
+ openAddScreen(
+ navController = navController,
+ stickers = mutableListOf(),
+ isEdit = false,
+ )
+ },
contentDescription = stringResource(R.string.home_screen_add),
)
},
@@ -299,7 +307,16 @@ private fun MainCard(
)
},
onDoubleClick = {
- navController.navigate("$ADD_SCREEN_ROUTE?stickerUuid=${stickerUuid}")
+ openAddScreen(
+ navController = navController,
+ stickers = mutableListOf(
+ UriWithStickerUuidBean(
+ uri = stickerUuidToUri(stickerBean.uuid),
+ stickerUuid = stickerBean.uuid,
+ )
+ ),
+ isEdit = true,
+ )
},
onClick = {}
)
diff --git a/app/src/main/java/com/skyd/rays/ui/screen/home/searchbar/HomeMenu.kt b/app/src/main/java/com/skyd/rays/ui/screen/home/searchbar/HomeMenu.kt
index 46c5bfd..e41c29d 100644
--- a/app/src/main/java/com/skyd/rays/ui/screen/home/searchbar/HomeMenu.kt
+++ b/app/src/main/java/com/skyd/rays/ui/screen/home/searchbar/HomeMenu.kt
@@ -19,15 +19,17 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import com.skyd.rays.R
+import com.skyd.rays.model.bean.UriWithStickerUuidBean
import com.skyd.rays.model.preference.CurrentStickerUuidPreference
import com.skyd.rays.model.preference.search.SearchResultSortPreference
import com.skyd.rays.ui.local.LocalCurrentStickerUuid
import com.skyd.rays.ui.local.LocalNavController
import com.skyd.rays.ui.local.LocalSearchResultSort
-import com.skyd.rays.ui.screen.add.ADD_SCREEN_ROUTE
+import com.skyd.rays.ui.screen.add.openAddScreen
import com.skyd.rays.ui.screen.home.HomeIntent
import com.skyd.rays.ui.screen.home.HomeViewModel
import com.skyd.rays.ui.screen.settings.searchconfig.SEARCH_CONFIG_SCREEN_ROUTE
+import com.skyd.rays.util.stickerUuidToUri
@Composable
@@ -104,7 +106,16 @@ internal fun HomeMenu(
enabled = stickerMenuItemEnabled,
text = { Text(stringResource(R.string.home_screen_edit)) },
onClick = {
- navController.navigate("$ADD_SCREEN_ROUTE?stickerUuid=${currentStickerUuid}")
+ openAddScreen(
+ navController = navController,
+ stickers = mutableListOf(
+ UriWithStickerUuidBean(
+ uri = stickerUuidToUri(currentStickerUuid),
+ stickerUuid = currentStickerUuid,
+ )
+ ),
+ isEdit = true
+ )
onDismissRequest()
},
leadingIcon = {