New mod option: (Un)distinguish as mod.

This commit is contained in:
Docile-Alligator
2025-07-10 17:18:31 -04:00
parent 73ff709340
commit 32cbcb1f89
12 changed files with 96 additions and 2 deletions

View File

@ -9,4 +9,5 @@ interface PostModerationActionHandler {
fun toggleLock(post: Post, position: Int)
fun toggleNSFW(post: Post, position: Int)
fun toggleSpoiler(post: Post, position: Int)
fun toggleMod(post: Post, position: Int)
}

View File

@ -449,4 +449,8 @@ public interface RedditAPI {
@FormUrlEncoded
@POST("/api/unlock")
Call<String> unLockThing(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params);
@FormUrlEncoded
@POST("/api/distinguish")
Call<String> toggleDistinguishedThing(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params);
}

View File

@ -67,7 +67,10 @@ class ModerationActionBottomSheetFragment : LandscapeExpandedRoundedBottomSheetD
AppCompatResources.getDrawable(it, if (post.isNSFW) R.drawable.ic_unmark_nsfw_24dp else R.drawable.ic_mark_nsfw_24dp), null, null, null
)
binding.toggleSpoilerTextViewModerationActionBottomSheetFragment.setCompoundDrawablesWithIntrinsicBounds(
AppCompatResources.getDrawable(it, if (post.isLocked) R.drawable.ic_unmark_spoiler_24dp else R.drawable.ic_spoiler_24dp), null, null, null
AppCompatResources.getDrawable(it, if (post.isSpoiler) R.drawable.ic_unmark_spoiler_24dp else R.drawable.ic_spoiler_24dp), null, null, null
)
binding.toggleModTextViewModerationActionBottomSheetFragment.setCompoundDrawablesWithIntrinsicBounds(
AppCompatResources.getDrawable(it, if (post.isModerator) R.drawable.ic_undistinguish_as_mod_24dp else R.drawable.ic_distinguish_as_mod_24dp), null, null, null
)
}
@ -94,6 +97,12 @@ class ModerationActionBottomSheetFragment : LandscapeExpandedRoundedBottomSheetD
(parentFragment as PostModerationActionHandler).toggleSpoiler(post, position)
dismiss()
}
binding.toggleModTextViewModerationActionBottomSheetFragment.setText(if (post.isModerator) R.string.undistinguish_as_mod else R.string.distinguish_as_mod)
binding.toggleModTextViewModerationActionBottomSheetFragment.setOnClickListener {
(parentFragment as PostModerationActionHandler).toggleMod(post, position)
dismiss()
}
}
}
return binding.root

View File

@ -1420,4 +1420,9 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat
public void toggleSpoiler(@NonNull Post post, int position) {
mPostViewModel.toggleSpoiler(post, position);
}
@Override
public void toggleMod(@NonNull Post post, int position) {
mPostViewModel.toggleMod(post, position);
}
}

View File

@ -624,6 +624,7 @@ public abstract class PostFragmentBase extends Fragment {
post.setSaved(event.post.isSaved());
post.setIsStickied(event.post.isStickied());
post.setIsLocked(event.post.isLocked());
post.setIsModerator(event.post.isModerator());
if (event.post.isRead()) {
post.markAsRead();
}

View File

@ -36,4 +36,10 @@ sealed class ModerationEvent(open val post: Post, open val position: Int, val to
data class UnmarkedSpoiler(override val post: Post, override val position: Int) : ModerationEvent(post, position, R.string.unmark_spoiler_success)
data class UnmarkSpoilerFailed(override val post: Post, override val position: Int) : ModerationEvent(post, position, R.string.unmark_spoiler_failed)
data class DistinguishedAsMod(override val post: Post, override val position: Int) : ModerationEvent(post, position, R.string.distinguished_as_mod)
data class DistinguishAsModFailed(override val post: Post, override val position: Int) : ModerationEvent(post, position, R.string.distinguish_as_mod_failed)
data class UndistinguishedAsMod(override val post: Post, override val position: Int) : ModerationEvent(post, position, R.string.undistinguished_as_mod)
data class UndistinguishAsModFailed(override val post: Post, override val position: Int) : ModerationEvent(post, position, R.string.undistinguish_as_mod_failed)
}

View File

@ -69,7 +69,7 @@ public class Post implements Parcelable {
private final boolean isCrosspost;
private boolean isRead;
private String crosspostParentId;
private final String distinguished;
private String distinguished;
private final String suggestedSort;
private String mp4Variant;
private ArrayList<Preview> previews = new ArrayList<>();
@ -408,6 +408,10 @@ public class Post implements Parcelable {
return distinguished != null && distinguished.equals("moderator");
}
public void setIsModerator(boolean value) {
distinguished = value ? "moderator" : null;
}
public boolean isAdmin() {
return distinguished != null && distinguished.equals("admin");
}

View File

@ -623,4 +623,26 @@ public class PostViewModel extends ViewModel {
}
});
}
public void toggleMod(@NonNull Post post, int position) {
Map<String, String> params = new HashMap<>();
params.put(APIUtils.ID_KEY, post.getFullName());
params.put(APIUtils.HOW_KEY, post.isModerator() ? APIUtils.HOW_NO : APIUtils.HOW_YES);
retrofit.create(RedditAPI.class).toggleDistinguishedThing(APIUtils.getOAuthHeader(accessToken), params).enqueue(new Callback<>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
post.setIsModerator(!post.isModerator());
moderationEventLiveData.postValue(post.isModerator() ? new ModerationEvent.DistinguishedAsMod(post, position): new ModerationEvent.UndistinguishedAsMod(post, position));
} else {
moderationEventLiveData.postValue(post.isModerator() ? new ModerationEvent.UndistinguishAsModFailed(post, position) : new ModerationEvent.DistinguishAsModFailed(post, position));
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable throwable) {
moderationEventLiveData.postValue(post.isModerator() ? new ModerationEvent.UndistinguishAsModFailed(post, position) : new ModerationEvent.DistinguishAsModFailed(post, position));
}
});
}
}

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:pathData="M480,880q-139,-35 -229.5,-159.5T160,444v-244l320,-120 320,120v227q-19,-8 -39,-14.5t-41,-9.5v-147l-240,-90 -240,90v188q0,47 12.5,94t35,89.5Q310,670 342,706t71,60q11,32 29,61t41,52q-1,0 -1.5,0.5t-1.5,0.5ZM680,880q-83,0 -141.5,-58.5T480,680q0,-83 58.5,-141.5T680,480q83,0 141.5,58.5T880,680q0,83 -58.5,141.5T680,880ZM480,466ZM660,800h40v-100h100v-40L700,660v-100h-40v100L560,660v40h100v100Z"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:pathData="m754,642 l-60,-62q12,-32 19,-66.5t7,-69.5v-189l-240,-90 -146,55 -62,-62 208,-78 320,120v244q0,51 -11.5,101T754,642ZM792,904L662,774q-38,39 -84.5,65.5T480,880q-139,-35 -229.5,-159.5T160,444v-172L56,168l56,-56 736,736 -56,56ZM423,535ZM514,400ZM480,796q35,-11 67,-31t59,-47L240,352v92q0,121 68,220t172,132Z"
android:fillColor="#000000"/>
</vector>

View File

@ -144,6 +144,24 @@
android:textSize="?attr/font_default"
app:drawableTint="?attr/primaryTextColor" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/toggle_mod_text_view_moderation_action_bottom_sheet_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:drawablePadding="48dp"
android:focusable="true"
android:fontFamily="?attr/font_family"
android:paddingStart="32dp"
android:paddingTop="16dp"
android:paddingEnd="32dp"
android:paddingBottom="16dp"
android:textColor="?attr/primaryTextColor"
android:textSize="?attr/font_default"
app:drawableTint="?attr/primaryTextColor" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -1566,4 +1566,10 @@
<string name="lock_failed">Lock failed</string>
<string name="unlocked">Unlocked</string>
<string name="unlock_failed">Unlock failed</string>
<string name="distinguish_as_mod">Distinguish as moderator</string>
<string name="undistinguish_as_mod">Undistinguish as moderator</string>
<string name="distinguished_as_mod">Distinguished as mod</string>
<string name="distinguish_as_mod_failed">Distinguish as moderator failed</string>
<string name="undistinguished_as_mod">Undistinguished as moderator</string>
<string name="undistinguish_as_mod_failed">Undistinguish as moderator failed</string>
</resources>