From 48371b636411e27bc3453f56156f83992e9e84cd Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Thu, 22 Jun 2023 13:04:30 +0500 Subject: [PATCH] web: add toolbar settings in new settings dialog --- apps/web/src/common/dialog-controller.tsx | 6 - apps/web/src/components/dialog/index.tsx | 8 +- apps/web/src/dialogs/index.ts | 2 - .../components/customize-toolbar.tsx} | 362 +++++++++--------- .../src/dialogs/settings/editor-settings.ts | 18 + 5 files changed, 198 insertions(+), 198 deletions(-) rename apps/web/src/dialogs/{toolbar-config-dialog.tsx => settings/components/customize-toolbar.tsx} (67%) diff --git a/apps/web/src/common/dialog-controller.tsx b/apps/web/src/common/dialog-controller.tsx index 6e70c71f4..c93079a7d 100644 --- a/apps/web/src/common/dialog-controller.tsx +++ b/apps/web/src/common/dialog-controller.tsx @@ -194,12 +194,6 @@ export function showEmailChangeDialog() { )); } -export function showToolbarConfigDialog() { - return showDialog("ToolbarConfigDialog", (Dialog, perform) => ( - perform(null)} /> - )); -} - export function showError(title: string, message: string) { return confirm({ title, message, positiveButtonText: "Okay" }); } diff --git a/apps/web/src/components/dialog/index.tsx b/apps/web/src/components/dialog/index.tsx index a27de165a..ced8a3e9c 100644 --- a/apps/web/src/components/dialog/index.tsx +++ b/apps/web/src/components/dialog/index.tsx @@ -23,6 +23,7 @@ import { Loading, Close } from "../icons"; import ReactModal from "react-modal"; import { FlexScrollContainer } from "../scroll-container"; import { SxProp } from "@theme-ui/core"; +import { useStore as useThemeStore } from "../../stores/theme-store"; ReactModal.setAppElement("#root"); @@ -52,7 +53,8 @@ type DialogProps = SxProp & { }; function BaseDialog(props: React.PropsWithChildren) { - // const theme: any = useTheme(); + const theme = useThemeStore((store) => store.theme); + return ( ) { justifyContent: "stretch", position: "relative", overflow: "hidden", - boxShadow: "4px 5px 18px 2px #00000038", + boxShadow: `0px 0px 25px 5px ${ + theme === "dark" ? "#000000aa" : "#0000004e" + }`, borderRadius: "dialog", ...props.sx diff --git a/apps/web/src/dialogs/index.ts b/apps/web/src/dialogs/index.ts index c51161902..dfb6a29dd 100644 --- a/apps/web/src/dialogs/index.ts +++ b/apps/web/src/dialogs/index.ts @@ -47,7 +47,6 @@ const RecoveryCodesDialog = React.lazy( const OnboardingDialog = React.lazy(() => import("./onboarding-dialog")); const AttachmentsDialog = React.lazy(() => import("./attachments-dialog")); const Prompt = React.lazy(() => import("./prompt")); -const ToolbarConfigDialog = React.lazy(() => import("./toolbar-config-dialog")); const MigrationDialog = React.lazy(() => import("./migration-dialog")); const EmailChangeDialog = React.lazy(() => import("./email-change-dialog")); const AddTagsDialog = React.lazy(() => import("./add-tags-dialog")); @@ -55,7 +54,6 @@ const SettingsDialog = React.lazy(() => import("./settings")); export const Dialogs = { AddNotebookDialog, - ToolbarConfigDialog, BuyDialog, Confirm, Prompt, diff --git a/apps/web/src/dialogs/toolbar-config-dialog.tsx b/apps/web/src/dialogs/settings/components/customize-toolbar.tsx similarity index 67% rename from apps/web/src/dialogs/toolbar-config-dialog.tsx rename to apps/web/src/dialogs/settings/components/customize-toolbar.tsx index 6f1a3aad8..9f8976b7d 100644 --- a/apps/web/src/dialogs/toolbar-config-dialog.tsx +++ b/apps/web/src/dialogs/settings/components/customize-toolbar.tsx @@ -18,8 +18,6 @@ along with this program. If not, see . */ import { Button, Flex, FlexProps, Text } from "@theme-ui/components"; -import { Perform } from "../common/dialog-controller"; -import Dialog from "../components/dialog"; import { getAllTools, getToolDefinition, @@ -50,9 +48,9 @@ import { useEffect, useState } from "react"; import { CSS } from "@dnd-kit/utilities"; import { createPortal } from "react-dom"; import { getId } from "@notesnook/core/utils/id"; -import { Label, Radio } from "@theme-ui/components"; -import { db } from "../common/db"; -import { useToolbarConfig } from "../components/editor/context"; +import { Label } from "@theme-ui/components"; +import { db } from "../../../common/db"; +import { useToolbarConfig } from "../../../components/editor/context"; import { getAllPresets, getCurrentPreset, @@ -60,15 +58,12 @@ import { getPresetTools, Preset, PresetId -} from "../common/toolbar-config"; -import { showToast } from "../utils/toast"; -import { isUserPremium } from "../hooks/use-is-user-premium"; -import { Pro } from "../components/icons"; -export type ToolbarConfigDialogProps = { - onClose: Perform; -}; +} from "../../../common/toolbar-config"; +import { showToast } from "../../../utils/toast"; +import { isUserPremium } from "../../../hooks/use-is-user-premium"; +import { Pro } from "../../../components/icons"; -export default function ToolbarConfigDialog(props: ToolbarConfigDialogProps) { +export function CustomizeToolbar() { const sensors = useSensors( useSensor(PointerSensor), useSensor(KeyboardSensor, { @@ -89,185 +84,177 @@ export default function ToolbarConfigDialog(props: ToolbarConfigDialogProps) { setItems(items); }, [currentPreset]); + useEffect(() => { + (async () => { + const tools = unflatten(items).slice(0, -1); + + await db.settings?.setToolbarConfig("desktop", { + preset: currentPreset.id, + config: currentPreset.id === "custom" ? tools : undefined + }); + + setToolbarConfig(tools); + })(); + }, [items]); + return ( - props.onClose(false)} - positiveButton={{ - text: "Save", - onClick: async () => { - const tools = unflatten(items).slice(0, -1); - - await db.settings?.setToolbarConfig("desktop", { - preset: currentPreset.id, - config: currentPreset.id === "custom" ? tools : undefined - }); - - setToolbarConfig(tools); - props.onClose(true); - } - }} - negativeButton={{ text: "Cancel", onClick: () => props.onClose(false) }} - > - - - - {getAllPresets().map((preset) => ( - - ))} - - {currentPreset.editable && ( - - )} + { + const { value } = e.target; + if (preset.id === "custom" && !isUserPremium()) { + showToast( + "info", + "You need to be Pro to use the custom preset." + ); + return; + } + + setCurrentPreset(getPreset(value as PresetId)); + }} + /> + {preset.title} + {preset.id === "custom" && !isUserPremium() ? ( + + ) : null} + + ))} - - { - if (!isUserPremium()) { - showToast("info", "You need to be Pro to customize the toolbar."); - return; - } - - if (currentPreset.id !== "custom") { - setCurrentPreset((c) => ({ - ...getPreset("custom"), - tools: getPresetTools(c) - })); - } - - const { active } = event; - const activeItem = items.find((item) => item.id === active.id); - setActiveItem(activeItem); - }} - onDragEnd={(event) => { - const { active, over } = event; - if (activeItem && over && active.id !== over.id) { - // const newIndex = items.findIndex((i) => i.id === over.id); - if (isGroup(activeItem) || isSubgroup(activeItem)) { - setItems(moveGroup(items, activeItem.id, over.id as string)); - } else { - setItems(moveItem(items, activeItem.id, over.id as string)); - } - - setTimeout(() => { - const element = document.getElementById(over.id as string); - element?.scrollIntoView({ behavior: "auto", block: "nearest" }); - }, 500); - } - setActiveItem(undefined); - }} - measuring={{ - droppable: { strategy: MeasuringStrategy.Always } - }} - > - - {items?.map((item) => { - const deleted = isDeleted(items, item); - const hasSubGroup = - isGroup(item) && - !!getGroup(items, item.id)?.items.some((t) => isSubgroup(t)); - const canAddSubGroup = - currentPreset.editable && !deleted && !hasSubGroup; - const canRemoveGroup = currentPreset.editable && !deleted; - const canRemoveItem = currentPreset.editable && !deleted; - - return ( - { - setItems((items) => addSubGroup(items, item.id)); - showToast("success", "Subgroup added successfully"); - } - : undefined - } - onRemoveGroup={ - canRemoveGroup - ? (group) => { - setItems(removeGroup(items, group.id)); - } - : undefined - } - onRemoveItem={ - canRemoveItem - ? (item) => { - setItems(removeItem(items, item.id)); - } - : undefined - } - /> - ); - })} - {activeItem && - createPortal( - - - , - document.querySelector(".ReactModal__Overlay") || document.body - )} - - + {currentPreset.editable && ( + + )} - + + { + if (!isUserPremium()) { + showToast("info", "You need to be Pro to customize the toolbar."); + return; + } + + if (currentPreset.id !== "custom") { + setCurrentPreset((c) => ({ + ...getPreset("custom"), + tools: getPresetTools(c) + })); + } + + const { active } = event; + const activeItem = items.find((item) => item.id === active.id); + setActiveItem(activeItem); + }} + onDragEnd={(event) => { + const { active, over } = event; + if (activeItem && over && active.id !== over.id) { + // const newIndex = items.findIndex((i) => i.id === over.id); + if (isGroup(activeItem) || isSubgroup(activeItem)) { + setItems(moveGroup(items, activeItem.id, over.id as string)); + } else { + setItems(moveItem(items, activeItem.id, over.id as string)); + } + + setTimeout(() => { + const element = document.getElementById(over.id as string); + element?.scrollIntoView({ behavior: "auto", block: "nearest" }); + }, 500); + } + setActiveItem(undefined); + }} + measuring={{ + droppable: { strategy: MeasuringStrategy.Always } + }} + > + + {items?.map((item) => { + const deleted = isDeleted(items, item); + const hasSubGroup = + isGroup(item) && + !!getGroup(items, item.id)?.items.some((t) => isSubgroup(t)); + const canAddSubGroup = + currentPreset.editable && !deleted && !hasSubGroup; + const canRemoveGroup = currentPreset.editable && !deleted; + const canRemoveItem = currentPreset.editable && !deleted; + + return ( + { + setItems((items) => addSubGroup(items, item.id)); + showToast("success", "Subgroup added successfully"); + } + : undefined + } + onRemoveGroup={ + canRemoveGroup + ? (group) => { + setItems(removeGroup(items, group.id)); + } + : undefined + } + onRemoveItem={ + canRemoveItem + ? (item) => { + setItems(removeItem(items, item.id)); + } + : undefined + } + /> + ); + })} + {activeItem && + createPortal( + + + , + document.querySelector(".ReactModal__Overlay") || document.body + )} + + + ); } - type TreeNodeComponentProps = { item: TreeNode; activeItem?: TreeNode; @@ -463,7 +450,6 @@ function unflatten(items: TreeNode[]): ToolbarDefinition { const item = items[i]; if (isGroup(item) || isSubgroup(item)) { const group = getGroup(items, item.id); - console.log(group?.items); if (!group) continue; tools.push(unflatten(group.items.slice(1)) as ToolbarGroupDefinition); @@ -707,7 +693,7 @@ function addGroup(items: TreeNode[]) { return newArray; } -export function getDisabledTools(tools: TreeNode[]) { +function getDisabledTools(tools: TreeNode[]) { const allTools = getAllTools(); const disabled: ToolbarGroupDefinition = []; const items: Item[] = tools.filter((t) => isItem(t)) as Item[]; diff --git a/apps/web/src/dialogs/settings/editor-settings.ts b/apps/web/src/dialogs/settings/editor-settings.ts index ce78c467d..beead80c8 100644 --- a/apps/web/src/dialogs/settings/editor-settings.ts +++ b/apps/web/src/dialogs/settings/editor-settings.ts @@ -28,6 +28,7 @@ import { getFonts } from "@notesnook/editor"; import { useSpellChecker } from "../../hooks/use-spell-checker"; import { SpellCheckerLanguages } from "./components/spell-checker-languages"; import { isDesktop } from "../../utils/platform"; +import { CustomizeToolbar } from "./components/customize-toolbar"; export const EditorSettings: SettingsGroup[] = [ { @@ -150,5 +151,22 @@ symbols (e.g. 202305261253)`, ] } ] + }, + { + key: "toolbar", + section: "editor", + header: "Toolbar", + settings: [ + { + key: "customize-toolbar", + title: "Customize toolbar", + components: [ + { + type: "custom", + component: CustomizeToolbar + } + ] + } + ] } ];