Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
pylixonly committed Dec 26, 2024
2 parents e80ab84 + c3cbc78 commit 9a82dfe
Show file tree
Hide file tree
Showing 61 changed files with 1,507 additions and 774 deletions.
1 change: 1 addition & 0 deletions scripts/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const {

let context = null;

/** @type {import("esbuild").BuildOptions} */
const config = {
entryPoints: ["src/entry.ts"],
bundle: true,
Expand Down
2 changes: 1 addition & 1 deletion scripts/serve.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ if (args.adb && isADBAvailableAndAppInstalled()) {

if (key.name === "r") {
console.info(chalk.yellow(`${chalk.bold("↻ Reloading")} ${packageName}`));
restartAppFromADB(server.port)
restartAppFromADB(server.address().port)
.then(() => console.info(chalk.greenBright(`${chalk.bold("✔ Executed")} reload command`)))
.catch(e => console.error(e));
}
Expand Down
17 changes: 17 additions & 0 deletions src/core/debug/safeMode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { getCurrentTheme, writeThemeToNative } from "@lib/addons/themes";
import { BundleUpdaterManager } from "@lib/api/native/modules";
import { settings } from "@lib/api/settings";

export function isSafeMode() {
return settings.safeMode?.enabled === true;
}

export async function toggleSafeMode({
to = !isSafeMode(),
reload = true
} = {}) {
const enabled = (settings.safeMode ??= { enabled: to }).enabled = to;
const currentColor = getCurrentTheme();
await writeThemeToNative(enabled ? {} : currentColor?.data ?? {});
if (reload) setTimeout(() => BundleUpdaterManager.reload(), 500);
}
53 changes: 34 additions & 19 deletions src/core/ui/components/AddonPage.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import { CardWrapper } from "@core/ui/components/AddonCard";
import { useProxy } from "@core/vendetta/storage";
import { findAssetId } from "@lib/api/assets";
import { settings } from "@lib/api/settings";
import AlertModal, { AlertActionButton } from "@lib/ui/components/wrappers/AlertModal";
import { dismissAlert, openAlert } from "@lib/ui/alerts";
import { showSheet } from "@lib/ui/sheets";
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, useSafeAreaInsets } from "@metro/common/components";
import { clipboard, NavigationNative } from "@metro/common";
import { AlertActionButton, AlertModal, Button, FlashList, FloatingActionButton, HelpMessage, IconButton, Stack, Text, TextInput, useSafeAreaInsets } from "@metro/common/components";
import { ErrorBoundary, Search } from "@ui/components";
import { isNotNil } from "es-toolkit";
import fuzzysort from "fuzzysort";
import { ComponentType, ReactNode, useCallback, useMemo } from "react";
import { ComponentType, ReactNode, useCallback, useEffect, useMemo } from "react";
import { Image, ScrollView, View } from "react-native";

const { showSimpleActionSheet, hideActionSheet } = lazyDestructure(() => findByProps("showSimpleActionSheet"));
const { openAlert, dismissAlert } = lazyDestructure(() => findByProps("openAlert", "dismissAlert"));

type SearchKeywords = Array<string | ((obj: any & {}) => string)>;
type SearchKeywords<T> = Array<string | ((obj: T & {}) => string)>;

interface AddonPageProps<T extends object, I = any> {
title: string;
items: I[];
searchKeywords: SearchKeywords;
sortOptions?: Record<string, (a: I, b: I) => number>;
searchKeywords: SearchKeywords<T>;
sortOptions?: Record<string, (a: T, b: T) => number>;
resolveItem?: (value: I) => T | undefined;
safeModeHint?: {
message?: string;
Expand All @@ -34,6 +34,9 @@ interface AddonPageProps<T extends object, I = any> {
fetchFn?: (url: string) => Promise<void>;
onPress?: () => void;
};

OptionsActionSheetComponent?: ComponentType<any>;

CardComponent: ComponentType<CardWrapper<T>>;
ListHeaderComponent?: ComponentType<any>;
ListFooterComponent?: ComponentType<any>;
Expand All @@ -55,7 +58,7 @@ function InputAlert(props: { label: string, fetchFn: (url: string) => Promise<vo

return <AlertModal
title={props.label}
content="Enter the URL of the source you want to install from:"
content="Type in the source URL you want to install from:"
extraContent={
<Stack style={{ marginTop: -12 }}>
<TextInput
Expand Down Expand Up @@ -107,16 +110,28 @@ function InputAlert(props: { label: string, fetchFn: (url: string) => Promise<vo
}

export default function AddonPage<T extends object>({ CardComponent, ...props }: AddonPageProps<T>) {
useProxy(settings);

const [search, setSearch] = React.useState("");
const [sortFn, setSortFn] = React.useState<((a: unknown, b: unknown) => number) | null>(() => null);
const [sortFn, setSortFn] = React.useState<((a: T, b: T) => number) | null>(() => null);
const { bottom: bottomInset } = useSafeAreaInsets();
const navigation = NavigationNative.useNavigation();

useEffect(() => {
if (props.OptionsActionSheetComponent) {
navigation.setOptions({
headerRight: () => <IconButton
size="sm"
variant="secondary"
icon={findAssetId("MoreHorizontalIcon")}
onPress={() => showSheet("AddonMoreSheet", props.OptionsActionSheetComponent!)}
/>
});
}
}, [navigation]);

const results = useMemo(() => {
let values = props.items;
if (props.resolveItem) values = values.map(props.resolveItem);
const items = values.filter(i => i && typeof i === "object");
if (props.resolveItem) values = values.map(props.resolveItem).filter(isNotNil);
const items = values.filter(i => isNotNil(i) && typeof i === "object");
if (!search && sortFn) items.sort(sortFn);

return fuzzysort.go(search, items, { keys: props.searchKeywords, all: true });
Expand All @@ -135,7 +150,7 @@ export default function AddonPage<T extends object>({ CardComponent, ...props }:
if (results.length === 0 && !search) {
return <View style={{ gap: 32, flexGrow: 1, justifyContent: "center", alignItems: "center" }}>
<View style={{ gap: 8, alignItems: "center" }}>
<Image source={findAssetId("empty_quick_switcher")} />
<Image source={findAssetId("empty_quick_switcher")!} />
<Text variant="text-lg/semibold" color="text-normal">
Oops! Nothing to see here… yet!
</Text>
Expand Down Expand Up @@ -176,7 +191,7 @@ export default function AddonPage<T extends object>({ CardComponent, ...props }:
})}
/>}
</View>
{props.ListHeaderComponent && !search && <props.ListHeaderComponent />}
{props.ListHeaderComponent && <props.ListHeaderComponent />}
</View>
);

Expand All @@ -188,12 +203,12 @@ export default function AddonPage<T extends object>({ CardComponent, ...props }:
estimatedItemSize={136}
ListHeaderComponent={headerElement}
ListEmptyComponent={() => <View style={{ gap: 12, padding: 12, alignItems: "center" }}>
<Image source={findAssetId("devices_not_found")} />
<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 }}
contentContainerStyle={{ padding: 8, paddingHorizontal: 12, paddingBottom: 90 }}
ItemSeparatorComponent={() => <View style={{ height: 8 }} />}
ListFooterComponent={props.ListFooterComponent}
renderItem={({ item }: any) => <CardComponent item={item.obj} result={item} />}
Expand Down
2 changes: 1 addition & 1 deletion src/core/ui/hooks/useFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export enum CheckState {
export function useFileExists(path: string, prefix?: string): [CheckState, typeof fs] {
const [state, setState] = useState<CheckState>(CheckState.LOADING);

const check = () => fs.fileExists(path, prefix)
const check = () => fs.fileExists(path, { prefix })
.then(exists => setState(exists ? CheckState.TRUE : CheckState.FALSE))
.catch(() => setState(CheckState.ERROR));

Expand Down
6 changes: 4 additions & 2 deletions src/core/ui/settings/pages/Developer/AssetBrowser.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import AssetDisplay from "@core/ui/settings/pages/Developer/AssetDisplay";
import { assetsMap } from "@lib/api/assets";
import { iterateAssets } from "@lib/api/assets";
import { LegacyFormDivider } from "@metro/common/components";
import { ErrorBoundary, Search } from "@ui/components";
import { useMemo } from "react";
import { FlatList, View } from "react-native";

export default function AssetBrowser() {
const [search, setSearch] = React.useState("");
const all = useMemo(() => Array.from(iterateAssets()), []);

return (
<ErrorBoundary>
Expand All @@ -15,7 +17,7 @@ export default function AssetBrowser() {
onChangeText={(v: string) => setSearch(v)}
/>
<FlatList
data={Object.values(assetsMap).filter(a => a.name.includes(search) || a.id.toString() === search)}
data={all.filter(a => a.name.includes(search) || a.id.toString() === search)}
renderItem={({ item }) => <AssetDisplay asset={item} />}
ItemSeparatorComponent={LegacyFormDivider}
keyExtractor={item => item.name}
Expand Down
23 changes: 12 additions & 11 deletions src/core/ui/settings/pages/General/About.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Strings } from "@core/i18n";
import { PyoncordIcon } from "@core/ui/settings";
import Version from "@core/ui/settings/pages/General/Version";
import { useProxy } from "@core/vendetta/storage";
import { getDebugInfo } from "@lib/api/debug";
Expand All @@ -14,7 +15,7 @@ export default function About() {
{
label: Strings.BUNNY,
version: debugInfo.bunny.version,
icon: "ic_progress_wrench_24px",
icon: { uri: PyoncordIcon },
},
{
label: "Discord",
Expand All @@ -24,55 +25,55 @@ export default function About() {
{
label: "React",
version: debugInfo.react.version,
icon: "ic_category_16px",
icon: "ScienceIcon",
},
{
label: "React Native",
version: debugInfo.react.nativeVersion,
icon: "mobile",
icon: "MobilePhoneIcon",
},
{
label: Strings.BYTECODE,
version: debugInfo.hermes.bytecodeVersion,
icon: "ic_server_security_24px",
icon: "TopicsIcon",
},
];

const platformInfo = [
{
label: Strings.LOADER,
version: `${debugInfo.bunny.loader.name} (${debugInfo.bunny.loader.version})`,
icon: "ic_download_24px",
icon: "DownloadIcon",
},
{
label: Strings.OPERATING_SYSTEM,
version: `${debugInfo.os.name} ${debugInfo.os.version}`,
icon: "ic_cog_24px"
icon: "ScreenIcon"
},
...(debugInfo.os.sdk ? [{
label: "SDK",
version: debugInfo.os.sdk,
icon: "pencil"
icon: "StaffBadgeIcon"
}] : []),
{
label: Strings.MANUFACTURER,
version: debugInfo.device.manufacturer,
icon: "ic_badge_staff"
icon: "WrenchIcon"
},
{
label: Strings.BRAND,
version: debugInfo.device.brand,
icon: "ic_settings_boost_24px"
icon: "SparklesIcon"
},
{
label: Strings.MODEL,
version: debugInfo.device.model,
icon: "ic_phonelink_24px"
icon: "MobilePhoneIcon"
},
{
label: Platform.select({ android: Strings.CODENAME, ios: Strings.MACHINE_ID })!,
version: debugInfo.device.codename,
icon: "ic_compose_24px"
icon: "TagIcon"
}
];

Expand Down
5 changes: 3 additions & 2 deletions src/core/ui/settings/pages/General/Version.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ import { findAssetId } from "@lib/api/assets";
import { clipboard } from "@metro/common";
import { LegacyFormText, TableRow } from "@metro/common/components";
import { showToast } from "@ui/toasts";
import { ImageURISource } from "react-native";

interface VersionProps {
label: string;
version: string;
icon: string;
icon: string | ImageURISource;
}

export default function Version({ label, version, icon }: VersionProps) {
return (
<TableRow
label={label}
icon={<TableRow.Icon source={findAssetId(icon)} />}
icon={<TableRow.Icon source={typeof icon === "string" ? findAssetId(icon) : icon} />}
trailing={<LegacyFormText>{version}</LegacyFormText>}
onPress={() => {
clipboard.setString(`${label} - ${version}`);
Expand Down
Loading

0 comments on commit 9a82dfe

Please sign in to comment.