193 lines
7.4 KiB
Java
193 lines
7.4 KiB
Java
package org.thoughtcrime.securesms.usernames.username;
|
|
|
|
import android.os.Bundle;
|
|
import android.text.TextUtils;
|
|
import android.view.KeyEvent;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.view.inputmethod.EditorInfo;
|
|
import android.widget.EditText;
|
|
import android.widget.TextView;
|
|
import android.widget.Toast;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.fragment.app.Fragment;
|
|
import androidx.lifecycle.ViewModelProviders;
|
|
import androidx.navigation.fragment.NavHostFragment;
|
|
|
|
import com.dd.CircularProgressButton;
|
|
|
|
import org.thoughtcrime.securesms.LoggingFragment;
|
|
import org.thoughtcrime.securesms.R;
|
|
import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher;
|
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|
import org.thoughtcrime.securesms.util.UsernameUtil;
|
|
|
|
public class UsernameEditFragment extends LoggingFragment {
|
|
|
|
private static final float DISABLED_ALPHA = 0.5f;
|
|
|
|
private UsernameEditViewModel viewModel;
|
|
|
|
private EditText usernameInput;
|
|
private TextView usernameSubtext;
|
|
private CircularProgressButton submitButton;
|
|
private CircularProgressButton deleteButton;
|
|
|
|
public static UsernameEditFragment newInstance() {
|
|
return new UsernameEditFragment();
|
|
}
|
|
|
|
@Override
|
|
public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
|
return inflater.inflate(R.layout.username_edit_fragment, container, false);
|
|
}
|
|
|
|
@Override
|
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
|
usernameInput = view.findViewById(R.id.username_text);
|
|
usernameSubtext = view.findViewById(R.id.username_subtext);
|
|
submitButton = view.findViewById(R.id.username_submit_button);
|
|
deleteButton = view.findViewById(R.id.username_delete_button);
|
|
|
|
viewModel = ViewModelProviders.of(this, new UsernameEditViewModel.Factory()).get(UsernameEditViewModel.class);
|
|
|
|
viewModel.getUiState().observe(getViewLifecycleOwner(), this::onUiStateChanged);
|
|
viewModel.getEvents().observe(getViewLifecycleOwner(), this::onEvent);
|
|
|
|
submitButton.setOnClickListener(v -> viewModel.onUsernameSubmitted(usernameInput.getText().toString()));
|
|
deleteButton.setOnClickListener(v -> viewModel.onUsernameDeleted());
|
|
|
|
usernameInput.setText(TextSecurePreferences.getLocalUsername(requireContext()));
|
|
usernameInput.addTextChangedListener(new SimpleTextWatcher() {
|
|
@Override
|
|
public void onTextChanged(String text) {
|
|
viewModel.onUsernameUpdated(text);
|
|
}
|
|
});
|
|
usernameInput.setOnEditorActionListener((v, actionId, event) -> {
|
|
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
|
viewModel.onUsernameSubmitted(usernameInput.getText().toString());
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
}
|
|
|
|
private void onUiStateChanged(@NonNull UsernameEditViewModel.State state) {
|
|
usernameInput.setEnabled(true);
|
|
|
|
switch (state.getButtonState()) {
|
|
case SUBMIT:
|
|
cancelSpinning(submitButton);
|
|
submitButton.setVisibility(View.VISIBLE);
|
|
submitButton.setEnabled(true);
|
|
submitButton.setAlpha(1);
|
|
deleteButton.setVisibility(View.GONE);
|
|
break;
|
|
case SUBMIT_DISABLED:
|
|
cancelSpinning(submitButton);
|
|
submitButton.setVisibility(View.VISIBLE);
|
|
submitButton.setEnabled(false);
|
|
submitButton.setAlpha(DISABLED_ALPHA);
|
|
deleteButton.setVisibility(View.GONE);
|
|
break;
|
|
case SUBMIT_LOADING:
|
|
setSpinning(submitButton);
|
|
submitButton.setVisibility(View.VISIBLE);
|
|
submitButton.setAlpha(1);
|
|
deleteButton.setVisibility(View.GONE);
|
|
usernameInput.setEnabled(false);
|
|
break;
|
|
case DELETE:
|
|
cancelSpinning(deleteButton);
|
|
deleteButton.setVisibility(View.VISIBLE);
|
|
deleteButton.setEnabled(true);
|
|
deleteButton.setAlpha(1);
|
|
submitButton.setVisibility(View.GONE);
|
|
break;
|
|
case DELETE_DISABLED:
|
|
cancelSpinning(deleteButton);
|
|
deleteButton.setVisibility(View.VISIBLE);
|
|
deleteButton.setEnabled(false);
|
|
deleteButton.setAlpha(DISABLED_ALPHA);
|
|
submitButton.setVisibility(View.GONE);
|
|
break;
|
|
case DELETE_LOADING:
|
|
setSpinning(deleteButton);
|
|
deleteButton.setVisibility(View.VISIBLE);
|
|
deleteButton.setAlpha(1);
|
|
submitButton.setVisibility(View.GONE);
|
|
usernameInput.setEnabled(false);
|
|
break;
|
|
}
|
|
|
|
switch (state.getUsernameStatus()) {
|
|
case NONE:
|
|
usernameSubtext.setText("");
|
|
break;
|
|
case TOO_SHORT:
|
|
case TOO_LONG:
|
|
usernameSubtext.setText(getResources().getString(R.string.UsernameEditFragment_usernames_must_be_between_a_and_b_characters, UsernameUtil.MIN_LENGTH, UsernameUtil.MAX_LENGTH));
|
|
usernameSubtext.setTextColor(getResources().getColor(R.color.core_red));
|
|
break;
|
|
case INVALID_CHARACTERS:
|
|
usernameSubtext.setText(R.string.UsernameEditFragment_usernames_can_only_include);
|
|
usernameSubtext.setTextColor(getResources().getColor(R.color.core_red));
|
|
break;
|
|
case CANNOT_START_WITH_NUMBER:
|
|
usernameSubtext.setText(R.string.UsernameEditFragment_usernames_cannot_begin_with_a_number);
|
|
usernameSubtext.setTextColor(getResources().getColor(R.color.core_red));
|
|
break;
|
|
case INVALID_GENERIC:
|
|
usernameSubtext.setText(R.string.UsernameEditFragment_username_is_invalid);
|
|
usernameSubtext.setTextColor(getResources().getColor(R.color.core_red));
|
|
break;
|
|
case TAKEN:
|
|
usernameSubtext.setText(R.string.UsernameEditFragment_this_username_is_taken);
|
|
usernameSubtext.setTextColor(getResources().getColor(R.color.core_red));
|
|
break;
|
|
case AVAILABLE:
|
|
usernameSubtext.setText(R.string.UsernameEditFragment_this_username_is_available);
|
|
usernameSubtext.setTextColor(getResources().getColor(R.color.core_green));
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void onEvent(@NonNull UsernameEditViewModel.Event event) {
|
|
switch (event) {
|
|
case SUBMIT_SUCCESS:
|
|
Toast.makeText(requireContext(), R.string.UsernameEditFragment_successfully_set_username, Toast.LENGTH_SHORT).show();
|
|
NavHostFragment.findNavController(this).popBackStack();
|
|
break;
|
|
case SUBMIT_FAIL_TAKEN:
|
|
Toast.makeText(requireContext(), R.string.UsernameEditFragment_this_username_is_taken, Toast.LENGTH_SHORT).show();
|
|
break;
|
|
case SUBMIT_FAIL_INVALID:
|
|
Toast.makeText(requireContext(), R.string.UsernameEditFragment_username_is_invalid, Toast.LENGTH_SHORT).show();
|
|
break;
|
|
case DELETE_SUCCESS:
|
|
Toast.makeText(requireContext(), R.string.UsernameEditFragment_successfully_removed_username, Toast.LENGTH_SHORT).show();
|
|
NavHostFragment.findNavController(this).popBackStack();
|
|
break;
|
|
case NETWORK_FAILURE:
|
|
Toast.makeText(requireContext(), R.string.UsernameEditFragment_encountered_a_network_error, Toast.LENGTH_SHORT).show();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private static void setSpinning(@NonNull CircularProgressButton button) {
|
|
button.setClickable(false);
|
|
button.setIndeterminateProgressMode(true);
|
|
button.setProgress(50);
|
|
}
|
|
|
|
private static void cancelSpinning(@NonNull CircularProgressButton button) {
|
|
button.setProgress(0);
|
|
button.setIndeterminateProgressMode(false);
|
|
button.setClickable(true);
|
|
}
|
|
}
|