Add view-once tooltip.

This commit is contained in:
Greyson Parrelli 2020-01-02 21:59:13 -05:00 committed by Alan Evans
parent e0e2c3a3f5
commit 7e72c9c33b
5 changed files with 48 additions and 10 deletions

View File

@ -566,6 +566,7 @@
<item quantity="other">You can\'t share more than %d items.</item> <item quantity="other">You can\'t share more than %d items.</item>
</plurals> </plurals>
<string name="MediaSendActivity_select_recipients_description">Select recipients</string> <string name="MediaSendActivity_select_recipients_description">Select recipients</string>
<string name="MediaSendActivity_tap_here_to_make_this_message_disappear_after_it_is_viewed">Tap here to make this message disappear after it is viewed.</string>
<!-- MediaRepository --> <!-- MediaRepository -->
<string name="MediaRepository_all_media">All media</string> <string name="MediaRepository_all_media">All media</string>

View File

@ -196,12 +196,12 @@ public class TooltipPopup extends PopupWindow {
this.anchor = anchor; this.anchor = anchor;
} }
public Builder setBackgroundTint(int color) { public Builder setBackgroundTint(@ColorInt int color) {
this.backgroundTint = color; this.backgroundTint = color;
return this; return this;
} }
public Builder setTextColor(int color) { public Builder setTextColor(@ColorInt int color) {
this.textColor = color; this.textColor = color;
return this; return this;
} }

View File

@ -610,7 +610,7 @@ public class MediaSendActivity extends PassphraseRequiredActionBarActivity imple
countButton.setVisibility(View.GONE); countButton.setVisibility(View.GONE);
continueButton.setVisibility(View.VISIBLE); continueButton.setVisibility(View.VISIBLE);
if (!TextSecurePreferences.hasSeendCameraFirstTooltip(this)) { if (!TextSecurePreferences.hasSeenCameraFirstTooltip(this)) {
TooltipPopup.forTarget(continueButton) TooltipPopup.forTarget(continueButton)
.setText(R.string.MediaSendActivity_select_recipients) .setText(R.string.MediaSendActivity_select_recipients)
.show(TooltipPopup.POSITION_ABOVE); .show(TooltipPopup.POSITION_ABOVE);
@ -697,6 +697,17 @@ public class MediaSendActivity extends PassphraseRequiredActionBarActivity imple
break; break;
} }
}); });
viewModel.getEvents().observe(this, event -> {
if (event == MediaSendViewModel.Event.VIEW_ONCE_TOOLTIP) {
TooltipPopup.forTarget(revealButton)
.setText(R.string.MediaSendActivity_tap_here_to_make_this_message_disappear_after_it_is_viewed)
.setBackgroundTint(getResources().getColor(R.color.core_blue))
.setTextColor(getResources().getColor(R.color.core_white))
.setOnDismissListener(() -> TextSecurePreferences.setHasSeenViewOnceTooltip(this, true))
.show(TooltipPopup.POSITION_ABOVE);
}
});
} }
private void presentRecipient(@Nullable Recipient recipient) { private void presentRecipient(@Nullable Recipient recipient) {

View File

@ -19,7 +19,6 @@ import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.MediaConstraints; import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.providers.BlobProvider;
import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.SingleLiveEvent; import org.thoughtcrime.securesms.util.SingleLiveEvent;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
@ -52,6 +51,7 @@ class MediaSendViewModel extends ViewModel {
private final MutableLiveData<List<MediaFolder>> folders; private final MutableLiveData<List<MediaFolder>> folders;
private final MutableLiveData<HudState> hudState; private final MutableLiveData<HudState> hudState;
private final SingleLiveEvent<Error> error; private final SingleLiveEvent<Error> error;
private final SingleLiveEvent<Event> event;
private final Map<Uri, Object> savedDrawState; private final Map<Uri, Object> savedDrawState;
private MediaConstraints mediaConstraints; private MediaConstraints mediaConstraints;
@ -82,6 +82,7 @@ class MediaSendViewModel extends ViewModel {
this.folders = new MutableLiveData<>(); this.folders = new MutableLiveData<>();
this.hudState = new MutableLiveData<>(); this.hudState = new MutableLiveData<>();
this.error = new SingleLiveEvent<>(); this.error = new SingleLiveEvent<>();
this.event = new SingleLiveEvent<>();
this.savedDrawState = new HashMap<>(); this.savedDrawState = new HashMap<>();
this.lastCameraCapture = Optional.absent(); this.lastCameraCapture = Optional.absent();
this.body = ""; this.body = "";
@ -193,7 +194,8 @@ class MediaSendViewModel extends ViewModel {
buttonState = (recipient != null) ? ButtonState.SEND : ButtonState.CONTINUE; buttonState = (recipient != null) ? ButtonState.SEND : ButtonState.CONTINUE;
if (viewOnceState == ViewOnceState.GONE && viewOnceSupported()) { if (viewOnceState == ViewOnceState.GONE && viewOnceSupported()) {
viewOnceState = TextSecurePreferences.isRevealableMessageEnabled(application) ? ViewOnceState.ENABLED : ViewOnceState.DISABLED; viewOnceState = TextSecurePreferences.isViewOnceMessageEnabled(application) ? ViewOnceState.ENABLED : ViewOnceState.DISABLED;
showViewOnceTooltipIfNecessary(viewOnceState);
} else if (!viewOnceSupported()) { } else if (!viewOnceSupported()) {
viewOnceState = ViewOnceState.GONE; viewOnceState = ViewOnceState.GONE;
} }
@ -271,7 +273,7 @@ class MediaSendViewModel extends ViewModel {
selectedMedia.setValue(uncaptioned); selectedMedia.setValue(uncaptioned);
TextSecurePreferences.setIsRevealableMessageEnabled(application, viewOnceState == ViewOnceState.ENABLED); TextSecurePreferences.setIsViewOnceMessageEnabled(application, viewOnceState == ViewOnceState.ENABLED);
hudState.setValue(buildHudState()); hudState.setValue(buildHudState());
} }
@ -445,6 +447,10 @@ class MediaSendViewModel extends ViewModel {
return error; return error;
} }
@NonNull LiveData<Event> getEvents() {
return event;
}
@NonNull LiveData<HudState> getHudState() { @NonNull LiveData<HudState> getHudState() {
return hudState; return hudState;
} }
@ -503,6 +509,12 @@ class MediaSendViewModel extends ViewModel {
return MediaUtil.isImageOrVideoType(media.get(0).getMimeType()); return MediaUtil.isImageOrVideoType(media.get(0).getMimeType());
} }
private void showViewOnceTooltipIfNecessary(@NonNull ViewOnceState viewOnceState) {
if (viewOnceState == ViewOnceState.DISABLED && !TextSecurePreferences.hasSeenViewOnceTooltip(application)) {
event.postValue(Event.VIEW_ONCE_TOOLTIP);
}
}
@Override @Override
protected void onCleared() { protected void onCleared() {
if (!sentMedia) { if (!sentMedia) {
@ -514,6 +526,10 @@ class MediaSendViewModel extends ViewModel {
ITEM_TOO_LARGE, TOO_MANY_ITEMS, NO_ITEMS ITEM_TOO_LARGE, TOO_MANY_ITEMS, NO_ITEMS
} }
enum Event {
VIEW_ONCE_TOOLTIP
}
enum Page { enum Page {
CAMERA, ITEM_PICKER, FOLDER_PICKER, EDITOR, CONTACT_SELECT, UNKNOWN CAMERA, ITEM_PICKER, FOLDER_PICKER, EDITOR, CONTACT_SELECT, UNKNOWN
} }

View File

@ -13,6 +13,7 @@ import androidx.annotation.ArrayRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.R;
@ -199,7 +200,8 @@ public class TextSecurePreferences {
private static final String MEDIA_KEYBOARD_MODE = "pref_media_keyboard_mode"; private static final String MEDIA_KEYBOARD_MODE = "pref_media_keyboard_mode";
private static final String VIEW_ONCE_DEFAULT = "pref_revealable_message_default"; private static final String VIEW_ONCE_DEFAULT = "pref_revealable_message_default";
private static final String VIEW_ONCE_TOOLTIP_SEEN = "pref_revealable_message_tooltip_seen";
private static final String SEEN_CAMERA_FIRST_TOOLTIP = "pref_seen_camera_first_tooltip"; private static final String SEEN_CAMERA_FIRST_TOOLTIP = "pref_seen_camera_first_tooltip";
@ -1274,19 +1276,27 @@ public class TextSecurePreferences {
return MediaKeyboardMode.valueOf(name); return MediaKeyboardMode.valueOf(name);
} }
public static void setIsRevealableMessageEnabled(Context context, boolean value) { public static void setIsViewOnceMessageEnabled(Context context, boolean value) {
setBooleanPreference(context, VIEW_ONCE_DEFAULT, value); setBooleanPreference(context, VIEW_ONCE_DEFAULT, value);
} }
public static boolean isRevealableMessageEnabled(Context context) { public static boolean isViewOnceMessageEnabled(Context context) {
return getBooleanPreference(context, VIEW_ONCE_DEFAULT, false); return getBooleanPreference(context, VIEW_ONCE_DEFAULT, false);
} }
public static void setHasSeenViewOnceTooltip(Context context, boolean value) {
setBooleanPreference(context, VIEW_ONCE_TOOLTIP_SEEN, value);
}
public static boolean hasSeenViewOnceTooltip(Context context) {
return getBooleanPreference(context, VIEW_ONCE_TOOLTIP_SEEN, false);
}
public static void setHasSeenCameraFirstTooltip(Context context, boolean value) { public static void setHasSeenCameraFirstTooltip(Context context, boolean value) {
setBooleanPreference(context, SEEN_CAMERA_FIRST_TOOLTIP, value); setBooleanPreference(context, SEEN_CAMERA_FIRST_TOOLTIP, value);
} }
public static boolean hasSeendCameraFirstTooltip(Context context) { public static boolean hasSeenCameraFirstTooltip(Context context) {
return getBooleanPreference(context, SEEN_CAMERA_FIRST_TOOLTIP, false); return getBooleanPreference(context, SEEN_CAMERA_FIRST_TOOLTIP, false);
} }