Add UI for changing who can quote when composing

This commit is contained in:
0xd9a 2025-08-22 20:47:57 +05:30
parent 8e2d0452e7
commit 89adb83c07
3 changed files with 144 additions and 11 deletions

View file

@ -1643,18 +1643,22 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
switch (statusDraft.visibility.toLowerCase()) { switch (statusDraft.visibility.toLowerCase()) {
case "public" -> { case "public" -> {
holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_public); holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_public);
holder.binding.buttonQuoteVisibility.setVisibility(View.VISIBLE);
statusDraft.visibility = MastodonHelper.visibility.PUBLIC.name(); statusDraft.visibility = MastodonHelper.visibility.PUBLIC.name();
} }
case "unlisted" -> { case "unlisted" -> {
holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_unlisted); holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_unlisted);
holder.binding.buttonQuoteVisibility.setVisibility(View.VISIBLE);
statusDraft.visibility = MastodonHelper.visibility.UNLISTED.name(); statusDraft.visibility = MastodonHelper.visibility.UNLISTED.name();
} }
case "private" -> { case "private" -> {
holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_private); holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_private);
holder.binding.buttonQuoteVisibility.setVisibility(View.GONE);
statusDraft.visibility = MastodonHelper.visibility.PRIVATE.name(); statusDraft.visibility = MastodonHelper.visibility.PRIVATE.name();
} }
case "direct" -> { case "direct" -> {
holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_direct); holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_direct);
holder.binding.buttonQuoteVisibility.setVisibility(View.GONE);
statusDraft.visibility = MastodonHelper.visibility.DIRECT.name(); statusDraft.visibility = MastodonHelper.visibility.DIRECT.name();
} }
} }
@ -1666,29 +1670,54 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
holder.binding.visibilityGroup.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); holder.binding.visibilityGroup.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
holder.binding.buttonVisibility.setChecked(false); holder.binding.buttonVisibility.setChecked(false);
}); });
holder.binding.buttonQuoteVisibility.setOnClickListener(v -> {
holder.binding.quoteVisibilityPanel.setVisibility(View.VISIBLE);
holder.binding.quoteVisibilityGroup.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
holder.binding.buttonQuoteVisibility.setChecked(false);
});
holder.binding.buttonCloseVisibilityPanel.setOnClickListener(v -> holder.binding.visibilityPanel.setVisibility(View.GONE)); holder.binding.buttonCloseVisibilityPanel.setOnClickListener(v -> holder.binding.visibilityPanel.setVisibility(View.GONE));
holder.binding.buttonCloseQuoteVisibilityPanel.setOnClickListener(v -> holder.binding.quoteVisibilityPanel.setVisibility(View.GONE));
holder.binding.buttonVisibilityDirect.setOnClickListener(v -> { holder.binding.buttonVisibilityDirect.setOnClickListener(v -> {
holder.binding.visibilityPanel.setVisibility(View.GONE); holder.binding.visibilityPanel.setVisibility(View.GONE);
holder.binding.buttonQuoteVisibility.setVisibility(View.GONE);
holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_direct); holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_direct);
statusDraft.visibility = MastodonHelper.visibility.DIRECT.name(); statusDraft.visibility = MastodonHelper.visibility.DIRECT.name();
}); });
holder.binding.buttonVisibilityPrivate.setOnClickListener(v -> { holder.binding.buttonVisibilityPrivate.setOnClickListener(v -> {
holder.binding.visibilityPanel.setVisibility(View.GONE); holder.binding.visibilityPanel.setVisibility(View.GONE);
holder.binding.buttonQuoteVisibility.setVisibility(View.GONE);
holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_private); holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_private);
statusDraft.visibility = MastodonHelper.visibility.PRIVATE.name(); statusDraft.visibility = MastodonHelper.visibility.PRIVATE.name();
}); });
holder.binding.buttonVisibilityUnlisted.setOnClickListener(v -> { holder.binding.buttonVisibilityUnlisted.setOnClickListener(v -> {
holder.binding.visibilityPanel.setVisibility(View.GONE); holder.binding.visibilityPanel.setVisibility(View.GONE);
holder.binding.buttonQuoteVisibility.setVisibility(View.VISIBLE);
holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_unlisted); holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_unlisted);
statusDraft.visibility = MastodonHelper.visibility.UNLISTED.name(); statusDraft.visibility = MastodonHelper.visibility.UNLISTED.name();
}); });
holder.binding.buttonVisibilityPublic.setOnClickListener(v -> { holder.binding.buttonVisibilityPublic.setOnClickListener(v -> {
holder.binding.visibilityPanel.setVisibility(View.GONE); holder.binding.visibilityPanel.setVisibility(View.GONE);
holder.binding.buttonQuoteVisibility.setVisibility(View.VISIBLE);
holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_public); holder.binding.buttonVisibility.setIconResource(R.drawable.ic_compose_visibility_public);
statusDraft.visibility = MastodonHelper.visibility.PUBLIC.name(); statusDraft.visibility = MastodonHelper.visibility.PUBLIC.name();
unlisted_changed = true; unlisted_changed = true;
}); });
holder.binding.buttonQuoteVisibilityNoOne.setOnClickListener(v -> {
holder.binding.quoteVisibilityPanel.setVisibility(View.GONE);
holder.binding.buttonQuoteVisibility.setIconResource(R.drawable.ic_baseline_block_24);
// Todo: "No one" quote visibility clicked
});
holder.binding.buttonQuoteVisibilityFollowersOnly.setOnClickListener(v -> {
holder.binding.quoteVisibilityPanel.setVisibility(View.GONE);
holder.binding.buttonQuoteVisibility.setIconResource(R.drawable.ic_baseline_people_alt_24);
// Todo: "No one" quote visibility clicked
});
holder.binding.buttonQuoteVisibilityAnyone.setOnClickListener(v -> {
holder.binding.quoteVisibilityPanel.setVisibility(View.GONE);
holder.binding.buttonQuoteVisibility.setIconResource(R.drawable.ic_compose_visibility_public);
// Todo: "No one" quote visibility clicked
});
if (statusDraft.spoilerChecked || statusDraft.spoiler_text != null && !statusDraft.spoiler_text.trim().isEmpty()) { if (statusDraft.spoilerChecked || statusDraft.spoiler_text != null && !statusDraft.spoiler_text.trim().isEmpty()) {
holder.binding.contentSpoiler.setVisibility(View.VISIBLE); holder.binding.contentSpoiler.setVisibility(View.VISIBLE);

View file

@ -208,19 +208,40 @@
app:layout_constraintTop_toBottomOf="@id/text_area_divider" app:layout_constraintTop_toBottomOf="@id/text_area_divider"
app:toggleCheckedStateOnClick="true" /> app:toggleCheckedStateOnClick="true" />
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/visibility_indicators_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginVertical="6dp"
app:layout_constraintBottom_toBottomOf="@id/action_buttons_barrier"
app:layout_constraintStart_toEndOf="@id/button_sensitive"
app:layout_constraintTop_toBottomOf="@id/text_area_divider"
app:selectionRequired="false">
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/button_visibility" android:id="@+id/button_visibility"
style="@style/Widget.Material3.Button.IconButton.Outlined" style="@style/Widget.Material3.Button.IconButton.Outlined"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginVertical="6dp" android:checkable="false"
android:contentDescription="@string/change_visibility" android:contentDescription="@string/change_visibility"
app:icon="@drawable/ic_compose_visibility_public" android:insetLeft="0dp"
app:iconGravity="textStart" android:insetRight="0dp"
app:iconPadding="0dp" app:icon="@drawable/ic_compose_visibility_public" />
app:layout_constraintBottom_toBottomOf="@id/action_buttons_barrier"
app:layout_constraintStart_toEndOf="@id/button_sensitive" <com.google.android.material.button.MaterialButton
app:layout_constraintTop_toBottomOf="@id/text_area_divider" /> android:id="@+id/button_quote_visibility"
style="@style/Widget.Material3.Button.IconButton.Outlined"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="false"
android:contentDescription="@string/change_visibility"
android:insetLeft="0dp"
android:insetRight="0dp"
app:icon="@drawable/ic_baseline_people_alt_24" />
</com.google.android.material.button.MaterialButtonToggleGroup>
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/button_language" android:id="@+id/button_language"
@ -232,7 +253,7 @@
android:fontFamily="monospace" android:fontFamily="monospace"
android:minWidth="72dp" android:minWidth="72dp"
app:layout_constraintBottom_toBottomOf="@id/action_buttons_barrier" app:layout_constraintBottom_toBottomOf="@id/action_buttons_barrier"
app:layout_constraintStart_toEndOf="@id/button_visibility" app:layout_constraintStart_toEndOf="@id/visibility_indicators_group"
app:layout_constraintTop_toBottomOf="@id/text_area_divider" app:layout_constraintTop_toBottomOf="@id/text_area_divider"
tools:text="EN" /> tools:text="EN" />
@ -409,7 +430,87 @@
style="@style/Widget.Material3.Button.IconButton.Outlined" style="@style/Widget.Material3.Button.IconButton.Outlined"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="96dp" android:layout_marginStart="98dp"
android:insetLeft="0dp"
android:insetRight="0dp"
app:icon="@drawable/ic_baseline_close_24" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/quote_visibility_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_compose_panels"
android:gravity="bottom"
android:orientation="vertical"
android:padding="6dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/action_buttons_barrier"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1">
<com.google.android.material.textview.MaterialTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="6dp"
android:text="@string/who_can_quote"
android:textAppearance="@style/TextAppearance.Material3.LabelLarge" />
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/quote_visibility_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="6dp"
android:orientation="vertical"
app:singleSelection="true">
<com.google.android.material.button.MaterialButton
android:id="@+id/button_quote_visibility_no_one"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:insetTop="0dp"
android:insetBottom="0dp"
android:minHeight="36dp"
android:text="@string/no_one"
android:textAlignment="textStart"
app:icon="@drawable/ic_baseline_block_24" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_quote_visibility_followers_only"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:insetTop="0dp"
android:insetBottom="0dp"
android:minHeight="36dp"
android:text="@string/followers_only"
android:textAlignment="textStart"
app:icon="@drawable/ic_baseline_people_alt_24" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_quote_visibility_anyone"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:insetTop="0dp"
android:insetBottom="0dp"
android:minHeight="36dp"
android:text="@string/anyone"
android:textAlignment="textStart"
app:icon="@drawable/ic_compose_visibility_public" />
</com.google.android.material.button.MaterialButtonToggleGroup>
<com.google.android.material.button.MaterialButton
android:id="@+id/button_close_quote_visibility_panel"
style="@style/Widget.Material3.Button.IconButton.Outlined"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="137dp"
android:insetLeft="0dp"
android:insetRight="0dp"
app:icon="@drawable/ic_baseline_close_24" /> app:icon="@drawable/ic_baseline_close_24" />
</androidx.appcompat.widget.LinearLayoutCompat> </androidx.appcompat.widget.LinearLayoutCompat>
@ -419,7 +520,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:barrierDirection="bottom" app:barrierDirection="bottom"
app:constraint_referenced_ids="button_attach,button_visibility, button_language, button_post, character_progress, button_sensitive" /> app:constraint_referenced_ids="button_attach, visibility_indicators_group, button_language, button_post, character_progress, button_sensitive" />
<com.google.android.material.checkbox.MaterialCheckBox <com.google.android.material.checkbox.MaterialCheckBox

View file

@ -686,6 +686,9 @@
<string name="boosted_by">Boosted by</string> <string name="boosted_by">Boosted by</string>
<string name="favourited_by">Favourited by</string> <string name="favourited_by">Favourited by</string>
<string name="followers_only">Followers only</string> <string name="followers_only">Followers only</string>
<string name="who_can_quote">Who can quote</string>
<string name="no_one">No one</string>
<string name="anyone">Anyone</string>
<string name="other">Other</string> <string name="other">Other</string>
<string name="eg_sensitive_content">Eg.: Sensitive Content</string> <string name="eg_sensitive_content">Eg.: Sensitive Content</string>
<string name="Pronouns">Pronouns</string> <string name="Pronouns">Pronouns</string>