Skip to content

Commit

Permalink
fix+refactor!: polishing and fix some crashes
Browse files Browse the repository at this point in the history
  • Loading branch information
pylixonly committed Sep 7, 2024
1 parent 04a1367 commit 2259abf
Show file tree
Hide file tree
Showing 14 changed files with 83 additions and 62 deletions.
2 changes: 1 addition & 1 deletion src/core/reporter/PluginReporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default {
disableReason: createStorage<Record<string, PluginDisableReason>>("plugins/reporter/disable-reason.json"),

useReporter() {
useObservable(this.stages, this.disableReason, this.errors);
useObservable([this.stages, this.disableReason, this.errors]);
},

prepare() {
Expand Down
2 changes: 1 addition & 1 deletion src/core/storage/BunnySettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default {
},

useSettings() {
useObservable(this.general, this.developer, this.loader);
useObservable([this.general, this.developer, this.loader]);
},

isSafeMode() {
Expand Down
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 @@ -61,7 +61,7 @@ function FontPreview({ font }: { font: FontManifest; }) {
}

export default function FontCard({ item: font }: CardWrapper<FontManifest>) {
useObservable(FontManager.preferences, FontManager.traces);
useObservable([FontManager.preferences, FontManager.traces]);

const navigation = NavigationNative.useNavigation();
const selected = FontManager.preferences.selected === font.id;
Expand Down
2 changes: 1 addition & 1 deletion src/core/ui/settings/pages/Fonts/FontEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ export default function FontEditor(props: { id?: string; }) {
return Observable.from(props.id ? { ...FontManager.getManifest(props.id).main } : {});
}, [props.id]);

useObservable(fontEntries);
useObservable([fontEntries]);

const navigation = NavigationNative.useNavigation();

Expand Down
2 changes: 1 addition & 1 deletion src/core/ui/settings/pages/Fonts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import FontCard from "./FontCard";

export default function Fonts() {
BunnySettings.useSettings();
useObservable(FontManager.preferences, FontManager.traces);
useObservable([FontManager.preferences, FontManager.traces]);

const navigation = NavigationNative.useNavigation();

Expand Down
2 changes: 2 additions & 0 deletions src/core/ui/settings/pages/Plugins/components/PluginCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ export default function PluginCard({ result, item: plugin }: CardWrapper<Unified
const navigation = NavigationNative.useNavigation();
const cardContextValue = useMemo(() => ({ plugin, result }), [plugin, result]);

if (!plugin.isInstalled()) return null;

return (
<CardContext.Provider value={cardContextValue}>
<Card onPress={() => void showSheet(
Expand Down
96 changes: 53 additions & 43 deletions src/core/ui/settings/pages/Plugins/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import { showToast } from "@lib/ui/toasts";
import { lazyDestructure } from "@lib/utils/lazy";
import { findByProps } from "@metro";
import { NavigationNative } from "@metro/common";
import { Button, Card, FlashList, Text } from "@metro/common/components";
import { ComponentProps } from "react";
import { Button, Card, FlashList, Text, TwinButtons } from "@metro/common/components";
import { ComponentProps, useState } from "react";
import { View } from "react-native";

import unifyVdPlugin from "./models/vendetta";
Expand Down Expand Up @@ -68,7 +68,7 @@ export default function Plugins() {

return <PluginPage
useItems={() => {
useObservable(PluginManager.settings);
useObservable([PluginManager.settings]);
return PluginManager.getAllIds().map(id => PluginManager.getManifest(id));
}}
resolveItem={unifyVdPlugin}
Expand All @@ -77,24 +77,26 @@ export default function Plugins() {
label: "Install a plugin",
fetchFn: async (url: string) => {
if (!url.startsWith(VD_PROXY_PREFIX) && !url.startsWith(BUNNY_PROXY_PREFIX) && !BunnySettings.developer.enabled) {
openAlert("bunny-plugin-unproxied-confirmation", <AlertModal
title="Hold On!"
content="You're trying to install a plugin from an unproxied external source. This means you're trusting the creator to run their code in this app without your knowledge. Are you sure you want to continue?"
extraContent={<Card><Text variant="text-md/bold">{url}</Text></Card>}
actions={<AlertActions>
<AlertActionButton text="Continue" variant="primary" onPress={() => {
PluginManager.install(url)
.then(() => showToast(Strings.TOASTS_INSTALLED_PLUGIN, findAssetId("Check")))
.catch(e => openAlert("bunny-plugin-install-failed", <AlertModal
title="Install Failed"
content={`Unable to install plugin from '${url}':`}
extraContent={<Card><Text variant="text-md/normal">{e instanceof Error ? e.message : String(e)}</Text></Card>}
actions={<AlertActionButton text="Okay" variant="primary" />}
/>));
}} />
<AlertActionButton text="Cancel" variant="secondary" />
</AlertActions>}
/>);
openAlert("bunny-plugin-unproxied-confirmation",
<AlertModal
title="Hold On!"
content="You're trying to install a plugin from an unproxied external source. This means you're trusting the creator to run their code in this app without your knowledge. Are you sure you want to continue?"
extraContent={<Card><Text variant="text-md/bold">{url}</Text></Card>}
actions={<AlertActions>
<AlertActionButton text="Continue" variant="primary" onPress={() => {
PluginManager.install(url)
.then(() => showToast(Strings.TOASTS_INSTALLED_PLUGIN, findAssetId("Check")))
.catch(e => openAlert("bunny-plugin-install-failed", <AlertModal
title="Install Failed"
content={`Unable to install plugin from '${url}':`}
extraContent={<Card><Text variant="text-md/normal">{e instanceof Error ? e.message : String(e)}</Text></Card>}
actions={<AlertActionButton text="Okay" variant="primary" />}
/>));
}} />
<AlertActionButton text="Cancel" variant="secondary" />
</AlertActions>}
/>
);
} else {
return await PluginManager.install(url);
}
Expand All @@ -103,14 +105,15 @@ export default function Plugins() {
/>;
}
function HeaderComponent() {
const [dismissUnproxied, setDismissUnproxied] = useState(false);
const navigation = NavigationNative.useNavigation();
const unproxiedPlugins = PluginManager.getUnproxiedPlugins();

return <View style={{ marginVertical: 8, gap: 8 }}>
{PluginReporter.hasErrors() && <Card border="strong" style={{ gap: 4 }}>
<Text color="text-danger" variant="eyebrow">Error</Text>
<Text variant="heading-lg/bold">Some plugins have been disabled</Text>
<Text variant="text-md/medium">These plugins have been disabled due to an error while starting it.</Text>
<Text variant="text-md/medium">These plugins were disabled due to an error during startup.</Text>
<Button
size="md"
text="Review"
Expand All @@ -122,29 +125,36 @@ function HeaderComponent() {
});
}} />
</Card>}
{/* TODO: Consider making this dismissable */}
{!!unproxiedPlugins.length && <Card border="strong" style={{ gap: 4 }}>
{!!unproxiedPlugins.length && !dismissUnproxied && <Card border="strong" style={{ gap: 4 }}>
<Text color="text-warning" variant="eyebrow">Warning</Text>
<Text variant="heading-lg/bold">Unproxied plugins detected</Text>
<Text variant="text-md/medium">Installed plugins from unproxied sources may execute unreviewed code in this app without your knowledge.</Text>
<Button
size="md"
text="Review"
style={{ marginTop: 8 }}
onPress={() => {
navigation.push("BUNNY_CUSTOM_PAGE", {
title: "Unproxied Plugins",
render: () => {
return <FlashList
data={unproxiedPlugins}
contentContainerStyle={{ padding: 8 }}
ItemSeparatorComponent={() => <View style={{ height: 8 }} />}
renderItem={({ item: id }: any) => <Card>
<Text variant="heading-md/semibold">{id}</Text>
</Card>} />;
}
});
} } />
<Text variant="text-md/medium">Plugins installed from unproxied sources may run unreviewed code in this app without your awareness.</Text>
<View style={{ height: 8 }} />
<TwinButtons>
<Button
size="md"
text="Dismiss"
variant="secondary"
onPress={() => setDismissUnproxied(true)}
/>
<Button
size="md"
text="Review"
onPress={() => {
navigation.push("BUNNY_CUSTOM_PAGE", {
title: "Unproxied Plugins",
render: () => {
return <FlashList
data={unproxiedPlugins}
contentContainerStyle={{ padding: 8 }}
ItemSeparatorComponent={() => <View style={{ height: 8 }} />}
renderItem={({ item: id }: any) => <Card>
<Text variant="heading-md/semibold">{id}</Text>
</Card>} />;
}
});
}} />
</TwinButtons>
</Card>}
</View>;
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/ui/settings/pages/Plugins/models/vendetta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function unifyVdPlugin(manifest: BunnyPluginManifest): UnifiedPlu
isEnabled: () => PluginManager.settings[manifest.id].enabled,
isInstalled: () => Boolean(PluginManager.settings[manifest.id]),
usePluginState() {
PluginManager.usePlugins();
PluginManager.usePlugin(manifest.id);
},
toggle(start: boolean) {
start
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export default function PluginInfoActionSheet({ plugin, navigation }: PluginInfo
<Text variant="heading-xl/semibold">
{plugin.name}
</Text>
{/* BEHOLD */}
{plugin.authors && <View style={{ flexDirection: "row", gap: 8, marginTop: -4, alignItems: "center" }}>
<AvatarPile size="xxsmall" names={[plugin.authors?.map(a => typeof a !== "string" ? a.name : a)]} totalCount={plugin.authors?.length}>
{plugin.authors.filter(a => typeof a === "object").map(a => <Avatar size="xxsmall" user={findByStoreName("UserStore").getUser(a.id)} />)}
Expand Down Expand Up @@ -95,9 +96,9 @@ export default function PluginInfoActionSheet({ plugin, navigation }: PluginInfo
</View>
{PluginReporter.errors[plugin.id] && <Card style={{ gap: 8 }}>
<Text color="text-danger" variant="eyebrow">Error</Text>
<Text variant="heading-lg/semibold">An error occured while starting the plugin the last time</Text>
<Text variant="heading-md/normal">An error occured while starting the plugin.</Text>
<Codeblock selectable={true}>{String(PluginReporter.getError(plugin.id))}</Codeblock>
<Button style={{ marginTop: 4 }} text="See more" onPress={() => {}} />
{/* <Button style={{ marginTop: 4 }} text="See more" onPress={() => {}} /> */}
</Card>}
<Stack spacing={12}>
<ActionSheetRow.Group>
Expand Down
2 changes: 1 addition & 1 deletion src/core/ui/settings/pages/Themes/ThemeCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { showToast } from "@ui/toasts";
type ColorDisplayInfo = ReturnType<typeof ColorManager.getDisplayInfo>;

export default function ThemeCard({ item: theme }: CardWrapper<ColorDisplayInfo>) {
useObservable(ColorManager.preferences);
useObservable([ColorManager.preferences]);

const { authors } = theme;

Expand Down
4 changes: 2 additions & 2 deletions src/core/ui/settings/pages/Themes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { View } from "react-native";

export default function Themes() {
BunnySettings.useSettings();
useObservable(ColorManager.infos, ColorManager.preferences);
useObservable([ColorManager.infos, ColorManager.preferences]);

return (
<AddonPage<ReturnType<typeof ColorManager.getDisplayInfo>>
Expand Down Expand Up @@ -44,7 +44,7 @@ export default function Themes() {
}}
CardComponent={ThemeCard}
OptionsActionSheetComponent={() => {
useObservable(ColorManager.preferences);
useObservable([ColorManager.preferences]);

return <ActionSheet>
<BottomSheetTitleHeader title="Options" />
Expand Down
16 changes: 12 additions & 4 deletions src/lib/addons/plugins/PluginManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,15 @@ export default {
};
}
});
}
,
},

usePlugin(id: string) {
id = this.sanitizeId(id);
useObservable([this.settings, this.traces, instances], { pathsFrom: id });
},

usePlugins() {
useObservable(this.settings, this.traces, instances);
useObservable([this.settings, this.traces, instances]);
},

convertToBn(source: string, vdManifest: VendettaPlugin["manifest"]): BunnyPluginManifest {
Expand Down Expand Up @@ -375,7 +380,10 @@ export default {
autoUpdate: true
};

if (start) await this.start(manifest.id, { awaitPlugin: true, throwOnPluginError: true });
if (start) await this.start(manifest.id, {
awaitPlugin: false,
throwOnPluginError: false
});
},

async uninstall(id: string, { keepData = false } = {}) {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/addons/themes/colors/patches/background.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const { MessagesWrapper } = lazyDestructure(() => findByProps("MessagesWrapper")
export default function patchChatBackground() {
const patches = [
after("default", MessagesWrapperConnected, (_, ret) => {
useObservable(ColorManager.preferences);
useObservable([ColorManager.preferences]);
if (!_colorRef.current || ColorManager.preferences.customBackground === "hidden") return ret;

return <ImageBackground
Expand Down
6 changes: 3 additions & 3 deletions src/lib/api/storage/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// New iteration of storage API, mostly yoinked from unreleased pyoncord (and sunrise?)
import { Emitter } from "@core/vendetta/Emitter";
import { Observable } from "@gullerya/object-observer";
import { Observable, ObserverOptions } from "@gullerya/object-observer";
import { fileExists, readFile, removeFile, writeFile } from "@lib/api/native/fs";
import { RTNMMKVManager } from "@lib/api/native/rn-modules";
import { debounce } from "es-toolkit";
Expand Down Expand Up @@ -65,7 +65,7 @@ export async function migrateToNewStorage(
});
}

export function useObservable(...observables: Observable[]) {
export function useObservable(observables: Observable[], opts?: ObserverOptions) {
if (observables.some((o: any) => o?.[storageInitErrorSymbol])) throw new Error(
"An error occured while initializing the storage",
);
Expand All @@ -79,7 +79,7 @@ export function useObservable(...observables: Observable[]) {
React.useEffect(() => {
const listener = () => forceUpdate();

observables.forEach(o => Observable.observe(o, listener));
observables.forEach(o => Observable.observe(o, listener, opts));

return () => {
observables.forEach(o => Observable.unobserve(o, listener));
Expand Down

0 comments on commit 2259abf

Please sign in to comment.