diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java index 52d1106d..0bb6c1d8 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java @@ -7,6 +7,7 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.CompoundButton; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -176,6 +177,7 @@ public class DirectMessageSettingsFragment extends Fragment { if (usersAdapter == null) return; usersAdapter.setAdminUserIds(adminUserIds); }); + viewModel.getMuted().observe(getViewLifecycleOwner(), muted -> binding.muteMessages.setChecked(muted)); final NavController navController = NavHostFragment.findNavController(this); final NavBackStackEntry backStackEntry = navController.getCurrentBackStackEntry(); if (backStackEntry != null) { @@ -202,7 +204,7 @@ public class DirectMessageSettingsFragment extends Fragment { detailsChangeResourceLiveData = viewModel.addMembers(users); } catch (Exception e) { Log.e(TAG, "search users result: ", e); - Snackbar.make(binding.getRoot(), e.getMessage(), Snackbar.LENGTH_LONG).show(); + Snackbar.make(binding.getRoot(), e.getMessage() != null ? e.getMessage() : "", Snackbar.LENGTH_LONG).show(); } } if (detailsChangeResourceLiveData != null) { @@ -274,6 +276,36 @@ public class DirectMessageSettingsFragment extends Fragment { .setMultiple(true); navController.navigate(actionGlobalUserSearch); }); + binding.muteMessagesLabel.setOnClickListener(v -> binding.muteMessages.toggle()); + binding.muteMessages.setOnCheckedChangeListener((buttonView, isChecked) -> { + final LiveData> resourceLiveData = isChecked ? viewModel.mute() : viewModel.unmute(); + handleMuteChangeResource(resourceLiveData, buttonView); + }); + binding.muteMentionsLabel.setOnClickListener(v -> binding.muteMentions.toggle()); + binding.muteMentions.setOnCheckedChangeListener((buttonView, isChecked) -> { + final LiveData> resourceLiveData = isChecked ? viewModel.muteMentions() : viewModel.unmuteMentions(); + handleMuteChangeResource(resourceLiveData, buttonView); + }); + } + + private void handleMuteChangeResource(final LiveData> resourceLiveData, final CompoundButton buttonView) { + resourceLiveData.observe(getViewLifecycleOwner(), resource -> { + if (resource == null) return; + switch (resource.status) { + case SUCCESS: + buttonView.setEnabled(true); + break; + case ERROR: + buttonView.setEnabled(true); + if (resource.message != null) { + Snackbar.make(binding.getRoot(), resource.message, Snackbar.LENGTH_LONG).show(); + } + break; + case LOADING: + buttonView.setEnabled(false); + break; + } + }); } private void setupMembers() { diff --git a/app/src/main/java/awais/instagrabber/repositories/DirectMessagesRepository.java b/app/src/main/java/awais/instagrabber/repositories/DirectMessagesRepository.java index 3bee824b..aec63ef7 100644 --- a/app/src/main/java/awais/instagrabber/repositories/DirectMessagesRepository.java +++ b/app/src/main/java/awais/instagrabber/repositories/DirectMessagesRepository.java @@ -75,4 +75,24 @@ public interface DirectMessagesRepository { @FormUrlEncoded @POST("/api/v1/direct_v2/create_group_thread/") Call createThread(@FieldMap final Map signedForm); + + @FormUrlEncoded + @POST("/api/v1/direct_v2/threads/{threadId}/mute/") + Call mute(@Path("threadId") String threadId, + @FieldMap final Map form); + + @FormUrlEncoded + @POST("/api/v1/direct_v2/threads/{threadId}/unmute/") + Call unmute(@Path("threadId") String threadId, + @FieldMap final Map form); + + @FormUrlEncoded + @POST("/api/v1/direct_v2/threads/{threadId}/mute_mentions/") + Call muteMentions(@Path("threadId") String threadId, + @FieldMap final Map form); + + @FormUrlEncoded + @POST("/api/v1/direct_v2/threads/{threadId}/unmute_mentions/") + Call unmuteMentions(@Path("threadId") String threadId, + @FieldMap final Map form); } diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectThread.java b/app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectThread.java index 89f056d7..2eaa9eab 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectThread.java +++ b/app/src/main/java/awais/instagrabber/repositories/responses/directmessages/DirectThread.java @@ -17,7 +17,7 @@ public class DirectThread implements Serializable { private final List adminUserIds; private final List items; private final long lastActivityAt; - private final boolean muted; + private boolean muted; private final boolean isPin; private final boolean named; private final boolean canonical; @@ -31,7 +31,7 @@ public class DirectThread implements Serializable { private final long folder; private final boolean vcMuted; private final boolean isGroup; - private final boolean mentionsMuted; + private boolean mentionsMuted; private final User inviter; private final boolean hasOlder; private final boolean hasNewer; @@ -138,6 +138,10 @@ public class DirectThread implements Serializable { return muted; } + public void setMuted(final boolean muted) { + this.muted = muted; + } + public boolean isPin() { return isPin; } @@ -194,6 +198,10 @@ public class DirectThread implements Serializable { return mentionsMuted; } + public void setMentionsMuted(final boolean mentionsMuted) { + this.mentionsMuted = mentionsMuted; + } + public User getInviter() { return inviter; } diff --git a/app/src/main/java/awais/instagrabber/viewmodels/DirectSettingsViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/DirectSettingsViewModel.java index 2b282340..fbd4eb3a 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/DirectSettingsViewModel.java +++ b/app/src/main/java/awais/instagrabber/viewmodels/DirectSettingsViewModel.java @@ -59,14 +59,16 @@ public class DirectSettingsViewModel extends AndroidViewModel { new Pair<>(Collections.emptyList(), Collections.emptyList())); private final MutableLiveData title = new MutableLiveData<>(""); private final MutableLiveData> adminUserIds = new MutableLiveData<>(Collections.emptyList()); + private final MutableLiveData muted = new MutableLiveData<>(false); + private final MutableLiveData mentionsMuted = new MutableLiveData<>(false); private final DirectMessagesService directMessagesService; - - private DirectThread thread; private final long userId; - private boolean viewerIsAdmin; private final Resources resources; private final FriendshipService friendshipService; private final String csrfToken; + + private DirectThread thread; + private boolean viewerIsAdmin; private User viewer; public DirectSettingsViewModel(final Application application) { @@ -103,6 +105,8 @@ public class DirectSettingsViewModel extends AndroidViewModel { final List adminUserIds = thread.getAdminUserIds(); this.adminUserIds.postValue(adminUserIds); viewerIsAdmin = adminUserIds.contains(userId); + muted.postValue(thread.isMuted()); + mentionsMuted.postValue(thread.isMentionsMuted()); } public boolean isGroup() { @@ -132,6 +136,10 @@ public class DirectSettingsViewModel extends AndroidViewModel { return adminUserIds; } + public LiveData getMuted() { + return muted; + } + public LiveData> updateTitle(final String newTitle) { final MutableLiveData> data = new MutableLiveData<>(); final Call addUsersRequest = directMessagesService @@ -156,7 +164,7 @@ public class DirectSettingsViewModel extends AndroidViewModel { @Override public void onResponse(@NonNull final Call call, @NonNull final Response response) { if (!response.isSuccessful()) { - handleAdminChangeResponseError(response, data); + handleSettingChangeResponseError(response, data); return; } Pair, List> usersValue = users.getValue(); @@ -198,7 +206,7 @@ public class DirectSettingsViewModel extends AndroidViewModel { @Override public void onResponse(@NonNull final Call call, @NonNull final Response response) { if (!response.isSuccessful()) { - handleAdminChangeResponseError(response, data); + handleSettingChangeResponseError(response, data); return; } final List currentAdmins = adminUserIds.getValue(); @@ -225,7 +233,7 @@ public class DirectSettingsViewModel extends AndroidViewModel { @Override public void onResponse(@NonNull final Call call, @NonNull final Response response) { if (!response.isSuccessful()) { - handleAdminChangeResponseError(response, data); + handleSettingChangeResponseError(response, data); return; } final List currentAdmins = adminUserIds.getValue(); @@ -244,8 +252,124 @@ public class DirectSettingsViewModel extends AndroidViewModel { return data; } - private void handleAdminChangeResponseError(@NonNull final Response response, - final MutableLiveData> data) { + public LiveData> mute() { + final MutableLiveData> data = new MutableLiveData<>(); + data.postValue(Resource.loading(null)); + if (thread.isMuted()) { + data.postValue(Resource.success(new Object())); + return data; + } + final Call request = directMessagesService.mute(thread.getThreadId()); + request.enqueue(new Callback() { + @Override + public void onResponse(@NonNull final Call call, @NonNull final Response response) { + if (!response.isSuccessful()) { + handleSettingChangeResponseError(response, data); + return; + } + thread.setMuted(true); + muted.postValue(true); + data.postValue(Resource.success(new Object())); + } + + @Override + public void onFailure(@NonNull final Call call, @NonNull final Throwable t) { + Log.e(TAG, "onFailure: ", t); + data.postValue(Resource.error(t.getMessage(), null)); + } + }); + return data; + } + + public LiveData> unmute() { + final MutableLiveData> data = new MutableLiveData<>(); + data.postValue(Resource.loading(null)); + if (!thread.isMuted()) { + data.postValue(Resource.success(new Object())); + return data; + } + final Call request = directMessagesService.unmute(thread.getThreadId()); + request.enqueue(new Callback() { + @Override + public void onResponse(@NonNull final Call call, @NonNull final Response response) { + if (!response.isSuccessful()) { + handleSettingChangeResponseError(response, data); + return; + } + thread.setMuted(false); + muted.postValue(false); + data.postValue(Resource.success(new Object())); + } + + @Override + public void onFailure(@NonNull final Call call, @NonNull final Throwable t) { + Log.e(TAG, "onFailure: ", t); + data.postValue(Resource.error(t.getMessage(), null)); + } + }); + return data; + } + + public LiveData> muteMentions() { + final MutableLiveData> data = new MutableLiveData<>(); + data.postValue(Resource.loading(null)); + if (thread.isMentionsMuted()) { + data.postValue(Resource.success(new Object())); + return data; + } + final Call request = directMessagesService.muteMentions(thread.getThreadId()); + request.enqueue(new Callback() { + @Override + public void onResponse(@NonNull final Call call, @NonNull final Response response) { + if (!response.isSuccessful()) { + handleSettingChangeResponseError(response, data); + return; + } + thread.setMentionsMuted(true); + mentionsMuted.postValue(true); + data.postValue(Resource.success(new Object())); + } + + @Override + public void onFailure(@NonNull final Call call, @NonNull final Throwable t) { + Log.e(TAG, "onFailure: ", t); + data.postValue(Resource.error(t.getMessage(), null)); + } + }); + return data; + } + + public LiveData> unmuteMentions() { + final MutableLiveData> data = new MutableLiveData<>(); + data.postValue(Resource.loading(null)); + if (!thread.isMentionsMuted()) { + data.postValue(Resource.success(new Object())); + return data; + } + final Call request = directMessagesService.unmuteMentions(thread.getThreadId()); + request.enqueue(new Callback() { + @Override + public void onResponse(@NonNull final Call call, @NonNull final Response response) { + if (!response.isSuccessful()) { + handleSettingChangeResponseError(response, data); + return; + } + thread.setMentionsMuted(false); + mentionsMuted.postValue(false); + data.postValue(Resource.success(new Object())); + } + + @Override + public void onFailure(@NonNull final Call call, @NonNull final Throwable t) { + Log.e(TAG, "onFailure: ", t); + data.postValue(Resource.error(t.getMessage(), null)); + } + }); + return data; + } + + private void handleSettingChangeResponseError(@NonNull final Response response, + final MutableLiveData> data) { final ResponseBody errorBody = response.errorBody(); if (errorBody == null) { handleErrorResponse(response, data); diff --git a/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.java b/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.java index 9e504196..774c2520 100644 --- a/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.java +++ b/app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.java @@ -317,4 +317,36 @@ public class DirectMessagesService extends BaseService { final Map signedForm = Utils.sign(formBuilder.build()); return repository.createThread(signedForm); } + + public Call mute(@NonNull final String threadId) { + final ImmutableMap form = ImmutableMap.of( + "_csrftoken", csrfToken, + "_uuid", deviceUuid + ); + return repository.mute(threadId, form); + } + + public Call unmute(@NonNull final String threadId) { + final ImmutableMap form = ImmutableMap.of( + "_csrftoken", csrfToken, + "_uuid", deviceUuid + ); + return repository.unmute(threadId, form); + } + + public Call muteMentions(@NonNull final String threadId) { + final ImmutableMap form = ImmutableMap.of( + "_csrftoken", csrfToken, + "_uuid", deviceUuid + ); + return repository.muteMentions(threadId, form); + } + + public Call unmuteMentions(@NonNull final String threadId) { + final ImmutableMap form = ImmutableMap.of( + "_csrftoken", csrfToken, + "_uuid", deviceUuid + ); + return repository.unmuteMentions(threadId, form); + } } diff --git a/app/src/main/res/layout/fragment_direct_messages_settings.xml b/app/src/main/res/layout/fragment_direct_messages_settings.xml index 1723c9fc..c1370a1b 100644 --- a/app/src/main/res/layout/fragment_direct_messages_settings.xml +++ b/app/src/main/res/layout/fragment_direct_messages_settings.xml @@ -50,11 +50,11 @@ - - - -