From eea00b0d53d088db96828c83ad68bfc8c0cc2aeb Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Mon, 31 Oct 2022 20:39:22 +0000 Subject: [PATCH] Load post privacy preference This queries the user's post visibility preference when opening the composer, and sets it on the composer. In the case of composing a reply, the user's preference is only respected if it is "more private" than the privacy of the post being replied to, as this appears to be the behaviour in the web interface (and is what I'd expect) --- .../api/requests/accounts/GetPreferences.java | 10 ++++ .../android/fragments/ComposeFragment.java | 51 ++++++++++++++++--- .../android/model/ExpandMedia.java | 12 +++++ .../android/model/Preferences.java | 38 ++++++++++++++ .../android/model/StatusPrivacy.java | 22 ++++++-- 5 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 mastodon/src/main/java/org/joinmastodon/android/api/requests/accounts/GetPreferences.java create mode 100644 mastodon/src/main/java/org/joinmastodon/android/model/ExpandMedia.java create mode 100644 mastodon/src/main/java/org/joinmastodon/android/model/Preferences.java diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/requests/accounts/GetPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/api/requests/accounts/GetPreferences.java new file mode 100644 index 000000000..8d5d79e94 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/api/requests/accounts/GetPreferences.java @@ -0,0 +1,10 @@ +package org.joinmastodon.android.api.requests.accounts; + +import org.joinmastodon.android.api.MastodonAPIRequest; +import org.joinmastodon.android.model.Preferences; + +public class GetPreferences extends MastodonAPIRequest { + public GetPreferences(){ + super(HttpMethod.GET, "/preferences", Preferences.class); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java index 1002788b5..df0be65dd 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeFragment.java @@ -59,6 +59,7 @@ import org.joinmastodon.android.R; import org.joinmastodon.android.api.MastodonAPIController; import org.joinmastodon.android.api.MastodonErrorResponse; import org.joinmastodon.android.api.ProgressListener; +import org.joinmastodon.android.api.requests.accounts.GetPreferences; import org.joinmastodon.android.api.requests.statuses.CreateStatus; import org.joinmastodon.android.api.requests.statuses.EditStatus; import org.joinmastodon.android.api.requests.statuses.GetAttachmentByID; @@ -75,6 +76,7 @@ import org.joinmastodon.android.model.EmojiCategory; import org.joinmastodon.android.model.Instance; import org.joinmastodon.android.model.Mention; import org.joinmastodon.android.model.Poll; +import org.joinmastodon.android.model.Preferences; import org.joinmastodon.android.model.Status; import org.joinmastodon.android.model.StatusPrivacy; import org.joinmastodon.android.ui.ComposeAutocompleteViewController; @@ -224,13 +226,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr else charLimit=500; - if(getArguments().containsKey("replyTo")){ - replyTo=Parcels.unwrap(getArguments().getParcelable("replyTo")); - statusVisibility=replyTo.visibility; - } - if(savedInstanceState!=null){ - statusVisibility=(StatusPrivacy) savedInstanceState.getSerializable("visibility"); - } + loadDefaultStatusVisibility(savedInstanceState); } @Override @@ -1276,6 +1272,47 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr menu.show(); } + private void loadDefaultStatusVisibility(Bundle savedInstanceState) { + if(getArguments().containsKey("replyTo")){ + replyTo=Parcels.unwrap(getArguments().getParcelable("replyTo")); + statusVisibility = replyTo.visibility; + } + + // A saved privacy setting from a previous compose session wins over the reply visibility + if(savedInstanceState !=null){ + statusVisibility = (StatusPrivacy) savedInstanceState.getSerializable("visibility"); + } + + new GetPreferences() + .setCallback(new Callback<>(){ + @Override + public void onSuccess(Preferences result){ + // Only override the reply visibility if our preference is more private + if (result.postingDefaultVisibility.isLessVisibleThan(statusVisibility)) { + // Map unlisted from the API onto public, because we don't have unlisted in the UI + statusVisibility = switch (result.postingDefaultVisibility) { + case PUBLIC, UNLISTED -> StatusPrivacy.PUBLIC; + case PRIVATE -> StatusPrivacy.PRIVATE; + case DIRECT -> StatusPrivacy.DIRECT; + }; + } + + // A saved privacy setting from a previous compose session wins over all + if(savedInstanceState !=null){ + statusVisibility = (StatusPrivacy) savedInstanceState.getSerializable("visibility"); + } + + updateVisibilityIcon (); + } + + @Override + public void onError(ErrorResponse error){ + Log.w(TAG, "Unable to get user preferences to set default post privacy"); + } + }) + .exec(accountID); + } + private void updateVisibilityIcon(){ if(statusVisibility==null){ // TODO find out why this happens statusVisibility=StatusPrivacy.PUBLIC; diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/ExpandMedia.java b/mastodon/src/main/java/org/joinmastodon/android/model/ExpandMedia.java new file mode 100644 index 000000000..215341122 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/model/ExpandMedia.java @@ -0,0 +1,12 @@ +package org.joinmastodon.android.model; + +import com.google.gson.annotations.SerializedName; + +public enum ExpandMedia { + @SerializedName("default") + DEFAULT, + @SerializedName("show_all") + SHOW_ALL, + @SerializedName("hide_all") + HIDE_ALL; +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/Preferences.java b/mastodon/src/main/java/org/joinmastodon/android/model/Preferences.java new file mode 100644 index 000000000..2c5ee8c9d --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/model/Preferences.java @@ -0,0 +1,38 @@ +package org.joinmastodon.android.model; + +import com.google.gson.annotations.SerializedName; + +/** + * Preferred common behaviors to be shared across clients. + */ +public class Preferences extends BaseModel { + /** + * Default visibility for new posts + */ + @SerializedName("posting:default:visibility") + public StatusPrivacy postingDefaultVisibility; + + /** + * Default sensitivity flag for new posts + */ + @SerializedName("posting:default:sensitive") + public boolean postingDefaultSensitive; + + /** + * Default language for new posts + */ + @SerializedName("posting:default:language") + public String postingDefaultLanguage; + + /** + * Whether media attachments should be automatically displayed or blurred/hidden. + */ + @SerializedName("reading:expand:media") + public ExpandMedia readingExpandMedia; + + /** + * Whether CWs should be expanded by default. + */ + @SerializedName("reading:expand:spoilers") + public boolean readingExpandSpoilers; +} \ No newline at end of file diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/StatusPrivacy.java b/mastodon/src/main/java/org/joinmastodon/android/model/StatusPrivacy.java index fd205e960..cb8d6a0e5 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/StatusPrivacy.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/StatusPrivacy.java @@ -4,11 +4,25 @@ import com.google.gson.annotations.SerializedName; public enum StatusPrivacy{ @SerializedName("public") - PUBLIC, + PUBLIC(0), @SerializedName("unlisted") - UNLISTED, + UNLISTED(1), @SerializedName("private") - PRIVATE, + PRIVATE(2), @SerializedName("direct") - DIRECT; + DIRECT(3); + + private int privacy; + + StatusPrivacy(int privacy) { + this.privacy = privacy; + } + + public boolean isLessVisibleThan(StatusPrivacy other) { + return privacy > other.getPrivacy(); + } + + public int getPrivacy() { + return privacy; + } }