mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-09-28 07:51:42 +01:00
Migrate symbols.
This commit is contained in:
+1
-1
@@ -540,7 +540,7 @@ private fun CallParticipantRow(
|
||||
}
|
||||
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.symbol_minus_circle_24),
|
||||
painter = SignalIcons.MinusCircle.painter,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.clickable(onClick = onBlockClicked)
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@ import org.signal.core.ui.compose.AllNightPreviews
|
||||
import org.signal.core.ui.compose.Dividers
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.Rows
|
||||
import org.signal.core.ui.compose.SignalIcons
|
||||
import org.signal.core.ui.compose.horizontalGutters
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView
|
||||
@@ -119,7 +120,7 @@ private fun ParticipantActionsSheetContent(
|
||||
|
||||
Rows.TextRow(
|
||||
text = stringResource(id = R.string.CallParticipantSheet__remove_from_call),
|
||||
icon = painterResource(id = R.drawable.symbol_minus_circle_24),
|
||||
icon = SignalIcons.MinusCircle.painter,
|
||||
onClick = {
|
||||
onRemoveFromCall(callParticipant)
|
||||
onDismiss()
|
||||
|
||||
@@ -69,6 +69,7 @@ import kotlinx.coroutines.launch
|
||||
import org.signal.core.ui.compose.AllNightPreviews
|
||||
import org.signal.core.ui.compose.BottomSheets
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.SignalIcons
|
||||
import org.signal.core.ui.compose.TriggerAlignedPopupState
|
||||
import org.signal.core.ui.compose.theme.SignalTheme
|
||||
import org.signal.core.util.DimensionUnit
|
||||
@@ -660,7 +661,7 @@ private fun ParticipantContextMenu(
|
||||
if (isSelfAdmin && isCallLink) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(R.string.CallParticipantSheet__remove_from_call)) },
|
||||
leadingIcon = { Icon(painter = painterResource(R.drawable.symbol_minus_circle_24), contentDescription = null) },
|
||||
leadingIcon = { Icon(painter = SignalIcons.MinusCircle.painter, contentDescription = null) },
|
||||
onClick = {
|
||||
onRemoveFromCall(resolved)
|
||||
onDismiss()
|
||||
|
||||
@@ -428,7 +428,7 @@ object ContactSearchModels {
|
||||
|
||||
private fun getGroupStoryContextMenuActions(model: StoryModel, callbacks: ContactSearchAdapter.StoryContextMenuCallbacks): List<ActionItem> {
|
||||
return listOf(
|
||||
ActionItem(R.drawable.symbol_minus_circle_24, context.getString(R.string.ContactSearchItems__remove_story)) {
|
||||
ActionItem(CoreUiR.drawable.symbol_minus_circle_24, context.getString(R.string.ContactSearchItems__remove_story)) {
|
||||
callbacks.onRemoveGroupStory(model.story, model.isSelected)
|
||||
}
|
||||
)
|
||||
|
||||
+1
-1
@@ -170,7 +170,7 @@ class ScheduledMessagesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment
|
||||
if (canCopy) {
|
||||
items.add(ActionItem(CoreUiR.drawable.symbol_copy_android_24, resources.getString(R.string.conversation_selection__menu_copy), action = { handleCopyMessage(message) }))
|
||||
}
|
||||
items.add(ActionItem(R.drawable.symbol_send_24, resources.getString(R.string.ScheduledMessagesBottomSheet_menu_send_now), action = { handleSendMessageNow(message.messageRecord) }))
|
||||
items.add(ActionItem(CoreUiR.drawable.symbol_send_24, resources.getString(R.string.ScheduledMessagesBottomSheet_menu_send_now), action = { handleSendMessageNow(message.messageRecord) }))
|
||||
items.add(ActionItem(R.drawable.symbol_calendar_24, resources.getString(R.string.ScheduledMessagesBottomSheet_menu_reschedule), action = { handleRescheduleMessage(message.messageRecord) }))
|
||||
return items
|
||||
}
|
||||
|
||||
@@ -354,11 +354,14 @@ import org.thoughtcrime.securesms.registration.ui.RegistrationActivity
|
||||
import org.thoughtcrime.securesms.revealable.ViewOnceMessageActivity
|
||||
import org.thoughtcrime.securesms.revealable.ViewOnceUtil
|
||||
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
|
||||
import org.thoughtcrime.securesms.sharing.MultiShareArgs
|
||||
import org.thoughtcrime.securesms.sharing.v2.ShareActivity
|
||||
import org.thoughtcrime.securesms.sms.MessageSender
|
||||
import org.thoughtcrime.securesms.stickers.StickerEventListener
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||
import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent
|
||||
import org.thoughtcrime.securesms.stickers.StickerUrl
|
||||
import org.thoughtcrime.securesms.stickers.manage.StickerManagementRepository
|
||||
import org.thoughtcrime.securesms.stickers.manage.StickerManagementScreen
|
||||
import org.thoughtcrime.securesms.stickers.preview.StickerPackPreviewActivityV2
|
||||
import org.thoughtcrime.securesms.stories.StoryViewerArgs
|
||||
@@ -714,6 +717,38 @@ class ConversationFragment :
|
||||
startActivity(StickerPackPreviewActivityV2.createIntent(StickerPackId(action.packId), StickerPackKey(action.packKey)))
|
||||
}
|
||||
|
||||
// Sending a pack means sending its link, so it goes through the same forward sheet as a
|
||||
// message. A child of this fragment, as with sticker search.
|
||||
is MediaKeyboardAction.SendStickerPackClicked -> {
|
||||
container.onHostWindowShown()
|
||||
MultiselectForwardFragment.showBottomSheet(
|
||||
supportFragmentManager = childFragmentManager,
|
||||
multiselectForwardFragmentArgs = MultiselectForwardFragmentArgs(
|
||||
multiShareArgs = listOf(
|
||||
MultiShareArgs.Builder()
|
||||
.withDraftText(StickerUrl.createShareLink(action.packId, action.packKey))
|
||||
.build()
|
||||
),
|
||||
title = R.string.StickerManagement_share_sheet_title
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is MediaKeyboardAction.RemoveStickerPackClicked -> {
|
||||
container.onHostWindowShown()
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(resources.getQuantityString(R.plurals.StickerManagement_delete_n_packs_confirmation, 1, 1))
|
||||
.setMessage(resources.getQuantityString(R.plurals.StickerManagement_delete_n_packs_confirmation_body, 1, 1))
|
||||
.setPositiveButton(R.string.StickerManagement_menu_remove_pack) { _, _ ->
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
StickerManagementRepository.uninstallStickerPacks(mapOf(StickerPackId(action.packId) to StickerPackKey(action.packKey)))
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setOnDismissListener { container.onHostWindowHidden() }
|
||||
.show()
|
||||
}
|
||||
|
||||
// A screen of its own rather than a window over this one, and picking a gif carries on into
|
||||
// media send, so the keyboard has no reason to still be up on the way back.
|
||||
MediaKeyboardAction.GifSearchClicked -> {
|
||||
|
||||
@@ -381,6 +381,17 @@ class StickerTables(
|
||||
notifyStickerPackListeners()
|
||||
}
|
||||
|
||||
fun clearRecentlyUsedStickers() {
|
||||
writableDatabase
|
||||
.update(Sticker.TABLE_NAME)
|
||||
.values(Sticker.LAST_USED to 0)
|
||||
.where("${Sticker.LAST_USED} > 0 AND ${Sticker.COVER} = 0")
|
||||
.run()
|
||||
|
||||
notifyStickerListeners()
|
||||
notifyStickerPackListeners()
|
||||
}
|
||||
|
||||
fun markPackAsInstalled(packId: String, notify: Boolean) {
|
||||
val transitioned = updatePackInstalled(
|
||||
db = databaseHelper.signalWritableDatabase,
|
||||
|
||||
+8
@@ -62,6 +62,12 @@ class SignalStickerKeyboardRepository(private val context: Context) : StickerKey
|
||||
}
|
||||
}
|
||||
|
||||
override fun clearRecentStickers() {
|
||||
SignalExecutors.BOUNDED_IO.execute {
|
||||
SignalDatabase.stickers.clearRecentlyUsedStickers()
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadStickerPacks(): List<KeyboardStickerPack> {
|
||||
val stickerTable = SignalDatabase.stickers
|
||||
|
||||
@@ -74,6 +80,7 @@ class SignalStickerKeyboardRepository(private val context: Context) : StickerKey
|
||||
|
||||
KeyboardStickerPack(
|
||||
id = pack.packId,
|
||||
packKey = pack.packKey,
|
||||
title = pack.title.nullIfBlank(),
|
||||
cover = DecryptableUri(pack.cover.uri),
|
||||
stickers = stickers
|
||||
@@ -87,6 +94,7 @@ class SignalStickerKeyboardRepository(private val context: Context) : StickerKey
|
||||
|
||||
val recentPack = KeyboardStickerPack(
|
||||
id = StickerKeyboardRepository.RECENT_PACK_ID,
|
||||
packKey = null,
|
||||
title = context.getString(R.string.StickerKeyboard__recently_used),
|
||||
cover = null,
|
||||
stickers = recentStickers.map { it.toKeyboardSticker() }
|
||||
|
||||
+2
-2
@@ -243,7 +243,7 @@ private fun StickerPackPreviewScreen(
|
||||
if (loadedState.isPackInstalled) {
|
||||
DropdownMenus.ItemWithIcon(
|
||||
menuController = menuController,
|
||||
imageVector = ImageVector.vectorResource(R.drawable.symbol_minus_circle_24),
|
||||
imageVector = SignalIcons.MinusCircle.imageVector,
|
||||
stringResId = R.string.StickerManagement_menu_remove_pack,
|
||||
onClick = { onEvent(StickerPackPreviewEvent.UninstallClicked) }
|
||||
)
|
||||
@@ -511,7 +511,7 @@ private fun StickerOptions(
|
||||
|
||||
Buttons.ActionButton(
|
||||
onClick = { onEvent(StickerPackPreviewEvent.UninstallClicked) },
|
||||
imageVector = ImageVector.vectorResource(R.drawable.symbol_minus_circle_24),
|
||||
imageVector = SignalIcons.MinusCircle.imageVector,
|
||||
label = stringResource(R.string.StickerManagement_menu_remove_pack)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,12 +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="#FF000000"
|
||||
android:pathData="M16.5 12.88c0.48 0 0.88-0.4 0.88-0.88s-0.4-0.88-0.88-0.88h-9c-0.48 0-0.88 0.4-0.88 0.88s0.4 0.88 0.88 0.88h9Z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12 1.13C6 1.13 1.12 5.99 1.12 12 1.13 18 6 22.88 12 22.88c6 0 10.88-4.87 10.88-10.88C22.88 6 18 1.12 12 1.12ZM2.87 12c0-5.04 4.09-9.13 9.13-9.13 5.04 0 9.13 4.09 9.13 9.13 0 5.04-4.09 9.13-9.13 9.13-5.04 0-9.13-4.09-9.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="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M6.16,2.807a2.125,2.125 0,0 0,-3.035 1.92v14.547a2.125,2.125 0,0 0,3.036 1.92l15.333,-7.274c1.62,-0.768 1.62,-3.072 0,-3.84L6.161,2.807ZM4.875,4.727c0,-0.276 0.287,-0.457 0.536,-0.34l15.333,7.274a0.375,0.375 0,0 1,0 0.678L5.411,19.612a0.375,0.375 0,0 1,-0.536 -0.338v-4.972l7.493,-1.816a0.5,0.5 0,0 0,0 -0.972L4.875,9.698L4.875,4.726Z"
|
||||
android:fillColor="#000"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
@@ -80,6 +80,7 @@ enum class SignalIcons(private val icon: SignalIcon) : SignalIcon by icon {
|
||||
LockFill(icon(R.drawable.symbol_lock_fill_24)),
|
||||
Maximize(icon(R.drawable.symbol_maximize_24)),
|
||||
Mic(icon(R.drawable.symbol_mic_24)),
|
||||
MinusCircle(icon(R.drawable.symbol_minus_circle_24)),
|
||||
MobileNextDisplay(icon(R.drawable.symbol_mobile_next_display_48)),
|
||||
MoreVertical(icon(R.drawable.symbol_more_vertical_24)),
|
||||
Nighttime(icon(R.drawable.ic_nighttime_26)),
|
||||
@@ -100,6 +101,7 @@ enum class SignalIcons(private val icon: SignalIcon) : SignalIcon by icon {
|
||||
Refresh(icon(R.drawable.symbol_refresh_24)),
|
||||
Save(icon(R.drawable.symbol_save_android_24)),
|
||||
Search(icon(R.drawable.symbol_search_24)),
|
||||
Send(icon(R.drawable.symbol_send_24)),
|
||||
SendFill(icon(R.drawable.symbol_send_fill_24)),
|
||||
Settings(icon(R.drawable.symbol_settings_android_24)),
|
||||
Share(icon(R.drawable.symbol_share_android_24)),
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<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="#FF000000"
|
||||
android:pathData="M12 21.1c-5.02 0-9.1-4.08-9.1-9.1 0-5.03 4.08-9.1 9.1-9.1 5.03 0 9.1 4.07 9.1 9.1 0 5.02-4.07 9.1-9.1 9.1m0 1.8c6.03 0 10.9-4.88 10.9-10.9 0-6.03-4.87-10.9-10.9-10.9C5.98 1.1 1.1 5.97 1.1 12c0 6.02 4.88 10.9 10.9 10.9m-4.5-10h9c0.5 0 0.9-0.4 0.9-0.9s-0.4-0.9-0.9-0.9h-9c-0.5 0-0.9 0.4-0.9 0.9s0.4 0.9 0.9 0.9m0 0"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<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="#FF000000"
|
||||
android:pathData="M5.71 21.3l16.5-7.81c1.24-0.58 1.24-2.4 0-2.98L5.71 2.7c-1.1-0.53-2.36 0.27-2.36 1.49v5.57c0 0.61 0.4 1.16 1.01 1.33 1.3 0.35 2.53 0.58 5.04 0.86v0.1c-2.51 0.27-3.74 0.51-5.04 0.86-0.61 0.16-1.01 0.71-1.01 1.33v5.57c0 1.23 1.26 2.01 2.36 1.49m-0.56-1.73v-5.01l8.05-2.17c0.6-0.17 0.6-0.62 0-0.78L5.15 9.44V4.43l16 7.57Zm0 0"/>
|
||||
</vector>
|
||||
@@ -57,4 +57,20 @@ sealed interface MediaKeyboardAction {
|
||||
* @param packKey Its key, which identifies the pack alongside [packId].
|
||||
*/
|
||||
data class ViewStickerPackClicked(val packId: String, val packKey: String) : MediaKeyboardAction
|
||||
|
||||
/**
|
||||
* Let the user send a sticker pack to someone, as a link.
|
||||
*
|
||||
* @param packId The pack to send.
|
||||
* @param packKey Its key, which identifies the pack alongside [packId].
|
||||
*/
|
||||
data class SendStickerPackClicked(val packId: String, val packKey: String) : MediaKeyboardAction
|
||||
|
||||
/**
|
||||
* Uninstall a sticker pack, confirming with the user first.
|
||||
*
|
||||
* @param packId The pack to remove.
|
||||
* @param packKey Its key, which identifies the pack alongside [packId].
|
||||
*/
|
||||
data class RemoveStickerPackClicked(val packId: String, val packKey: String) : MediaKeyboardAction
|
||||
}
|
||||
|
||||
+8
@@ -30,6 +30,11 @@ interface StickerKeyboardRepository {
|
||||
*/
|
||||
fun onStickerUsed(sticker: KeyboardSticker) = Unit
|
||||
|
||||
/**
|
||||
* Forget every recently-used sticker, emptying the synthetic [RECENT_PACK_ID] pack.
|
||||
*/
|
||||
fun clearRecentStickers() = Unit
|
||||
|
||||
companion object {
|
||||
const val RECENT_PACK_ID = "media-keyboard-recents"
|
||||
}
|
||||
@@ -53,10 +58,13 @@ data class KeyboardSticker(
|
||||
)
|
||||
|
||||
/**
|
||||
* @param packKey The pack's key, which identifies it alongside [id] wherever it is opened or
|
||||
* forwarded. Null for the synthetic recents pack, which is not a real pack.
|
||||
* @param cover A Glide-loadable model for the pack's cover image.
|
||||
*/
|
||||
data class KeyboardStickerPack(
|
||||
val id: String,
|
||||
val packKey: String?,
|
||||
val title: String?,
|
||||
val cover: Any?,
|
||||
val stickers: List<KeyboardSticker>
|
||||
|
||||
+139
-13
@@ -8,6 +8,8 @@ package org.signal.mediakeyboard.screens.sticker
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
@@ -36,9 +38,13 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.PreviewWrapper
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.signal.core.ui.compose.DayNightPreviews
|
||||
import org.signal.core.ui.compose.DropdownMenus
|
||||
import org.signal.core.ui.compose.SignalIcons
|
||||
import org.signal.core.ui.compose.SignalPreviewWrapper
|
||||
import org.signal.core.ui.compose.theme.SignalTheme
|
||||
import org.signal.glide.compose.GlideImage
|
||||
import org.signal.mediakeyboard.R
|
||||
@@ -190,18 +196,7 @@ private fun StickerGrid(
|
||||
|
||||
state.packs.forEach { pack ->
|
||||
item(key = "header:${pack.id}", span = { GridItemSpan(maxLineSpan) }) {
|
||||
val title = if (pack.id == StickerKeyboardRepository.RECENT_PACK_ID) {
|
||||
stringResource(R.string.MediaKeyboard__recently_used)
|
||||
} else {
|
||||
pack.title.orEmpty()
|
||||
}
|
||||
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(start = 8.dp, top = 12.dp, bottom = 4.dp)
|
||||
)
|
||||
StickerPackHeader(pack = pack, onEvent = onEvent)
|
||||
}
|
||||
|
||||
pack.stickers.forEachIndexed { index, sticker ->
|
||||
@@ -217,6 +212,137 @@ private fun StickerGrid(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StickerPackHeader(
|
||||
pack: KeyboardStickerPack,
|
||||
onEvent: (StickerPageScreenEvents) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val isRecents = pack.id == StickerKeyboardRepository.RECENT_PACK_ID
|
||||
val menuController = remember { DropdownMenus.MenuController() }
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 8.dp, end = 4.dp, top = 12.dp, bottom = 4.dp)
|
||||
) {
|
||||
Text(
|
||||
text = if (isRecents) stringResource(R.string.MediaKeyboard__recently_used) else pack.title.orEmpty(),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
|
||||
Box {
|
||||
IconButton(
|
||||
onClick = { menuController.show() },
|
||||
modifier = Modifier.size(32.dp)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = SignalIcons.MoreVertical.imageVector,
|
||||
contentDescription = stringResource(R.string.MediaKeyboard__more_options),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
StickerPackHeaderMenu(
|
||||
pack = pack,
|
||||
isRecents = isRecents,
|
||||
menuController = menuController,
|
||||
onEvent = onEvent
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StickerPackHeaderMenu(
|
||||
pack: KeyboardStickerPack,
|
||||
isRecents: Boolean,
|
||||
menuController: DropdownMenus.MenuController,
|
||||
onEvent: (StickerPageScreenEvents) -> Unit
|
||||
) {
|
||||
DropdownMenus.Menu(
|
||||
controller = menuController,
|
||||
offsetX = 0.dp
|
||||
) {
|
||||
if (isRecents) {
|
||||
DropdownMenus.ItemWithIcon(
|
||||
menuController = menuController,
|
||||
imageVector = SignalIcons.Trash.imageVector,
|
||||
stringResId = R.string.MediaKeyboard__clear_recents,
|
||||
onClick = {
|
||||
onEvent(StickerPageScreenEvents.ClearRecentStickersClicked)
|
||||
}
|
||||
)
|
||||
|
||||
return@Menu
|
||||
}
|
||||
|
||||
// Everything below acts on the pack itself, which needs the key the recents pack does not have.
|
||||
val packKey = pack.packKey ?: return@Menu
|
||||
|
||||
DropdownMenus.ItemWithIcon(
|
||||
menuController = menuController,
|
||||
imageVector = SignalIcons.Send.imageVector,
|
||||
stringResId = R.string.MediaKeyboard__send,
|
||||
onClick = {
|
||||
onEvent(StickerPageScreenEvents.SendStickerPackClicked(pack.id, packKey))
|
||||
}
|
||||
)
|
||||
|
||||
DropdownMenus.ItemWithIcon(
|
||||
menuController = menuController,
|
||||
imageVector = SignalIcons.StickerPack.imageVector,
|
||||
stringResId = R.string.MediaKeyboard__view_pack,
|
||||
onClick = {
|
||||
onEvent(StickerPageScreenEvents.ViewStickerPackClicked(pack.id, packKey))
|
||||
}
|
||||
)
|
||||
|
||||
DropdownMenus.ItemWithIcon(
|
||||
menuController = menuController,
|
||||
imageVector = SignalIcons.MinusCircle.imageVector,
|
||||
stringResId = R.string.MediaKeyboard__remove_pack,
|
||||
onClick = {
|
||||
onEvent(StickerPageScreenEvents.RemoveStickerPackClicked(pack.id, packKey))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewWrapper(SignalPreviewWrapper::class)
|
||||
@DayNightPreviews
|
||||
@Composable
|
||||
private fun StickerPackHeaderPreview() {
|
||||
Column {
|
||||
StickerPackHeader(
|
||||
pack = KeyboardStickerPack(
|
||||
id = StickerKeyboardRepository.RECENT_PACK_ID,
|
||||
packKey = null,
|
||||
title = null,
|
||||
cover = null,
|
||||
stickers = emptyList()
|
||||
),
|
||||
onEvent = {}
|
||||
)
|
||||
|
||||
StickerPackHeader(
|
||||
pack = KeyboardStickerPack(
|
||||
id = "pack-1",
|
||||
packKey = "pack-1-key",
|
||||
title = "Bandit the Cat",
|
||||
cover = null,
|
||||
stickers = emptyList()
|
||||
),
|
||||
onEvent = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StickerCell(
|
||||
sticker: KeyboardSticker,
|
||||
@@ -252,7 +378,7 @@ private fun StickerCell(
|
||||
) {
|
||||
DropdownMenus.ItemWithIcon(
|
||||
menuController = controller,
|
||||
imageVector = SignalIcons.SendFill.imageVector,
|
||||
imageVector = SignalIcons.Send.imageVector,
|
||||
stringResId = R.string.MediaKeyboard__send,
|
||||
onClick = {
|
||||
onEvent(StickerPageScreenEvents.StickerClicked(sticker))
|
||||
|
||||
+3
@@ -17,4 +17,7 @@ sealed interface StickerPageScreenEvents {
|
||||
data class StickerClicked(val sticker: KeyboardSticker) : StickerPageScreenEvents
|
||||
data object SearchClicked : StickerPageScreenEvents
|
||||
data class ViewStickerPackClicked(val packId: String, val packKey: String) : StickerPageScreenEvents
|
||||
data class SendStickerPackClicked(val packId: String, val packKey: String) : StickerPageScreenEvents
|
||||
data class RemoveStickerPackClicked(val packId: String, val packKey: String) : StickerPageScreenEvents
|
||||
data object ClearRecentStickersClicked : StickerPageScreenEvents
|
||||
}
|
||||
|
||||
+12
@@ -83,6 +83,18 @@ class StickerPageViewModel(
|
||||
is StickerPageScreenEvents.ViewStickerPackClicked -> {
|
||||
onAction(MediaKeyboardAction.ViewStickerPackClicked(event.packId, event.packKey))
|
||||
}
|
||||
|
||||
is StickerPageScreenEvents.SendStickerPackClicked -> {
|
||||
onAction(MediaKeyboardAction.SendStickerPackClicked(event.packId, event.packKey))
|
||||
}
|
||||
|
||||
is StickerPageScreenEvents.RemoveStickerPackClicked -> {
|
||||
onAction(MediaKeyboardAction.RemoveStickerPackClicked(event.packId, event.packKey))
|
||||
}
|
||||
|
||||
is StickerPageScreenEvents.ClearRecentStickersClicked -> {
|
||||
repository.clearRecentStickers()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,10 +55,16 @@
|
||||
<!-- Sticker page -->
|
||||
<!-- Accessibility description for the button in the media keyboard top bar that opens the screen where sticker packs are managed. -->
|
||||
<string name="MediaKeyboard__manage_stickers">Manage stickers</string>
|
||||
<!-- Menu option on a long-pressed sticker that sends that sticker. Verb, imperative. -->
|
||||
<!-- Menu option that sends a sticker, on a long-pressed sticker, or the whole pack as a link, in a sticker pack header's menu. Verb, imperative. -->
|
||||
<string name="MediaKeyboard__send">Send</string>
|
||||
<!-- Menu option on a long-pressed sticker that opens the pack the sticker belongs to. Verb phrase, imperative. -->
|
||||
<!-- Menu option, on a long-pressed sticker and in a sticker pack header's menu, that opens the pack the sticker belongs to. Verb phrase, imperative. -->
|
||||
<string name="MediaKeyboard__view_pack">View pack</string>
|
||||
<!-- Accessibility description for the three-dot button at the end of a sticker pack header, which opens that pack's menu. -->
|
||||
<string name="MediaKeyboard__more_options">More options</string>
|
||||
<!-- Menu option in a sticker pack header's menu that uninstalls the pack. Verb, imperative. -->
|
||||
<string name="MediaKeyboard__remove_pack">Remove</string>
|
||||
<!-- Menu option in the recently used header's menu that forgets every recently used sticker. Verb phrase, imperative. -->
|
||||
<string name="MediaKeyboard__clear_recents">Clear recents</string>
|
||||
|
||||
<!-- Gif page -->
|
||||
<!-- Label of the GIF quick search chip that shows the GIFs trending right now. -->
|
||||
|
||||
+2
-2
@@ -31,8 +31,8 @@ class StickerPageViewModelTest {
|
||||
|
||||
private val sticker = KeyboardSticker(packId = "pack-1", packKey = "pack-1-key", stickerId = 1, emoji = "😀", image = "image-1")
|
||||
private val packs = listOf(
|
||||
KeyboardStickerPack(id = "pack-1", title = "Pack One", cover = null, stickers = listOf(sticker)),
|
||||
KeyboardStickerPack(id = "pack-2", title = "Pack Two", cover = null, stickers = emptyList())
|
||||
KeyboardStickerPack(id = "pack-1", packKey = "pack-1-key", title = "Pack One", cover = null, stickers = listOf(sticker)),
|
||||
KeyboardStickerPack(id = "pack-2", packKey = "pack-2-key", title = "Pack Two", cover = null, stickers = emptyList())
|
||||
)
|
||||
|
||||
private lateinit var repository: StickerKeyboardRepository
|
||||
|
||||
Reference in New Issue
Block a user