feat: add media grid bulk actions in chat info
This commit is contained in:
@@ -110,6 +110,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.snapshotFlow
|
import androidx.compose.runtime.snapshotFlow
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.platform.LocalClipboardManager
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
@@ -119,6 +120,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.TextRange
|
import androidx.compose.ui.text.TextRange
|
||||||
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
@@ -5976,6 +5978,8 @@ private fun ChatInfoTabContent(
|
|||||||
onUnbanMember: (Long) -> Unit,
|
onUnbanMember: (Long) -> Unit,
|
||||||
onEntryClick: (ChatInfoEntry) -> Unit,
|
onEntryClick: (ChatInfoEntry) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val clipboardManager = LocalClipboardManager.current
|
||||||
if (tab == ChatInfoTab.Members) {
|
if (tab == ChatInfoTab.Members) {
|
||||||
ChatMembersTabContent(
|
ChatMembersTabContent(
|
||||||
members = members,
|
members = members,
|
||||||
@@ -6029,6 +6033,9 @@ private fun ChatInfoTabContent(
|
|||||||
val selectedEntries = remember(filtered, selectionCount) {
|
val selectedEntries = remember(filtered, selectionCount) {
|
||||||
filtered.filter { entry -> buildChatInfoEntrySelectionKey(entry) in selectedMediaKeys }
|
filtered.filter { entry -> buildChatInfoEntrySelectionKey(entry) in selectedMediaKeys }
|
||||||
}
|
}
|
||||||
|
val selectedUrls = remember(selectedEntries) {
|
||||||
|
selectedEntries.mapNotNull { it.resourceUrl ?: it.previewImageUrl }.distinct()
|
||||||
|
}
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -6054,11 +6061,53 @@ private fun ChatInfoTabContent(
|
|||||||
style = MaterialTheme.typography.titleSmall,
|
style = MaterialTheme.typography.titleSmall,
|
||||||
fontWeight = FontWeight.SemiBold,
|
fontWeight = FontWeight.SemiBold,
|
||||||
)
|
)
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
selectedMediaKeys = filtered
|
||||||
|
.take(120)
|
||||||
|
.map(::buildChatInfoEntrySelectionKey)
|
||||||
|
.toSet()
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text(stringResource(id = R.string.chat_info_select_all))
|
||||||
|
}
|
||||||
if (selectedEntries.size == 1) {
|
if (selectedEntries.size == 1) {
|
||||||
TextButton(onClick = { onEntryClick(selectedEntries.first()) }) {
|
TextButton(onClick = { onEntryClick(selectedEntries.first()) }) {
|
||||||
Text(stringResource(id = R.string.chat_info_open_selected))
|
Text(stringResource(id = R.string.chat_info_open_selected))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (selectedUrls.isNotEmpty()) {
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
clipboardManager.setText(
|
||||||
|
AnnotatedString(selectedUrls.joinToString(separator = "\n")),
|
||||||
|
)
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
context.getString(R.string.chat_info_links_copied),
|
||||||
|
Toast.LENGTH_SHORT,
|
||||||
|
).show()
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text(stringResource(id = R.string.chat_info_copy_links))
|
||||||
|
}
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
val shareIntent = Intent(Intent.ACTION_SEND).apply {
|
||||||
|
type = "text/plain"
|
||||||
|
putExtra(Intent.EXTRA_TEXT, selectedUrls.joinToString(separator = "\n"))
|
||||||
|
}
|
||||||
|
context.startActivity(
|
||||||
|
Intent.createChooser(
|
||||||
|
shareIntent,
|
||||||
|
context.getString(R.string.chat_info_share_links),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text(stringResource(id = R.string.chat_info_share_links))
|
||||||
|
}
|
||||||
|
}
|
||||||
TextButton(onClick = { selectedMediaKeys = emptySet() }) {
|
TextButton(onClick = { selectedMediaKeys = emptySet() }) {
|
||||||
Text(stringResource(id = R.string.chat_info_clear_selection))
|
Text(stringResource(id = R.string.chat_info_clear_selection))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,6 +165,10 @@
|
|||||||
<string name="chat_info_selected_count">Выбрано: %1$d</string>
|
<string name="chat_info_selected_count">Выбрано: %1$d</string>
|
||||||
<string name="chat_info_open_selected">Открыть</string>
|
<string name="chat_info_open_selected">Открыть</string>
|
||||||
<string name="chat_info_clear_selection">Сбросить</string>
|
<string name="chat_info_clear_selection">Сбросить</string>
|
||||||
|
<string name="chat_info_select_all">Все</string>
|
||||||
|
<string name="chat_info_copy_links">Копировать ссылки</string>
|
||||||
|
<string name="chat_info_share_links">Поделиться</string>
|
||||||
|
<string name="chat_info_links_copied">Ссылки скопированы</string>
|
||||||
<string name="chat_info_media_selection_hint">Удерживайте медиа, чтобы перейти в режим выбора.</string>
|
<string name="chat_info_media_selection_hint">Удерживайте медиа, чтобы перейти в режим выбора.</string>
|
||||||
<string name="chat_members_header">Участники (%1$d)</string>
|
<string name="chat_members_header">Участники (%1$d)</string>
|
||||||
<string name="chat_banned_header">Заблокированные (%1$d)</string>
|
<string name="chat_banned_header">Заблокированные (%1$d)</string>
|
||||||
|
|||||||
@@ -165,6 +165,10 @@
|
|||||||
<string name="chat_info_selected_count">%1$d selected</string>
|
<string name="chat_info_selected_count">%1$d selected</string>
|
||||||
<string name="chat_info_open_selected">Open</string>
|
<string name="chat_info_open_selected">Open</string>
|
||||||
<string name="chat_info_clear_selection">Clear</string>
|
<string name="chat_info_clear_selection">Clear</string>
|
||||||
|
<string name="chat_info_select_all">All</string>
|
||||||
|
<string name="chat_info_copy_links">Copy links</string>
|
||||||
|
<string name="chat_info_share_links">Share links</string>
|
||||||
|
<string name="chat_info_links_copied">Links copied</string>
|
||||||
<string name="chat_info_media_selection_hint">Long press media to select multiple items.</string>
|
<string name="chat_info_media_selection_hint">Long press media to select multiple items.</string>
|
||||||
<string name="chat_members_header">Members (%1$d)</string>
|
<string name="chat_members_header">Members (%1$d)</string>
|
||||||
<string name="chat_banned_header">Banned (%1$d)</string>
|
<string name="chat_banned_header">Banned (%1$d)</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user