Browse Source
Convert DirectMessageSettingsFragment to kotlin
renovate/org.robolectric-robolectric-4.x
Convert DirectMessageSettingsFragment to kotlin
renovate/org.robolectric-robolectric-4.x
Ammar Githam
4 years ago
2 changed files with 475 additions and 531 deletions
-
531app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java
-
475app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.kt
@ -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 |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue