[UI > Card] Move most actions into overflow action sheet (#43)

* [Plugin/ThemeCard] Move most actions into overflow action sheet

* [UI > Card] Move overflow menu, add icon to header

---------

Co-authored-by: Beef <beefers@riseup.net>
This commit is contained in:
Jack 2023-03-23 19:07:03 -04:00 committed by Beef
parent 72c9055b5a
commit ef702fb5ca
3 changed files with 79 additions and 44 deletions

View file

@ -1,9 +1,12 @@
import { ReactNative as RN, stylesheet } from "@metro/common";
import { findByProps } from "@metro/filters";
import { Forms } from "@ui/components";
import { getAssetIDByName } from "@ui/assets";
import { semanticColors } from "@ui/color";
const { FormRow, FormSwitch, FormRadio } = Forms;
const { hideActionSheet } = findByProps("openLazy", "hideActionSheet");
const { showSimpleActionSheet } = findByProps("showSimpleActionSheet");
// TODO: These styles work weirdly. iOS has cramped text, Android with low DPI probably does too. Fix?
const styles = stylesheet.createThemedStyleSheet({
@ -36,6 +39,11 @@ interface Action {
onPress: () => void;
}
interface OverflowAction extends Action {
label: string;
isDestructive?: boolean;
}
interface CardProps {
index?: number;
headerLabel: string | React.ComponentType;
@ -45,13 +53,15 @@ interface CardProps {
onToggleChange?: (v: boolean) => void;
descriptionLabel?: string | React.ComponentType;
actions?: Action[];
overflowTitle?: string;
overflowActions?: OverflowAction[];
}
export default function Card(props: CardProps) {
let pressableState = props.toggleValue ?? false;
return (
<RN.View style={[styles.card, {marginTop: props.index === 0 ? 10 : 0}]}>
<RN.View style={[styles.card, { marginTop: props.index === 0 ? 10 : 0 }]}>
<FormRow
style={styles.header}
label={props.headerLabel}
@ -76,6 +86,19 @@ export default function Card(props: CardProps) {
label={props.descriptionLabel}
trailing={
<RN.View style={styles.actions}>
{props.overflowActions && <RN.TouchableOpacity
onPress={() => showSimpleActionSheet({
key: "CardOverflow",
header: {
title: props.overflowTitle,
icon: props.headerIcon && <FormRow.Icon style={{ marginRight: 8 }} source={getAssetIDByName(props.headerIcon)} />,
onClose: () => hideActionSheet(),
},
options: props.overflowActions?.map(i => ({ ...i, icon: getAssetIDByName(i.icon) })),
})}
>
<RN.Image style={styles.icon} source={getAssetIDByName("ic_more_24px")} />
</RN.TouchableOpacity>}
{props.actions?.map(({ icon, onPress }) => (
<RN.TouchableOpacity
onPress={onPress}

View file

@ -35,9 +35,28 @@ export default function PluginCard({ plugin, index }: PluginCardProps) {
}
}}
descriptionLabel={plugin.manifest.description}
actions={[
overflowTitle={plugin.manifest.name}
overflowActions={[
{
icon: "ic_download_24px",
label: plugin.update ? "Disable updates" : "Enable updates",
onPress: () => {
plugin.update = !plugin.update;
showToast(`${plugin.update ? "Enabled" : "Disabled"} updates for ${plugin.manifest.name}.`, getAssetIDByName("toast_image_saved"));
}
},
{
icon: "copy",
label: "Copy plugin URL",
onPress: () => {
clipboard.setString(plugin.id);
showToast("Copied plugin URL to clipboard.", getAssetIDByName("toast_copy_link"));
}
},
{
icon: "ic_message_delete",
label: "Delete plugin",
isDestructive: true,
onPress: () => showConfirmationAlert({
title: "Wait!",
content: `Are you sure you wish to delete ${plugin.manifest.name}?`,
@ -54,20 +73,8 @@ export default function PluginCard({ plugin, index }: PluginCardProps) {
}
}),
},
{
icon: "copy",
onPress: () => {
clipboard.setString(plugin.id);
showToast("Copied plugin URL to clipboard.", getAssetIDByName("toast_copy_link"));
},
},
{
icon: plugin.update ? "Check" : "Small",
onPress: () => {
plugin.update = !plugin.update;
showToast(`${plugin.update ? "Enabled" : "Disabled"} updates for ${plugin.manifest.name}.`, getAssetIDByName("toast_image_saved"));
}
},
]}
actions={[
...(settings ? [{
icon: "settings",
onPress: () => navigation.push("VendettaCustomPage", {

View file

@ -34,34 +34,11 @@ export default function ThemeCard({ theme, index }: ThemeCardProps) {
onToggleChange={(v: boolean) => {
selectAndReload(v, theme.id);
}}
actions={[
{
icon: "ic_message_delete",
onPress: () => showConfirmationAlert({
title: "Wait!",
content: `Are you sure you wish to delete ${theme.data.name}?`,
confirmText: "Delete",
cancelText: "Cancel",
confirmColor: ButtonColors.RED,
onConfirm: () => {
removeTheme(theme.id).then((wasSelected) => {
setRemoved(true);
if (wasSelected) selectAndReload(false, theme.id);
}).catch((e: Error) => {
showToast(e.message, getAssetIDByName("Small"));
});
}
}),
},
{
icon: "copy",
onPress: () => {
clipboard.setString(theme.id);
showToast("Copied theme URL to clipboard.", getAssetIDByName("toast_copy_link"));
},
},
overflowTitle={theme.data.name}
overflowActions={[
{
icon: "ic_sync_24px",
label: "Refetch",
onPress: () => {
fetchTheme(theme.id).then(() => {
if (theme.selected) {
@ -81,6 +58,34 @@ export default function ThemeCard({ theme, index }: ThemeCardProps) {
});
},
},
{
icon: "copy",
label: "Copy theme URL",
onPress: () => {
clipboard.setString(theme.id);
showToast("Copied theme URL to clipboard.", getAssetIDByName("toast_copy_link"));
}
},
{
icon: "ic_message_delete",
label: "Delete theme",
isDestructive: true,
onPress: () => showConfirmationAlert({
title: "Wait!",
content: `Are you sure you wish to delete ${theme.data.name}?`,
confirmText: "Delete",
cancelText: "Cancel",
confirmColor: ButtonColors.RED,
onConfirm: () => {
removeTheme(theme.id).then((wasSelected) => {
setRemoved(true);
if (wasSelected) selectAndReload(false, theme.id);
}).catch((e: Error) => {
showToast(e.message, getAssetIDByName("Small"));
});
}
})
},
]}
/>
)