mirror of
				https://github.com/KokaKiwi/BarInsta
				synced 2025-10-31 11:35:34 +00:00 
			
		
		
		
	Convert DirectMessageSettingsFragment to kotlin
This commit is contained in:
		
							parent
							
								
									01c944486d
								
							
						
					
					
						commit
						45e629ee61
					
				| @ -1,531 +0,0 @@ | ||||
| package awais.instagrabber.fragments.directmessages; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.os.Bundle; | ||||
| import android.text.Editable; | ||||
| 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; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.lifecycle.LiveData; | ||||
| import androidx.lifecycle.MutableLiveData; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
| import androidx.navigation.NavBackStackEntry; | ||||
| import androidx.navigation.NavController; | ||||
| import androidx.navigation.NavDestination; | ||||
| import androidx.navigation.NavDirections; | ||||
| import androidx.navigation.fragment.NavHostFragment; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
| 
 | ||||
| import com.google.android.material.snackbar.Snackbar; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
| import java.util.Set; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| import awais.instagrabber.ProfileNavGraphDirections; | ||||
| import awais.instagrabber.R; | ||||
| import awais.instagrabber.UserSearchNavGraphDirections; | ||||
| import awais.instagrabber.activities.MainActivity; | ||||
| import awais.instagrabber.adapters.DirectPendingUsersAdapter; | ||||
| import awais.instagrabber.adapters.DirectPendingUsersAdapter.PendingUser; | ||||
| import awais.instagrabber.adapters.DirectPendingUsersAdapter.PendingUserCallback; | ||||
| import awais.instagrabber.adapters.DirectUsersAdapter; | ||||
| import awais.instagrabber.customviews.helpers.TextWatcherAdapter; | ||||
| import awais.instagrabber.databinding.FragmentDirectMessagesSettingsBinding; | ||||
| import awais.instagrabber.dialogs.ConfirmDialogFragment; | ||||
| import awais.instagrabber.dialogs.ConfirmDialogFragment.ConfirmDialogFragmentCallback; | ||||
| import awais.instagrabber.dialogs.MultiOptionDialogFragment; | ||||
| import awais.instagrabber.dialogs.MultiOptionDialogFragment.Option; | ||||
| import awais.instagrabber.fragments.UserSearchFragment; | ||||
| import awais.instagrabber.fragments.UserSearchFragmentDirections; | ||||
| import awais.instagrabber.models.Resource; | ||||
| import awais.instagrabber.repositories.responses.User; | ||||
| import awais.instagrabber.repositories.responses.directmessages.DirectThreadParticipantRequestsResponse; | ||||
| import awais.instagrabber.repositories.responses.directmessages.RankedRecipient; | ||||
| import awais.instagrabber.utils.TextUtils; | ||||
| import awais.instagrabber.utils.Utils; | ||||
| import awais.instagrabber.viewmodels.AppStateViewModel; | ||||
| import awais.instagrabber.viewmodels.DirectSettingsViewModel; | ||||
| import awais.instagrabber.viewmodels.factories.DirectSettingsViewModelFactory; | ||||
| 
 | ||||
| public class DirectMessageSettingsFragment extends Fragment implements ConfirmDialogFragmentCallback { | ||||
|     private static final String TAG = DirectMessageSettingsFragment.class.getSimpleName(); | ||||
|     private static final int APPROVAL_REQUIRED_REQUEST_CODE = 200; | ||||
|     private static final int LEAVE_THREAD_REQUEST_CODE = 201; | ||||
|     private static final int END_THREAD_REQUEST_CODE = 202; | ||||
| 
 | ||||
|     private FragmentDirectMessagesSettingsBinding binding; | ||||
|     private DirectSettingsViewModel viewModel; | ||||
|     private DirectUsersAdapter usersAdapter; | ||||
|     private boolean isPendingRequestsSetupDone = false; | ||||
|     private DirectPendingUsersAdapter pendingUsersAdapter; | ||||
|     private Set<User> approvalRequiredUsers; | ||||
| 
 | ||||
|     @Override | ||||
|     public void onCreate(@Nullable final Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|         final Bundle arguments = getArguments(); | ||||
|         if (arguments == null) return; | ||||
|         final DirectMessageSettingsFragmentArgs args = DirectMessageSettingsFragmentArgs.fromBundle(arguments); | ||||
|         final MainActivity fragmentActivity = (MainActivity) requireActivity(); | ||||
|         final AppStateViewModel appStateViewModel = new ViewModelProvider(fragmentActivity).get(AppStateViewModel.class); | ||||
|         final DirectSettingsViewModelFactory viewModelFactory = new DirectSettingsViewModelFactory( | ||||
|                 fragmentActivity.getApplication(), | ||||
|                 args.getThreadId(), | ||||
|                 args.getPending(), | ||||
|                 appStateViewModel.getCurrentUser() | ||||
|         ); | ||||
|         viewModel = new ViewModelProvider(this, viewModelFactory).get(DirectSettingsViewModel.class); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public View onCreateView(@NonNull final LayoutInflater inflater, | ||||
|                              final ViewGroup container, | ||||
|                              final Bundle savedInstanceState) { | ||||
|         binding = FragmentDirectMessagesSettingsBinding.inflate(inflater, container, false); | ||||
|         // currentlyRunning = new DirectMessageInboxThreadFetcher(threadId, null, null, fetchListener).execute(); | ||||
|         return binding.getRoot(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { | ||||
|         final Bundle arguments = getArguments(); | ||||
|         if (arguments == null) return; | ||||
|         init(); | ||||
|         setupObservers(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onDestroyView() { | ||||
|         super.onDestroyView(); | ||||
|         binding = null; | ||||
|         isPendingRequestsSetupDone = false; | ||||
|     } | ||||
| 
 | ||||
|     private void setupObservers() { | ||||
|         viewModel.getInputMode().observe(getViewLifecycleOwner(), inputMode -> { | ||||
|             if (inputMode == null || inputMode == 0) return; | ||||
|             if (inputMode == 1) { | ||||
|                 binding.groupSettings.setVisibility(View.GONE); | ||||
|                 binding.pendingMembersGroup.setVisibility(View.GONE); | ||||
|                 binding.approvalRequired.setVisibility(View.GONE); | ||||
|                 binding.approvalRequiredLabel.setVisibility(View.GONE); | ||||
|                 binding.muteMessagesLabel.setVisibility(View.GONE); | ||||
|                 binding.muteMessages.setVisibility(View.GONE); | ||||
|             } | ||||
|         }); | ||||
|         // Need to observe, so that getValue is correct | ||||
|         viewModel.getUsers().observe(getViewLifecycleOwner(), users -> {}); | ||||
|         viewModel.getLeftUsers().observe(getViewLifecycleOwner(), users -> {}); | ||||
|         viewModel.getUsersAndLeftUsers().observe(getViewLifecycleOwner(), usersPair -> { | ||||
|             if (usersAdapter == null) return; | ||||
|             usersAdapter.submitUsers(usersPair.first, usersPair.second); | ||||
|         }); | ||||
|         viewModel.getTitle().observe(getViewLifecycleOwner(), title -> binding.titleEdit.setText(title)); | ||||
|         viewModel.getAdminUserIds().observe(getViewLifecycleOwner(), adminUserIds -> { | ||||
|             if (usersAdapter == null) return; | ||||
|             usersAdapter.setAdminUserIds(adminUserIds); | ||||
|         }); | ||||
|         viewModel.isMuted().observe(getViewLifecycleOwner(), muted -> binding.muteMessages.setChecked(muted)); | ||||
|         viewModel.isPending().observe(getViewLifecycleOwner(), pending -> binding.muteMessages.setVisibility(pending ? View.GONE : View.VISIBLE)); | ||||
|         viewModel.isViewerAdmin().observe(getViewLifecycleOwner(), this::setApprovalRelatedUI); | ||||
|         viewModel.getApprovalRequiredToJoin().observe(getViewLifecycleOwner(), required -> binding.approvalRequired.setChecked(required)); | ||||
|         viewModel.getPendingRequests().observe(getViewLifecycleOwner(), this::setPendingRequests); | ||||
|         viewModel.isGroup().observe(getViewLifecycleOwner(), this::setupSettings); | ||||
|         final NavController navController = NavHostFragment.findNavController(this); | ||||
|         final NavBackStackEntry backStackEntry = navController.getCurrentBackStackEntry(); | ||||
|         if (backStackEntry != null) { | ||||
|             final MutableLiveData<Object> resultLiveData = backStackEntry.getSavedStateHandle().getLiveData("result"); | ||||
|             resultLiveData.observe(getViewLifecycleOwner(), result -> { | ||||
|                 if ((result instanceof RankedRecipient)) { | ||||
|                     final RankedRecipient recipient = (RankedRecipient) result; | ||||
|                     final User user = getUser(recipient); | ||||
|                     // Log.d(TAG, "result: " + user); | ||||
|                     if (user != null) { | ||||
|                         addMembers(Collections.singleton(recipient.getUser())); | ||||
|                     } | ||||
|                 } else if ((result instanceof Set)) { | ||||
|                     try { | ||||
|                         //noinspection unchecked | ||||
|                         final Set<RankedRecipient> recipients = (Set<RankedRecipient>) result; | ||||
|                         final Set<User> users = recipients.stream() | ||||
|                                                           .filter(Objects::nonNull) | ||||
|                                                           .map(this::getUser) | ||||
|                                                           .filter(Objects::nonNull) | ||||
|                                                           .collect(Collectors.toSet()); | ||||
|                         // Log.d(TAG, "result: " + users); | ||||
|                         addMembers(users); | ||||
|                     } catch (Exception e) { | ||||
|                         Log.e(TAG, "search users result: ", e); | ||||
|                         Snackbar.make(binding.getRoot(), e.getMessage() != null ? e.getMessage() : "", Snackbar.LENGTH_LONG).show(); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void addMembers(final Set<User> users) { | ||||
|         final Boolean approvalRequired = viewModel.getApprovalRequiredToJoin().getValue(); | ||||
|         Boolean isViewerAdmin = viewModel.isViewerAdmin().getValue(); | ||||
|         if (isViewerAdmin == null) { | ||||
|             isViewerAdmin = false; | ||||
|         } | ||||
|         if (!isViewerAdmin && approvalRequired != null && approvalRequired) { | ||||
|             approvalRequiredUsers = users; | ||||
|             final ConfirmDialogFragment confirmDialogFragment = ConfirmDialogFragment.newInstance( | ||||
|                     APPROVAL_REQUIRED_REQUEST_CODE, | ||||
|                     R.string.admin_approval_required, | ||||
|                     R.string.admin_approval_required_description, | ||||
|                     R.string.ok, | ||||
|                     R.string.cancel, | ||||
|                     0 | ||||
|             ); | ||||
|             confirmDialogFragment.show(getChildFragmentManager(), "approval_required_dialog"); | ||||
|             return; | ||||
|         } | ||||
|         final LiveData<Resource<Object>> detailsChangeResourceLiveData = viewModel.addMembers(users); | ||||
|         observeDetailsChange(detailsChangeResourceLiveData); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     private User getUser(@NonNull final RankedRecipient recipient) { | ||||
|         User user = null; | ||||
|         if (recipient.getUser() != null) { | ||||
|             user = recipient.getUser(); | ||||
|         } else if (recipient.getThread() != null && !recipient.getThread().isGroup()) { | ||||
|             user = recipient.getThread().getUsers().get(0); | ||||
|         } | ||||
|         return user; | ||||
|     } | ||||
| 
 | ||||
|     private void init() { | ||||
|         // setupSettings(); | ||||
|         setupMembers(); | ||||
|     } | ||||
| 
 | ||||
|     private void setupSettings(final boolean isGroup) { | ||||
|         binding.groupSettings.setVisibility(isGroup ? View.VISIBLE : View.GONE); | ||||
|         binding.muteMessagesLabel.setOnClickListener(v -> binding.muteMessages.toggle()); | ||||
|         binding.muteMessages.setOnCheckedChangeListener((buttonView, isChecked) -> { | ||||
|             final LiveData<Resource<Object>> resourceLiveData = isChecked ? viewModel.mute() : viewModel.unmute(); | ||||
|             handleSwitchChangeResource(resourceLiveData, buttonView); | ||||
|         }); | ||||
|         if (!isGroup) return; | ||||
|         binding.titleEdit.addTextChangedListener(new TextWatcherAdapter() { | ||||
|             @Override | ||||
|             public void onTextChanged(final CharSequence s, final int start, final int before, final int count) { | ||||
|                 if (s.toString().trim().equals(viewModel.getTitle().getValue())) { | ||||
|                     binding.titleEditInputLayout.setSuffixText(null); | ||||
|                     return; | ||||
|                 } | ||||
|                 binding.titleEditInputLayout.setSuffixText(getString(R.string.save)); | ||||
|             } | ||||
|         }); | ||||
|         binding.titleEditInputLayout.getSuffixTextView().setOnClickListener(v -> { | ||||
|             final Editable text = binding.titleEdit.getText(); | ||||
|             if (text == null) return; | ||||
|             final String newTitle = text.toString().trim(); | ||||
|             if (newTitle.equals(viewModel.getTitle().getValue())) return; | ||||
|             observeDetailsChange(viewModel.updateTitle(newTitle)); | ||||
|         }); | ||||
|         binding.addMembers.setOnClickListener(v -> { | ||||
|             if (!isAdded()) return; | ||||
|             final NavController navController = NavHostFragment.findNavController(this); | ||||
|             final NavDestination currentDestination = navController.getCurrentDestination(); | ||||
|             if (currentDestination == null) return; | ||||
|             if (currentDestination.getId() != R.id.directMessagesSettingsFragment) return; | ||||
|             final List<User> users = viewModel.getUsers().getValue(); | ||||
|             final long[] currentUserIds; | ||||
|             if (users != null) { | ||||
|                 currentUserIds = users.stream() | ||||
|                                       .mapToLong(User::getPk) | ||||
|                                       .sorted() | ||||
|                                       .toArray(); | ||||
|             } else { | ||||
|                 currentUserIds = new long[0]; | ||||
|             } | ||||
|             final UserSearchNavGraphDirections.ActionGlobalUserSearch actionGlobalUserSearch = UserSearchFragmentDirections | ||||
|                     .actionGlobalUserSearch() | ||||
|                     .setTitle(getString(R.string.add_members)) | ||||
|                     .setActionLabel(getString(R.string.add)) | ||||
|                     .setHideUserIds(currentUserIds) | ||||
|                     .setSearchMode(UserSearchFragment.SearchMode.RAVEN) | ||||
|                     .setMultiple(true); | ||||
|             navController.navigate(actionGlobalUserSearch); | ||||
|         }); | ||||
|         binding.muteMentionsLabel.setOnClickListener(v -> binding.muteMentions.toggle()); | ||||
|         binding.muteMentions.setOnCheckedChangeListener((buttonView, isChecked) -> { | ||||
|             final LiveData<Resource<Object>> resourceLiveData = isChecked ? viewModel.muteMentions() : viewModel.unmuteMentions(); | ||||
|             handleSwitchChangeResource(resourceLiveData, buttonView); | ||||
|         }); | ||||
|         binding.leave.setOnClickListener(v -> { | ||||
|             final ConfirmDialogFragment confirmDialogFragment = ConfirmDialogFragment.newInstance( | ||||
|                     LEAVE_THREAD_REQUEST_CODE, | ||||
|                     R.string.dms_action_leave_question, | ||||
|                     0, | ||||
|                     R.string.yes, | ||||
|                     R.string.no, | ||||
|                     0 | ||||
|             ); | ||||
|             confirmDialogFragment.show(getChildFragmentManager(), "leave_thread_confirmation_dialog"); | ||||
|         }); | ||||
|         Boolean isViewerAdmin = viewModel.isViewerAdmin().getValue(); | ||||
|         if (isViewerAdmin == null) isViewerAdmin = false; | ||||
|         if (isViewerAdmin) { | ||||
|             binding.end.setVisibility(View.VISIBLE); | ||||
|             binding.end.setOnClickListener(v -> { | ||||
|                 final ConfirmDialogFragment confirmDialogFragment = ConfirmDialogFragment.newInstance( | ||||
|                         END_THREAD_REQUEST_CODE, | ||||
|                         R.string.dms_action_end_question, | ||||
|                         R.string.dms_action_end_description, | ||||
|                         R.string.yes, | ||||
|                         R.string.no, | ||||
|                         0 | ||||
|                 ); | ||||
|                 confirmDialogFragment.show(getChildFragmentManager(), "end_thread_confirmation_dialog"); | ||||
|             }); | ||||
|         } else { | ||||
|             binding.end.setVisibility(View.GONE); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void setApprovalRelatedUI(final boolean isViewerAdmin) { | ||||
|         if (!isViewerAdmin) { | ||||
|             binding.pendingMembersGroup.setVisibility(View.GONE); | ||||
|             binding.approvalRequired.setVisibility(View.GONE); | ||||
|             binding.approvalRequiredLabel.setVisibility(View.GONE); | ||||
|             return; | ||||
|         } | ||||
|         binding.approvalRequired.setVisibility(View.VISIBLE); | ||||
|         binding.approvalRequiredLabel.setVisibility(View.VISIBLE); | ||||
|         binding.approvalRequiredLabel.setOnClickListener(v -> binding.approvalRequired.toggle()); | ||||
|         binding.approvalRequired.setOnCheckedChangeListener((buttonView, isChecked) -> { | ||||
|             final LiveData<Resource<Object>> resourceLiveData = isChecked ? viewModel.approvalRequired() : viewModel.approvalNotRequired(); | ||||
|             handleSwitchChangeResource(resourceLiveData, buttonView); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     private void handleSwitchChangeResource(final LiveData<Resource<Object>> 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); | ||||
|                     buttonView.setChecked(!buttonView.isChecked()); | ||||
|                     if (resource.message != null) { | ||||
|                         Snackbar.make(binding.getRoot(), resource.message, Snackbar.LENGTH_LONG).show(); | ||||
|                     } | ||||
|                     if (resource.resId != 0) { | ||||
|                         Snackbar.make(binding.getRoot(), resource.resId, Snackbar.LENGTH_LONG).show(); | ||||
|                     } | ||||
|                     break; | ||||
|                 case LOADING: | ||||
|                     buttonView.setEnabled(false); | ||||
|                     break; | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     private void setupMembers() { | ||||
|         final Context context = getContext(); | ||||
|         if (context == null) return; | ||||
|         binding.users.setLayoutManager(new LinearLayoutManager(context)); | ||||
|         final User inviter = viewModel.getInviter().getValue(); | ||||
|         usersAdapter = new DirectUsersAdapter( | ||||
|                 inviter != null ? inviter.getPk() : -1, | ||||
|                 (position, user, selected) -> { | ||||
|                     if (TextUtils.isEmpty(user.getUsername()) && !TextUtils.isEmpty(user.getFbId())) { | ||||
|                         Utils.openURL(context, "https://facebook.com/" + user.getFbId()); | ||||
|                         return; | ||||
|                     } | ||||
|                     if (TextUtils.isEmpty(user.getUsername())) return; | ||||
|                     final ProfileNavGraphDirections.ActionGlobalProfileFragment directions = ProfileNavGraphDirections | ||||
|                             .actionGlobalProfileFragment("@" + user.getUsername()); | ||||
|                     NavHostFragment.findNavController(this).navigate(directions); | ||||
|                 }, | ||||
|                 (position, user) -> { | ||||
|                     final ArrayList<Option<String>> options = viewModel.createUserOptions(user); | ||||
|                     if (options == null || options.isEmpty()) return true; | ||||
|                     final MultiOptionDialogFragment<String> fragment = MultiOptionDialogFragment.newInstance(-1, options); | ||||
|                     fragment.setSingleCallback(new MultiOptionDialogFragment.MultiOptionDialogSingleCallback<String>() { | ||||
|                         @Override | ||||
|                         public void onSelect(final String action) { | ||||
|                             if (action == null) return; | ||||
|                             observeDetailsChange(viewModel.doAction(user, action)); | ||||
|                         } | ||||
| 
 | ||||
|                         @Override | ||||
|                         public void onCancel() {} | ||||
|                     }); | ||||
|                     final FragmentManager fragmentManager = getChildFragmentManager(); | ||||
|                     fragment.show(fragmentManager, "actions"); | ||||
|                     return true; | ||||
|                 } | ||||
|         ); | ||||
|         binding.users.setAdapter(usersAdapter); | ||||
|     } | ||||
| 
 | ||||
|     private void setPendingRequests(final DirectThreadParticipantRequestsResponse requests) { | ||||
|         if (requests == null || requests.getUsers() == null || requests.getUsers().isEmpty()) { | ||||
|             binding.pendingMembersGroup.setVisibility(View.GONE); | ||||
|             return; | ||||
|         } | ||||
|         if (!isPendingRequestsSetupDone) { | ||||
|             final Context context = getContext(); | ||||
|             if (context == null) return; | ||||
|             binding.pendingMembers.setLayoutManager(new LinearLayoutManager(context)); | ||||
|             pendingUsersAdapter = new DirectPendingUsersAdapter(new PendingUserCallback() { | ||||
|                 @Override | ||||
|                 public void onClick(final int position, final PendingUser pendingUser) { | ||||
|                     final ProfileNavGraphDirections.ActionGlobalProfileFragment directions = ProfileNavGraphDirections | ||||
|                             .actionGlobalProfileFragment("@" + pendingUser.getUser().getUsername()); | ||||
|                     NavHostFragment.findNavController(DirectMessageSettingsFragment.this).navigate(directions); | ||||
|                 } | ||||
| 
 | ||||
|                 @Override | ||||
|                 public void onApprove(final int position, final PendingUser pendingUser) { | ||||
|                     final LiveData<Resource<Object>> resourceLiveData = viewModel.approveUsers(Collections.singletonList(pendingUser.getUser())); | ||||
|                     observeApprovalChange(resourceLiveData, position, pendingUser); | ||||
|                 } | ||||
| 
 | ||||
|                 @Override | ||||
|                 public void onDeny(final int position, final PendingUser pendingUser) { | ||||
|                     final LiveData<Resource<Object>> resourceLiveData = viewModel.denyUsers(Collections.singletonList(pendingUser.getUser())); | ||||
|                     observeApprovalChange(resourceLiveData, position, pendingUser); | ||||
|                 } | ||||
|             }); | ||||
|             binding.pendingMembers.setAdapter(pendingUsersAdapter); | ||||
|             binding.pendingMembersGroup.setVisibility(View.VISIBLE); | ||||
|             isPendingRequestsSetupDone = true; | ||||
|         } | ||||
|         if (pendingUsersAdapter != null) { | ||||
|             pendingUsersAdapter.submitPendingRequests(requests); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void observeDetailsChange(@NonNull final LiveData<Resource<Object>> resourceLiveData) { | ||||
|         resourceLiveData.observe(getViewLifecycleOwner(), resource -> { | ||||
|             if (resource == null) return; | ||||
|             switch (resource.status) { | ||||
|                 case SUCCESS: | ||||
|                 case LOADING: | ||||
|                     break; | ||||
|                 case ERROR: | ||||
|                     if (resource.message != null) { | ||||
|                         Snackbar.make(binding.getRoot(), resource.message, Snackbar.LENGTH_LONG).show(); | ||||
|                     } | ||||
|                     if (resource.resId != 0) { | ||||
|                         Snackbar.make(binding.getRoot(), resource.resId, Snackbar.LENGTH_LONG).show(); | ||||
|                     } | ||||
|                     break; | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     private void observeApprovalChange(@NonNull final LiveData<Resource<Object>> detailsChangeResourceLiveData, | ||||
|                                        final int position, | ||||
|                                        @NonNull final PendingUser pendingUser) { | ||||
|         detailsChangeResourceLiveData.observe(getViewLifecycleOwner(), resource -> { | ||||
|             if (resource == null) return; | ||||
|             switch (resource.status) { | ||||
|                 case SUCCESS: | ||||
|                     // pending user will be removed from the list, so no need to set the progress to false | ||||
|                     // pendingUser.setInProgress(false); | ||||
|                     break; | ||||
|                 case LOADING: | ||||
|                     pendingUser.setInProgress(true); | ||||
|                     break; | ||||
|                 case ERROR: | ||||
|                     pendingUser.setInProgress(false); | ||||
|                     if (resource.message != null) { | ||||
|                         Snackbar.make(binding.getRoot(), resource.message, Snackbar.LENGTH_LONG).show(); | ||||
|                     } | ||||
|                     if (resource.resId != 0) { | ||||
|                         Snackbar.make(binding.getRoot(), resource.resId, Snackbar.LENGTH_LONG).show(); | ||||
|                     } | ||||
|                     break; | ||||
|             } | ||||
|             pendingUsersAdapter.notifyItemChanged(position); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onPositiveButtonClicked(final int requestCode) { | ||||
|         if (requestCode == APPROVAL_REQUIRED_REQUEST_CODE && approvalRequiredUsers != null) { | ||||
|             final LiveData<Resource<Object>> detailsChangeResourceLiveData = viewModel.addMembers(approvalRequiredUsers); | ||||
|             observeDetailsChange(detailsChangeResourceLiveData); | ||||
|             return; | ||||
|         } | ||||
|         if (requestCode == LEAVE_THREAD_REQUEST_CODE) { | ||||
|             final LiveData<Resource<Object>> resourceLiveData = viewModel.leave(); | ||||
|             resourceLiveData.observe(getViewLifecycleOwner(), resource -> { | ||||
|                 if (resource == null) return; | ||||
|                 switch (resource.status) { | ||||
|                     case SUCCESS: | ||||
|                         final NavDirections directions = DirectMessageSettingsFragmentDirections.actionSettingsToInbox(); | ||||
|                         NavHostFragment.findNavController(this).navigate(directions); | ||||
|                         break; | ||||
|                     case ERROR: | ||||
|                         binding.leave.setEnabled(true); | ||||
|                         if (resource.message != null) { | ||||
|                             Snackbar.make(binding.getRoot(), resource.message, Snackbar.LENGTH_LONG).show(); | ||||
|                         } | ||||
|                         if (resource.resId != 0) { | ||||
|                             Snackbar.make(binding.getRoot(), resource.resId, Snackbar.LENGTH_LONG).show(); | ||||
|                         } | ||||
|                         break; | ||||
|                     case LOADING: | ||||
|                         binding.leave.setEnabled(false); | ||||
|                         break; | ||||
|                 } | ||||
|             }); | ||||
|             return; | ||||
|         } | ||||
|         if (requestCode == END_THREAD_REQUEST_CODE) { | ||||
|             final LiveData<Resource<Object>> resourceLiveData = viewModel.end(); | ||||
|             resourceLiveData.observe(getViewLifecycleOwner(), resource -> { | ||||
|                 if (resource == null) return; | ||||
|                 switch (resource.status) { | ||||
|                     case SUCCESS: | ||||
|                         break; | ||||
|                     case ERROR: | ||||
|                         binding.end.setEnabled(true); | ||||
|                         if (resource.message != null) { | ||||
|                             Snackbar.make(binding.getRoot(), resource.message, Snackbar.LENGTH_LONG).show(); | ||||
|                         } | ||||
|                         if (resource.resId != 0) { | ||||
|                             Snackbar.make(binding.getRoot(), resource.resId, Snackbar.LENGTH_LONG).show(); | ||||
|                         } | ||||
|                         break; | ||||
|                     case LOADING: | ||||
|                         binding.end.setEnabled(false); | ||||
|                         break; | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onNegativeButtonClicked(final int requestCode) { | ||||
|         if (requestCode == APPROVAL_REQUIRED_REQUEST_CODE) { | ||||
|             approvalRequiredUsers = null; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onNeutralButtonClicked(final int requestCode) {} | ||||
| } | ||||
| @ -0,0 +1,475 @@ | ||||
| package awais.instagrabber.fragments.directmessages | ||||
| 
 | ||||
| import android.os.Bundle | ||||
| import android.util.Log | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.CompoundButton | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.fragment.app.activityViewModels | ||||
| import androidx.lifecycle.LiveData | ||||
| import androidx.lifecycle.ViewModelProvider | ||||
| import androidx.navigation.fragment.NavHostFragment | ||||
| import androidx.recyclerview.widget.LinearLayoutManager | ||||
| import awais.instagrabber.ProfileNavGraphDirections | ||||
| import awais.instagrabber.R | ||||
| import awais.instagrabber.activities.MainActivity | ||||
| import awais.instagrabber.adapters.DirectPendingUsersAdapter | ||||
| import awais.instagrabber.adapters.DirectPendingUsersAdapter.PendingUser | ||||
| import awais.instagrabber.adapters.DirectPendingUsersAdapter.PendingUserCallback | ||||
| import awais.instagrabber.adapters.DirectUsersAdapter | ||||
| import awais.instagrabber.customviews.helpers.TextWatcherAdapter | ||||
| import awais.instagrabber.databinding.FragmentDirectMessagesSettingsBinding | ||||
| import awais.instagrabber.dialogs.ConfirmDialogFragment | ||||
| import awais.instagrabber.dialogs.ConfirmDialogFragment.ConfirmDialogFragmentCallback | ||||
| import awais.instagrabber.dialogs.MultiOptionDialogFragment | ||||
| import awais.instagrabber.dialogs.MultiOptionDialogFragment.MultiOptionDialogSingleCallback | ||||
| import awais.instagrabber.fragments.UserSearchFragment | ||||
| import awais.instagrabber.fragments.UserSearchFragmentDirections | ||||
| import awais.instagrabber.models.Resource | ||||
| import awais.instagrabber.repositories.responses.User | ||||
| import awais.instagrabber.repositories.responses.directmessages.DirectThreadParticipantRequestsResponse | ||||
| import awais.instagrabber.repositories.responses.directmessages.RankedRecipient | ||||
| import awais.instagrabber.utils.TextUtils.isEmpty | ||||
| import awais.instagrabber.utils.Utils | ||||
| import awais.instagrabber.utils.extensions.TAG | ||||
| import awais.instagrabber.viewmodels.AppStateViewModel | ||||
| import awais.instagrabber.viewmodels.DirectSettingsViewModel | ||||
| import awais.instagrabber.viewmodels.factories.DirectSettingsViewModelFactory | ||||
| import com.google.android.material.snackbar.Snackbar | ||||
| import java.util.* | ||||
| 
 | ||||
| class DirectMessageSettingsFragment : Fragment(), ConfirmDialogFragmentCallback { | ||||
|     private lateinit var viewModel: DirectSettingsViewModel | ||||
|     private lateinit var binding: FragmentDirectMessagesSettingsBinding | ||||
| 
 | ||||
|     private var usersAdapter: DirectUsersAdapter? = null | ||||
|     private var isPendingRequestsSetupDone = false | ||||
|     private var pendingUsersAdapter: DirectPendingUsersAdapter? = null | ||||
|     private var approvalRequiredUsers: Set<User>? = null | ||||
| 
 | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         super.onCreate(savedInstanceState) | ||||
|         val arguments = arguments ?: return | ||||
|         val args = DirectMessageSettingsFragmentArgs.fromBundle(arguments) | ||||
|         val fragmentActivity = requireActivity() as MainActivity | ||||
|         val appStateViewModel: AppStateViewModel by activityViewModels() | ||||
|         val currentUser = appStateViewModel.currentUser ?: return | ||||
|         val viewModelFactory = DirectSettingsViewModelFactory( | ||||
|             fragmentActivity.application, | ||||
|             args.threadId, | ||||
|             args.pending, | ||||
|             currentUser | ||||
|         ) | ||||
|         viewModel = ViewModelProvider(this, viewModelFactory).get(DirectSettingsViewModel::class.java) | ||||
|     } | ||||
| 
 | ||||
|     override fun onCreateView( | ||||
|         inflater: LayoutInflater, | ||||
|         container: ViewGroup?, | ||||
|         savedInstanceState: Bundle?, | ||||
|     ): View { | ||||
|         binding = FragmentDirectMessagesSettingsBinding.inflate(inflater, container, false) | ||||
|         // currentlyRunning = new DirectMessageInboxThreadFetcher(threadId, null, null, fetchListener).execute(); | ||||
|         return binding.root | ||||
|     } | ||||
| 
 | ||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
|         init() | ||||
|         setupObservers() | ||||
|     } | ||||
| 
 | ||||
|     override fun onDestroyView() { | ||||
|         super.onDestroyView() | ||||
|         isPendingRequestsSetupDone = false | ||||
|     } | ||||
| 
 | ||||
|     private fun setupObservers() { | ||||
|         viewModel.inputMode.observe(viewLifecycleOwner, { inputMode: Int? -> | ||||
|             if (inputMode == null || inputMode == 0) return@observe | ||||
|             if (inputMode == 1) { | ||||
|                 binding.groupSettings.visibility = View.GONE | ||||
|                 binding.pendingMembersGroup.visibility = View.GONE | ||||
|                 binding.approvalRequired.visibility = View.GONE | ||||
|                 binding.approvalRequiredLabel.visibility = View.GONE | ||||
|                 binding.muteMessagesLabel.visibility = View.GONE | ||||
|                 binding.muteMessages.visibility = View.GONE | ||||
|             } | ||||
|         }) | ||||
|         // Need to observe, so that getValue is correct | ||||
|         viewModel.getUsers().observe(viewLifecycleOwner, { }) | ||||
|         viewModel.getLeftUsers().observe(viewLifecycleOwner, { }) | ||||
|         viewModel.getUsersAndLeftUsers().observe(viewLifecycleOwner, { usersAdapter?.submitUsers(it.first, it.second) }) | ||||
|         viewModel.getTitle().observe(viewLifecycleOwner, { binding.titleEdit.setText(it) }) | ||||
|         viewModel.getAdminUserIds().observe(viewLifecycleOwner, { usersAdapter?.setAdminUserIds(it) }) | ||||
|         viewModel.isMuted().observe(viewLifecycleOwner, { binding.muteMessages.isChecked = it }) | ||||
|         viewModel.isPending().observe(viewLifecycleOwner, { binding.muteMessages.visibility = if (it) View.GONE else View.VISIBLE }) | ||||
|         viewModel.isViewerAdmin().observe(viewLifecycleOwner, { setApprovalRelatedUI(it) }) | ||||
|         viewModel.getApprovalRequiredToJoin().observe(viewLifecycleOwner, { binding.approvalRequired.isChecked = it }) | ||||
|         viewModel.getPendingRequests().observe(viewLifecycleOwner, { setPendingRequests(it) }) | ||||
|         viewModel.isGroup().observe(viewLifecycleOwner, { isGroup: Boolean -> setupSettings(isGroup) }) | ||||
|         val navController = NavHostFragment.findNavController(this) | ||||
|         val backStackEntry = navController.currentBackStackEntry | ||||
|         if (backStackEntry != null) { | ||||
|             val resultLiveData = backStackEntry.savedStateHandle.getLiveData<Any>("result") | ||||
|             resultLiveData.observe(viewLifecycleOwner, { result: Any? -> | ||||
|                 if (result == null) return@observe | ||||
|                 if (result is RankedRecipient) { | ||||
|                     val user = getUser(result) | ||||
|                     // Log.d(TAG, "result: " + user); | ||||
|                     if (user != null) { | ||||
|                         addMembers(setOf(user)) | ||||
|                     } | ||||
|                 } else if (result is Set<*>) { | ||||
|                     try { | ||||
|                         @Suppress("UNCHECKED_CAST") val recipients = result as Set<RankedRecipient> | ||||
|                         val users: Set<User> = recipients.asSequence() | ||||
|                             .filterNotNull() | ||||
|                             .map { getUser(it) } | ||||
|                             .filterNotNull() | ||||
|                             .toSet() | ||||
|                         // Log.d(TAG, "result: " + users); | ||||
|                         addMembers(users) | ||||
|                     } catch (e: Exception) { | ||||
|                         Log.e(TAG, "search users result: ", e) | ||||
|                         Snackbar.make(binding.root, e.message ?: "", Snackbar.LENGTH_LONG).show() | ||||
|                     } | ||||
|                 } | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun addMembers(users: Set<User>) { | ||||
|         val approvalRequired = viewModel.getApprovalRequiredToJoin().value | ||||
|         var isViewerAdmin = viewModel.isViewerAdmin().value | ||||
|         if (isViewerAdmin == null) { | ||||
|             isViewerAdmin = false | ||||
|         } | ||||
|         if (!isViewerAdmin && approvalRequired != null && approvalRequired) { | ||||
|             approvalRequiredUsers = users | ||||
|             val confirmDialogFragment = ConfirmDialogFragment.newInstance( | ||||
|                 APPROVAL_REQUIRED_REQUEST_CODE, | ||||
|                 R.string.admin_approval_required, | ||||
|                 R.string.admin_approval_required_description, | ||||
|                 R.string.ok, | ||||
|                 R.string.cancel, | ||||
|                 0 | ||||
|             ) | ||||
|             confirmDialogFragment.show(childFragmentManager, "approval_required_dialog") | ||||
|             return | ||||
|         } | ||||
|         val detailsChangeResourceLiveData = viewModel.addMembers(users) | ||||
|         observeDetailsChange(detailsChangeResourceLiveData) | ||||
|     } | ||||
| 
 | ||||
|     private fun getUser(recipient: RankedRecipient): User? { | ||||
|         var user: User? = null | ||||
|         if (recipient.user != null) { | ||||
|             user = recipient.user | ||||
|         } else if (recipient.thread != null && !recipient.thread.isGroup) { | ||||
|             user = recipient.thread.users?.get(0) | ||||
|         } | ||||
|         return user | ||||
|     } | ||||
| 
 | ||||
|     private fun init() { | ||||
|         // setupSettings(); | ||||
|         setupMembers() | ||||
|     } | ||||
| 
 | ||||
|     private fun setupSettings(isGroup: Boolean) { | ||||
|         binding.groupSettings.visibility = if (isGroup) View.VISIBLE else View.GONE | ||||
|         binding.muteMessagesLabel.setOnClickListener { binding.muteMessages.toggle() } | ||||
|         binding.muteMessages.setOnCheckedChangeListener { buttonView: CompoundButton, isChecked: Boolean -> | ||||
|             val resourceLiveData = if (isChecked) viewModel.mute() else viewModel.unmute() | ||||
|             handleSwitchChangeResource(resourceLiveData, buttonView) | ||||
|         } | ||||
|         if (!isGroup) return | ||||
|         binding.titleEdit.addTextChangedListener(object : TextWatcherAdapter() { | ||||
|             override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { | ||||
|                 if (s.toString().trim { it <= ' ' } == viewModel.getTitle().value) { | ||||
|                     binding.titleEditInputLayout.suffixText = null | ||||
|                     return | ||||
|                 } | ||||
|                 binding.titleEditInputLayout.suffixText = getString(R.string.save) | ||||
|             } | ||||
|         }) | ||||
|         binding.titleEditInputLayout.suffixTextView.setOnClickListener { | ||||
|             val text = binding.titleEdit.text ?: return@setOnClickListener | ||||
|             val newTitle = text.toString().trim { it <= ' ' } | ||||
|             if (newTitle == viewModel.getTitle().value) return@setOnClickListener | ||||
|             observeDetailsChange(viewModel.updateTitle(newTitle)) | ||||
|         } | ||||
|         binding.addMembers.setOnClickListener { | ||||
|             if (!isAdded) return@setOnClickListener | ||||
|             val navController = NavHostFragment.findNavController(this) | ||||
|             val currentDestination = navController.currentDestination ?: return@setOnClickListener | ||||
|             if (currentDestination.id != R.id.directMessagesSettingsFragment) return@setOnClickListener | ||||
|             val users = viewModel.getUsers().value | ||||
|             val currentUserIds: LongArray = users?.asSequence()?.map { obj: User -> obj.pk }?.sorted()?.toList()?.toLongArray() ?: LongArray(0) | ||||
|             val actionGlobalUserSearch = UserSearchFragmentDirections | ||||
|                 .actionGlobalUserSearch() | ||||
|                 .setTitle(getString(R.string.add_members)) | ||||
|                 .setActionLabel(getString(R.string.add)) | ||||
|                 .setHideUserIds(currentUserIds) | ||||
|                 .setSearchMode(UserSearchFragment.SearchMode.RAVEN) | ||||
|                 .setMultiple(true) | ||||
|             navController.navigate(actionGlobalUserSearch) | ||||
|         } | ||||
|         binding.muteMentionsLabel.setOnClickListener { binding.muteMentions.toggle() } | ||||
|         binding.muteMentions.setOnCheckedChangeListener { buttonView: CompoundButton, isChecked: Boolean -> | ||||
|             val resourceLiveData = if (isChecked) viewModel.muteMentions() else viewModel.unmuteMentions() | ||||
|             handleSwitchChangeResource(resourceLiveData, buttonView) | ||||
|         } | ||||
|         binding.leave.setOnClickListener { | ||||
|             val confirmDialogFragment = ConfirmDialogFragment.newInstance( | ||||
|                 LEAVE_THREAD_REQUEST_CODE, | ||||
|                 R.string.dms_action_leave_question, | ||||
|                 0, | ||||
|                 R.string.yes, | ||||
|                 R.string.no, | ||||
|                 0 | ||||
|             ) | ||||
|             confirmDialogFragment.show(childFragmentManager, "leave_thread_confirmation_dialog") | ||||
|         } | ||||
|         var isViewerAdmin = viewModel.isViewerAdmin().value | ||||
|         if (isViewerAdmin == null) isViewerAdmin = false | ||||
|         if (isViewerAdmin) { | ||||
|             binding.end.visibility = View.VISIBLE | ||||
|             binding.end.setOnClickListener { | ||||
|                 val confirmDialogFragment = ConfirmDialogFragment.newInstance( | ||||
|                     END_THREAD_REQUEST_CODE, | ||||
|                     R.string.dms_action_end_question, | ||||
|                     R.string.dms_action_end_description, | ||||
|                     R.string.yes, | ||||
|                     R.string.no, | ||||
|                     0 | ||||
|                 ) | ||||
|                 confirmDialogFragment.show(childFragmentManager, "end_thread_confirmation_dialog") | ||||
|             } | ||||
|         } else { | ||||
|             binding.end.visibility = View.GONE | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun setApprovalRelatedUI(isViewerAdmin: Boolean) { | ||||
|         if (!isViewerAdmin) { | ||||
|             binding.pendingMembersGroup.visibility = View.GONE | ||||
|             binding.approvalRequired.visibility = View.GONE | ||||
|             binding.approvalRequiredLabel.visibility = View.GONE | ||||
|             return | ||||
|         } | ||||
|         binding.approvalRequired.visibility = View.VISIBLE | ||||
|         binding.approvalRequiredLabel.visibility = View.VISIBLE | ||||
|         binding.approvalRequiredLabel.setOnClickListener { binding.approvalRequired.toggle() } | ||||
|         binding.approvalRequired.setOnCheckedChangeListener { buttonView: CompoundButton, isChecked: Boolean -> | ||||
|             val resourceLiveData = if (isChecked) viewModel.approvalRequired() else viewModel.approvalNotRequired() | ||||
|             handleSwitchChangeResource(resourceLiveData, buttonView) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun handleSwitchChangeResource(resourceLiveData: LiveData<Resource<Any?>>, buttonView: CompoundButton) { | ||||
|         resourceLiveData.observe(viewLifecycleOwner, { resource: Resource<Any?>? -> | ||||
|             if (resource == null) return@observe | ||||
|             when (resource.status) { | ||||
|                 Resource.Status.SUCCESS -> buttonView.isEnabled = true | ||||
|                 Resource.Status.ERROR -> { | ||||
|                     buttonView.isEnabled = true | ||||
|                     buttonView.isChecked = !buttonView.isChecked | ||||
|                     if (resource.message != null) { | ||||
|                         Snackbar.make(binding.root, resource.message, Snackbar.LENGTH_LONG).show() | ||||
|                     } | ||||
|                     if (resource.resId != 0) { | ||||
|                         Snackbar.make(binding.root, resource.resId, Snackbar.LENGTH_LONG).show() | ||||
|                     } | ||||
|                 } | ||||
|                 Resource.Status.LOADING -> buttonView.isEnabled = false | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     private fun setupMembers() { | ||||
|         val context = context ?: return | ||||
|         binding.users.layoutManager = LinearLayoutManager(context) | ||||
|         val inviter = viewModel.getInviter().value | ||||
|         usersAdapter = DirectUsersAdapter( | ||||
|             inviter?.pk ?: -1, | ||||
|             { _: Int, user: User, _: Boolean -> | ||||
|                 if (isEmpty(user.username) && !isEmpty(user.fbId)) { | ||||
|                     Utils.openURL(context, "https://facebook.com/" + user.fbId) | ||||
|                     return@DirectUsersAdapter | ||||
|                 } | ||||
|                 if (isEmpty(user.username)) return@DirectUsersAdapter | ||||
|                 val directions = ProfileNavGraphDirections | ||||
|                     .actionGlobalProfileFragment("@" + user.username) | ||||
|                 NavHostFragment.findNavController(this).navigate(directions) | ||||
|             }, | ||||
|             { _: Int, user: User? -> | ||||
|                 val options = viewModel.createUserOptions(user) | ||||
|                 if (options.isEmpty()) return@DirectUsersAdapter true | ||||
|                 val fragment = MultiOptionDialogFragment.newInstance(-1, options) | ||||
|                 fragment.setSingleCallback(object : MultiOptionDialogSingleCallback<String?> { | ||||
|                     override fun onSelect(action: String?) { | ||||
|                         if (action == null) return | ||||
|                         val resourceLiveData = viewModel.doAction(user, action) | ||||
|                         if (resourceLiveData != null) { | ||||
|                             observeDetailsChange(resourceLiveData) | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     override fun onCancel() {} | ||||
|                 }) | ||||
|                 val fragmentManager = childFragmentManager | ||||
|                 fragment.show(fragmentManager, "actions") | ||||
|                 true | ||||
|             } | ||||
|         ) | ||||
|         binding.users.adapter = usersAdapter | ||||
|     } | ||||
| 
 | ||||
|     private fun setPendingRequests(requests: DirectThreadParticipantRequestsResponse?) { | ||||
|         val nullOrEmpty: Boolean = requests?.users?.isNullOrEmpty() ?: true | ||||
|         if (nullOrEmpty) { | ||||
|             binding.pendingMembersGroup.visibility = View.GONE | ||||
|             return | ||||
|         } | ||||
|         if (!isPendingRequestsSetupDone) { | ||||
|             val context = context ?: return | ||||
|             binding.pendingMembers.layoutManager = LinearLayoutManager(context) | ||||
|             pendingUsersAdapter = DirectPendingUsersAdapter(object : PendingUserCallback { | ||||
|                 override fun onClick(position: Int, pendingUser: PendingUser) { | ||||
|                     val directions = ProfileNavGraphDirections | ||||
|                         .actionGlobalProfileFragment("@" + pendingUser.user.username) | ||||
|                     NavHostFragment.findNavController(this@DirectMessageSettingsFragment).navigate(directions) | ||||
|                 } | ||||
| 
 | ||||
|                 override fun onApprove(position: Int, pendingUser: PendingUser) { | ||||
|                     val resourceLiveData = viewModel.approveUsers(listOf(pendingUser.user)) | ||||
|                     observeApprovalChange(resourceLiveData, position, pendingUser) | ||||
|                 } | ||||
| 
 | ||||
|                 override fun onDeny(position: Int, pendingUser: PendingUser) { | ||||
|                     val resourceLiveData = viewModel.denyUsers(listOf(pendingUser.user)) | ||||
|                     observeApprovalChange(resourceLiveData, position, pendingUser) | ||||
|                 } | ||||
|             }) | ||||
|             binding.pendingMembers.adapter = pendingUsersAdapter | ||||
|             binding.pendingMembersGroup.visibility = View.VISIBLE | ||||
|             isPendingRequestsSetupDone = true | ||||
|         } | ||||
|         pendingUsersAdapter?.submitPendingRequests(requests) | ||||
|     } | ||||
| 
 | ||||
|     private fun observeDetailsChange(resourceLiveData: LiveData<Resource<Any?>>) { | ||||
|         resourceLiveData.observe(viewLifecycleOwner, { resource: Resource<Any?>? -> | ||||
|             if (resource == null) return@observe | ||||
|             when (resource.status) { | ||||
|                 Resource.Status.SUCCESS, | ||||
|                 Resource.Status.LOADING, | ||||
|                 -> { | ||||
|                 } | ||||
|                 Resource.Status.ERROR -> { | ||||
|                     if (resource.message != null) { | ||||
|                         Snackbar.make(binding.root, resource.message, Snackbar.LENGTH_LONG).show() | ||||
|                     } | ||||
|                     if (resource.resId != 0) { | ||||
|                         Snackbar.make(binding.root, resource.resId, Snackbar.LENGTH_LONG).show() | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     private fun observeApprovalChange( | ||||
|         detailsChangeResourceLiveData: LiveData<Resource<Any?>>, | ||||
|         position: Int, | ||||
|         pendingUser: PendingUser, | ||||
|     ) { | ||||
|         detailsChangeResourceLiveData.observe(viewLifecycleOwner, { resource: Resource<Any?>? -> | ||||
|             if (resource == null) return@observe | ||||
|             when (resource.status) { | ||||
|                 Resource.Status.SUCCESS -> { | ||||
|                 } | ||||
|                 Resource.Status.LOADING -> pendingUser.isInProgress = true | ||||
|                 Resource.Status.ERROR -> { | ||||
|                     pendingUser.isInProgress = false | ||||
|                     if (resource.message != null) { | ||||
|                         Snackbar.make(binding.root, resource.message, Snackbar.LENGTH_LONG).show() | ||||
|                     } | ||||
|                     if (resource.resId != 0) { | ||||
|                         Snackbar.make(binding.root, resource.resId, Snackbar.LENGTH_LONG).show() | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             pendingUsersAdapter?.notifyItemChanged(position) | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     override fun onPositiveButtonClicked(requestCode: Int) { | ||||
|         if (requestCode == APPROVAL_REQUIRED_REQUEST_CODE) { | ||||
|             approvalRequiredUsers?.let { | ||||
|                 val detailsChangeResourceLiveData = viewModel.addMembers(it) | ||||
|                 observeDetailsChange(detailsChangeResourceLiveData) | ||||
|             } | ||||
|             return | ||||
|         } | ||||
|         if (requestCode == LEAVE_THREAD_REQUEST_CODE) { | ||||
|             val resourceLiveData = viewModel.leave() | ||||
|             resourceLiveData.observe(viewLifecycleOwner, { resource: Resource<Any?>? -> | ||||
|                 if (resource == null) return@observe | ||||
|                 when (resource.status) { | ||||
|                     Resource.Status.SUCCESS -> { | ||||
|                         val directions = DirectMessageSettingsFragmentDirections.actionSettingsToInbox() | ||||
|                         NavHostFragment.findNavController(this).navigate(directions) | ||||
|                     } | ||||
|                     Resource.Status.ERROR -> { | ||||
|                         binding.leave.isEnabled = true | ||||
|                         if (resource.message != null) { | ||||
|                             Snackbar.make(binding.root, resource.message, Snackbar.LENGTH_LONG).show() | ||||
|                         } | ||||
|                         if (resource.resId != 0) { | ||||
|                             Snackbar.make(binding.root, resource.resId, Snackbar.LENGTH_LONG).show() | ||||
|                         } | ||||
|                     } | ||||
|                     Resource.Status.LOADING -> binding.leave.isEnabled = false | ||||
|                 } | ||||
|             }) | ||||
|             return | ||||
|         } | ||||
|         if (requestCode == END_THREAD_REQUEST_CODE) { | ||||
|             val resourceLiveData = viewModel.end() | ||||
|             resourceLiveData.observe(viewLifecycleOwner, { resource: Resource<Any?>? -> | ||||
|                 if (resource == null) return@observe | ||||
|                 when (resource.status) { | ||||
|                     Resource.Status.SUCCESS -> { | ||||
|                     } | ||||
|                     Resource.Status.ERROR -> { | ||||
|                         binding.end.isEnabled = true | ||||
|                         if (resource.message != null) { | ||||
|                             Snackbar.make(binding.root, resource.message, Snackbar.LENGTH_LONG).show() | ||||
|                         } | ||||
|                         if (resource.resId != 0) { | ||||
|                             Snackbar.make(binding.root, resource.resId, Snackbar.LENGTH_LONG).show() | ||||
|                         } | ||||
|                     } | ||||
|                     Resource.Status.LOADING -> binding.end.isEnabled = false | ||||
|                 } | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun onNegativeButtonClicked(requestCode: Int) { | ||||
|         if (requestCode == APPROVAL_REQUIRED_REQUEST_CODE) { | ||||
|             approvalRequiredUsers = null | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun onNeutralButtonClicked(requestCode: Int) {} | ||||
| 
 | ||||
|     companion object { | ||||
|         private const val APPROVAL_REQUIRED_REQUEST_CODE = 200 | ||||
|         private const val LEAVE_THREAD_REQUEST_CODE = 201 | ||||
|         private const val END_THREAD_REQUEST_CODE = 202 | ||||
|     } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user