Fix NPE when returning to profile from background.
Also generally improves saved-state management for Profile editor.
This commit is contained in:
parent
e3878ffde7
commit
4ae7d56db4
3 changed files with 58 additions and 22 deletions
|
@ -31,8 +31,10 @@ public class EditProfileActivity extends BaseActionBarActivity implements EditPr
|
|||
|
||||
setContentView(R.layout.profile_create_activity);
|
||||
|
||||
NavGraph graph = Navigation.findNavController(this, R.id.nav_host_fragment).getGraph();
|
||||
Navigation.findNavController(this, R.id.nav_host_fragment).setGraph(graph, getIntent().getExtras());
|
||||
if (bundle == null) {
|
||||
NavGraph graph = Navigation.findNavController(this, R.id.nav_host_fragment).getGraph();
|
||||
Navigation.findNavController(this, R.id.nav_host_fragment).setGraph(graph, getIntent().getExtras());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -57,7 +57,8 @@ import static org.thoughtcrime.securesms.profiles.edit.EditProfileActivity.SHOW_
|
|||
|
||||
public class EditProfileFragment extends Fragment {
|
||||
|
||||
private static final String TAG = Log.tag(EditProfileFragment.class);
|
||||
private static final String TAG = Log.tag(EditProfileFragment.class);
|
||||
private static final String AVATAR_STATE = "avatar";
|
||||
|
||||
private Toolbar toolbar;
|
||||
private View title;
|
||||
|
@ -115,7 +116,7 @@ public class EditProfileFragment extends Fragment {
|
|||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
initializeResources(view);
|
||||
initializeViewModel(requireArguments().getBoolean(EXCLUDE_SYSTEM, false));
|
||||
initializeViewModel(requireArguments().getBoolean(EXCLUDE_SYSTEM, false), savedInstanceState != null);
|
||||
initializeProfileName();
|
||||
initializeProfileAvatar();
|
||||
initializeUsername();
|
||||
|
@ -123,6 +124,20 @@ public class EditProfileFragment extends Fragment {
|
|||
requireActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
outState.putByteArray(AVATAR_STATE, viewModel.getAvatarSnapshot());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
|
||||
super.onViewStateRestored(savedInstanceState);
|
||||
|
||||
if (savedInstanceState != null && savedInstanceState.containsKey(AVATAR_STATE)) {
|
||||
viewModel.setAvatar(savedInstanceState.getByteArray(AVATAR_STATE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
|
||||
|
@ -181,9 +196,9 @@ public class EditProfileFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void initializeViewModel(boolean excludeSystem) {
|
||||
EditProfileRepository repository = new EditProfileRepository(requireContext(), excludeSystem);
|
||||
EditProfileViewModel.Factory factory = new EditProfileViewModel.Factory(repository);
|
||||
private void initializeViewModel(boolean excludeSystem, boolean hasSavedInstanceState) {
|
||||
EditProfileRepository repository = new EditProfileRepository(requireContext(), excludeSystem);
|
||||
EditProfileViewModel.Factory factory = new EditProfileViewModel.Factory(repository, hasSavedInstanceState);
|
||||
|
||||
viewModel = ViewModelProviders.of(this, factory).get(EditProfileViewModel.class);
|
||||
}
|
||||
|
@ -246,17 +261,17 @@ public class EditProfileFragment extends Fragment {
|
|||
}
|
||||
|
||||
private void initializeProfileName() {
|
||||
viewModel.profileName().observe(this, profileName -> {
|
||||
viewModel.givenName().observe(this, givenName -> updateFieldIfNeeded(this.givenName, givenName));
|
||||
|
||||
updateFieldIfNeeded(givenName, profileName.getGivenName());
|
||||
updateFieldIfNeeded(familyName, profileName.getFamilyName());
|
||||
viewModel.familyName().observe(this, familyName -> updateFieldIfNeeded(this.familyName, familyName));
|
||||
|
||||
viewModel.profileName().observe(this, profileName -> {
|
||||
preview.setText(profileName.toString());
|
||||
|
||||
boolean validEntry = !profileName.isGivenNameEmpty();
|
||||
|
||||
finishButton.setEnabled(validEntry);
|
||||
finishButton.setAlpha(validEntry ? 1f : 0.5f);
|
||||
|
||||
preview.setText(profileName.toString());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.thoughtcrime.securesms.profiles.edit;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.util.Consumer;
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
@ -22,19 +23,30 @@ class EditProfileViewModel extends ViewModel {
|
|||
private final MutableLiveData<Optional<String>> internalUsername = new MutableLiveData<>();
|
||||
private final EditProfileRepository repository;
|
||||
|
||||
private EditProfileViewModel(@NonNull EditProfileRepository repository) {
|
||||
private EditProfileViewModel(@NonNull EditProfileRepository repository, boolean hasInstanceState) {
|
||||
this.repository = repository;
|
||||
|
||||
repository.getCurrentUsername(internalUsername::postValue);
|
||||
repository.getCurrentProfileName(name -> {
|
||||
givenName.setValue(name.getGivenName());
|
||||
familyName.setValue(name.getFamilyName());
|
||||
});
|
||||
repository.getCurrentAvatar(internalAvatar::setValue);
|
||||
|
||||
if (!hasInstanceState) {
|
||||
repository.getCurrentProfileName(name -> {
|
||||
givenName.setValue(name.getGivenName());
|
||||
familyName.setValue(name.getFamilyName());
|
||||
});
|
||||
repository.getCurrentAvatar(internalAvatar::setValue);
|
||||
}
|
||||
}
|
||||
|
||||
public LiveData<String> givenName() {
|
||||
return Transformations.distinctUntilChanged(givenName);
|
||||
}
|
||||
|
||||
public LiveData<String> familyName() {
|
||||
return Transformations.distinctUntilChanged(familyName);
|
||||
}
|
||||
|
||||
public LiveData<ProfileName> profileName() {
|
||||
return internalProfileName;
|
||||
return Transformations.distinctUntilChanged(internalProfileName);
|
||||
}
|
||||
|
||||
public LiveData<byte[]> avatar() {
|
||||
|
@ -49,6 +61,11 @@ class EditProfileViewModel extends ViewModel {
|
|||
return internalAvatar.getValue() != null;
|
||||
}
|
||||
|
||||
@MainThread
|
||||
public byte[] getAvatarSnapshot() {
|
||||
return internalAvatar.getValue();
|
||||
}
|
||||
|
||||
public void setGivenName(String givenName) {
|
||||
this.givenName.setValue(givenName);
|
||||
}
|
||||
|
@ -73,16 +90,18 @@ class EditProfileViewModel extends ViewModel {
|
|||
static class Factory implements ViewModelProvider.Factory {
|
||||
|
||||
private final EditProfileRepository repository;
|
||||
private final boolean hasInstanceState;
|
||||
|
||||
Factory(EditProfileRepository repository) {
|
||||
this.repository = repository;
|
||||
Factory(@NonNull EditProfileRepository repository, boolean hasInstanceState) {
|
||||
this.repository = repository;
|
||||
this.hasInstanceState = hasInstanceState;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
|
||||
//noinspection unchecked
|
||||
return (T) new EditProfileViewModel(repository);
|
||||
return (T) new EditProfileViewModel(repository, hasInstanceState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue