From c168237fc97bcf34353d6bf391f360cbccdbed84 Mon Sep 17 00:00:00 2001 From: pylixonly <82711525+pylixonly@users.noreply.github.com> Date: Sat, 16 Nov 2024 23:01:18 +0800 Subject: [PATCH] feat(ui/plugins): Bunny plugin sheet impl --- .../pages/Plugins/components/PluginCard.tsx | 38 +++--- src/core/ui/settings/pages/Plugins/index.tsx | 16 +-- .../ui/settings/pages/Plugins/models/bunny.ts | 10 +- .../ui/settings/pages/Plugins/models/index.ts | 23 ++++ .../settings/pages/Plugins/models/vendetta.ts | 5 +- .../Plugins/sheets/PluginInfoActionSheet.tsx | 117 +++++++++++++----- .../pages/Plugins/sheets/TitleComponent.tsx | 57 +++++++++ .../pages/Plugins/usePluginCardStyles.ts | 12 ++ src/lib/addons/plugins/index.ts | 1 + src/metro/common/components.ts | 1 + src/metro/common/types/components.ts | 18 +++ 11 files changed, 234 insertions(+), 64 deletions(-) create mode 100644 src/core/ui/settings/pages/Plugins/models/index.ts create mode 100644 src/core/ui/settings/pages/Plugins/sheets/TitleComponent.tsx diff --git a/src/core/ui/settings/pages/Plugins/components/PluginCard.tsx b/src/core/ui/settings/pages/Plugins/components/PluginCard.tsx index a13330e..81ce732 100644 --- a/src/core/ui/settings/pages/Plugins/components/PluginCard.tsx +++ b/src/core/ui/settings/pages/Plugins/components/PluginCard.tsx @@ -1,4 +1,5 @@ import { CardWrapper } from "@core/ui/components/AddonCard"; +import { UnifiedPluginModel } from "@core/ui/settings/pages/Plugins/models"; import { usePluginCardStyles } from "@core/ui/settings/pages/Plugins/usePluginCardStyles"; import { findAssetId } from "@lib/api/assets"; import { NavigationNative, tokens } from "@metro/common"; @@ -8,8 +9,6 @@ import chroma from "chroma-js"; import { createContext, useContext, useMemo } from "react"; import { Image, View } from "react-native"; -import { UnifiedPluginModel } from ".."; - const CardContext = createContext<{ plugin: UnifiedPluginModel, result: Fuzzysort.KeysResult; }>(null!); const useCardContext = () => useContext(CardContext); @@ -50,6 +49,8 @@ function Title() { function Authors() { const { plugin, result } = useCardContext(); + const styles = usePluginCardStyles(); + if (!plugin.authors) return null; // could be empty if the author(s) are irrelevant with the search! @@ -59,24 +60,23 @@ function Authors() { ); - if (highlightedNode.length > 0) return ( - - by {highlightedNode} - + const badges = plugin.getBadges(); + const authorText = highlightedNode.length > 0 ? highlightedNode : plugin.authors.map(a => a.name).join(", "); + + return ( + + + by {authorText} + + {badges.length > 0 && + {badges.map((b, i) => )} + } + ); - - const children = ["by "]; - - for (const author of plugin.authors) { - children.push(typeof author === "string" ? author : author.name); - children.push(", "); - } - - children.pop(); - - return - {children} - ; } function Description() { diff --git a/src/core/ui/settings/pages/Plugins/index.tsx b/src/core/ui/settings/pages/Plugins/index.tsx index da2c11c..81a7f51 100644 --- a/src/core/ui/settings/pages/Plugins/index.tsx +++ b/src/core/ui/settings/pages/Plugins/index.tsx @@ -17,24 +17,10 @@ import { Button, Card, FlashList, IconButton, Text } from "@metro/common/compone import { ComponentProps } from "react"; import { View } from "react-native"; +import { UnifiedPluginModel } from "./models"; import unifyBunnyPlugin from "./models/bunny"; import unifyVdPlugin from "./models/vendetta"; -export interface UnifiedPluginModel { - id: string; - name: string; - description?: string; - authors?: Author[]; - icon?: string; - - isEnabled(): boolean; - usePluginState(): void; - isInstalled(): boolean; - toggle(start: boolean): void; - resolveSheetComponent(): Promise<{ default: React.ComponentType; }>; - getPluginSettingsComponent(): React.ComponentType | null | undefined; -} - const { openAlert } = lazyDestructure(() => findByProps("openAlert", "dismissAlert")); const { AlertModal, AlertActions, AlertActionButton } = lazyDestructure(() => findByProps("AlertModal", "AlertActions")); diff --git a/src/core/ui/settings/pages/Plugins/models/bunny.ts b/src/core/ui/settings/pages/Plugins/models/bunny.ts index 713307c..5f4d9e5 100644 --- a/src/core/ui/settings/pages/Plugins/models/bunny.ts +++ b/src/core/ui/settings/pages/Plugins/models/bunny.ts @@ -1,8 +1,9 @@ +import { PyoncordIcon } from "@core/ui/settings"; import { disablePlugin, enablePlugin, getPluginSettingsComponent, isPluginEnabled, pluginSettings } from "@lib/addons/plugins"; import { BunnyPluginManifest } from "@lib/addons/plugins/types"; import { useObservable } from "@lib/api/storage"; -import { UnifiedPluginModel } from ".."; +import { UnifiedPluginModel } from "."; export default function unifyBunnyPlugin(manifest: BunnyPluginManifest): UnifiedPluginModel { return { @@ -10,6 +11,13 @@ export default function unifyBunnyPlugin(manifest: BunnyPluginManifest): Unified name: manifest.display.name, description: manifest.display.description, authors: manifest.display.authors, + + getBadges() { + return [ + { source: { uri: PyoncordIcon } }, + // { source: findAssetId("CheckmarkLargeBoldIcon")! } + ]; + }, isEnabled: () => isPluginEnabled(manifest.id), isInstalled: () => manifest.id in pluginSettings, usePluginState() { diff --git a/src/core/ui/settings/pages/Plugins/models/index.ts b/src/core/ui/settings/pages/Plugins/models/index.ts new file mode 100644 index 0000000..43375e9 --- /dev/null +++ b/src/core/ui/settings/pages/Plugins/models/index.ts @@ -0,0 +1,23 @@ +import { Author } from "@lib/addons/types"; +import { ImageSourcePropType } from "react-native"; + +interface Badge { + source: ImageSourcePropType; + color?: string; + onPress?: () => void; +} + +export interface UnifiedPluginModel { + id: string; + name: string; + description?: string; + authors?: Author[]; + icon?: string; + getBadges(): Badge[]; + isEnabled(): boolean; + usePluginState(): void; + isInstalled(): boolean; + toggle(start: boolean): void; + resolveSheetComponent(): Promise<{ default: React.ComponentType; }>; + getPluginSettingsComponent(): React.ComponentType | null | undefined; +} diff --git a/src/core/ui/settings/pages/Plugins/models/vendetta.ts b/src/core/ui/settings/pages/Plugins/models/vendetta.ts index 0c573e9..ee735f5 100644 --- a/src/core/ui/settings/pages/Plugins/models/vendetta.ts +++ b/src/core/ui/settings/pages/Plugins/models/vendetta.ts @@ -1,7 +1,7 @@ import { VdPluginManager, VendettaPlugin } from "@core/vendetta/plugins"; import { useProxy } from "@core/vendetta/storage"; -import { UnifiedPluginModel } from ".."; +import { UnifiedPluginModel } from "."; export default function unifyVdPlugin(vdPlugin: VendettaPlugin): UnifiedPluginModel { return { @@ -11,6 +11,9 @@ export default function unifyVdPlugin(vdPlugin: VendettaPlugin): UnifiedPluginMo authors: vdPlugin.manifest.authors, icon: vdPlugin.manifest.vendetta?.icon, + getBadges() { + return []; + }, isEnabled: () => vdPlugin.enabled, isInstalled: () => Boolean(vdPlugin && VdPluginManager.plugins[vdPlugin.id]), usePluginState() { diff --git a/src/core/ui/settings/pages/Plugins/sheets/PluginInfoActionSheet.tsx b/src/core/ui/settings/pages/Plugins/sheets/PluginInfoActionSheet.tsx index 2a60a02..145b3f2 100644 --- a/src/core/ui/settings/pages/Plugins/sheets/PluginInfoActionSheet.tsx +++ b/src/core/ui/settings/pages/Plugins/sheets/PluginInfoActionSheet.tsx @@ -1,45 +1,106 @@ +import { startPlugin } from "@lib/addons/plugins"; import { findAssetId } from "@lib/api/assets"; import { hideSheet } from "@lib/ui/sheets"; -import { ActionSheet, Button, Text } from "@metro/common/components"; +import { ActionSheet, Card, ContextMenu, IconButton, Text } from "@metro/common/components"; +import { ComponentProps } from "react"; import { ScrollView, View } from "react-native"; import { PluginInfoActionSheetProps } from "./common"; +import TitleComponent from "./TitleComponent"; + +function PluginInfoIconButton(props: ComponentProps) { + const { onPress } = props; + props.onPress &&= () => { + hideSheet("PluginInfoActionSheet"); + onPress?.(); + }; + + return ; +} export default function PluginInfoActionSheet({ plugin, navigation }: PluginInfoActionSheetProps) { plugin.usePluginState(); return - - - - - {plugin.name} - - - {plugin.description} - - - - {plugin.getPluginSettingsComponent() &&