Delete old/unused sticker management v1 code.

Deletes the old code related to sticker management v1 and removes the v2 prefix from the new classes.
This commit is contained in:
Jeffrey Starke
2025-05-02 16:21:24 -04:00
committed by Michelle Tang
parent 5306a9dd7a
commit 844dec06b1
18 changed files with 16 additions and 905 deletions

View File

@@ -878,13 +878,6 @@
android:exported="false"/>
<activity android:name=".stickers.StickerManagementActivity"
android:launchMode="singleTask"
android:theme="@style/TextSecure.LightTheme"
android:windowSoftInputMode="stateUnchanged"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:exported="false"/>
<activity android:name=".stickers.StickerManagementActivityV2"
android:exported="false"
android:theme="@style/Signal.DayNight.NoActionBar" />

View File

@@ -298,7 +298,7 @@ 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.StickerManagementActivityV2
import org.thoughtcrime.securesms.stickers.StickerManagementActivity
import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent
import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity
import org.thoughtcrime.securesms.stories.StoryViewerArgs
@@ -828,7 +828,7 @@ class ConversationFragment :
}
override fun onStickerManagementClicked() {
startActivity(StickerManagementActivityV2.createIntent(requireContext()))
startActivity(StickerManagementActivity.createIntent(requireContext()))
container.hideInput()
}

View File

@@ -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.StickerManagementActivityV2;
import org.thoughtcrime.securesms.stickers.StickerManagementActivity;
import org.thoughtcrime.securesms.util.ViewUtil;
public final class ImageEditorStickerSelectActivity extends AppCompatActivity implements StickerEventListener, MediaKeyboard.MediaKeyboardListener, StickerKeyboardPageFragment.Callback, ScribbleStickersFragment.Callback {
@@ -66,7 +66,7 @@ public final class ImageEditorStickerSelectActivity extends AppCompatActivity im
@Override
public void onStickerManagementClicked() {
startActivity(StickerManagementActivityV2.createIntent(ImageEditorStickerSelectActivity.this));
startActivity(StickerManagementActivity.createIntent(ImageEditorStickerSelectActivity.this));
}

View File

@@ -1,153 +0,0 @@
package org.thoughtcrime.securesms.stickers;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import org.thoughtcrime.securesms.PassphraseRequiredActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment;
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs;
import org.thoughtcrime.securesms.sharing.MultiShareArgs;
import org.thoughtcrime.securesms.util.DeviceProperties;
import org.thoughtcrime.securesms.util.DynamicTheme;
import java.util.Collections;
/**
* Allows the user to view and manage (install, uninstall, etc) their stickers.
*/
public final class StickerManagementActivity extends PassphraseRequiredActivity implements StickerManagementAdapter.EventListener {
private final DynamicTheme dynamicTheme = new DynamicTheme();
private RecyclerView list;
private StickerManagementAdapter adapter;
private StickerManagementViewModel viewModel;
public static Intent getIntent(@NonNull Context context) {
return new Intent(context, StickerManagementActivity.class);
}
@Override
protected void onPreCreate() {
super.onPreCreate();
dynamicTheme.onCreate(this);
}
@Override
protected void onCreate(Bundle savedInstanceState, boolean ready) {
setContentView(R.layout.sticker_management_activity);
initView();
initToolbar();
initViewModel();
getSupportFragmentManager().setFragmentResultListener(MultiselectForwardFragment.RESULT_KEY, this, (requestKey, result) -> {
if (result.getBoolean(MultiselectForwardFragment.RESULT_SENT, false)) {
finish();
}
});
}
@Override
protected void onStart() {
super.onStart();
viewModel.onVisible();
}
@Override
protected void onResume() {
super.onResume();
dynamicTheme.onResume(this);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onStickerPackClicked(@NonNull String packId, @NonNull String packKey) {
startActivity(StickerPackPreviewActivity.getIntent(packId, packKey));
}
@Override
public void onStickerPackUninstallClicked(@NonNull String packId, @NonNull String packKey) {
viewModel.onStickerPackUninstallClicked(packId, packKey);
}
@Override
public void onStickerPackInstallClicked(@NonNull String packId, @NonNull String packKey) {
viewModel.onStickerPackInstallClicked(packId, packKey);
}
@Override
public void onStickerPackShareClicked(@NonNull String packId, @NonNull String packKey) {
MultiselectForwardFragment.showBottomSheet(
getSupportFragmentManager(),
new MultiselectForwardFragmentArgs(
Collections.singletonList(new MultiShareArgs.Builder()
.withDraftText(StickerUrl.createShareLink(packId, packKey))
.build()),
R.string.MultiselectForwardFragment__share_with
)
);
}
private void initView() {
this.list = findViewById(R.id.sticker_management_list);
this.adapter = new StickerManagementAdapter(Glide.with(this), this, DeviceProperties.shouldAllowApngStickerAnimation(this));
list.setLayoutManager(new LinearLayoutManager(this));
list.setAdapter(adapter);
new ItemTouchHelper(new StickerManagementItemTouchHelper(new ItemTouchCallback())).attachToRecyclerView(list);
}
private void initToolbar() {
getSupportActionBar().setTitle(R.string.StickerManagementActivity_stickers);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void initViewModel() {
StickerManagementRepository repository = StickerManagementRepository.INSTANCE;
viewModel = new ViewModelProvider(this, new StickerManagementViewModel.Factory(getApplication(), repository)).get(StickerManagementViewModel.class);
viewModel.init();
viewModel.getStickerPacks().observe(this, packResult -> {
if (packResult == null) return;
adapter.setPackLists(packResult.getInstalledPacks(), packResult.getAvailablePacks(), packResult.getBlessedPacks());
});
}
private class ItemTouchCallback implements StickerManagementItemTouchHelper.Callback {
@Override
public boolean onMove(int start, int end) {
return adapter.onMove(start, end);
}
@Override
public boolean isMovable(int position) {
return adapter.isMovable(position);
}
@Override
public void onMoveCommitted() {
viewModel.onOrderChanged(adapter.getInstalledPacksInOrder());
}
}
}

View File

@@ -98,13 +98,13 @@ import java.text.NumberFormat
/**
* Displays all of the available and installed sticker packs, enabling installation, uninstallation, and sorting.
*/
class StickerManagementActivityV2 : PassphraseRequiredActivity() {
class StickerManagementActivity : PassphraseRequiredActivity() {
companion object {
@JvmStatic
fun createIntent(context: Context): Intent = Intent(context, StickerManagementActivityV2::class.java)
fun createIntent(context: Context): Intent = Intent(context, StickerManagementActivity::class.java)
}
private val viewModel by viewModel { StickerManagementViewModelV2() }
private val viewModel by viewModel { StickerManagementViewModel() }
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
super.onCreate(savedInstanceState, ready)
@@ -311,7 +311,7 @@ private fun TopAppBar(
onSetMultiSelectModeEnabled: (Boolean) -> Unit
) {
Scaffolds.DefaultTopAppBar(
title = stringResource(R.string.StickerManagementActivity_stickers),
title = stringResource(R.string.StickerManagement_title_stickers),
titleContent = { _, title -> Text(text = title, style = MaterialTheme.typography.titleLarge) },
navigationIconPainter = painterResource(R.drawable.symbol_arrow_start_24),
navigationContentDescription = stringResource(R.string.DefaultTopAppBar__navigate_up_content_description),

View File

@@ -1,357 +0,0 @@
package org.thoughtcrime.securesms.stickers;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.style.ImageSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
import org.thoughtcrime.securesms.database.model.StickerPackRecord;
import org.thoughtcrime.securesms.glide.cache.ApngOptions;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
import org.thoughtcrime.securesms.util.DrawableUtil;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.adapter.SectionedRecyclerViewAdapter;
import org.thoughtcrime.securesms.util.adapter.StableIdGenerator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
final class StickerManagementAdapter extends SectionedRecyclerViewAdapter<String, StickerManagementAdapter.StickerSection> {
private static final String TAG_YOUR_STICKERS = "YourStickers";
private static final String TAG_MESSAGE_STICKERS = "MessageStickers";
private static final String TAG_BLESSED_STICKERS = "BlessedStickers";
private final RequestManager requestManager;
private final EventListener eventListener;
private final boolean allowApngAnimation;
private final List<StickerSection> sections = new ArrayList<StickerSection>(3) {{
StickerSection yourStickers = new StickerSection(TAG_YOUR_STICKERS,
R.string.StickerManagement_installed_stickers_header,
R.string.StickerManagementAdapter_no_stickers_installed,
new ArrayList<>(),
0);
StickerSection messageStickers = new StickerSection(TAG_MESSAGE_STICKERS,
R.string.StickerManagement_stickers_you_received_header,
R.string.StickerManagementAdapter_stickers_from_incoming_messages_will_appear_here,
new ArrayList<>(),
yourStickers.size());
add(yourStickers);
add(messageStickers);
}};
StickerManagementAdapter(@NonNull RequestManager requestManager, @NonNull EventListener eventListener, boolean allowApngAnimation) {
this.requestManager = requestManager;
this.eventListener = eventListener;
this.allowApngAnimation = allowApngAnimation;
}
@Override
protected @NonNull List<StickerSection> getSections() {
return sections;
}
@Override
protected @NonNull RecyclerView.ViewHolder createHeaderViewHolder(@NonNull ViewGroup parent) {
return new HeaderViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.sticker_management_header_item, parent, false));
}
@Override
protected @NonNull RecyclerView.ViewHolder createContentViewHolder(@NonNull ViewGroup parent) {
return new StickerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.sticker_management_sticker_item, parent, false));
}
@Override
protected @NonNull RecyclerView.ViewHolder createEmptyViewHolder(@NonNull ViewGroup viewGroup) {
return new EmptyViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.sticker_management_empty_item, viewGroup, false));
}
@Override
public void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull StickerSection section, int localPosition) {
section.bindViewHolder(viewHolder, localPosition, requestManager, eventListener, allowApngAnimation);
}
@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
if (holder instanceof StickerViewHolder) {
((StickerViewHolder) holder).recycle();
}
}
boolean onMove(int start, int end) {
StickerSection installed = sections.get(0);
if (!installed.isContent(start)) {
return false;
}
if (!installed.isContent(end)) {
return false;
}
installed.swap(start, end);
notifyItemMoved(start, end);
return true;
}
boolean isMovable(int position) {
return sections.get(0).isContent(position);
}
@NonNull List<StickerPackRecord> getInstalledPacksInOrder() {
return sections.get(0).records;
}
void setPackLists(@NonNull List<StickerPackRecord> installedPacks,
@NonNull List<StickerPackRecord> availablePacks,
@NonNull List<StickerPackRecord> blessedPacks)
{
StickerSection yourStickers = new StickerSection(TAG_YOUR_STICKERS,
R.string.StickerManagement_installed_stickers_header,
R.string.StickerManagementAdapter_no_stickers_installed,
installedPacks,
0);
StickerSection blessedStickers = new StickerSection(TAG_BLESSED_STICKERS,
R.string.StickerManagement_signal_artist_series_header,
0,
blessedPacks,
yourStickers.size());
StickerSection messageStickers = new StickerSection(TAG_MESSAGE_STICKERS,
R.string.StickerManagement_stickers_you_received_header,
R.string.StickerManagementAdapter_stickers_from_incoming_messages_will_appear_here,
availablePacks,
yourStickers.size() + (blessedPacks.isEmpty() ? 0 : blessedStickers.size()));
sections.clear();
sections.add(yourStickers);
if (!blessedPacks.isEmpty()) {
sections.add(blessedStickers);
}
sections.add(messageStickers);
notifyDataSetChanged();
}
public static class StickerSection extends SectionedRecyclerViewAdapter.Section<String> {
private static final String STABLE_ID_HEADER = "header";
private static final String STABLE_ID_TEXT = "text";
private final String tag;
private final int titleResId;
private final int emptyResId;
private final List<StickerPackRecord> records;
StickerSection(@NonNull String tag,
@StringRes int titleResId,
@StringRes int emptyResId,
@NonNull List<StickerPackRecord> records,
int offset)
{
super(offset);
this.tag = tag;
this.titleResId = titleResId;
this.emptyResId = emptyResId;
this.records = records;
}
@Override
public boolean hasEmptyState() {
return true;
}
@Override
public int getContentSize() {
return records.size();
}
@Override
public long getItemId(@NonNull StableIdGenerator<String> idGenerator, int globalPosition) {
int localPosition = getLocalPosition(globalPosition);
if (localPosition == 0) {
return idGenerator.getId(tag + "_" + STABLE_ID_HEADER);
} else if (records.isEmpty()) {
return idGenerator.getId(tag + "_" + STABLE_ID_TEXT);
} else {
return idGenerator.getId(records.get(localPosition - 1).packId);
}
}
void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder,
int localPosition,
@NonNull RequestManager requestManager,
@NonNull EventListener eventListener,
boolean allowApngAnimation)
{
if (localPosition == 0) {
((HeaderViewHolder) viewHolder).bind(titleResId);
} else if (records.isEmpty()) {
((EmptyViewHolder) viewHolder).bind(emptyResId);
} else {
((StickerViewHolder) viewHolder).bind(requestManager, eventListener, records.get(localPosition - 1), localPosition == records.size(), allowApngAnimation);
}
}
void swap(int start, int end) {
int localStart = getLocalPosition(start) - 1;
int localEnd = getLocalPosition(end) - 1;
if (localStart < localEnd) {
for (int i = localStart; i < localEnd; i++) {
Collections.swap(records, i, i + 1);
}
} else {
for (int i = localStart; i > localEnd; i--) {
Collections.swap(records, i, i - 1);
}
}
}
}
static class StickerViewHolder extends RecyclerView.ViewHolder {
private final ImageView cover;
private final EmojiTextView title;
private final TextView author;
private final View divider;
private final View actionButton;
private final ImageView actionButtonImage;
private final View shareButton;
private final ImageView shareButtonImage;
private final CharSequence blessedBadge;
StickerViewHolder(@NonNull View itemView) {
super(itemView);
this.cover = itemView.findViewById(R.id.sticker_management_cover);
this.title = itemView.findViewById(R.id.sticker_management_title);
this.author = itemView.findViewById(R.id.sticker_management_author);
this.divider = itemView.findViewById(R.id.sticker_management_divider);
this.actionButton = itemView.findViewById(R.id.sticker_management_action_button);
this.actionButtonImage = itemView.findViewById(R.id.sticker_management_action_button_image);
this.shareButton = itemView.findViewById(R.id.sticker_management_share_button);
this.shareButtonImage = itemView.findViewById(R.id.sticker_management_share_button_image);
this.blessedBadge = buildBlessedBadge(itemView.getContext());
}
void bind(@NonNull RequestManager requestManager,
@NonNull EventListener eventListener,
@NonNull StickerPackRecord stickerPack,
boolean lastInList,
boolean allowApngAnimation)
{
SpannableStringBuilder titleBuilder = new SpannableStringBuilder(stickerPack.titleOptional.orElse(itemView.getResources().getString(R.string.StickerManagementAdapter_untitled)));
if (BlessedPacks.contains(stickerPack.packId)) {
titleBuilder.append(blessedBadge);
}
title.setText(titleBuilder);
author.setText(stickerPack.authorOptional.orElse(itemView.getResources().getString(R.string.StickerManagement_author_unknown)));
divider.setVisibility(lastInList ? View.GONE : View.VISIBLE);
requestManager.load(new DecryptableUri(stickerPack.cover.uri))
.transition(DrawableTransitionOptions.withCrossFade())
.fitCenter()
.set(ApngOptions.ANIMATE, allowApngAnimation)
.into(cover);
if (stickerPack.isInstalled) {
actionButtonImage.setImageResource(R.drawable.ic_x);
actionButton.setOnClickListener(v -> eventListener.onStickerPackUninstallClicked(stickerPack.packId, stickerPack.packKey));
shareButton.setVisibility(View.VISIBLE);
shareButtonImage.setVisibility(View.VISIBLE);
shareButton.setOnClickListener(v -> eventListener.onStickerPackShareClicked(stickerPack.packId, stickerPack.packKey));
} else {
actionButtonImage.setImageResource(R.drawable.symbol_arrow_down_24);
actionButton.setOnClickListener(v -> eventListener.onStickerPackInstallClicked(stickerPack.packId, stickerPack.packKey));
shareButton.setVisibility(View.GONE);
shareButtonImage.setVisibility(View.GONE);
shareButton.setOnClickListener(null);
}
itemView.setOnClickListener(v -> eventListener.onStickerPackClicked(stickerPack.packId, stickerPack.packKey));
}
void recycle() {
actionButton.setOnClickListener(null);
shareButton.setOnClickListener(null);
itemView.setOnClickListener(null);
}
private static @NonNull CharSequence buildBlessedBadge(@NonNull Context context) {
SpannableString badgeSpan = new SpannableString(" ");
Drawable badge = ContextCompat.getDrawable(context, R.drawable.symbol_check_circle_fill_24);
badge.setBounds(0, 0, ViewUtil.dpToPx(18), ViewUtil.dpToPx(18));
DrawableUtil.tint(badge, ContextCompat.getColor(context, R.color.core_ultramarine));
badgeSpan.setSpan(new ImageSpan(badge), 1, badgeSpan.length(), 0);
return badgeSpan;
}
}
static class HeaderViewHolder extends RecyclerView.ViewHolder {
private final TextView titleView;
HeaderViewHolder(@NonNull View itemView) {
super(itemView);
this.titleView = itemView.findViewById(R.id.sticker_management_header);
}
void bind(@StringRes int title) {
titleView.setText(title);
}
}
static class EmptyViewHolder extends RecyclerView.ViewHolder {
private final TextView text;
EmptyViewHolder(@NonNull View itemView) {
super(itemView);
this.text = itemView.findViewById(R.id.sticker_management_empty_text);
}
void bind(@StringRes int title) {
text.setText(title);
}
}
interface EventListener {
void onStickerPackClicked(@NonNull String packId, @NonNull String packKey);
void onStickerPackUninstallClicked(@NonNull String packId, @NonNull String packKey);
void onStickerPackInstallClicked(@NonNull String packId, @NonNull String packKey);
void onStickerPackShareClicked(@NonNull String packId, @NonNull String packKey);
}
private static class NoSectionException extends IllegalStateException {}
}

View File

@@ -1,58 +0,0 @@
package org.thoughtcrime.securesms.stickers;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
public class StickerManagementItemTouchHelper extends ItemTouchHelper.Callback {
private final Callback callback;
public StickerManagementItemTouchHelper(Callback callback) {
this.callback = callback;
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public boolean isItemViewSwipeEnabled() {
return false;
}
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
if (callback.isMovable(viewHolder.getAdapterPosition())) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
return makeMovementFlags(dragFlags, 0);
} else {
return 0;
}
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return callback.onMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
}
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
callback.onMoveCommitted();
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
public interface Callback {
/**
* @return True if both the start and end positions are valid, and therefore the move will occur.
*/
boolean onMove(int start, int end);
void onMoveCommitted();
boolean isMovable(int position);
}
}

View File

@@ -6,7 +6,6 @@
package org.thoughtcrime.securesms.stickers
import androidx.annotation.Discouraged
import androidx.annotation.WorkerThread
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.awaitClose
@@ -39,14 +38,6 @@ object StickerManagementRepository {
private val attachmentsDbTable: AttachmentTable = SignalDatabase.attachments
private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)
@Discouraged("For Java use only. In Kotlin, use the getStickerPacks() overload that returns a Flow instead.")
@WorkerThread
fun getStickerPacks(callback: Callback<StickerPacksResult>) {
coroutineScope.launch {
callback.onComplete(loadStickerPacks())
}
}
/**
* Emits the sticker packs along with any updates.
*/
@@ -91,13 +82,6 @@ object StickerManagementRepository {
}
}
@Discouraged("For Java use only. In Kotlin, use deleteOrphanedStickerPacks() instead.")
fun deleteOrphanedStickerPacksAsync() {
coroutineScope.launch {
deleteOrphanedStickerPacks()
}
}
suspend fun deleteOrphanedStickerPacks() = withContext(Dispatchers.IO) {
stickersDbTable.deleteOrphanedPacks()
}
@@ -112,6 +96,7 @@ object StickerManagementRepository {
}
}
@Discouraged("For Java use only. In Kotlin, use installStickerPack() instead.")
fun installStickerPackAsync(packId: String, packKey: String, notify: Boolean) {
coroutineScope.launch {
installStickerPack(StickerPackId(packId), StickerPackKey(packKey), notify)
@@ -145,13 +130,6 @@ object StickerManagementRepository {
}
}
@Discouraged("For Java use only. In Kotlin, use setStickerPackOrder() instead.")
fun setStickerPacksOrderAsync(packsInOrder: List<StickerPackRecord>) {
coroutineScope.launch {
setStickerPacksOrder(packsInOrder)
}
}
suspend fun setStickerPacksOrder(packsInOrder: List<StickerPackRecord>) = withContext(Dispatchers.IO) {
stickersDbTable.updatePackOrder(packsInOrder)
}

View File

@@ -1,83 +0,0 @@
package org.thoughtcrime.securesms.stickers;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import org.thoughtcrime.securesms.database.DatabaseObserver;
import org.thoughtcrime.securesms.database.model.StickerPackRecord;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import java.util.List;
final class StickerManagementViewModel extends ViewModel {
private final Application application;
private final StickerManagementRepository repository;
private final MutableLiveData<StickerPacksResult> packs;
private final DatabaseObserver.Observer observer;
private StickerManagementViewModel(@NonNull Application application, @NonNull StickerManagementRepository repository) {
this.application = application;
this.repository = repository;
this.packs = new MutableLiveData<>();
this.observer = () -> {
repository.deleteOrphanedStickerPacksAsync();
repository.getStickerPacks(packs::postValue);
};
AppDependencies.getDatabaseObserver().registerStickerPackObserver(observer);
}
void init() {
repository.deleteOrphanedStickerPacksAsync();
repository.fetchUnretrievedReferencePacks();
}
void onVisible() {
repository.deleteOrphanedStickerPacksAsync();
}
@NonNull LiveData<StickerPacksResult> getStickerPacks() {
repository.getStickerPacks(packs::postValue);
return packs;
}
void onStickerPackUninstallClicked(@NonNull String packId, @NonNull String packKey) {
repository.uninstallStickerPackAsync(packId, packKey);
}
void onStickerPackInstallClicked(@NonNull String packId, @NonNull String packKey) {
repository.installStickerPackAsync(packId, packKey, false);
}
void onOrderChanged(List<StickerPackRecord> packsInOrder) {
repository.setStickerPacksOrderAsync(packsInOrder);
}
@Override
protected void onCleared() {
AppDependencies.getDatabaseObserver().unregisterObserver(observer);
}
static class Factory extends ViewModelProvider.NewInstanceFactory {
private final Application application;
private final StickerManagementRepository repository;
Factory(@NonNull Application application, @NonNull StickerManagementRepository repository) {
this.application = application;
this.repository = repository;
}
@Override
public @NonNull <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
//noinspection ConstantConditions
return modelClass.cast(new StickerManagementViewModel(application, repository));
}
}
}

View File

@@ -21,7 +21,7 @@ import org.thoughtcrime.securesms.database.model.StickerPackKey
import org.thoughtcrime.securesms.database.model.StickerPackRecord
import org.thoughtcrime.securesms.stickers.AvailableStickerPack.DownloadStatus
class StickerManagementViewModelV2 : ViewModel() {
class StickerManagementViewModel : ViewModel() {
private val stickerManagementRepo = StickerManagementRepository
private val _uiState = MutableStateFlow(StickerManagementUiState())

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="@color/core_white"/>
<corners android:radius="8dp"/>
</shape>

View File

@@ -1,9 +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="M12 1.5C6.2 1.5 1.5 6.2 1.5 12S6.2 22.5 12 22.5 22.5 17.8 22.5 12 17.8 1.5 12 1.5Zm4.46 6c0.41 0.26 0.54 0.8 0.28 1.21l-5 8c-0.15 0.24-0.4 0.4-0.69 0.41-0.28 0.02-0.56-0.1-0.73-0.32l-3-3.75c-0.3-0.38-0.24-0.93 0.13-1.23 0.38-0.3 0.93-0.24 1.23 0.13l2.23 2.79 4.35-6.95c0.25-0.41 0.8-0.54 1.2-0.28Z"/>
</vector>

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:tools="http://schemas.android.com/tools"
tools:viewBindingIgnore="true"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/sticker_management_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"/>
</LinearLayout>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
tools:viewBindingIgnore="true"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/sticker_management_horizontal_margin"
android:layout_marginEnd="@dimen/sticker_management_horizontal_margin">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:src="@drawable/sticker_management_empty_background"
android:tint="@color/signal_background_secondary"
app:layout_constraintTop_toTopOf="@id/sticker_management_empty_text"
app:layout_constraintBottom_toBottomOf="@id/sticker_management_empty_text"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/sticker_management_empty_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="13sp"
android:padding="12dp"
style="@style/Signal.Text.Caption"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="With great power there must also come -- great responsibility!"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
xmlns:android="http://schemas.android.com/apk/res/android"
tools:viewBindingIgnore="true"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/sticker_management_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/sticker_management_horizontal_margin"
android:layout_marginEnd="@dimen/sticker_management_horizontal_margin"
android:layout_marginTop="16dp"
android:layout_marginBottom="24dp"
style="@style/Signal.Text.Preview"
android:fontFamily="sans-serif-medium"
tools:text="@string/StickerManagementAdapter_installed_stickers"/>

View File

@@ -1,125 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:viewBindingIgnore="true"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="?colorSurface">
<View
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="?selectableItemBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/sticker_management_cover"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="@dimen/sticker_management_horizontal_margin"
app:layout_constraintBottom_toTopOf="@id/sticker_management_divider"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/symbol_person_24"
tools:tint="@color/core_ultramarine" />
<LinearLayout
android:id="@+id/sticker_management_title_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="4dp"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@id/sticker_management_divider"
app:layout_constraintEnd_toStartOf="@id/sticker_management_button_barrier"
app:layout_constraintStart_toEndOf="@id/sticker_management_cover"
app:layout_constraintTop_toTopOf="parent">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/sticker_management_title"
style="@style/Signal.Text.Body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
app:emoji_maxLength="45"
tools:text="Spider-Man" />
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/sticker_management_author"
style="@style/Signal.Text.Body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/core_grey_60"
tools:text="Peter Parker" />
</LinearLayout>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/sticker_management_button_barrier"
android:layout_width="0dp"
android:layout_height="match_parent"
app:barrierDirection="start"
app:constraint_referenced_ids="sticker_management_action_button,sticker_management_share_button" />
<View
android:id="@+id/sticker_management_share_button"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="4dp"
android:background="@drawable/sticker_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/sticker_management_action_button"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/sticker_management_share_button_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tint="@color/sticker_management_action_button_color"
app:layout_constraintBottom_toBottomOf="@id/sticker_management_share_button"
app:layout_constraintEnd_toEndOf="@id/sticker_management_share_button"
app:layout_constraintStart_toStartOf="@id/sticker_management_share_button"
app:layout_constraintTop_toTopOf="@id/sticker_management_share_button"
app:srcCompat="@drawable/symbol_forward_24" />
<View
android:id="@+id/sticker_management_action_button"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="@dimen/sticker_management_horizontal_margin"
android:background="@drawable/sticker_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/sticker_management_action_button_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tint="@color/sticker_management_action_button_color"
app:layout_constraintBottom_toBottomOf="@id/sticker_management_action_button"
app:layout_constraintEnd_toEndOf="@id/sticker_management_action_button"
app:layout_constraintStart_toStartOf="@id/sticker_management_action_button"
app:layout_constraintTop_toTopOf="@id/sticker_management_action_button"
tools:src="@drawable/symbol_arrow_down_24" />
<View
android:id="@+id/sticker_management_divider"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="@color/signal_divider_minor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/sticker_management_title_container" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -107,8 +107,6 @@
<dimen name="sticker_page_item_padding">16dp</dimen>
<dimen name="sticker_page_item_width">72dp</dimen>
<dimen name="sticker_management_horizontal_margin">16dp</dimen>
<dimen name="sticker_preview_sticker_size">96dp</dimen>
<dimen name="sticker_preview_gutter_size">16dp</dimen>

View File

@@ -2798,10 +2798,9 @@
<string name="SmsMessageRecord_secure_session_reset_s">%s reset the secure session.</string>
<string name="SmsMessageRecord_duplicate_message">Duplicate message.</string>
<!-- StickerManagementActivity -->
<string name="StickerManagementActivity_stickers">Stickers</string>
<!-- Title displayed when multiple sticker packs are selected in order to perform an action. The placeholder is the number of selected items-->
<!-- Sticker management screen default title. -->
<string name="StickerManagement_title_stickers">Stickers</string>
<!-- Sticker management screen title displayed when multiple sticker packs are selected in order to perform an action. The placeholder is the number of selected items. -->
<plurals name="StickerManagement_title_n_selected">
<item quantity="one">%1$s selected</item>
<item quantity="other">%1$s selected</item>
@@ -2810,11 +2809,11 @@
<string name="StickerManagement_available_tab_label">Available</string>
<!-- Label for the sticker management screen tab which shows the stickers that are currently installed. -->
<string name="StickerManagement_installed_tab_label">Installed</string>
<!-- Shown when there are no sticker packs available for installation -->
<!-- Shown when there are no sticker packs available for installation. -->
<string name="StickerManagement_available_tab_empty_text">No sticker packs are available</string>
<!-- Shown when there are no sticker packs currently installed -->
<!-- Shown when there are no sticker packs currently installed. -->
<string name="StickerManagement_installed_tab_empty_text">No sticker packs are installed</string>
<!-- Message shown when the author of the sticker pack is unknown -->
<!-- Message shown when the author of the sticker pack is unknown. -->
<string name="StickerManagement_author_unknown">Unknown</string>
<!-- Sticker pack list section header for packs that are already installed. -->
<string name="StickerManagement_installed_stickers_header">Installed stickers</string>
@@ -2845,7 +2844,6 @@
<item quantity="other">%1$s sticker packs removed.</item>
</plurals>
<!-- Sticker pack list dropdown menu label for the button to forward a sticker pack to another user. -->
<string name="StickerManagement_menu_forward_pack">Forward</string>
<!-- Sticker pack list dropdown menu label for the button to mark a sticker pack as selected in order to perform additional actions. -->
@@ -2873,8 +2871,6 @@
<string name="StickerManagement_accessibility_exit_multi_select_mode">Exit selection mode and clear selections</string>
<!-- StickerManagementAdapter -->
<string name="StickerManagementAdapter_no_stickers_installed">No stickers installed</string>
<string name="StickerManagementAdapter_stickers_from_incoming_messages_will_appear_here">Stickers from incoming messages will appear here</string>
<string name="StickerManagementAdapter_untitled">Untitled</string>
<!-- StickerPackPreviewActivity -->