chore: mock repository manager

This commit is contained in:
pylixonly 2024-10-23 12:07:45 +08:00
parent 85c10aff12
commit 6836d23e78
3 changed files with 55 additions and 8 deletions

View file

@ -1,13 +1,15 @@
import { installPlugin, isPluginInstalled, uninstallPlugin } from "@lib/addons/plugins";
import { BunnyPluginManifest } from "@lib/addons/plugins/types";
import { findAssetId } from "@lib/api/assets";
import { showSheet } from "@lib/ui/sheets";
import { showToast } from "@lib/ui/toasts";
import { safeFetch } from "@lib/utils";
import { OFFICIAL_PLUGINS_REPO_URL } from "@lib/utils/constants";
import { Button, Card, FlashList, IconButton, Stack, Text } from "@metro/common/components";
import { NavigationNative } from "@metro/common";
import { ActionSheet, Button, Card, FlashList, IconButton, Stack, TableRow, TableRowGroup, Text } from "@metro/common/components";
import { QueryClient, QueryClientProvider, useMutation, useQuery } from "@tanstack/react-query";
import { chunk } from "es-toolkit";
import { useState } from "react";
import { useEffect, useState } from "react";
import { View } from "react-native";
const queryClient = new QueryClient();
@ -112,6 +114,51 @@ function PluginCard(props: { repoUrl: string, id: string, manifest: BunnyPluginM
}
function BrowserPage() {
const navigation = NavigationNative.useNavigation();
useEffect(() => {
navigation.setOptions({
title: "Plugin Browser",
headerRight: () => <IconButton
size="sm"
variant="secondary"
icon={findAssetId("PlusSmallIcon")}
onPress={() => {
showSheet("plugin-browser-options", () => {
return <ActionSheet>
<TableRowGroup title="Repositories">
<TableRow
label="Bunny Repository"
subLabel={OFFICIAL_PLUGINS_REPO_URL}
trailing={
<Stack direction="horizontal">
<IconButton
size="sm"
variant="secondary"
icon={findAssetId("LinkIcon")}
onPress={() => { }}
/>
<IconButton
size="sm"
variant="destructive"
disabled={true}
icon={findAssetId("TrashIcon")}
onPress={() => { }}
/>
</Stack>}
/>
<TableRow
label="Add Repository..."
icon={<TableRow.Icon source={findAssetId("PlusMediumIcon")} />}
onPress={() => { }}
/>
</TableRowGroup>
</ActionSheet>;
});
}}
/>
});
}, [navigation]);
const { data, error, isPending, refetch } = useQuery({
queryKey: ["plugins-repo-fetch"],
queryFn: () => arrayFromAsync(getManifests(OFFICIAL_PLUGINS_REPO_URL))

View file

@ -15,7 +15,7 @@ function shimDisposableFn<F extends DisposableFn>(unpatches: (() => void)[], f:
}) as F;
}
export function createBunnyPluginAPI(id: string) {
export function createBunnyPluginApi(id: string) {
const disposers = new Array<DisposableFn>;
// proxying this would be a good idea

View file

@ -5,7 +5,7 @@ import { safeFetch } from "@lib/utils";
import { OFFICIAL_PLUGINS_REPO_URL } from "@lib/utils/constants";
import { semver } from "@metro/common";
import { createBunnyPluginAPI } from "./api";
import { createBunnyPluginApi } from "./api";
import * as t from "./types";
type PluginInstantiator = (
@ -20,7 +20,7 @@ export const corePluginInstances = new Map<string, t.PluginInstanceInternal>();
export const registeredPlugins = new Map<string, t.BunnyPluginManifest>();
export const pluginInstances = new Map<string, t.PluginInstanceInternal>();
export const apiObjects = new Map<string, ReturnType<typeof createBunnyPluginAPI>>();
export const apiObjects = new Map<string, ReturnType<typeof createBunnyPluginApi>>();
export const pluginRepositories = createStorage<t.PluginRepoStorage>("plugins/repositories.json");
export const pluginSettings = createStorage<t.PluginSettingsStorage>("plugins/settings.json");
@ -270,7 +270,7 @@ export async function uninstallPlugin(id: string) {
* Starts a registered, installed, enabled and unstarted plugin. Otherwise, would throw.
* @param id The enabled plugin ID
*/
export async function startPlugin(id: string, { throwIfDisabled = false } = {}) {
export async function startPlugin(id: string, { throwIfDisabled = false, disableWhenThrown = true } = {}) {
const manifest = registeredPlugins.get(id);
assert(manifest, id, "start a non-registered plugin");
@ -297,7 +297,7 @@ export async function startPlugin(id: string, { throwIfDisabled = false } = {})
// Stage two, load the plugin
try {
const api = createBunnyPluginAPI(id);
const api = createBunnyPluginApi(id);
pluginInstance = instantiator(api.object, p => {
return Object.assign(p, {
manifest
@ -322,8 +322,8 @@ export async function startPlugin(id: string, { throwIfDisabled = false } = {})
pluginInstance.start?.();
pluginSettings[id]!.enabled = true;
} catch (error) {
disableWhenThrown && disablePlugin(id);
throw new Error("An error occured while starting the plugin", { cause: error });
// TODO: stopPlugin? disablePlugin?
}
}