diff --git a/plugins/server-drawer/src/components/DmTile.tsx b/plugins/server-drawer/src/components/DmTile.tsx new file mode 100644 index 0000000..e6a238e --- /dev/null +++ b/plugins/server-drawer/src/components/DmTile.tsx @@ -0,0 +1,45 @@ +import React from "react"; +import { View, Pressable, Image, StyleSheet } from "react-native"; +import { getAssetIDByName } from "@vendetta/ui/assets"; +import { findByProps, findByName } from "@vendetta/metro"; + +const ICON = 48; + +const ChatIcon = getAssetIDByName("ChatIcon"); +const Haptic = findByProps("triggerHapticFeedback", "HapticFeedbackTypes"); +const ChannelActions = findByProps("selectPrivateChannel"); +const SelectedChannelStore = findByName("SelectedChannelStore"); +const Flux = findByProps("useStateFromStores"); +const NavContext = findByProps("getGuildId"); +const colors = findByProps("colors", "unsafe_rawColors")?.colors; + +function openDms() { + Haptic?.triggerHapticFeedback?.(Haptic.HapticFeedbackTypes.SOFT); + if (ChannelActions?.selectPrivateChannel) { + const lastChannelId = SelectedChannelStore?.getLastSelectedChannelId?.(); + ChannelActions.selectPrivateChannel(lastChannelId); + } +} + +// Was previously only reachable via the native left server rail's own DM shortcut icon - moved +// into the drawer's own grid instead, as the first tile, so DMs live in the same place as every +// other server rather than in a spot that only exists on the rail this plugin otherwise hides. +export default function DmTile() { + const selected = Flux?.useStateFromStores?.( + [NavContext], + () => NavContext?.getGuildId?.() == null, + ) ?? false; + + return ( + + + + + + ); +} + +const st = StyleSheet.create({ + outer: { width: ICON, height: ICON }, + icon: { width: ICON, height: ICON, borderRadius: 16, alignItems: "center", justifyContent: "center" }, +}); diff --git a/plugins/server-drawer/src/components/ServerDrawerSheet.tsx b/plugins/server-drawer/src/components/ServerDrawerSheet.tsx index ca07a14..5a4dbb6 100644 --- a/plugins/server-drawer/src/components/ServerDrawerSheet.tsx +++ b/plugins/server-drawer/src/components/ServerDrawerSheet.tsx @@ -1,9 +1,12 @@ import React from "react"; import { View, Text, Pressable, Animated, Dimensions, StyleSheet, BackHandler } from "react-native"; import { find, findByProps, findByStoreName } from "@vendetta/metro"; +import { storage } from "@vendetta/plugin"; +import { useProxy } from "@vendetta/storage"; import { GuildNode } from "../utils/theme"; import GuildItem from "./GuildItem"; import FolderItem from "./FolderItem"; +import DmTile from "./DmTile"; const Flux = findByProps("useStateFromStores"); const SortedGuildStore = findByStoreName("SortedGuildStore"); @@ -54,6 +57,8 @@ function CreateJoinButton() { } export default function ServerDrawerSheet({ gestureContext }: { gestureContext: any }) { + useProxy(storage); + const pick = React.useCallback((id: string) => { Haptic?.triggerHapticFeedback(Haptic.HapticFeedbackTypes.SOFT); if (Routing?.transitionToGuild) { @@ -110,6 +115,7 @@ export default function ServerDrawerSheet({ gestureContext }: { gestureContext: style={[st.grid, { paddingHorizontal: padX, gap: GAP }]} onLayout={onLayout} > + {!storage.hideDmTile && } {nodes.map((node) => node.type === "folder" ? diff --git a/plugins/server-drawer/src/index.tsx b/plugins/server-drawer/src/index.tsx index d88cde9..e52ae20 100644 --- a/plugins/server-drawer/src/index.tsx +++ b/plugins/server-drawer/src/index.tsx @@ -5,12 +5,16 @@ import { patchGetQuestAsset } from "./patches/getQuestAsset"; import { patchExpanded, patchEmpty } from "./patches/contentPatch"; import { patchHideGuildsBar } from "./patches/hideGuildsBar"; import { patchCreateElement } from "./patches/createElementIntercept"; +import { storage } from "@vendetta/plugin"; +import Settings from "./ui/Settings"; const TAG = "[ServerDrawer]"; const cleanups: (() => void)[] = []; export default { onLoad() { + storage.hideDmTile ??= false; + console.log(TAG, "onLoad"); let patched = 0; @@ -37,4 +41,5 @@ export default { for (const fn of cleanups) fn(); cleanups.length = 0; }, + settings: Settings, }; diff --git a/plugins/server-drawer/src/ui/NoteBox.tsx b/plugins/server-drawer/src/ui/NoteBox.tsx new file mode 100644 index 0000000..50a5055 --- /dev/null +++ b/plugins/server-drawer/src/ui/NoteBox.tsx @@ -0,0 +1,29 @@ +import { React, ReactNative } from "@vendetta/metro/common"; +import { findByProps } from "@vendetta/metro"; + +const { View, Text } = ReactNative; + +const colors = findByProps("colors", "unsafe_rawColors")?.colors; + +/** Small bordered callout for explanatory text in a settings screen. */ +export default function NoteBox({ children, style }: { children: any; style?: any }) { + const textColor = colors?.TEXT_MUTED ?? colors?.TEXT_NORMAL ?? "#96989d"; + + return ( + + {children} + + ); +} diff --git a/plugins/server-drawer/src/ui/Settings.tsx b/plugins/server-drawer/src/ui/Settings.tsx new file mode 100644 index 0000000..8a3f50d --- /dev/null +++ b/plugins/server-drawer/src/ui/Settings.tsx @@ -0,0 +1,28 @@ +import { React } from "@vendetta/metro/common"; +import { storage } from "@vendetta/plugin"; +import { useProxy } from "@vendetta/storage"; +import { TableRowGroup, TableSwitchRow } from "@shared/ui/table"; +import SettingsScaffold from "@shared/ui/SettingsScaffold"; +import NoteBox from "./NoteBox"; + +export default function Settings() { + useProxy(storage); + + return ( + + + Server Drawer takes over the Quest Dock (the strip above the tab bar) to show your + servers as a grid instead - tap to expand, long-press a server for its usual context + menu, and the + button creates or joins a server through Discord's own modal. + + + { storage.hideDmTile = v; }} + /> + + + ); +}