Add manual mark as seen menu item in thread when auto mark is disabled

This commit is contained in:
Ammar Githam 2021-03-20 21:04:49 +09:00
parent d7ecc935f7
commit 9cdbd89328
5 changed files with 91 additions and 19 deletions

View File

@ -100,6 +100,7 @@ import awais.instagrabber.repositories.responses.directmessages.DirectThread;
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient;
import awais.instagrabber.utils.AppExecutors;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.DMUtils;
import awais.instagrabber.utils.DownloadUtils;
import awais.instagrabber.utils.PermissionUtils;
import awais.instagrabber.utils.ResponseBodyUtils;
@ -317,6 +318,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
backStackSavedStateResultLiveData.postValue(null);
};
private final MutableLiveData<Integer> inputLength = new MutableLiveData<>(0);
private MenuItem markAsSeenMenuItem;
@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
@ -367,9 +369,13 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
@Override
public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) {
inflater.inflate(R.menu.dm_thread_menu, menu);
final MenuItem markAsSeenMenuItem = menu.findItem(R.id.mark_as_seen);
markAsSeenMenuItem = menu.findItem(R.id.mark_as_seen);
if (markAsSeenMenuItem != null) {
markAsSeenMenuItem.setVisible(false);
if (autoMarkAsSeen) {
markAsSeenMenuItem.setVisible(false);
} else {
markAsSeenMenuItem.setEnabled(false);
}
}
}
@ -385,8 +391,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
return true;
}
if (itemId == R.id.mark_as_seen) {
// new ThreadAction().execute("seen", lastMessage);
item.setVisible(false);
handleMarkAsSeen(item);
return true;
}
if (itemId == R.id.refresh && viewModel != null) {
@ -396,6 +401,40 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
return super.onOptionsItemSelected(item);
}
private void handleMarkAsSeen(@NonNull final MenuItem item) {
final LiveData<Resource<Object>> resourceLiveData = viewModel.markAsSeen();
resourceLiveData.observe(getViewLifecycleOwner(), new Observer<Resource<Object>>() {
@Override
public void onChanged(final Resource<Object> resource) {
try {
if (resource == null) return;
final Context context = getContext();
if (context == null) return;
switch (resource.status) {
case SUCCESS:
Toast.makeText(context, R.string.marked_as_seen, Toast.LENGTH_SHORT).show();
case LOADING:
item.setEnabled(false);
break;
case ERROR:
item.setEnabled(true);
if (resource.message != null) {
Snackbar.make(context, binding.getRoot(), resource.message, Snackbar.LENGTH_LONG).show();
return;
}
if (resource.resId != 0) {
Snackbar.make(binding.getRoot(), resource.resId, Snackbar.LENGTH_LONG).show();
return;
}
break;
}
} finally {
resourceLiveData.removeObserver(this);
}
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
@ -908,9 +947,15 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact
}
private void submitItemsToAdapter(final List<DirectItem> items) {
if (autoMarkAsSeen) {
binding.chats.post(() -> viewModel.markAsSeen());
}
binding.chats.post(() -> {
if (autoMarkAsSeen) {
viewModel.markAsSeen();
return;
}
final DirectThread thread = threadLiveData.getValue();
if (thread == null) return;
markAsSeenMenuItem.setEnabled(!DMUtils.isRead(thread));
});
if (itemsAdapter == null) return;
itemsAdapter.submitList(items, () -> {
itemOrHeaders = itemsAdapter.getList();

View File

@ -1797,18 +1797,23 @@ public final class ThreadManager {
return inviter;
}
public void markAsSeen(@NonNull final DirectItem directItem) {
public LiveData<Resource<Object>> markAsSeen(@NonNull final DirectItem directItem) {
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
data.postValue(Resource.loading(null));
final Call<DirectItemSeenResponse> request = service.markAsSeen(threadId, directItem);
request.enqueue(new Callback<DirectItemSeenResponse>() {
@Override
public void onResponse(@NonNull final Call<DirectItemSeenResponse> call,
@NonNull final Response<DirectItemSeenResponse> response) {
if (!response.isSuccessful()) {
handleErrorBody(call, response, null);
handleErrorBody(call, response, data);
return;
}
final DirectItemSeenResponse seenResponse = response.body();
if (seenResponse == null) return;
if (seenResponse == null) {
data.postValue(Resource.error(R.string.generic_null_response, null));
return;
}
inboxManager.fetchUnseenCount();
final DirectItemSeenResponsePayload payload = seenResponse.getPayload();
if (payload == null) return;
@ -1820,14 +1825,17 @@ public final class ThreadManager {
lastSeenAt.put(currentUser.getPk(), new DirectThreadLastSeenAt(timestamp, directItem.getItemId()));
thread.setLastSeenAt(lastSeenAt);
setThread(thread, true);
data.postValue(Resource.success(new Object()));
}
@Override
public void onFailure(@NonNull final Call<DirectItemSeenResponse> call,
@NonNull final Throwable t) {
Log.e(TAG, "onFailure: ", t);
data.postValue(Resource.error(t.getMessage(), null));
}
});
return data;
}
private interface OnSuccessAction {

View File

@ -278,16 +278,24 @@ public class DirectThreadViewModel extends AndroidViewModel {
return threadManager.declineRequest();
}
public void markAsSeen() {
if (currentUser == null) return;
public LiveData<Resource<Object>> markAsSeen() {
if (currentUser == null) {
return getSuccessEventResObjectLiveData();
}
final DirectThread thread = getThread().getValue();
if (thread == null) return;
if (thread == null) {
return getSuccessEventResObjectLiveData();
}
final List<DirectItem> items = thread.getItems();
if (items == null || items.isEmpty()) return;
if (items == null || items.isEmpty()) {
return getSuccessEventResObjectLiveData();
}
final Optional<DirectItem> itemOptional = items.stream()
.filter(item -> item.getUserId() != currentUser.getPk())
.findFirst();
if (!itemOptional.isPresent()) return;
if (!itemOptional.isPresent()) {
return getSuccessEventResObjectLiveData();
}
final DirectItem directItem = itemOptional.get();
final Map<Long, DirectThreadLastSeenAt> lastSeenAt = thread.getLastSeenAt();
if (lastSeenAt != null) {
@ -296,11 +304,20 @@ public class DirectThreadViewModel extends AndroidViewModel {
if (seenAt != null
&& (Objects.equals(seenAt.getItemId(), directItem.getItemId())
|| Long.parseLong(seenAt.getTimestamp()) >= directItem.getTimestamp())) {
return;
return getSuccessEventResObjectLiveData();
}
} catch (Exception ignored) {}
} catch (Exception ignored) {
return getSuccessEventResObjectLiveData();
}
}
threadManager.markAsSeen(directItem);
return threadManager.markAsSeen(directItem);
}
@NonNull
private MutableLiveData<Resource<Object>> getSuccessEventResObjectLiveData() {
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
data.postValue(Resource.success(new Object()));
return data;
}
public void deleteThreadIfRequired() {
@ -311,4 +328,5 @@ public class DirectThreadViewModel extends AndroidViewModel {
inboxManager.removeThread(threadId);
}
}
}

View File

@ -8,7 +8,7 @@
app:showAsAction="ifRoom" />
<item
android:id="@+id/mark_as_seen"
android:icon="@drawable/ic_outline_views_24"
android:icon="@drawable/ic_check_all_24"
android:title="@string/mark_as_seen"
app:showAsAction="ifRoom" />
<item

View File

@ -466,4 +466,5 @@
<string name="generic_null_response">Response is null!</string>
<string name="generic_not_ok_response">Response status is not ok!</string>
<string name="generic_failed_request">Request failed!</string>
<string name="marked_as_seen">Marked as seen</string>
</resources>