Funny UI changes
This commit is contained in:
parent
cea9b1c7ba
commit
190940b417
13 changed files with 268 additions and 203 deletions
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"ABOUT": "About",
|
||||
"ACTIONS": "Actions",
|
||||
"ARE_YOU_SURE_TO_CLEAR_DATA": "Are you sure you wish to clear the data of {name}?",
|
||||
"ARE_YOU_SURE_TO_DELETE_PLUGIN": "Are you sure you wish to delete {name}? This will clear all of the plugin's data.",
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ function getItemsByQuery<T extends { id?: string; }>(items: T[], query: string):
|
|||
const reanimated = findByProps("useSharedValue");
|
||||
const { FloatingActionButton } = findByProps("FloatingActionButton");
|
||||
|
||||
export default function AddonPage<T>({ title, floatingButtonText, fetchFunction, items, safeModeMessage, safeModeExtras, card: CardComponent }: AddonPageProps<T>) {
|
||||
export default function AddonPage<T>({ floatingButtonText, fetchFunction, items, safeModeMessage, safeModeExtras, card: CardComponent }: AddonPageProps<T>) {
|
||||
useProxy(settings);
|
||||
useProxy(items);
|
||||
|
||||
|
|
@ -67,9 +67,8 @@ export default function AddonPage<T>({ title, floatingButtonText, fetchFunction,
|
|||
collapseText.value = Number(e.nativeEvent.contentOffset.y > yOffset.current);
|
||||
yOffset.current = e.nativeEvent.contentOffset.y;
|
||||
}}
|
||||
onMomentumScrollEnd={() => collapseText.value = 0}
|
||||
style={{ paddingHorizontal: 10, paddingTop: 10 }}
|
||||
contentContainerStyle={{ paddingBottom: 70 }}
|
||||
contentContainerStyle={{ paddingBottom: 90, paddingHorizontal: 5 }}
|
||||
data={getItemsByQuery(Object.values(items), search)}
|
||||
renderItem={({ item, index }) => <CardComponent item={item} index={index} />}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,41 +1,67 @@
|
|||
import { getAssetIDByName } from "@lib/api/assets";
|
||||
import { TableCheckboxRow, TableRow, TableRowGroup, TableRowIcon, TableSwitchRow } from "@lib/ui/components/discord/Redesign";
|
||||
import { FormRow } from "@lib/ui/components/discord/Forms";
|
||||
import { FormCheckbox, FormSwitch, IconButton } from "@lib/ui/components/discord/Redesign";
|
||||
import { createStyles, TextStyleSheet } from "@lib/ui/styles";
|
||||
import { ReactNative as RN } from "@metro/common";
|
||||
import { findByProps } from "@metro/filters";
|
||||
import { semanticColors } from "@ui/color";
|
||||
import ContextMenu from "@ui/components/ContextMenu";
|
||||
import { createStyles } from "@ui/styles";
|
||||
import { Image, TouchableOpacity, View } from "react-native";
|
||||
import { ImageBackground, View } from "react-native";
|
||||
|
||||
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 useStyles = createStyles({
|
||||
card: {
|
||||
backgroundColor: semanticColors?.BACKGROUND_SECONDARY,
|
||||
borderRadius: 15,
|
||||
backgroundColor: semanticColors?.CARD_SECONDARY_BG,
|
||||
borderRadius: 12,
|
||||
overflow: "hidden"
|
||||
},
|
||||
header: {
|
||||
padding: 0,
|
||||
backgroundColor: semanticColors?.BACKGROUND_TERTIARY,
|
||||
},
|
||||
headerLeading: {
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
scale: 1.2
|
||||
},
|
||||
headerTrailing: {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: 15,
|
||||
alignItems: "center"
|
||||
},
|
||||
headerLabel: {
|
||||
...TextStyleSheet["heading-md/semibold"],
|
||||
color: semanticColors.TEXT_NORMAL,
|
||||
},
|
||||
headerSubtitle: {
|
||||
...TextStyleSheet["text-md/semibold"],
|
||||
color: semanticColors.TEXT_MUTED,
|
||||
},
|
||||
descriptionLabel: {
|
||||
...TextStyleSheet["text-md/semibold"],
|
||||
color: semanticColors.TEXT_NORMAL,
|
||||
},
|
||||
actions: {
|
||||
flexDirection: "row-reverse",
|
||||
alignItems: "center",
|
||||
gap: 5
|
||||
},
|
||||
actionIcon: {
|
||||
width: 22,
|
||||
height: 22,
|
||||
marginLeft: 5,
|
||||
tintColor: semanticColors?.INTERACTIVE_NORMAL,
|
||||
},
|
||||
icon: {
|
||||
width: 22,
|
||||
height: 22,
|
||||
marginLeft: 5,
|
||||
tintColor: semanticColors?.INTERACTIVE_NORMAL,
|
||||
iconStyle: {
|
||||
tintColor: semanticColors.LOGO_PRIMARY,
|
||||
opacity: 0.2,
|
||||
height: 64,
|
||||
width: 64,
|
||||
left: void 0,
|
||||
right: "30%",
|
||||
top: "-10%"
|
||||
}
|
||||
});
|
||||
|
||||
interface Action {
|
||||
icon: string;
|
||||
disabled?: boolean;
|
||||
onPress: () => void;
|
||||
}
|
||||
|
||||
|
|
@ -51,69 +77,89 @@ export interface CardWrapper<T> {
|
|||
|
||||
interface CardProps {
|
||||
index?: number;
|
||||
headerLabel: string | React.ComponentType;
|
||||
headerLabel: string;
|
||||
headerSublabel?: string;
|
||||
headerIcon?: string;
|
||||
toggleType?: "switch" | "radio";
|
||||
toggleValue?: boolean;
|
||||
onToggleChange?: (v: boolean) => void;
|
||||
descriptionLabel?: string | React.ComponentType;
|
||||
/** @deprecated use overflowActions */
|
||||
descriptionLabel?: string;
|
||||
actions?: Action[];
|
||||
overflowTitle?: string;
|
||||
overflowActions?: OverflowAction[];
|
||||
overflowIcon?: string;
|
||||
}
|
||||
|
||||
export default function Card(props: CardProps) {
|
||||
const styles = useStyles();
|
||||
let pressableState = props.toggleValue ?? false;
|
||||
|
||||
const headerProps = {
|
||||
style: styles.header,
|
||||
label: props.headerLabel,
|
||||
icon: props.headerIcon && <TableRowIcon source={getAssetIDByName(props.headerIcon)} />
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={[styles.card, { marginTop: props.index !== 0 ? 10 : 0 }]}>
|
||||
<TableRowGroup>
|
||||
{props.toggleType && (props.toggleType === "switch" ?
|
||||
<TableSwitchRow
|
||||
{...headerProps}
|
||||
value={props.toggleValue}
|
||||
onValueChange={props.onToggleChange}
|
||||
/> : props.toggleType === "radio" ?
|
||||
<TableCheckboxRow
|
||||
{...headerProps}
|
||||
onPress={() => {
|
||||
pressableState = !pressableState;
|
||||
props.onToggleChange?.(pressableState);
|
||||
}}
|
||||
checked={props.toggleValue}
|
||||
/> : undefined) || <TableRow {...headerProps} />}
|
||||
<TableRow
|
||||
label={props.descriptionLabel}
|
||||
<RN.View style={[styles.card, { marginTop: props.index !== 0 ? 15 : 0 }]}>
|
||||
<ImageBackground
|
||||
source={props.headerIcon && getAssetIDByName(props.headerIcon) || {}}
|
||||
resizeMode="cover"
|
||||
imageStyle={styles.iconStyle}
|
||||
>
|
||||
<FormRow
|
||||
style={styles.header}
|
||||
label={
|
||||
<View style={styles.headerLeading}>
|
||||
<RN.Text style={styles.headerLabel}>{props.headerLabel}</RN.Text>
|
||||
{props.headerSublabel && (
|
||||
<RN.Text style={styles.headerSubtitle}>{props.headerSublabel}</RN.Text>
|
||||
)}
|
||||
</View>
|
||||
}
|
||||
trailing={
|
||||
<View style={styles.actions}>
|
||||
{props.overflowActions &&
|
||||
<ContextMenu
|
||||
triggerOnLongPress={false}
|
||||
items={props.overflowActions.map(i => ({
|
||||
label: i.label,
|
||||
iconSource: getAssetIDByName(i.icon),
|
||||
action: i.onPress
|
||||
}))}
|
||||
align="auto"
|
||||
title={props.overflowTitle!!}
|
||||
children={props => <TouchableOpacity {...props}>
|
||||
<Image style={styles.icon} source={getAssetIDByName("ic_more_24px")} />
|
||||
</TouchableOpacity>}
|
||||
<View style={styles.headerTrailing}>
|
||||
<View style={styles.actions}>
|
||||
{props.overflowActions &&
|
||||
<IconButton
|
||||
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) })),
|
||||
})}
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
icon={getAssetIDByName("CircleInformationIcon")}
|
||||
/>}
|
||||
{props.actions?.map(({ icon, onPress, disabled }) => (
|
||||
<IconButton
|
||||
onPress={onPress}
|
||||
disabled={disabled}
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
icon={getAssetIDByName(icon)}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
{props.toggleType && (props.toggleType === "switch" ?
|
||||
<FormSwitch
|
||||
value={props.toggleValue}
|
||||
onValueChange={props.onToggleChange}
|
||||
/>
|
||||
}
|
||||
:
|
||||
<RN.Pressable onPress={() => {
|
||||
props.onToggleChange?.(!props.toggleValue);
|
||||
}}>
|
||||
<FormCheckbox checked={props.toggleValue} />
|
||||
</RN.Pressable>
|
||||
)}
|
||||
</View>
|
||||
}
|
||||
/>
|
||||
</TableRowGroup>
|
||||
</View>
|
||||
<FormRow
|
||||
label={
|
||||
<RN.View>
|
||||
<RN.Text style={styles.descriptionLabel}>{props.descriptionLabel}</RN.Text>
|
||||
</RN.View>
|
||||
}
|
||||
/>
|
||||
</ImageBackground>
|
||||
</RN.View>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,9 @@ export default function PluginCard({ item: plugin, index }: CardWrapper<BunnyPlu
|
|||
<Card
|
||||
index={index}
|
||||
// TODO: Actually make use of user IDs
|
||||
headerLabel={`${plugin.manifest.name} by ${plugin.manifest.authors.map(i => i.name).join(", ")}`}
|
||||
headerIcon={plugin.manifest.vendetta?.icon || "ic_application_command_24px"}
|
||||
headerLabel={`${plugin.manifest.name}`}
|
||||
headerSublabel={plugin.manifest.authors?.[0] && `by ${plugin.manifest.authors.map(i => i.name).join(", ")}`}
|
||||
headerIcon={plugin.manifest.vendetta?.icon}
|
||||
toggleType="switch"
|
||||
toggleValue={plugin.enabled}
|
||||
onToggleChange={(v: boolean) => {
|
||||
|
|
@ -42,6 +43,14 @@ export default function PluginCard({ item: plugin, index }: CardWrapper<BunnyPlu
|
|||
}}
|
||||
descriptionLabel={plugin.manifest.description}
|
||||
overflowTitle={plugin.manifest.name}
|
||||
actions={[{
|
||||
icon: "WrenchIcon",
|
||||
disabled: !settings,
|
||||
onPress: () => navigation.push("VendettaCustomPage", {
|
||||
title: plugin.manifest.name,
|
||||
render: settings,
|
||||
})
|
||||
}]}
|
||||
overflowActions={[
|
||||
...(settings ? [{
|
||||
label: Strings.OVERFLOW_PLUGIN_SETTINGS,
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
import { Strings } from "@core/i18n";
|
||||
import { getScreens } from "@core/ui/settings/data";
|
||||
import { getAssetIDByName } from "@lib/api/assets";
|
||||
import { useProxy } from "@lib/api/storage";
|
||||
import { settings } from "@lib/settings";
|
||||
import { FormDivider, FormRow, FormSection } from "@lib/ui/components/discord/Forms";
|
||||
import { NavigationNative } from "@metro/common";
|
||||
import { ErrorBoundary } from "@ui/components";
|
||||
|
||||
export default function SettingsSection() {
|
||||
const navigation = NavigationNative.useNavigation();
|
||||
useProxy(settings);
|
||||
|
||||
const screens = getScreens();
|
||||
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<FormSection key="Vendetta" title={`${Strings.BUNNY}${settings.safeMode?.enabled ? ` (${Strings.SAFE_MODE})` : ""}`}>
|
||||
{screens.filter(s => (s.shouldRender?.() ?? true)).map((s, i) => (
|
||||
<>
|
||||
<FormRow
|
||||
label={s.title()}
|
||||
leading={<FormRow.Icon source={getAssetIDByName(s.icon!)} />}
|
||||
trailing={FormRow.Arrow}
|
||||
onPress={() => navigation.push(s.key)}
|
||||
/>
|
||||
{i !== screens.length - 1 && <FormDivider />}
|
||||
</>
|
||||
))}
|
||||
</FormSection>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
|
@ -12,11 +12,8 @@ import { showToast } from "@ui/toasts";
|
|||
|
||||
async function selectAndApply(value: boolean, id: string) {
|
||||
try {
|
||||
await selectTheme(value ? id : "default");
|
||||
value ? applyTheme(themes[id]) : applyTheme(null);
|
||||
|
||||
// TODO: Implement native side reload-less & check if it's applied by 100%
|
||||
showToast(Strings.THEMES_RELOAD_FOR_CHANGES, getAssetIDByName("yellow-alert"));
|
||||
await selectTheme(value ? id : null);
|
||||
applyTheme(value ? themes[id] : null);
|
||||
} catch (e: any) {
|
||||
console.error("Error while selectAndApply,", e);
|
||||
}
|
||||
|
|
@ -25,6 +22,8 @@ async function selectAndApply(value: boolean, id: string) {
|
|||
export default function ThemeCard({ item: theme, index }: CardWrapper<Theme>) {
|
||||
useProxy(theme);
|
||||
|
||||
// little hack, our useProxy is kinda not reliable here
|
||||
const [, forceUpdate] = React.useReducer(n => ~n, 0);
|
||||
const [removed, setRemoved] = React.useState(false);
|
||||
|
||||
// This is needed because of React™
|
||||
|
|
@ -35,12 +34,14 @@ export default function ThemeCard({ item: theme, index }: CardWrapper<Theme>) {
|
|||
return (
|
||||
<Card
|
||||
index={index}
|
||||
headerLabel={`${theme.data.name} ${authors ? `by ${authors.map(i => i.name).join(", ")}` : ""}`}
|
||||
headerLabel={theme.data.name}
|
||||
headerSublabel={authors ? `by ${authors.map(i => i.name).join(", ")}` : ""}
|
||||
descriptionLabel={theme.data.description ?? "No description."}
|
||||
toggleType={!settings.safeMode?.enabled ? "radio" : undefined}
|
||||
toggleValue={theme.selected}
|
||||
onToggleChange={(v: boolean) => {
|
||||
selectAndApply(v, theme.id);
|
||||
forceUpdate();
|
||||
}}
|
||||
overflowTitle={theme.data.name}
|
||||
overflowActions={[
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ import { registerSection } from "@lib/ui/settings";
|
|||
import { version } from "bunny-build";
|
||||
|
||||
// @ts-ignore
|
||||
import PyoncordIcon from "../../../assets/icons/pyon64.png";
|
||||
import _PyoncordIcon from "../../../assets/icons/pyon64.png";
|
||||
|
||||
export const PyoncordIcon = _PyoncordIcon as string;
|
||||
|
||||
export default function initSettings() {
|
||||
registerSection({
|
||||
|
|
|
|||
91
src/core/ui/settings/pages/About.tsx
Normal file
91
src/core/ui/settings/pages/About.tsx
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import { Strings } from "@core/i18n";
|
||||
import Version from "@core/ui/components/Version";
|
||||
import { useProxy } from "@lib/api/storage";
|
||||
import { getDebugInfo } from "@lib/debug";
|
||||
import { settings } from "@lib/settings";
|
||||
import { Stack, TableRowGroup } from "@lib/ui/components/discord/Redesign";
|
||||
import { Platform, ScrollView } from "react-native";
|
||||
|
||||
export default function About() {
|
||||
const debugInfo = getDebugInfo();
|
||||
useProxy(settings);
|
||||
|
||||
const versions = [
|
||||
{
|
||||
label: Strings.BUNNY,
|
||||
version: debugInfo.bunny.version,
|
||||
icon: "ic_progress_wrench_24px",
|
||||
},
|
||||
{
|
||||
label: "Discord",
|
||||
version: `${debugInfo.discord.version} (${debugInfo.discord.build})`,
|
||||
icon: "Discord",
|
||||
},
|
||||
{
|
||||
label: "React",
|
||||
version: debugInfo.react.version,
|
||||
icon: "ic_category_16px",
|
||||
},
|
||||
{
|
||||
label: "React Native",
|
||||
version: debugInfo.react.nativeVersion,
|
||||
icon: "mobile",
|
||||
},
|
||||
{
|
||||
label: Strings.BYTECODE,
|
||||
version: debugInfo.hermes.bytecodeVersion,
|
||||
icon: "ic_server_security_24px",
|
||||
},
|
||||
];
|
||||
|
||||
const platformInfo = [
|
||||
{
|
||||
label: Strings.LOADER,
|
||||
version: debugInfo.bunny.loader,
|
||||
icon: "ic_download_24px",
|
||||
},
|
||||
{
|
||||
label: Strings.OPERATING_SYSTEM,
|
||||
version: `${debugInfo.os.name} ${debugInfo.os.version}`,
|
||||
icon: "ic_cog_24px"
|
||||
},
|
||||
...(debugInfo.os.sdk ? [{
|
||||
label: "SDK",
|
||||
version: debugInfo.os.sdk,
|
||||
icon: "pencil"
|
||||
}] : []),
|
||||
{
|
||||
label: Strings.MANUFACTURER,
|
||||
version: debugInfo.device.manufacturer,
|
||||
icon: "ic_badge_staff"
|
||||
},
|
||||
{
|
||||
label: Strings.BRAND,
|
||||
version: debugInfo.device.brand,
|
||||
icon: "ic_settings_boost_24px"
|
||||
},
|
||||
{
|
||||
label: Strings.MODEL,
|
||||
version: debugInfo.device.model,
|
||||
icon: "ic_phonelink_24px"
|
||||
},
|
||||
{
|
||||
label: Platform.select({ android: Strings.CODENAME, ios: Strings.MACHINE_ID })!,
|
||||
version: debugInfo.device.codename,
|
||||
icon: "ic_compose_24px"
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingBottom: 38 }}>
|
||||
<Stack style={{ paddingVertical: 24, paddingHorizontal: 12 }} spacing={24}>
|
||||
<TableRowGroup title={Strings.VERSIONS}>
|
||||
{versions.map(v => <Version padding label={v.label} version={v.version} icon={v.icon} />)}
|
||||
</TableRowGroup>
|
||||
<TableRowGroup title={Strings.PLATFORM}>
|
||||
{platformInfo.map(p => <Version padding label={p.label} version={p.version} icon={p.icon} />)}
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,99 +1,47 @@
|
|||
import { Strings } from "@core/i18n";
|
||||
import Version from "@core/ui/components/Version";
|
||||
import { PyoncordIcon } from "@core/ui/settings";
|
||||
import { getAssetIDByName } from "@lib/api/assets";
|
||||
import { useProxy } from "@lib/api/storage";
|
||||
import { _toggleSafeMode, getDebugInfo } from "@lib/debug";
|
||||
import { settings } from "@lib/settings";
|
||||
import { Stack, TableRow, TableRowGroup, TableSwitchRow } from "@lib/ui/components/discord/Redesign";
|
||||
import { Stack, TableRow, TableRowGroup, TableSwitchRow, useNavigation } from "@lib/ui/components/discord/Redesign";
|
||||
import { DISCORD_SERVER, GITHUB } from "@lib/utils/constants";
|
||||
import { url } from "@metro/common";
|
||||
import { semanticColors } from "@ui/color";
|
||||
import { Summary } from "@ui/components";
|
||||
import { createStyles } from "@ui/styles";
|
||||
import { NativeModules, Platform, ScrollView } from "react-native";
|
||||
import { NativeModules, ScrollView } from "react-native";
|
||||
|
||||
const debugInfo = getDebugInfo();
|
||||
|
||||
const useStyles = createStyles({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: semanticColors.BACKGROUND_MOBILE_SECONDARY,
|
||||
}
|
||||
});
|
||||
import About from "./About";
|
||||
|
||||
export default function General() {
|
||||
const styles = useStyles();
|
||||
useProxy(settings);
|
||||
|
||||
const versions = [
|
||||
{
|
||||
label: Strings.BUNNY,
|
||||
version: debugInfo.bunny.version,
|
||||
icon: "ic_progress_wrench_24px",
|
||||
},
|
||||
{
|
||||
label: "Discord",
|
||||
version: `${debugInfo.discord.version} (${debugInfo.discord.build})`,
|
||||
icon: "Discord",
|
||||
},
|
||||
{
|
||||
label: "React",
|
||||
version: debugInfo.react.version,
|
||||
icon: "ic_category_16px",
|
||||
},
|
||||
{
|
||||
label: "React Native",
|
||||
version: debugInfo.react.nativeVersion,
|
||||
icon: "mobile",
|
||||
},
|
||||
{
|
||||
label: Strings.BYTECODE,
|
||||
version: debugInfo.hermes.bytecodeVersion,
|
||||
icon: "ic_server_security_24px",
|
||||
},
|
||||
];
|
||||
|
||||
const platformInfo = [
|
||||
{
|
||||
label: Strings.LOADER,
|
||||
version: debugInfo.bunny.loader,
|
||||
icon: "ic_download_24px",
|
||||
},
|
||||
{
|
||||
label: Strings.OPERATING_SYSTEM,
|
||||
version: `${debugInfo.os.name} ${debugInfo.os.version}`,
|
||||
icon: "ic_cog_24px"
|
||||
},
|
||||
...(debugInfo.os.sdk ? [{
|
||||
label: "SDK",
|
||||
version: debugInfo.os.sdk,
|
||||
icon: "pencil"
|
||||
}] : []),
|
||||
{
|
||||
label: Strings.MANUFACTURER,
|
||||
version: debugInfo.device.manufacturer,
|
||||
icon: "ic_badge_staff"
|
||||
},
|
||||
{
|
||||
label: Strings.BRAND,
|
||||
version: debugInfo.device.brand,
|
||||
icon: "ic_settings_boost_24px"
|
||||
},
|
||||
{
|
||||
label: Strings.MODEL,
|
||||
version: debugInfo.device.model,
|
||||
icon: "ic_phonelink_24px"
|
||||
},
|
||||
{
|
||||
label: Platform.select({ android: Strings.CODENAME, ios: Strings.MACHINE_ID })!,
|
||||
version: debugInfo.device.codename,
|
||||
icon: "ic_compose_24px"
|
||||
}
|
||||
];
|
||||
const debugInfo = getDebugInfo();
|
||||
const navigation = useNavigation();
|
||||
|
||||
return (
|
||||
<ScrollView style={styles.container}>
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingBottom: 38 }}>
|
||||
<Stack style={{ paddingVertical: 24, paddingHorizontal: 12 }} spacing={24}>
|
||||
<TableRowGroup title={Strings.INFO}>
|
||||
<TableRow
|
||||
label={Strings.BUNNY}
|
||||
icon={<TableRow.Icon source={{ uri: PyoncordIcon }} />}
|
||||
trailing={<TableRow.TrailingText text={debugInfo.bunny.version} />}
|
||||
/>
|
||||
<TableRow
|
||||
label={"Discord"}
|
||||
icon={<TableRow.Icon source={getAssetIDByName("Discord")} />}
|
||||
trailing={<TableRow.TrailingText text={`${debugInfo.discord.version} (${debugInfo.discord.build})`} />}
|
||||
/>
|
||||
<TableRow
|
||||
arrow
|
||||
label={Strings.ABOUT}
|
||||
icon={<TableRow.Icon source={getAssetIDByName("CircleInformationIcon")} />}
|
||||
trailing={TableRow.Arrow}
|
||||
onPress={() => navigation.push("VendettaCustomPage", {
|
||||
title: Strings.ABOUT,
|
||||
render: () => <About />,
|
||||
})}
|
||||
/>
|
||||
</TableRowGroup>
|
||||
<TableRowGroup title={Strings.LINKS}>
|
||||
<TableRow
|
||||
label={Strings.DISCORD_SERVER}
|
||||
|
|
@ -129,14 +77,6 @@ export default function General() {
|
|||
}}
|
||||
/>
|
||||
</TableRowGroup>
|
||||
<TableRowGroup title={Strings.INFO}>
|
||||
<Summary noPadding label={Strings.VERSIONS} icon="ic_information_filled_24px">
|
||||
{versions.map(v => <Version padding label={v.label} version={v.version} icon={v.icon} />)}
|
||||
</Summary>
|
||||
<Summary noPadding label={Strings.PLATFORM} icon="ic_mobile_device">
|
||||
{platformInfo.map(p => <Version padding label={p.label} version={p.version} icon={p.icon} />)}
|
||||
</Summary>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { Button } from "@ui/components/discord";
|
|||
|
||||
export default function Themes() {
|
||||
useProxy(settings);
|
||||
useProxy(themes);
|
||||
|
||||
return (
|
||||
<AddonPage<Theme>
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ export const createVendettaObject = (unloads: any[]): any => ({
|
|||
themes: themes.themes,
|
||||
fetchTheme: (id: string, selected?: boolean) => themes.fetchTheme(id, selected),
|
||||
installTheme: (id: string) => themes.installTheme(id),
|
||||
selectTheme: (id: string) => themes.selectTheme(id),
|
||||
selectTheme: (id: string) => themes.selectTheme(id === "default" ? null : id),
|
||||
removeTheme: (id: string) => themes.removeTheme(id),
|
||||
getCurrentTheme: () => themes._getThemeFromLoader(),
|
||||
updateThemes: () => themes.updateThemes()
|
||||
|
|
|
|||
|
|
@ -177,11 +177,13 @@ export async function installTheme(id: string) {
|
|||
await fetchTheme(id);
|
||||
}
|
||||
|
||||
export async function selectTheme(id: string) {
|
||||
export async function selectTheme(id: string | null) {
|
||||
Object.values(themes).forEach(s => s.selected = s.id === id);
|
||||
|
||||
if (id === "default") {
|
||||
if (id === null) {
|
||||
return await writeTheme({});
|
||||
} else {
|
||||
themes[id].selected = true;
|
||||
}
|
||||
|
||||
await writeTheme(themes[id]);
|
||||
|
|
@ -189,7 +191,7 @@ export async function selectTheme(id: string) {
|
|||
|
||||
export async function removeTheme(id: string) {
|
||||
const theme = themes[id];
|
||||
if (theme.selected) await selectTheme("default");
|
||||
if (theme.selected) await selectTheme(null);
|
||||
delete themes[id];
|
||||
|
||||
return theme.selected;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { findByProps } from "@lib/metro";
|
||||
import { find, findByProps } from "@lib/metro";
|
||||
import { RedesignModuleKeys } from "@lib/ui/types";
|
||||
|
||||
const findSingular = (prop: string) => find(m => m[prop] && Object.keys(m).length === 1)?.[prop];
|
||||
|
||||
export const Redesign = findByProps("TableRow") as Record<RedesignModuleKeys, any>;
|
||||
|
||||
export const CompatfulRedesign = findByProps("ActionSheetRow") as unknown as {
|
||||
|
|
@ -8,6 +10,10 @@ export const CompatfulRedesign = findByProps("ActionSheetRow") as unknown as {
|
|||
[key: string]: any;
|
||||
};
|
||||
|
||||
export const FormSwitch = findSingular("FormSwitch");
|
||||
export const FormRadio = findSingular("FormRadio");
|
||||
export const FormCheckbox = findSingular("FormCheckbox");
|
||||
|
||||
export const {
|
||||
AlertActionButton,
|
||||
AlertModal,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue