diff --git a/common/components.ts b/common/components.ts deleted file mode 100644 index f6d0052..0000000 --- a/common/components.ts +++ /dev/null @@ -1,120 +0,0 @@ -/* eslint-disable prefer-destructuring */ -import { lazyDestructure, proxyLazy } from "@lib/utils/lazy"; -import { createFilterDefinition } from "@metro/factories"; -import { findExports } from "@metro/finders"; -import { findByDisplayNameLazy, findByNameLazy, findByProps, findByPropsLazy } from "@metro/wrappers"; - -import * as t from "./types/components"; - -const bySingularProp = createFilterDefinition<[string]>( - ([prop], m) => m[prop] && Object.keys(m).length === 1, - prop => `bunny.metro.common.components.bySingularProp(${prop})` -); - -const findSingular = (prop: string) => proxyLazy(() => findExports(bySingularProp(prop))?.[prop]); -const findProp = (...props: string[]) => proxyLazy(() => findByProps(...props)[props[0]]); - -// Discord -export const LegacyAlert = findByDisplayNameLazy("FluxContainer(Alert)"); -export const CompatButton = findByPropsLazy("Looks", "Colors", "Sizes"); -export const HelpMessage = findByNameLazy("HelpMessage"); - -// React Native's included SafeAreaView only adds padding on iOS. -export const { SafeAreaView, SafeAreaProvider, useSafeAreaInsets } = lazyDestructure(() => findByProps("useSafeAreaInsets")); - -// ActionSheet -export const ActionSheetRow = findProp("ActionSheetRow"); - -// Buttons -export const Button = findSingular("Button") as t.Button; -export const TwinButtons = findProp("TwinButtons") as t.TwinButtons; -export const IconButton = findSingular("IconButton") as t.IconButton; -export const RowButton = findProp("RowButton") as t.RowButton; - -export const PressableScale = findProp("PressableScale"); - -// Tables -export const TableRow = findProp("TableRow") as t.TableRow; -export const TableRowIcon = findProp("TableRowIcon") as t.TableRowIcon; -export const TableRowTrailingText = findProp("TableRowTrailingText") as t.TableRowTrailingText; -export const TableRowGroup = findProp("TableRowGroup") as t.TableRowGroup; -export const TableRadioGroup = findProp("TableRadioGroup") as t.TableRadioGroup; -export const TableRadioRow = findProp("TableRadioRow") as t.TableRadioRow; -export const TableSwitchRow = findProp("TableSwitchRow") as t.TableSwitchRow; -export const TableCheckboxRow = findProp("TableCheckboxRow") as t.TableCheckboxRow; - -export const TableSwitch = findSingular("FormSwitch"); -export const TableRadio = findSingular("FormRadio"); -export const TableCheckbox = findSingular("FormCheckbox"); - -export const FormSwitch = findSingular("FormSwitch"); -export const FormRadio = findSingular("FormRadio"); -export const FormCheckbox = findSingular("FormCheckbox"); - -// Card -export const Card = findProp("Card"); -export const RedesignCompat = proxyLazy(() => findByProps("RedesignCompat").RedesignCompat); - -// Alert -export const AlertModal = findProp("AlertModal"); -export const AlertActionButton = findProp("AlertActionButton"); -export const AlertActions = findProp("AlertActions"); - -// Pile -export const AvatarPile = findSingular("AvatarPile"); - -// Misc. -export const ContextMenu = findProp("ContextMenu") as t.ContextMenu; -export const Stack = findProp("Stack") as t.Stack; -export const Avatar = findProp("default", "AvatarSizes", "getStatusSize"); - - -// Inputs -export const TextInput = findSingular("TextInput") as t.TextInput; -export const TextArea = findSingular("TextArea"); - -// SegmentedControl -export const SegmentedControl = findProp("SegmentedControl") as t.SegmentedControl; -export const SegmentedControlPages = findProp("SegmentedControlPages") as t.SegmentedControlPages; -export const useSegmentedControlState = findSingular("useSegmentedControlState") as (arg: t.SegmentedControlStateArgs) => t.SegmentedControlState; -export const CompatSegmentedControl = findProp("CompatSegmentedControl") as t.CompatSegmentedControl; - -export const FloatingActionButton = findProp("FloatingActionButton") as t.FloatingActionButton; -export const ActionSheet = findProp("ActionSheet") as t.ActionSheet; -export const BottomSheetTitleHeader = findProp("BottomSheetTitleHeader"); - -const textsModule = findByPropsLazy("Text", "LegacyText"); -export const Text = proxyLazy(() => textsModule.Text) as t.Text; - -export const Forms = findByPropsLazy("Form", "FormSection"); - -export const { - Form: LegacyForm, - FormArrow: LegacyFormArrow, - FormCTA: LegacyFormCTA, - FormCTAButton: LegacyFormCTAButton, - FormCardSection: LegacyFormCardSection, - FormCheckbox: LegacyFormCheckbox, - FormCheckboxRow: LegacyFormCheckboxRow, - FormCheckmark: LegacyFormCheckmark, - FormDivider: LegacyFormDivider, - FormHint: LegacyFormHint, - FormIcon: LegacyFormIcon, - FormInput: LegacyFormInput, - FormLabel: LegacyFormLabel, - FormRadio: LegacyFormRadio, - FormRadioGroup: LegacyFormRadioGroup, - FormRadioRow: LegacyFormRadioRow, - FormRow: LegacyFormRow, - FormSection: LegacyFormSection, - FormSelect: LegacyFormSelect, - FormSliderRow: LegacyFormSliderRow, - FormSubLabel: LegacyFormSubLabel, - FormSwitch: LegacyFormSwitch, - FormSwitchRow: LegacyFormSwitchRow, - FormTernaryCheckBox: LegacyFormTernaryCheckBox, - FormText: LegacyFormText, - FormTitle: LegacyFormTitle -} = lazyDestructure(() => Forms); - -export const FlashList = findProp("FlashList"); diff --git a/common/index.ts b/common/index.ts deleted file mode 100644 index e374aa0..0000000 --- a/common/index.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { lazyDestructure } from "@lib/utils/lazy"; -import { findByFilePathLazy, findByProps, findByPropsLazy } from "@metro/wrappers"; -import { Linking } from "react-native"; -import type { Dispatcher } from "./types/flux"; - -export * as components from "./components"; - -// Discord -export const constants = findByPropsLazy("Fonts", "Permissions"); -export const channels = findByPropsLazy("getVoiceChannelId"); -export const i18n = findByPropsLazy("Messages"); - -export const clipboard = findByPropsLazy("setString", "getString", "hasString"); -export const assets = findByPropsLazy("registerAsset"); -export const invites = findByPropsLazy("acceptInviteAndTransitionToInviteChannel"); -export const commands = findByPropsLazy("getBuiltInCommands"); -export const navigation = findByPropsLazy("pushLazy"); -export const toasts = findByFilePathLazy("modules/toast/native/ToastActionCreators.tsx", true); -export const messageUtil = findByPropsLazy("sendBotMessage"); -export const navigationStack = findByPropsLazy("createStackNavigator"); -export const NavigationNative = findByPropsLazy("NavigationContainer"); -export const semver = findByPropsLazy("parse", "clean"); - -export const tokens = findByPropsLazy("unsafe_rawColors", "colors"); -export const { useToken } = lazyDestructure(() => findByProps("useToken")); - -// Polyfill LinkingUtils - -const openURL = (url: string) => Linking.openURL(url); -export const url = nativeModuleProxy.NativeLinkingModule || nativeModuleProxy.DCDLinkingManager ? { - openURL, - openDeeplink: openURL, - handleSupportedURL: openURL, - isDiscordConnectOauth2Deeplink: () => { - console.warn("url.isDiscordConnectOauth2Deeplink is not implemented and will always return false"); - return false; - }, - showLongPressUrlActionSheet: () => console.warn("url.showLongPressUrlActionSheet is not implemented"), - handleMessageLinking: findByFilePathLazy("modules/links/native/handleContentLinking.tsx", true), -} : findByPropsLazy("openURL", "openDeeplink"); - -// Flux -export const Flux = findByPropsLazy("connectStores"); -// TODO: Making this a proxy/lazy fuck things up for some reason -export const FluxDispatcher = findByProps("_interceptors") as Dispatcher; -export const FluxUtils = findByProps("useStateFromStores"); - -// React -export const React = window.React = findByPropsLazy("createElement") as typeof import("react"); -export const ReactNative = window.ReactNative = findByPropsLazy("AppRegistry") as typeof import("react-native"); diff --git a/common/stores.ts b/common/stores.ts deleted file mode 100644 index bef2ebf..0000000 --- a/common/stores.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { findByStoreNameLazy } from "@metro/wrappers"; - -export const UserStore = findByStoreNameLazy("UserStore"); diff --git a/common/types/components.ts b/common/types/components.ts deleted file mode 100644 index 254fa34..0000000 --- a/common/types/components.ts +++ /dev/null @@ -1,265 +0,0 @@ -import { Nullish } from "@lib/utils/types"; -import { TextStyles, ThemeColors } from "@ui/types"; -import { Falsey } from "lodash"; -import { FC, MutableRefObject, PropsWithoutRef, ReactNode, RefObject } from "react"; -import type * as RN from "react-native"; -import { ImageSourcePropType, PressableProps } from "react-native"; -import { SharedValue } from "react-native-reanimated"; -import { LiteralUnion } from "type-fest"; - -// Abandon all hope, ye who enter here -type Style = RN.ViewStyle & RN.ImageStyle & RN.TextStyle; - -type InteractiveSize = "sm" | "md" | "lg"; - -// Buttons -type ButtonVariant = "primary" | "secondary" | "tertiary" | "destructive" | "active"; - -interface ButtonProps { - disabled?: boolean; - onPress: () => void; - loading?: boolean; - variant?: LiteralUnion; - text?: string; - size?: LiteralUnion; - iconPosition?: "start" | "end"; - scaleAmountInPx?: number; - icon?: ImageSourcePropType | ReactNode; - style?: Style; - grow?: boolean; -} - -export type Button = React.ForwardRefExoticComponent; - -interface TwinButtonsProps { - children: ReactNode; -} - -export type TwinButtons = React.ComponentType; - -// Segmented Control -interface SegmentedControlItem { - id: string; - label: string; - page?: JSX.Element | null; -} - -export interface SegmentedControlStateArgs { - items: SegmentedControlItem[]; - pageWidth: number; - defaultIndex?: number; -} - -export interface SegmentedControlState { - activeIndex: SharedValue; - pagerRef: RefObject; - scrollTarget: SharedValue; - scrollOverflow: SharedValue; - scrollOffset: SharedValue; - items: SegmentedControlItem[]; - itemDimensions: SharedValue; - pageWidth: number; - pressedIndex: SharedValue; - onPageChangeRef: MutableRefObject; // { current: undefined } - setActiveIndex: (index: number) => void; - setItemDimensions: (index: number, dimensions: unknown[]) => void; - useReducedMotion: boolean; -} - -interface SegmentedControlProps { - state: SegmentedControlState; - variant?: string; -} - -export type SegmentedControl = React.FC; - -interface SegmentedControlPagesProps { - state: SegmentedControlState; -} - -export type SegmentedControlPages = React.FC; - -interface CompatSegmentedControlProps { - values: string[]; - selectedSegmentIndex?: number; - onValueChange?: (index: number) => void; - onSetActiveIndex?: (index: number) => void; -} - -export type CompatSegmentedControl = React.FC; - -// TODO: Confirm if this is real -interface TextInputProps extends Omit { - defaultValue?: string; - description?: string; - editable?: boolean; - errorMessage?: string; - focusable?: boolean; - grow?: boolean; - isCentered?: boolean; - isClearable?: boolean; - isDisabled?: boolean; - isRound?: boolean; - label?: string; - leadingIcon?: React.FC; - leadingPressableProps?: PressableProps; - leadingText?: string; - onChange?: (text: string) => void; - size?: "sm" | "md" | "lg"; - state?: "error" | "default"; - style?: Style; - trailingIcon?: React.FC; - trailingPressableProps?: PressableProps; - trailingText?: string; - value?: string | Nullish; -} - -export type TextInput = React.FC; - -interface RowButtonProps { - variant?: LiteralUnion; - style?: Style; - icon?: ImageSourcePropType | ReactNode; - label: string | ReactNode; - subLabel?: string | ReactNode; - onPress: () => void; - disabled?: boolean; -} - -export type RowButton = React.FC; - -interface StackProps { - /** defaults to vertical */ - direction?: "vertical" | "horizontal"; - /** defaults to 8 */ - spacing?: number; -} - -export type Stack = React.FC & RN.ViewProps>; - -interface FABProps { - icon: ImageSourcePropType | ReactNode; - style?: Style; - onPress: () => void; - positionBottom?: number; -} - -export type FloatingActionButton = React.FC; - -interface ActionSheetProps { - scrollable?: boolean; -} - -export type ActionSheet = React.FC>; - -type TextProps = React.ComponentProps & { - variant?: TextStyles; - color?: ThemeColors; - lineClamp?: number; - maxFontSizeMultiplier?: number; - style?: RN.TextStyle; -}; - -export type Text = React.FC; - -interface IconButtonProps { - label?: string; - icon: ImageSourcePropType | ReactNode; - onPress: () => void; - disabled?: boolean; - size?: InteractiveSize; - variant?: ButtonVariant; - style?: Style; -} - -export type IconButton = React.FC; - -export type PressableScale = React.FC>; - -interface TableRowBaseProps { - arrow?: boolean; - label: string | ReactNode; - subLabel?: string | ReactNode; - variant?: LiteralUnion<"danger", string>; - icon?: JSX.Element | Falsey; - disabled?: boolean; - trailing?: ReactNode | React.ComponentType; -} - -interface TableRowProps extends TableRowBaseProps { - onPress?: () => void; -} - -export type TableRow = React.FC & { - Icon: TableRowIcon; - TrailingText: TableRowTrailingText; - Arrow: FC<{}>; -}; - -interface TableRowTrailingTextProps { - text: string; -} - -export type TableRowTrailingText = FC; - -interface TableRowIconProps { - style?: RN.ImageStyle; - variant?: LiteralUnion<"danger", string>, - source: ImageSourcePropType | undefined; -} - -export type TableRowIcon = React.FC; - -interface TableRowGroupProps { - title: string; - children: ReactNode; -} - -export type TableRowGroup = React.FC; - -interface TableRadioGroupProps { - title: string; - value: string; - hasIcons?: boolean; - onChange: (type: T) => void; - children: ReactNode; -} - -export type TableRadioGroup = FC; - -interface TableRadioRowProps extends TableRowBaseProps { - value: string; -} - -export type TableRadioRow = FC; - -interface TableSwitchRowProps extends TableRowBaseProps { - value: boolean; - onValueChange: (value: boolean) => void; -} - -export type TableSwitchRow = FC; - -interface TableCheckboxRowProps extends TableRowBaseProps { - checked: boolean; - onPress: () => void; -} - -export type TableCheckboxRow = FC; - -interface ContextMenuItem { - label: string; - variant?: LiteralUnion<"destructive", string>; - iconSource?: number; - action: () => unknown; -} - -interface ContextMenuProps { - triggerOnLongPress?: boolean; - items: ContextMenuItem[] | ContextMenuItem[][]; - align?: "left" | "right" | "above" | "below" | "auto" | null; - title?: string; - children: React.FC>; -} - -export type ContextMenu = FC; diff --git a/common/types/flux.ts b/common/types/flux.ts deleted file mode 100644 index fb414d0..0000000 --- a/common/types/flux.ts +++ /dev/null @@ -1,18 +0,0 @@ -export interface Dispatcher { - _actionHandlers: unknown; - _interceptors?: ((payload: any) => void | boolean)[]; - _currentDispatchActionType: undefined | string; - _processingWaitQueue: boolean; - _subscriptions: Record void>>; - _waitQueue: unknown[]; - - addDependencies(node1: any, node2: any): void; - dispatch(payload: any): Promise; - flushWaitQueue(): void; - isDispatching(): boolean; - register(name: string, actionHandler: Record void>, storeDidChange: (e: any) => boolean): string; - setInterceptor(interceptor?: (payload: any) => void | boolean): void; - subscribe(actionType: string, callback: (payload: any) => void): void; - unsubscribe(actionType: string, callback: (payload: any) => void): void; - wait(cb: () => void): void; -}