mirror of
https://github.com/oxen-io/session-android.git
synced 2025-06-09 05:38:33 +00:00
Enable Media Preview to respond to media changes.
This commit is contained in:
parent
1fe38f5ed1
commit
3c069fb588
@ -20,10 +20,12 @@ import android.Manifest;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.database.ContentObserver;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@ -73,6 +75,7 @@ import org.thoughtcrime.securesms.util.SaveAttachmentTask.Attachment;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity for displaying media attachments in-app
|
* Activity for displaying media attachments in-app
|
||||||
@ -117,17 +120,20 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||||||
private boolean showThread;
|
private boolean showThread;
|
||||||
private MediaDatabase.Sorting sorting;
|
private MediaDatabase.Sorting sorting;
|
||||||
|
|
||||||
|
private @Nullable Cursor cursor = null;
|
||||||
|
|
||||||
public static @NonNull Intent intentFromMediaRecord(@NonNull Context context,
|
public static @NonNull Intent intentFromMediaRecord(@NonNull Context context,
|
||||||
@NonNull MediaRecord mediaRecord,
|
@NonNull MediaRecord mediaRecord,
|
||||||
boolean leftIsRecent)
|
boolean leftIsRecent)
|
||||||
{
|
{
|
||||||
|
DatabaseAttachment attachment = Objects.requireNonNull(mediaRecord.getAttachment());
|
||||||
Intent intent = new Intent(context, MediaPreviewActivity.class);
|
Intent intent = new Intent(context, MediaPreviewActivity.class);
|
||||||
intent.putExtra(MediaPreviewActivity.THREAD_ID_EXTRA, mediaRecord.getThreadId());
|
intent.putExtra(MediaPreviewActivity.THREAD_ID_EXTRA, mediaRecord.getThreadId());
|
||||||
intent.putExtra(MediaPreviewActivity.DATE_EXTRA, mediaRecord.getDate());
|
intent.putExtra(MediaPreviewActivity.DATE_EXTRA, mediaRecord.getDate());
|
||||||
intent.putExtra(MediaPreviewActivity.SIZE_EXTRA, mediaRecord.getAttachment().getSize());
|
intent.putExtra(MediaPreviewActivity.SIZE_EXTRA, attachment.getSize());
|
||||||
intent.putExtra(MediaPreviewActivity.CAPTION_EXTRA, mediaRecord.getAttachment().getCaption());
|
intent.putExtra(MediaPreviewActivity.CAPTION_EXTRA, attachment.getCaption());
|
||||||
intent.putExtra(MediaPreviewActivity.LEFT_IS_RECENT_EXTRA, leftIsRecent);
|
intent.putExtra(MediaPreviewActivity.LEFT_IS_RECENT_EXTRA, leftIsRecent);
|
||||||
intent.setDataAndType(mediaRecord.getAttachment().getDataUri(), mediaRecord.getContentType());
|
intent.setDataAndType(attachment.getDataUri(), mediaRecord.getContentType());
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,6 +234,15 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||||||
restartItem = cleanupMedia();
|
restartItem = cleanupMedia();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.close();
|
||||||
|
cursor = null;
|
||||||
|
}
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onNewIntent(Intent intent) {
|
protected void onNewIntent(Intent intent) {
|
||||||
super.onNewIntent(intent);
|
super.onNewIntent(intent);
|
||||||
@ -344,6 +359,7 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||||||
|
|
||||||
mediaPager.removeAllViews();
|
mediaPager.removeAllViews();
|
||||||
mediaPager.setAdapter(null);
|
mediaPager.setAdapter(null);
|
||||||
|
viewModel.setCursor(this, null, leftIsRecent);
|
||||||
|
|
||||||
return restartItem;
|
return restartItem;
|
||||||
}
|
}
|
||||||
@ -475,19 +491,46 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(@NonNull Loader<Pair<Cursor, Integer>> loader, @Nullable Pair<Cursor, Integer> data) {
|
public void onLoadFinished(@NonNull Loader<Pair<Cursor, Integer>> loader, @Nullable Pair<Cursor, Integer> data) {
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
@SuppressWarnings("ConstantConditions")
|
if (data.first == cursor) {
|
||||||
CursorPagerAdapter adapter = new CursorPagerAdapter(getSupportFragmentManager(),this, data.first, data.second, leftIsRecent);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
cursor = Objects.requireNonNull(data.first);
|
||||||
|
|
||||||
|
int mediaPosition = Objects.requireNonNull(data.second);
|
||||||
|
|
||||||
|
CursorPagerAdapter adapter = new CursorPagerAdapter(getSupportFragmentManager(),this, cursor, mediaPosition, leftIsRecent);
|
||||||
mediaPager.setAdapter(adapter);
|
mediaPager.setAdapter(adapter);
|
||||||
adapter.setActive(true);
|
adapter.setActive(true);
|
||||||
|
|
||||||
viewModel.setCursor(this, data.first, leftIsRecent);
|
viewModel.setCursor(this, cursor, leftIsRecent);
|
||||||
|
|
||||||
int item = restartItem >= 0 ? restartItem : data.second;
|
int item = restartItem >= 0 ? restartItem : mediaPosition;
|
||||||
mediaPager.setCurrentItem(item);
|
mediaPager.setCurrentItem(item);
|
||||||
|
|
||||||
if (item == 0) {
|
if (item == 0) {
|
||||||
viewPagerListener.onPageSelected(0);
|
viewPagerListener.onPageSelected(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursor.registerContentObserver(new ContentObserver(new Handler(getMainLooper())) {
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
onMediaChange();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
mediaNotAvailable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onMediaChange() {
|
||||||
|
MediaItemAdapter adapter = (MediaItemAdapter) mediaPager.getAdapter();
|
||||||
|
|
||||||
|
if (adapter != null) {
|
||||||
|
adapter.checkMedia(mediaPager.getCurrentItem());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,6 +545,12 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mediaNotAvailable() {
|
||||||
|
Toast.makeText(this, R.string.MediaPreviewActivity_media_no_longer_available, Toast.LENGTH_LONG).show();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
private void toggleUiVisibility() {
|
private void toggleUiVisibility() {
|
||||||
int systemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
|
int systemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
|
||||||
if ((systemUiVisibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0) {
|
if ((systemUiVisibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0) {
|
||||||
@ -621,6 +670,11 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||||||
public boolean hasFragmentFor(int position) {
|
public boolean hasFragmentFor(int position) {
|
||||||
return mediaPreviewFragment != null;
|
return mediaPreviewFragment != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkMedia(int currentItem) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void anchorMarginsToBottomInsets(@NonNull View viewToAnchor) {
|
private static void anchorMarginsToBottomInsets(@NonNull View viewToAnchor) {
|
||||||
@ -712,7 +766,7 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||||||
cursor.moveToPosition(cursorPosition);
|
cursor.moveToPosition(cursorPosition);
|
||||||
|
|
||||||
MediaDatabase.MediaRecord mediaRecord = MediaDatabase.MediaRecord.from(context, cursor);
|
MediaDatabase.MediaRecord mediaRecord = MediaDatabase.MediaRecord.from(context, cursor);
|
||||||
DatabaseAttachment attachment = mediaRecord.getAttachment();
|
DatabaseAttachment attachment = Objects.requireNonNull(mediaRecord.getAttachment());
|
||||||
MediaPreviewFragment fragment = MediaPreviewFragment.newInstance(attachment, autoPlay);
|
MediaPreviewFragment fragment = MediaPreviewFragment.newInstance(attachment, autoPlay);
|
||||||
|
|
||||||
mediaFragments.put(position, fragment);
|
mediaFragments.put(position, fragment);
|
||||||
@ -735,15 +789,14 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||||||
cursor.moveToPosition(getCursorPosition(position));
|
cursor.moveToPosition(getCursorPosition(position));
|
||||||
|
|
||||||
MediaRecord mediaRecord = MediaRecord.from(context, cursor);
|
MediaRecord mediaRecord = MediaRecord.from(context, cursor);
|
||||||
|
DatabaseAttachment attachment = Objects.requireNonNull(mediaRecord.getAttachment());
|
||||||
RecipientId recipientId = mediaRecord.getRecipientId();
|
RecipientId recipientId = mediaRecord.getRecipientId();
|
||||||
RecipientId threadRecipientId = mediaRecord.getThreadRecipientId();
|
RecipientId threadRecipientId = mediaRecord.getThreadRecipientId();
|
||||||
|
|
||||||
if (mediaRecord.getAttachment().getDataUri() == null) throw new AssertionError();
|
|
||||||
|
|
||||||
return new MediaItem(Recipient.live(recipientId).get(),
|
return new MediaItem(Recipient.live(recipientId).get(),
|
||||||
Recipient.live(threadRecipientId).get(),
|
Recipient.live(threadRecipientId).get(),
|
||||||
mediaRecord.getAttachment(),
|
attachment,
|
||||||
mediaRecord.getAttachment().getDataUri(),
|
Objects.requireNonNull(attachment.getDataUri()),
|
||||||
mediaRecord.getContentType(),
|
mediaRecord.getContentType(),
|
||||||
mediaRecord.getDate(),
|
mediaRecord.getDate(),
|
||||||
mediaRecord.isOutgoing());
|
mediaRecord.isOutgoing());
|
||||||
@ -767,6 +820,14 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||||||
return mediaFragments.containsKey(position);
|
return mediaFragments.containsKey(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkMedia(int position) {
|
||||||
|
MediaPreviewFragment fragment = mediaFragments.get(position);
|
||||||
|
if (fragment != null) {
|
||||||
|
fragment.checkMediaStillAvailable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int getCursorPosition(int position) {
|
private int getCursorPosition(int position) {
|
||||||
if (leftIsRecent) return position;
|
if (leftIsRecent) return position;
|
||||||
else return cursor.getCount() - 1 - position;
|
else return cursor.getCount() - 1 - position;
|
||||||
@ -805,5 +866,6 @@ public final class MediaPreviewActivity extends PassphraseRequiredActivity
|
|||||||
void pause(int position);
|
void pause(int position);
|
||||||
@Nullable View getPlaybackControls(int position);
|
@Nullable View getPlaybackControls(int position);
|
||||||
boolean hasFragmentFor(int position);
|
boolean hasFragmentFor(int position);
|
||||||
|
void checkMedia(int currentItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,6 +309,23 @@ public class AttachmentDatabase extends Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasAttachment(@NonNull AttachmentId id) {
|
||||||
|
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||||
|
|
||||||
|
try (Cursor cursor = database.query(TABLE_NAME,
|
||||||
|
new String[]{ROW_ID, UNIQUE_ID},
|
||||||
|
PART_ID_WHERE,
|
||||||
|
id.toStrings(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null)) {
|
||||||
|
if (cursor != null && cursor.getCount() > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasAttachmentFilesForMessage(long mmsId) {
|
public boolean hasAttachmentFilesForMessage(long mmsId) {
|
||||||
String selection = MMS_ID + " = ? AND (" + DATA + " NOT NULL OR " + TRANSFER_STATE + " != ?)";
|
String selection = MMS_ID + " = ? AND (" + DATA + " NOT NULL OR " + TRANSFER_STATE + " != ?)";
|
||||||
String[] args = new String[] { String.valueOf(mmsId), String.valueOf(TRANSFER_PROGRESS_DONE) };
|
String[] args = new String[] { String.valueOf(mmsId), String.valueOf(TRANSFER_PROGRESS_DONE) };
|
||||||
|
@ -67,6 +67,10 @@ public abstract class Database {
|
|||||||
cursor.setNotificationUri(context.getContentResolver(), DatabaseContentProviders.Conversation.getUriForThread(threadId));
|
cursor.setNotificationUri(context.getContentResolver(), DatabaseContentProviders.Conversation.getUriForThread(threadId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setNotifyConversationListeners(Cursor cursor) {
|
||||||
|
cursor.setNotificationUri(context.getContentResolver(), DatabaseContentProviders.Conversation.getUriForAllThreads());
|
||||||
|
}
|
||||||
|
|
||||||
protected void setNotifyVerboseConversationListeners(Cursor cursor, long threadId) {
|
protected void setNotifyVerboseConversationListeners(Cursor cursor, long threadId) {
|
||||||
cursor.setNotificationUri(context.getContentResolver(), DatabaseContentProviders.Conversation.getVerboseUriForThread(threadId));
|
cursor.setNotificationUri(context.getContentResolver(), DatabaseContentProviders.Conversation.getVerboseUriForThread(threadId));
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,10 @@ public class DatabaseContentProviders {
|
|||||||
public static Uri getVerboseUriForThread(long threadId) {
|
public static Uri getVerboseUriForThread(long threadId) {
|
||||||
return Uri.parse(CONTENT_URI_STRING + "verbose/" + threadId);
|
return Uri.parse(CONTENT_URI_STRING + "verbose/" + threadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Uri getUriForAllThreads() {
|
||||||
|
return Uri.parse(CONTENT_URI_STRING);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Attachment extends NoopContentProvider {
|
public static class Attachment extends NoopContentProvider {
|
||||||
|
@ -89,11 +89,19 @@ public class MediaDatabase extends Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull Cursor getGalleryMediaForThread(long threadId, @NonNull Sorting sorting) {
|
public @NonNull Cursor getGalleryMediaForThread(long threadId, @NonNull Sorting sorting) {
|
||||||
|
return getGalleryMediaForThread(threadId, sorting, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull Cursor getGalleryMediaForThread(long threadId, @NonNull Sorting sorting, boolean listenToAllThreads) {
|
||||||
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||||
String query = sorting.applyToQuery(applyEqualityOperator(threadId, GALLERY_MEDIA_QUERY));
|
String query = sorting.applyToQuery(applyEqualityOperator(threadId, GALLERY_MEDIA_QUERY));
|
||||||
String[] args = {threadId + ""};
|
String[] args = {threadId + ""};
|
||||||
Cursor cursor = database.rawQuery(query, args);
|
Cursor cursor = database.rawQuery(query, args);
|
||||||
|
if (listenToAllThreads) {
|
||||||
|
setNotifyConversationListeners(cursor);
|
||||||
|
} else {
|
||||||
setNotifyConversationListeners(cursor, threadId);
|
setNotifyConversationListeners(cursor, threadId);
|
||||||
|
}
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import androidx.core.util.Pair;
|
|||||||
import org.thoughtcrime.securesms.attachments.AttachmentId;
|
import org.thoughtcrime.securesms.attachments.AttachmentId;
|
||||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
import org.thoughtcrime.securesms.database.MediaDatabase;
|
||||||
import org.thoughtcrime.securesms.database.MediaDatabase.Sorting;
|
import org.thoughtcrime.securesms.database.MediaDatabase.Sorting;
|
||||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||||
import org.thoughtcrime.securesms.util.AsyncLoader;
|
import org.thoughtcrime.securesms.util.AsyncLoader;
|
||||||
@ -35,7 +36,7 @@ public final class PagingMediaLoader extends AsyncLoader<Pair<Cursor, Integer>>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Pair<Cursor, Integer> loadInBackground() {
|
public @Nullable Pair<Cursor, Integer> loadInBackground() {
|
||||||
Cursor cursor = DatabaseFactory.getMediaDatabase(getContext()).getGalleryMediaForThread(threadId, sorting);
|
Cursor cursor = DatabaseFactory.getMediaDatabase(getContext()).getGalleryMediaForThread(threadId, sorting, threadId == MediaDatabase.ALL_THREADS);
|
||||||
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
AttachmentId attachmentId = new AttachmentId(cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.ROW_ID)), cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.UNIQUE_ID)));
|
AttachmentId attachmentId = new AttachmentId(cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.ROW_ID)), cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.UNIQUE_ID)));
|
||||||
|
@ -10,7 +10,13 @@ import androidx.annotation.Nullable;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||||
|
import org.thoughtcrime.securesms.attachments.AttachmentId;
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
import org.thoughtcrime.securesms.mms.PartUriParser;
|
||||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||||
|
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public abstract class MediaPreviewFragment extends Fragment {
|
public abstract class MediaPreviewFragment extends Fragment {
|
||||||
|
|
||||||
@ -19,6 +25,7 @@ public abstract class MediaPreviewFragment extends Fragment {
|
|||||||
static final String DATA_CONTENT_TYPE = "DATA_CONTENT_TYPE";
|
static final String DATA_CONTENT_TYPE = "DATA_CONTENT_TYPE";
|
||||||
static final String AUTO_PLAY = "AUTO_PLAY";
|
static final String AUTO_PLAY = "AUTO_PLAY";
|
||||||
|
|
||||||
|
private AttachmentId attachmentId;
|
||||||
protected Events events;
|
protected Events events;
|
||||||
|
|
||||||
public static MediaPreviewFragment newInstance(@NonNull Attachment attachment, boolean autoPlay) {
|
public static MediaPreviewFragment newInstance(@NonNull Attachment attachment, boolean autoPlay) {
|
||||||
@ -60,6 +67,12 @@ public abstract class MediaPreviewFragment extends Fragment {
|
|||||||
events = (Events) context;
|
events = (Events) context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
checkMediaStillAvailable();
|
||||||
|
}
|
||||||
|
|
||||||
public void cleanUp() {
|
public void cleanUp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,8 +83,18 @@ public abstract class MediaPreviewFragment extends Fragment {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Events {
|
public void checkMediaStillAvailable() {
|
||||||
|
if (attachmentId == null) {
|
||||||
|
attachmentId = new PartUriParser(Objects.requireNonNull(requireArguments().getParcelable(DATA_URI))).getPartId();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTask.run(getViewLifecycleOwner().getLifecycle(),
|
||||||
|
() -> DatabaseFactory.getAttachmentDatabase(requireContext()).hasAttachment(attachmentId),
|
||||||
|
hasAttachment -> { if (!hasAttachment) events.mediaNotAvailable(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Events {
|
||||||
boolean singleTapOnMedia();
|
boolean singleTapOnMedia();
|
||||||
|
void mediaNotAvailable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1271,6 +1271,7 @@
|
|||||||
<string name="MediaPreviewActivity_media_delete_confirmation_title">Delete message?</string>
|
<string name="MediaPreviewActivity_media_delete_confirmation_title">Delete message?</string>
|
||||||
<string name="MediaPreviewActivity_media_delete_confirmation_message">This will permanently delete this message.</string>
|
<string name="MediaPreviewActivity_media_delete_confirmation_message">This will permanently delete this message.</string>
|
||||||
<string name="MediaPreviewActivity_s_to_s">%1$s to %2$s</string>
|
<string name="MediaPreviewActivity_s_to_s">%1$s to %2$s</string>
|
||||||
|
<string name="MediaPreviewActivity_media_no_longer_available">Media no longer available.</string>
|
||||||
|
|
||||||
<!-- MessageNotifier -->
|
<!-- MessageNotifier -->
|
||||||
<string name="MessageNotifier_d_new_messages_in_d_conversations">%1$d new messages in %2$d conversations</string>
|
<string name="MessageNotifier_d_new_messages_in_d_conversations">%1$d new messages in %2$d conversations</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user