diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 634f39f728..4a9e8b5aca 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -620,7 +620,7 @@
android:windowSoftInputMode="stateHidden" />
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt
index 192340b87b..38fa5250ab 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt
@@ -321,9 +321,9 @@ import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
import org.thoughtcrime.securesms.sms.MessageSender
import org.thoughtcrime.securesms.stickers.StickerEventListener
import org.thoughtcrime.securesms.stickers.StickerLocator
-import org.thoughtcrime.securesms.stickers.StickerManagementScreen
import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent
import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity
+import org.thoughtcrime.securesms.stickers.manage.StickerManagementScreen
import org.thoughtcrime.securesms.stories.StoryViewerArgs
import org.thoughtcrime.securesms.stories.viewer.StoryViewerActivity
import org.thoughtcrime.securesms.util.BottomSheetUtil
diff --git a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java
index f0f399a29a..ad34d8192b 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java
@@ -21,7 +21,7 @@ import org.thoughtcrime.securesms.keyboard.sticker.StickerSearchDialogFragment;
import org.thoughtcrime.securesms.scribbles.stickers.FeatureSticker;
import org.thoughtcrime.securesms.scribbles.stickers.ScribbleStickersFragment;
import org.thoughtcrime.securesms.stickers.StickerEventListener;
-import org.thoughtcrime.securesms.stickers.StickerManagementScreen;
+import org.thoughtcrime.securesms.stickers.manage.StickerManagementScreen;
import org.thoughtcrime.securesms.util.ViewUtil;
public final class ImageEditorStickerSelectActivity extends AppCompatActivity implements StickerEventListener, MediaKeyboard.MediaKeyboardListener, StickerKeyboardPageFragment.Callback, ScribbleStickersFragment.Callback {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewActivity.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewActivity.java
index 0ccaeb9e9c..48703292b0 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewActivity.java
@@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.glide.cache.ApngOptions;
import org.thoughtcrime.securesms.mms.DecryptableUri;
import org.thoughtcrime.securesms.sharing.MultiShareArgs;
import org.thoughtcrime.securesms.stickers.StickerManifest.Sticker;
+import org.thoughtcrime.securesms.stickers.manage.StickerManagementRepository;
import org.thoughtcrime.securesms.util.DeviceProperties;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.DynamicTheme;
diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewViewModel.java
index b03e20edf3..c45f4dd550 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewViewModel.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewViewModel.java
@@ -12,6 +12,7 @@ import androidx.lifecycle.ViewModelProvider;
import org.thoughtcrime.securesms.database.DatabaseObserver;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import org.thoughtcrime.securesms.stickers.StickerPackPreviewRepository.StickerManifestResult;
+import org.thoughtcrime.securesms.stickers.manage.StickerManagementRepository;
import java.util.Optional;
diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewViewModelV2.kt b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewViewModelV2.kt
index 2d716f8a84..f63c0890dd 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewViewModelV2.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackPreviewViewModelV2.kt
@@ -15,6 +15,7 @@ import kotlinx.coroutines.launch
import org.signal.core.util.orNull
import org.thoughtcrime.securesms.database.model.StickerPackParams
import org.thoughtcrime.securesms.stickers.StickerPackPreviewUiState.ContentState
+import org.thoughtcrime.securesms.stickers.manage.StickerManagementRepository
import kotlin.jvm.optionals.getOrElse
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPreviewDataFactory.kt b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPreviewDataFactory.kt
index d15e7c39d0..4bc4b2a871 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPreviewDataFactory.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPreviewDataFactory.kt
@@ -7,6 +7,8 @@ package org.thoughtcrime.securesms.stickers
import org.thoughtcrime.securesms.database.model.StickerPackRecord
import org.thoughtcrime.securesms.database.model.StickerRecord
+import org.thoughtcrime.securesms.stickers.manage.AvailableStickerPack
+import org.thoughtcrime.securesms.stickers.manage.InstalledStickerPack
import java.util.UUID
/**
diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementActivity.kt
new file mode 100644
index 0000000000..274836cde9
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementActivity.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2026 Signal Messenger, LLC
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+package org.thoughtcrime.securesms.stickers.manage
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import androidx.activity.compose.setContent
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import kotlinx.coroutines.launch
+import org.signal.core.ui.compose.copied.androidx.compose.DragAndDropEvent
+import org.thoughtcrime.securesms.PassphraseRequiredActivity
+import org.thoughtcrime.securesms.R
+import org.thoughtcrime.securesms.compose.SignalTheme
+import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment
+import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
+import org.thoughtcrime.securesms.database.model.StickerPackId
+import org.thoughtcrime.securesms.database.model.StickerPackKey
+import org.thoughtcrime.securesms.sharing.MultiShareArgs
+import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity
+import org.thoughtcrime.securesms.stickers.StickerUrl
+import org.thoughtcrime.securesms.util.viewModel
+
+/**
+ * Activity implementation of [StickerManagementScreen].
+ */
+class StickerManagementActivity : PassphraseRequiredActivity() {
+ companion object {
+ @JvmStatic
+ fun createIntent(context: Context): Intent = Intent(context, StickerManagementActivity::class.java)
+ }
+
+ private val viewModel by viewModel { StickerManagementViewModel() }
+
+ override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
+ super.onCreate(savedInstanceState, ready)
+
+ lifecycleScope.launch {
+ repeatOnLifecycle(Lifecycle.State.STARTED) {
+ viewModel.onScreenVisible()
+ }
+ }
+
+ setContent {
+ val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+
+ SignalTheme {
+ StickerManagementScreen(
+ uiState = uiState,
+ onNavigateBack = ::supportFinishAfterTransition,
+ onSetMultiSelectModeEnabled = viewModel::setMultiSelectEnabled,
+ onSnackbarDismiss = viewModel::onSnackbarDismiss,
+ availableTabCallbacks = remember {
+ object : AvailableStickersContentCallbacks {
+ override fun onForwardClick(pack: AvailableStickerPack) = openShareSheet(pack.id, pack.key)
+ override fun onInstallClick(pack: AvailableStickerPack) = viewModel.installStickerPack(pack)
+ override fun onShowPreviewClick(pack: AvailableStickerPack) = navigateToStickerPreview(pack.id, pack.key)
+ }
+ },
+ installedTabCallbacks = remember {
+ object : InstalledStickersContentCallbacks {
+ override fun onForwardClick(pack: InstalledStickerPack) = openShareSheet(pack.id, pack.key)
+ override fun onRemoveClick(packIds: Set) = viewModel.onUninstallStickerPacksRequested(packIds)
+ override fun onRemoveStickerPacksConfirmed(packIds: Set) = viewModel.onUninstallStickerPacksConfirmed(packIds)
+ override fun onRemoveStickerPacksCanceled() = viewModel.onUninstallStickerPacksCanceled()
+ override fun onSelectionToggle(pack: InstalledStickerPack) = viewModel.toggleSelection(pack)
+ override fun onSelectAllToggle() = viewModel.toggleSelectAll()
+ override fun onDragAndDropEvent(event: DragAndDropEvent) {
+ when (event) {
+ is DragAndDropEvent.OnItemMove -> viewModel.updatePosition(event.fromIndex, event.toIndex)
+ is DragAndDropEvent.OnItemDrop -> viewModel.saveInstalledPacksSortOrder()
+ is DragAndDropEvent.OnDragCancel -> {}
+ }
+ }
+
+ override fun onShowPreviewClick(pack: InstalledStickerPack) = navigateToStickerPreview(pack.id, pack.key)
+ }
+ }
+ )
+ }
+ }
+ }
+
+ private fun openShareSheet(packId: StickerPackId, packKey: StickerPackKey) {
+ MultiselectForwardFragment.showBottomSheet(
+ supportFragmentManager = supportFragmentManager,
+ multiselectForwardFragmentArgs = MultiselectForwardFragmentArgs(
+ multiShareArgs = listOf(
+ MultiShareArgs.Builder()
+ .withDraftText(StickerUrl.createShareLink(packId.value, packKey.value))
+ .build()
+ ),
+ title = R.string.StickerManagement_share_sheet_title
+ )
+ )
+ }
+
+ private fun navigateToStickerPreview(packId: StickerPackId, packKey: StickerPackKey) {
+ startActivity(StickerPackPreviewActivity.getIntent(packId.value, packKey.value))
+ }
+}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementBottomSheet.kt b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementBottomSheet.kt
similarity index 96%
rename from app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementBottomSheet.kt
rename to app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementBottomSheet.kt
index 1f5cd6f1e4..f043b2d289 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementBottomSheet.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementBottomSheet.kt
@@ -1,9 +1,9 @@
/*
- * Copyright 2025 Signal Messenger, LLC
+ * Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
-package org.thoughtcrime.securesms.stickers
+package org.thoughtcrime.securesms.stickers.manage
import android.app.Dialog
import android.os.Bundle
@@ -36,6 +36,8 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor
import org.thoughtcrime.securesms.database.model.StickerPackId
import org.thoughtcrime.securesms.database.model.StickerPackKey
import org.thoughtcrime.securesms.sharing.MultiShareArgs
+import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity
+import org.thoughtcrime.securesms.stickers.StickerUrl
import org.thoughtcrime.securesms.util.viewModel
/**
diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementRepository.kt
similarity index 97%
rename from app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementRepository.kt
rename to app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementRepository.kt
index ea83e3ff9b..b4ed33dec8 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementRepository.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementRepository.kt
@@ -1,9 +1,9 @@
/*
- * Copyright 2025 Signal Messenger, LLC
+ * Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
-package org.thoughtcrime.securesms.stickers
+package org.thoughtcrime.securesms.stickers.manage
import androidx.annotation.Discouraged
import kotlinx.coroutines.CoroutineScope
@@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.jobmanager.JobManager
import org.thoughtcrime.securesms.jobs.MultiDeviceStickerPackOperationJob
import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob
import org.thoughtcrime.securesms.keyvalue.SignalStore
+import org.thoughtcrime.securesms.stickers.BlessedPacks
/**
* Handles the retrieval and modification of sticker pack data.
diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementScreen.kt
similarity index 83%
rename from app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementActivity.kt
rename to app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementScreen.kt
index 26e308bae2..91b2e6d1e8 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementActivity.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementScreen.kt
@@ -1,16 +1,12 @@
/*
- * Copyright 2025 Signal Messenger, LLC
+ * Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
-package org.thoughtcrime.securesms.stickers
+package org.thoughtcrime.securesms.stickers.manage
-import android.content.Context
-import android.content.Intent
import android.content.res.Resources
-import android.os.Bundle
import androidx.activity.compose.BackHandler
-import androidx.activity.compose.setContent
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
@@ -63,10 +59,6 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import androidx.lifecycle.lifecycleScope
-import androidx.lifecycle.repeatOnLifecycle
import androidx.window.core.layout.WindowSizeClass
import kotlinx.coroutines.launch
import org.signal.core.ui.compose.DayNightPreviews
@@ -81,99 +73,45 @@ import org.signal.core.ui.compose.copied.androidx.compose.DraggableItem
import org.signal.core.ui.compose.copied.androidx.compose.dragContainer
import org.signal.core.ui.compose.copied.androidx.compose.rememberDragDropState
import org.signal.core.ui.compose.showSnackbar
-import org.thoughtcrime.securesms.PassphraseRequiredActivity
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.menu.ActionItem
import org.thoughtcrime.securesms.components.menu.SignalBottomActionBar
-import org.thoughtcrime.securesms.compose.SignalTheme
-import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment
-import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
import org.thoughtcrime.securesms.database.model.StickerPackId
-import org.thoughtcrime.securesms.database.model.StickerPackKey
-import org.thoughtcrime.securesms.sharing.MultiShareArgs
-import org.thoughtcrime.securesms.stickers.AvailableStickerPack.DownloadStatus
-import org.thoughtcrime.securesms.stickers.StickerManagementActivity.Companion.createIntent
-import org.thoughtcrime.securesms.util.viewModel
+import org.thoughtcrime.securesms.stickers.StickerPreviewDataFactory
+import org.thoughtcrime.securesms.stickers.manage.AvailableStickerPack.DownloadStatus
import org.thoughtcrime.securesms.window.getWindowSizeClass
import java.text.NumberFormat
-/**
- * Displays all the available and installed sticker packs, enabling installation, uninstallation, and sorting.
- */
-class StickerManagementActivity : PassphraseRequiredActivity() {
- companion object {
- @JvmStatic
- fun createIntent(context: Context): Intent = Intent(context, StickerManagementActivity::class.java)
- }
-
- private val viewModel by viewModel { StickerManagementViewModel() }
-
- override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
- super.onCreate(savedInstanceState, ready)
-
- lifecycleScope.launch {
- repeatOnLifecycle(Lifecycle.State.STARTED) {
- viewModel.onScreenVisible()
- }
- }
-
- setContent {
- val uiState by viewModel.uiState.collectAsStateWithLifecycle()
-
- SignalTheme {
- StickerManagementScreen(
- uiState = uiState,
- onNavigateBack = ::supportFinishAfterTransition,
- onSetMultiSelectModeEnabled = viewModel::setMultiSelectEnabled,
- onSnackbarDismiss = viewModel::onSnackbarDismiss,
- availableTabCallbacks = remember {
- object : AvailableStickersContentCallbacks {
- override fun onForwardClick(pack: AvailableStickerPack) = openShareSheet(pack.id, pack.key)
- override fun onInstallClick(pack: AvailableStickerPack) = viewModel.installStickerPack(pack)
- override fun onShowPreviewClick(pack: AvailableStickerPack) = navigateToStickerPreview(pack.id, pack.key)
- }
- },
- installedTabCallbacks = remember {
- object : InstalledStickersContentCallbacks {
- override fun onForwardClick(pack: InstalledStickerPack) = openShareSheet(pack.id, pack.key)
- override fun onRemoveClick(packIds: Set) = viewModel.onUninstallStickerPacksRequested(packIds)
- override fun onRemoveStickerPacksConfirmed(packIds: Set) = viewModel.onUninstallStickerPacksConfirmed(packIds)
- override fun onRemoveStickerPacksCanceled() = viewModel.onUninstallStickerPacksCanceled()
- override fun onSelectionToggle(pack: InstalledStickerPack) = viewModel.toggleSelection(pack)
- override fun onSelectAllToggle() = viewModel.toggleSelectAll()
- override fun onDragAndDropEvent(event: DragAndDropEvent) {
- when (event) {
- is DragAndDropEvent.OnItemMove -> viewModel.updatePosition(event.fromIndex, event.toIndex)
- is DragAndDropEvent.OnItemDrop -> viewModel.saveInstalledPacksSortOrder()
- is DragAndDropEvent.OnDragCancel -> {}
- }
- }
-
- override fun onShowPreviewClick(pack: InstalledStickerPack) = navigateToStickerPreview(pack.id, pack.key)
- }
- }
- )
- }
+object StickerManagementScreen {
+ /**
+ * Shows the screen as a bottom sheet on large devices (tablets/foldables), activity on phones.
+ */
+ @JvmStatic
+ fun show(activity: FragmentActivity) {
+ if (showAsBottomSheet(activity.resources)) {
+ StickerManagementBottomSheet.show(activity.supportFragmentManager)
+ } else {
+ activity.startActivity(StickerManagementActivity.createIntent(activity))
}
}
- private fun openShareSheet(packId: StickerPackId, packKey: StickerPackKey) {
- MultiselectForwardFragment.showBottomSheet(
- supportFragmentManager = supportFragmentManager,
- multiselectForwardFragmentArgs = MultiselectForwardFragmentArgs(
- multiShareArgs = listOf(
- MultiShareArgs.Builder()
- .withDraftText(StickerUrl.createShareLink(packId.value, packKey.value))
- .build()
- ),
- title = R.string.StickerManagement_share_sheet_title
- )
+ /**
+ * Shows the screen as a bottom sheet on large devices (tablets/foldables), activity on phones.
+ */
+ fun show(fragment: Fragment) {
+ if (showAsBottomSheet(fragment.resources)) {
+ StickerManagementBottomSheet.show(fragment.parentFragmentManager)
+ } else {
+ fragment.startActivity(StickerManagementActivity.createIntent(fragment.requireContext()))
+ }
+ }
+
+ private fun showAsBottomSheet(resources: Resources): Boolean {
+ return resources.getWindowSizeClass().isAtLeastBreakpoint(
+ widthDpBreakpoint = WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND,
+ heightDpBreakpoint = WindowSizeClass.HEIGHT_DP_MEDIUM_LOWER_BOUND
)
}
-
- private fun navigateToStickerPreview(packId: StickerPackId, packKey: StickerPackKey) {
- startActivity(StickerPackPreviewActivity.getIntent(packId.value, packKey.value))
- }
}
private data class Page(
@@ -215,38 +153,12 @@ interface InstalledStickersContentCallbacks {
}
}
-object StickerManagementScreen {
- /**
- * Shows the screen as a bottom sheet on large devices (tablets/foldables), activity on phones.
- */
- @JvmStatic
- fun show(activity: FragmentActivity) {
- if (showAsBottomSheet(activity.resources)) {
- StickerManagementBottomSheet.show(activity.supportFragmentManager)
- } else {
- activity.startActivity(createIntent(activity))
- }
- }
-
- /**
- * Shows the screen as a bottom sheet on large devices (tablets/foldables), activity on phones.
- */
- fun show(fragment: Fragment) {
- if (showAsBottomSheet(fragment.resources)) {
- StickerManagementBottomSheet.show(fragment.parentFragmentManager)
- } else {
- fragment.startActivity(createIntent(fragment.requireContext()))
- }
- }
-
- private fun showAsBottomSheet(resources: Resources): Boolean {
- return resources.getWindowSizeClass().isAtLeastBreakpoint(
- widthDpBreakpoint = WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND,
- heightDpBreakpoint = WindowSizeClass.HEIGHT_DP_MEDIUM_LOWER_BOUND
- )
- }
-}
-
+/**
+ * Displays all the available and installed sticker packs, enabling installation, uninstallation, and sorting.
+ *
+ * @see StickerManagementActivity
+ * @see StickerManagementBottomSheet
+ */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun StickerManagementScreen(
diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementViewModel.kt
similarity index 97%
rename from app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementViewModel.kt
rename to app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementViewModel.kt
index cf031ca15d..a47ba34038 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementViewModel.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerManagementViewModel.kt
@@ -1,9 +1,9 @@
/*
- * Copyright 2025 Signal Messenger, LLC
+ * Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
-package org.thoughtcrime.securesms.stickers
+package org.thoughtcrime.securesms.stickers.manage
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@@ -19,7 +19,8 @@ import org.signal.core.util.swap
import org.thoughtcrime.securesms.database.model.StickerPackId
import org.thoughtcrime.securesms.database.model.StickerPackKey
import org.thoughtcrime.securesms.database.model.StickerPackRecord
-import org.thoughtcrime.securesms.stickers.AvailableStickerPack.DownloadStatus
+import org.thoughtcrime.securesms.stickers.BlessedPacks
+import org.thoughtcrime.securesms.stickers.manage.AvailableStickerPack.DownloadStatus
class StickerManagementViewModel : ViewModel() {
private val stickerManagementRepo = StickerManagementRepository
diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackListItems.kt b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerPackListItems.kt
similarity index 98%
rename from app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackListItems.kt
rename to app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerPackListItems.kt
index c402c7caa0..feeb2baa54 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerPackListItems.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/manage/StickerPackListItems.kt
@@ -1,9 +1,9 @@
/*
- * Copyright 2025 Signal Messenger, LLC
+ * Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
-package org.thoughtcrime.securesms.stickers
+package org.thoughtcrime.securesms.stickers.manage
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandHorizontally
@@ -42,7 +42,8 @@ import org.thoughtcrime.securesms.components.transfercontrols.TransferProgressIn
import org.thoughtcrime.securesms.components.transfercontrols.TransferProgressState
import org.thoughtcrime.securesms.compose.GlideImage
import org.thoughtcrime.securesms.mms.DecryptableUri
-import org.thoughtcrime.securesms.stickers.AvailableStickerPack.DownloadStatus
+import org.thoughtcrime.securesms.stickers.StickerPreviewDataFactory
+import org.thoughtcrime.securesms.stickers.manage.AvailableStickerPack.DownloadStatus
import org.thoughtcrime.securesms.util.DeviceProperties
@Composable