Skip to content

Commit

Permalink
chore: merge dev to main (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
PalmDevs authored Oct 23, 2024
2 parents cc5d908 + 0502d8a commit 566feef
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 69 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# [1.3.0-dev.2](https://github.com/revenge-mod/revenge-bundle/compare/v1.3.0-dev.1...v1.3.0-dev.2) (2024-10-22)


### Bug Fixes

* wrap `addonpage` in `safeareaview` ([724fc1e](https://github.com/revenge-mod/revenge-bundle/commit/724fc1e135850d9439abcba03df1cd288ca3593b))

# [1.3.0-dev.1](https://github.com/revenge-mod/revenge-bundle/compare/v1.2.0...v1.3.0-dev.1) (2024-10-21)


### Features

* improve fonts management ux ([b30e33d](https://github.com/revenge-mod/revenge-bundle/commit/b30e33d2c6be9d5fefc26903fecbf8fcccc0df42))
* show error when failing to import font entries ([9511f17](https://github.com/revenge-mod/revenge-bundle/commit/9511f174498dfa5758ad60a2e918220a685849e0))

# [1.2.0](https://github.com/revenge-mod/revenge-bundle/compare/v1.1.2...v1.2.0) (2024-10-20)


Expand Down
44 changes: 23 additions & 21 deletions src/core/ui/components/AddonPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import isValidHttpUrl from "@lib/utils/isValidHttpUrl";
import { lazyDestructure } from "@lib/utils/lazy";
import { findByProps } from "@metro";
import { clipboard } from "@metro/common";
import { Button, FlashList, FloatingActionButton, HelpMessage, IconButton, Stack, Text, TextInput } from "@metro/common/components";
import { Button, FlashList, FloatingActionButton, HelpMessage, IconButton, SafeAreaView, Stack, Text, TextInput } from "@metro/common/components";
import { ErrorBoundary, Search } from "@ui/components";
import fuzzysort from "fuzzysort";
import { ComponentType, ReactNode, useCallback, useMemo } from "react";
Expand Down Expand Up @@ -181,26 +181,28 @@ export default function AddonPage<T extends object>({ CardComponent, ...props }:

return (
<ErrorBoundary>
<FlashList
data={results}
extraData={search}
estimatedItemSize={136}
ListHeaderComponent={headerElement}
ListEmptyComponent={() => <View style={{ gap: 12, padding: 12, alignItems: "center" }}>
<Image source={findAssetId("devices_not_found")} />
<Text variant="text-lg/semibold" color="text-normal">
Hmmm... could not find that!
</Text>
</View>}
contentContainerStyle={{ padding: 8, paddingHorizontal: 12 }}
ItemSeparatorComponent={() => <View style={{ height: 8 }} />}
ListFooterComponent={props.ListFooterComponent}
renderItem={({ item }: any) => <CardComponent item={item.obj} result={item} />}
/>
{props.installAction && <FloatingActionButton
icon={findAssetId("PlusLargeIcon")}
onPress={onInstallPress}
/>}
<SafeAreaView>
<FlashList
data={results}
extraData={search}
estimatedItemSize={136}
ListHeaderComponent={headerElement}
ListEmptyComponent={() => <View style={{ gap: 12, padding: 12, alignItems: "center" }}>
<Image source={findAssetId("devices_not_found")} />
<Text variant="text-lg/semibold" color="text-normal">
Hmmm... could not find that!
</Text>
</View>}
contentContainerStyle={{ padding: 8, paddingHorizontal: 12 }}
ItemSeparatorComponent={() => <View style={{ height: 8 }} />}
ListFooterComponent={props.ListFooterComponent}
renderItem={({ item }: any) => <CardComponent item={item.obj} result={item} />}
/>
{props.installAction && <FloatingActionButton
icon={findAssetId("PlusLargeIcon")}
onPress={onInstallPress}
/>}
</SafeAreaView>
</ErrorBoundary>
);
}
2 changes: 1 addition & 1 deletion src/core/ui/settings/pages/Fonts/FontCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export default function FontCard({ item: font }: CardWrapper<FontDefinition>) {
size="sm"
variant="secondary"
disabled={selected}
icon={findAssetId("PencilIcon")}
icon={findAssetId("WrenchIcon")}
/>
<Button
size="sm"
Expand Down
105 changes: 81 additions & 24 deletions src/core/ui/settings/pages/Fonts/FontEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,46 @@
import { formatString, Strings } from "@core/i18n";
import { createProxy, useProxy } from "@core/vendetta/storage";
import { FontDefinition, fonts, removeFont, saveFont, validateFont } from "@lib/addons/fonts";
import { FontDefinition, fonts, removeFont, saveFont, updateFont, validateFont } from "@lib/addons/fonts";
import { getCurrentTheme } from "@lib/addons/themes";
import { findAssetId } from "@lib/api/assets";
import { semanticColors } from "@lib/ui/color";
import { createStyles, TextStyleSheet } from "@lib/ui/styles";
import { safeFetch } from "@lib/utils";
import { lazyDestructure } from "@lib/utils/lazy";
import { NavigationNative } from "@metro/common";
import { ActionSheet, BottomSheetTitleHeader, Button, IconButton, Stack, TableRow, TableRowGroup, Text, TextInput } from "@metro/common/components";
import { findByPropsLazy } from "@metro/wrappers";
import { findByProps, findByPropsLazy } from "@metro/wrappers";
import { ErrorBoundary } from "@ui/components";
import { useMemo, useRef, useState } from "react";
import { ScrollView, View } from "react-native";

const useStyles = createStyles({
errorText: {
...TextStyleSheet["text-xs/medium"],
color: semanticColors.TEXT_DANGER,
},
});

const actionSheet = findByPropsLazy("hideActionSheet");
const { openAlert } = lazyDestructure(() => findByProps("openAlert", "dismissAlert"));
const { AlertModal, AlertActionButton } = lazyDestructure(() => findByProps("AlertModal", "AlertActions"));

function promptDetachConfirmationForThen(fontName: string | undefined, cb: () => void) {
if (fontName && fonts[fontName].source) openAlert("revenge-fonts-detach-source-confirmation", <AlertModal
title="Detach font pack URL?"
content="You need to detach the font pack URL from this font pack before you can manually edit its font entries. Do you want to detach the font pack URL?"
actions={
<Stack>
<AlertActionButton text="Detach" variant="destructive" onPress={() => {
delete fonts[fontName!].source;
cb();
}} />
<AlertActionButton text={Strings.CANCEL} variant="secondary" />
</Stack>
}
/>);
else cb();
};

function guessFontName(urls: string[]) {
const fileNames = urls.map(url => {
Expand Down Expand Up @@ -121,7 +150,6 @@ function JsonFontImporter({ fonts, setName, setSource }: {
.then(() => actionSheet.hideActionSheet())
.catch(e => setError(String(e)))
.finally(() => setSaving(false));

}}
/>
</View>;
Expand All @@ -130,6 +158,7 @@ function JsonFontImporter({ fonts, setName, setSource }: {
function EntryEditorActionSheet(props: {
fontEntries: Record<string, string>;
name: string;
onChange: () => void;
}) {
const [familyName, setFamilyName] = useState<string>(props.name);
const [fontUrl, setFontUrl] = useState<string>(props.fontEntries[props.name]);
Expand Down Expand Up @@ -157,6 +186,8 @@ function EntryEditorActionSheet(props: {
onPress={() => {
delete props.fontEntries[props.name];
props.fontEntries[familyName] = fontUrl;
props.onChange();
actionSheet.hideActionSheet();
}}
/>
</View>;
Expand All @@ -182,7 +213,7 @@ function promptActionSheet(
);
}

function NewEntryRow({ fontEntry }: { fontEntry: Record<string, string>; }) {
function NewEntryRow({ fontName, fontEntry }: { fontName: string | undefined, fontEntry: Record<string, string>; }) {
const nameRef = useRef<string>();
const urlRef = useRef<string>();

Expand Down Expand Up @@ -215,7 +246,7 @@ function NewEntryRow({ fontEntry }: { fontEntry: Record<string, string>; }) {
<IconButton
size="md"
variant="primary"
onPress={() => {
onPress={() => promptDetachConfirmationForThen(fontName, () => {
if (!nameSet && nameRef.current) {
setNameSet(true);
} else if (nameSet && nameRef.current && urlRef.current) {
Expand All @@ -233,7 +264,7 @@ function NewEntryRow({ fontEntry }: { fontEntry: Record<string, string>; }) {
setError(String(e));
}
}
}}
})}
icon={findAssetId(nameSet ? "PlusSmallIcon" : "ArrowLargeRightIcon")}
/>
</View>;
Expand All @@ -243,8 +274,11 @@ export default function FontEditor(props: {
name?: string;
}) {
const [name, setName] = useState<string | undefined>(props.name);
const [source, setSource] = useState<string>();
const [source, setSource] = useState<string | undefined>(props.name && fonts[props.name].source);
const [importing, setIsImporting] = useState<boolean>(false);
const [errors, setErrors] = useState<Array<Error | undefined> | undefined>();

const styles = useStyles();

const memoEntry = useMemo(() => {
return createProxy(props.name ? { ...fonts[props.name].main } : {}).proxy;
Expand All @@ -254,6 +288,8 @@ export default function FontEditor(props: {

const navigation = NavigationNative.useNavigation();

const [, forceUpdate] = React.useReducer(() => ({}), 0);

return <ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingBottom: 38 }}>
<Stack style={{ paddingVertical: 24, paddingHorizontal: 12 }} spacing={12}>
{!props.name
Expand All @@ -277,15 +313,14 @@ export default function FontEditor(props: {
label={"Refetch fonts from source"}
icon={<TableRow.Icon source={findAssetId("RetryIcon")} />}
onPress={async () => {
const ftCopy = { ...fonts[props.name!] };
await removeFont(props.name!);
await saveFont(ftCopy);
await updateFont(fonts[props.name!]);
navigation.goBack();
}}
/>
<TableRow
variant="danger"
label={"Delete font pack"}
icon={<TableRow.Icon source={findAssetId("TrashIcon")} />}
icon={<TableRow.Icon variant="danger" source={findAssetId("TrashIcon")} />}
onPress={() => removeFont(props.name!).then(() => navigation.goBack())}
/>
</TableRowGroup>}
Expand All @@ -296,32 +331,50 @@ export default function FontEditor(props: {
placeholder={"Whitney"}
onChange={setName}
/>
{props.name && fonts[props.name].source && <TextInput
size="lg"
value={source}
label="Font Pack URL"
onChange={setSource}
/>}
<TableRowGroup title="Font Entries">
{Object.entries(fontEntries).map(([name, url]) => {
{Object.entries(fontEntries).map(([name, url], index) => {
const error = errors?.[index];

return <TableRow
label={name}
subLabel={url}
trailing={<Stack spacing={2} direction="horizontal">
subLabel={error ? <Text style={styles.errorText}>{error.message}</Text> : url}
trailing={<Stack spacing={8} direction="horizontal">
<IconButton
size="sm"
variant="secondary"
icon={findAssetId("PencilIcon")}
onPress={() => promptActionSheet(EntryEditorActionSheet, fontEntries, {
name,
fontEntries,
})}
onPress={() => promptDetachConfirmationForThen(props.name, () =>
promptActionSheet(EntryEditorActionSheet, fontEntries, {
name,
fontEntries,
onChange: () => {
setErrors(undefined);
forceUpdate();
}
})
)}
/>
<IconButton
size="sm"
variant="secondary"
icon={findAssetId("TrashIcon")}
onPress={() => delete fontEntries[name]}
onPress={() => promptDetachConfirmationForThen(props.name, () => {
delete fontEntries[name];
setErrors(undefined);
})}
/>
</Stack>}
/>;
})}
<TableRow label={<NewEntryRow fontEntry={fontEntries} />} />
<TableRow label={<NewEntryRow fontName={props.name} fontEntry={fontEntries} />} />
</TableRowGroup>
{errors && <Text style={styles.errorText}>Some font entries cannot be imported. Please modify the entries and try again.</Text>}
<View style={{ flexDirection: "row", justifyContent: "flex-end", bottom: 0, left: 0 }}>
<Button
size="lg"
Expand All @@ -332,25 +385,29 @@ export default function FontEditor(props: {
onPress={async () => {
if (!name) return;

setErrors(undefined);
setIsImporting(true);

if (!props.name) {
saveFont({
spec: 1,
name: name,
main: fontEntries,
__source: source
source
})
.then(() => navigation.goBack())
.catch(e => setErrors(e))
.finally(() => setIsImporting(false));
} else {
Object.assign(fonts[props.name], {
name: name,
main: fontEntries,
__edited: true
});
setIsImporting(false);
navigation.goBack();

updateFont(fonts[props.name])
.then(() => navigation.goBack())
.catch(e => setErrors(e))
.finally(() => setIsImporting(false));
}
}}
icon={findAssetId(props.name ? "toast_image_saved" : "DownloadIcon")}
Expand Down
Loading

0 comments on commit 566feef

Please sign in to comment.