Made setting profile name and About synchronous operations.
This commit is contained in:
parent
1dc737b5e5
commit
ee548d27e5
8 changed files with 303 additions and 56 deletions
|
@ -1,24 +1,14 @@
|
|||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.zkgroup.profiles.ProfileKey;
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.ProfileUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.util.StreamDetails;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -30,9 +20,6 @@ public final class ProfileUploadJob extends BaseJob {
|
|||
|
||||
public static final String QUEUE = "ProfileAlteration";
|
||||
|
||||
private final Context context;
|
||||
private final SignalServiceAccountManager accountManager;
|
||||
|
||||
public ProfileUploadJob() {
|
||||
this(new Job.Parameters.Builder()
|
||||
.addConstraint(NetworkConstraint.KEY)
|
||||
|
@ -45,9 +32,6 @@ public final class ProfileUploadJob extends BaseJob {
|
|||
|
||||
private ProfileUploadJob(@NonNull Parameters parameters) {
|
||||
super(parameters);
|
||||
|
||||
this.context = ApplicationDependencies.getApplication();
|
||||
this.accountManager = ApplicationDependencies.getSignalServiceAccountManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -57,17 +41,7 @@ public final class ProfileUploadJob extends BaseJob {
|
|||
return;
|
||||
}
|
||||
|
||||
ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey();
|
||||
ProfileName profileName = Recipient.self().getProfileName();
|
||||
String about = Optional.fromNullable(Recipient.self().getAbout()).or("");
|
||||
String aboutEmoji = Optional.fromNullable(Recipient.self().getAboutEmoji()).or("");
|
||||
String avatarPath;
|
||||
|
||||
try (StreamDetails avatar = AvatarHelper.getSelfProfileAvatarStream(context)) {
|
||||
avatarPath = accountManager.setVersionedProfile(Recipient.self().getUuid().get(), profileKey, profileName.serialize(), about, aboutEmoji, avatar).orNull();
|
||||
}
|
||||
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileAvatar(Recipient.self().getId(), avatarPath);
|
||||
ProfileUtil.uploadProfile(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,30 +9,30 @@ import android.view.ViewGroup;
|
|||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.ListAdapter;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.signal.core.util.BreakIteratorCompat;
|
||||
import org.signal.core.util.EditTextUtil;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiUtil;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobs.ProfileUploadJob;
|
||||
import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiBottomSheetDialogFragment;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.StringUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.adapter.AlwaysChangedDiffUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.text.AfterTextChanged;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.crypto.ProfileCipher;
|
||||
|
@ -60,9 +60,11 @@ public class EditAboutFragment extends Fragment implements ManageProfileActivity
|
|||
new AboutPreset("\uD83D\uDE80", R.string.EditAboutFragment_working_on_something_new)
|
||||
);
|
||||
|
||||
private ImageView emojiView;
|
||||
private EditText bodyView;
|
||||
private TextView countView;
|
||||
private ImageView emojiView;
|
||||
private EditText bodyView;
|
||||
private TextView countView;
|
||||
private CircularProgressButton saveButton;
|
||||
private EditAboutViewModel viewModel;
|
||||
|
||||
private String selectedEmoji;
|
||||
|
||||
|
@ -76,6 +78,9 @@ public class EditAboutFragment extends Fragment implements ManageProfileActivity
|
|||
this.emojiView = view.findViewById(R.id.edit_about_emoji);
|
||||
this.bodyView = view.findViewById(R.id.edit_about_body);
|
||||
this.countView = view.findViewById(R.id.edit_about_count);
|
||||
this.saveButton = view.findViewById(R.id.edit_about_save);
|
||||
|
||||
initializeViewModel();
|
||||
|
||||
view.<Toolbar>findViewById(R.id.toolbar)
|
||||
.setNavigationOnClickListener(v -> Navigation.findNavController(view)
|
||||
|
@ -92,9 +97,13 @@ public class EditAboutFragment extends Fragment implements ManageProfileActivity
|
|||
.show(requireFragmentManager(), "BOTTOM");
|
||||
});
|
||||
|
||||
view.findViewById(R.id.edit_about_save).setOnClickListener(this::onSaveClicked);
|
||||
view.findViewById(R.id.edit_about_clear).setOnClickListener(v -> onClearClicked());
|
||||
|
||||
saveButton.setOnClickListener(v -> viewModel.onSaveClicked(requireContext(),
|
||||
bodyView.getText().toString(),
|
||||
selectedEmoji));
|
||||
|
||||
|
||||
RecyclerView presetList = view.findViewById(R.id.edit_about_presets);
|
||||
PresetAdapter presetAdapter = new PresetAdapter();
|
||||
|
||||
|
@ -135,6 +144,13 @@ public class EditAboutFragment extends Fragment implements ManageProfileActivity
|
|||
}
|
||||
}
|
||||
|
||||
private void initializeViewModel() {
|
||||
this.viewModel = ViewModelProviders.of(this).get(EditAboutViewModel.class);
|
||||
|
||||
viewModel.getSaveState().observe(getViewLifecycleOwner(), this::presentSaveState);
|
||||
viewModel.getEvents().observe(getViewLifecycleOwner(), this::presentEvent);
|
||||
}
|
||||
|
||||
private void presentCount(@NonNull String aboutBody) {
|
||||
BreakIteratorCompat breakIterator = BreakIteratorCompat.getInstance();
|
||||
breakIterator.setText(aboutBody);
|
||||
|
@ -148,14 +164,26 @@ public class EditAboutFragment extends Fragment implements ManageProfileActivity
|
|||
}
|
||||
}
|
||||
|
||||
private void onSaveClicked(View view) {
|
||||
SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> {
|
||||
DatabaseFactory.getRecipientDatabase(requireContext()).setAbout(Recipient.self().getId(), bodyView.getText().toString(), selectedEmoji);
|
||||
ApplicationDependencies.getJobManager().add(new ProfileUploadJob());
|
||||
return null;
|
||||
}, (nothing) -> {
|
||||
Navigation.findNavController(view).popBackStack();
|
||||
});
|
||||
private void presentSaveState(@NonNull EditAboutViewModel.SaveState state) {
|
||||
switch (state) {
|
||||
case IDLE:
|
||||
saveButton.setIndeterminateProgressMode(false);
|
||||
saveButton.setProgress(0);
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
saveButton.setIndeterminateProgressMode(true);
|
||||
saveButton.setProgress(50);
|
||||
break;
|
||||
case DONE:
|
||||
Navigation.findNavController(requireView()).popBackStack();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void presentEvent(@NonNull EditAboutViewModel.Event event) {
|
||||
if (event == EditAboutViewModel.Event.NETWORK_FAILURE) {
|
||||
Toast.makeText(requireContext(), R.string.EditProfileNameFragment_failed_to_save_due_to_network_issues_try_again_later, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void onClearClicked() {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package org.thoughtcrime.securesms.profiles.manage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.util.SingleLiveEvent;
|
||||
|
||||
public final class EditAboutViewModel extends ViewModel {
|
||||
|
||||
private final ManageProfileRepository repository;
|
||||
private final MutableLiveData<SaveState> saveState;
|
||||
private final SingleLiveEvent<Event> events;
|
||||
|
||||
public EditAboutViewModel() {
|
||||
this.repository = new ManageProfileRepository();
|
||||
this.saveState = new MutableLiveData<>(SaveState.IDLE);
|
||||
this.events = new SingleLiveEvent<>();
|
||||
}
|
||||
|
||||
@NonNull LiveData<SaveState> getSaveState() {
|
||||
return saveState;
|
||||
}
|
||||
|
||||
@NonNull LiveData<Event> getEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
void onSaveClicked(@NonNull Context context, @NonNull String about, @NonNull String emoji) {
|
||||
saveState.setValue(SaveState.IN_PROGRESS);
|
||||
repository.setAbout(context, about, emoji, result -> {
|
||||
switch (result) {
|
||||
case SUCCESS:
|
||||
saveState.postValue(SaveState.DONE);
|
||||
break;
|
||||
case FAILURE_NETWORK:
|
||||
saveState.postValue(SaveState.IDLE);
|
||||
events.postValue(Event.NETWORK_FAILURE);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
enum SaveState {
|
||||
IDLE, IN_PROGRESS, DONE
|
||||
}
|
||||
|
||||
enum Event {
|
||||
NETWORK_FAILURE
|
||||
}
|
||||
}
|
|
@ -6,13 +6,17 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.signal.core.util.EditTextUtil;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
|
@ -31,8 +35,10 @@ public class EditProfileNameFragment extends Fragment {
|
|||
|
||||
public static final int NAME_MAX_GLYPHS = 26;
|
||||
|
||||
private EditText givenName;
|
||||
private EditText familyName;
|
||||
private EditText givenName;
|
||||
private EditText familyName;
|
||||
private CircularProgressButton saveButton;
|
||||
private EditProfileNameViewModel viewModel;
|
||||
|
||||
@Override
|
||||
public @NonNull View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
|
@ -43,6 +49,9 @@ public class EditProfileNameFragment extends Fragment {
|
|||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
this.givenName = view.findViewById(R.id.edit_profile_name_given_name);
|
||||
this.familyName = view.findViewById(R.id.edit_profile_name_family_name);
|
||||
this.saveButton = view.findViewById(R.id.edit_profile_name_save);
|
||||
|
||||
initializeViewModel();
|
||||
|
||||
this.givenName.setText(Recipient.self().getProfileName().getGivenName());
|
||||
this.familyName.setText(Recipient.self().getProfileName().getFamilyName());
|
||||
|
@ -57,19 +66,38 @@ public class EditProfileNameFragment extends Fragment {
|
|||
this.givenName.addTextChangedListener(new AfterTextChanged(EditProfileNameFragment::trimFieldToMaxByteLength));
|
||||
this.familyName.addTextChangedListener(new AfterTextChanged(EditProfileNameFragment::trimFieldToMaxByteLength));
|
||||
|
||||
view.findViewById(R.id.edit_profile_name_save).setOnClickListener(this::onSaveClicked);
|
||||
saveButton.setOnClickListener(v -> viewModel.onSaveClicked(requireContext(),
|
||||
givenName.getText().toString(),
|
||||
familyName.getText().toString()));
|
||||
}
|
||||
|
||||
private void onSaveClicked(View view) {
|
||||
ProfileName profileName = ProfileName.fromParts(givenName.getText().toString(), familyName.getText().toString());
|
||||
private void initializeViewModel() {
|
||||
this.viewModel = ViewModelProviders.of(this).get(EditProfileNameViewModel.class);
|
||||
|
||||
SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> {
|
||||
DatabaseFactory.getRecipientDatabase(requireContext()).setProfileName(Recipient.self().getId(), profileName);
|
||||
ApplicationDependencies.getJobManager().add(new ProfileUploadJob());
|
||||
return null;
|
||||
}, (nothing) -> {
|
||||
Navigation.findNavController(view).popBackStack();
|
||||
});
|
||||
viewModel.getSaveState().observe(getViewLifecycleOwner(), this::presentSaveState);
|
||||
viewModel.getEvents().observe(getViewLifecycleOwner(), this::presentEvent);
|
||||
}
|
||||
|
||||
private void presentSaveState(@NonNull EditProfileNameViewModel.SaveState state) {
|
||||
switch (state) {
|
||||
case IDLE:
|
||||
saveButton.setIndeterminateProgressMode(false);
|
||||
saveButton.setProgress(0);
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
saveButton.setIndeterminateProgressMode(true);
|
||||
saveButton.setProgress(50);
|
||||
break;
|
||||
case DONE:
|
||||
Navigation.findNavController(requireView()).popBackStack();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void presentEvent(@NonNull EditProfileNameViewModel.Event event) {
|
||||
if (event == EditProfileNameViewModel.Event.NETWORK_FAILURE) {
|
||||
Toast.makeText(requireContext(), R.string.EditProfileNameFragment_failed_to_save_due_to_network_issues_try_again_later, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
public static void trimFieldToMaxByteLength(Editable s) {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package org.thoughtcrime.securesms.profiles.manage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.util.SingleLiveEvent;
|
||||
|
||||
public final class EditProfileNameViewModel extends ViewModel {
|
||||
|
||||
private final ManageProfileRepository repository;
|
||||
private final MutableLiveData<SaveState> saveState;
|
||||
private final SingleLiveEvent<Event> events;
|
||||
|
||||
public EditProfileNameViewModel() {
|
||||
this.repository = new ManageProfileRepository();
|
||||
this.saveState = new MutableLiveData<>(SaveState.IDLE);
|
||||
this.events = new SingleLiveEvent<>();
|
||||
}
|
||||
|
||||
@NonNull LiveData<SaveState> getSaveState() {
|
||||
return saveState;
|
||||
}
|
||||
|
||||
@NonNull LiveData<Event> getEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
void onSaveClicked(@NonNull Context context, @NonNull String givenName, @NonNull String familyName) {
|
||||
saveState.setValue(SaveState.IN_PROGRESS);
|
||||
repository.setName(context, ProfileName.fromParts(givenName, familyName), result -> {
|
||||
switch (result) {
|
||||
case SUCCESS:
|
||||
saveState.postValue(SaveState.DONE);
|
||||
break;
|
||||
case FAILURE_NETWORK:
|
||||
saveState.postValue(SaveState.IDLE);
|
||||
events.postValue(Event.NETWORK_FAILURE);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
enum SaveState {
|
||||
IDLE, IN_PROGRESS, DONE
|
||||
}
|
||||
|
||||
enum Event {
|
||||
NETWORK_FAILURE
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package org.thoughtcrime.securesms.profiles.manage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.util.Consumer;
|
||||
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.ProfileUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
final class ManageProfileRepository {
|
||||
|
||||
private static final String TAG = Log.tag(ManageProfileRepository.class);
|
||||
|
||||
public void setName(@NonNull Context context, @NonNull ProfileName profileName, @NonNull Consumer<Result> callback) {
|
||||
SignalExecutors.UNBOUNDED.execute(() -> {
|
||||
try {
|
||||
ProfileUtil.uploadProfileWithName(context, profileName);
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileName(Recipient.self().getId(), profileName);
|
||||
callback.accept(Result.SUCCESS);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Failed to upload profile during name change.", e);
|
||||
callback.accept(Result.FAILURE_NETWORK);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setAbout(@NonNull Context context, @NonNull String about, @NonNull String emoji, @NonNull Consumer<Result> callback) {
|
||||
SignalExecutors.UNBOUNDED.execute(() -> {
|
||||
try {
|
||||
ProfileUtil.uploadProfileWithAbout(context, about, emoji);
|
||||
DatabaseFactory.getRecipientDatabase(context).setAbout(Recipient.self().getId(), about, emoji);
|
||||
callback.accept(Result.SUCCESS);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Failed to upload profile during name change.", e);
|
||||
callback.accept(Result.FAILURE_NETWORK);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
enum Result {
|
||||
SUCCESS, FAILURE_NETWORK
|
||||
}
|
||||
}
|
|
@ -9,12 +9,16 @@ import androidx.annotation.WorkerThread;
|
|||
import org.signal.zkgroup.profiles.ProfileKey;
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.messages.IncomingMessageObserver;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessagePipe;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
|
||||
import org.whispersystems.signalservice.api.crypto.InvalidCiphertextException;
|
||||
|
@ -26,6 +30,7 @@ import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
|
|||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NotFoundException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
import org.whispersystems.signalservice.api.util.StreamDetails;
|
||||
import org.whispersystems.signalservice.internal.util.concurrent.CascadingFuture;
|
||||
import org.whispersystems.signalservice.internal.util.concurrent.ListenableFuture;
|
||||
|
||||
|
@ -96,6 +101,57 @@ public final class ProfileUtil {
|
|||
return new String(profileCipher.decryptName(Base64.decode(encryptedName)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads the profile based on all state that's written to disk, except we'll use the provided
|
||||
* profile name instead. This is useful when you want to ensure that the profile has been uploaded
|
||||
* successfully before persisting the change to disk.
|
||||
*/
|
||||
public static void uploadProfileWithName(@NonNull Context context, @NonNull ProfileName profileName) throws IOException {
|
||||
uploadProfile(context,
|
||||
profileName,
|
||||
Optional.fromNullable(Recipient.self().getAbout()).or(""),
|
||||
Optional.fromNullable(Recipient.self().getAboutEmoji()).or(""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads the profile based on all state that's written to disk, except we'll use the provided
|
||||
* about/emoji instead. This is useful when you want to ensure that the profile has been uploaded
|
||||
* successfully before persisting the change to disk.
|
||||
*/
|
||||
public static void uploadProfileWithAbout(@NonNull Context context, @NonNull String about, @NonNull String emoji) throws IOException {
|
||||
uploadProfile(context,
|
||||
Recipient.self().getProfileName(),
|
||||
about,
|
||||
emoji);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads the profile based on all state that's already written to disk.
|
||||
*/
|
||||
public static void uploadProfile(@NonNull Context context) throws IOException {
|
||||
uploadProfile(context,
|
||||
Recipient.self().getProfileName(),
|
||||
Optional.fromNullable(Recipient.self().getAbout()).or(""),
|
||||
Optional.fromNullable(Recipient.self().getAboutEmoji()).or(""));
|
||||
}
|
||||
|
||||
public static void uploadProfile(@NonNull Context context,
|
||||
@NonNull ProfileName profileName,
|
||||
@Nullable String about,
|
||||
@Nullable String aboutEmoji)
|
||||
throws IOException
|
||||
{
|
||||
ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey();
|
||||
String avatarPath;
|
||||
|
||||
try (StreamDetails avatar = AvatarHelper.getSelfProfileAvatarStream(context)) {
|
||||
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
|
||||
avatarPath = accountManager.setVersionedProfile(Recipient.self().getUuid().get(), profileKey, profileName.serialize(), about, aboutEmoji, avatar).orNull();
|
||||
}
|
||||
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileAvatar(Recipient.self().getId(), avatarPath);
|
||||
}
|
||||
|
||||
private static @NonNull ListenableFuture<ProfileAndCredential> getPipeRetrievalFuture(@NonNull SignalServiceAddress address,
|
||||
@NonNull Optional<ProfileKey> profileKey,
|
||||
@NonNull Optional<UnidentifiedAccess> unidentifiedAccess,
|
||||
|
|
|
@ -2021,6 +2021,7 @@
|
|||
<string name="EditProfileNameFragment_first_name">First name</string>
|
||||
<string name="EditProfileNameFragment_last_name_optional">Last name (optional)</string>
|
||||
<string name="EditProfileNameFragment_save">Save</string>
|
||||
<string name="EditProfileNameFragment_failed_to_save_due_to_network_issues_try_again_later">Failed to save due to network issues. Try again later.</string>
|
||||
|
||||
<!-- recipient_preferences_activity -->
|
||||
<string name="recipient_preference_activity__shared_media">Shared media</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue