diff --git a/apps/mobile/app/components/list/index.tsx b/apps/mobile/app/components/list/index.tsx index 6395dd3d7..19fd1c570 100644 --- a/apps/mobile/app/components/list/index.tsx +++ b/apps/mobile/app/components/list/index.tsx @@ -38,7 +38,6 @@ import { fluidTabsRef } from "../../utils/global-refs"; import { Header } from "../list-items/headers/header"; import { Empty, PlaceholderData } from "./empty"; import { ListItemWrapper } from "./list-item.wrapper"; -import { useSelectionStore } from "../../stores/use-selection-store"; type ListProps = { data: VirtualizedGrouping | undefined; diff --git a/apps/mobile/app/components/properties/items.tsx b/apps/mobile/app/components/properties/items.tsx index ae8b37713..58dc106fa 100644 --- a/apps/mobile/app/components/properties/items.tsx +++ b/apps/mobile/app/components/properties/items.tsx @@ -66,6 +66,7 @@ const COLUMN_BAR_ITEMS: ActionId[] = [ "move-notebook", "pin", "default-notebook", + "default-homepage", "add-shortcut", "reorder", "rename-color", diff --git a/apps/mobile/app/components/sheets/menu-item-properties/index.tsx b/apps/mobile/app/components/sheets/menu-item-properties/index.tsx new file mode 100644 index 000000000..57296c8cc --- /dev/null +++ b/apps/mobile/app/components/sheets/menu-item-properties/index.tsx @@ -0,0 +1,98 @@ +/* +This file is part of the Notesnook project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +import { strings } from "@notesnook/intl"; +import { useThemeColors } from "@notesnook/theme"; +import React from "react"; +import { View } from "react-native"; +import { eSendEvent, presentSheet } from "../../../services/event-manager"; +import SettingsService from "../../../services/settings"; +import { eCloseSheet } from "../../../utils/events"; +import { SideMenuItem } from "../../../utils/menu-items"; +import { AppFontSize } from "../../../utils/size"; +import { DefaultAppStyles } from "../../../utils/styles"; +import { useSideBarDraggingStore } from "../../side-menu/dragging-store"; +import AppIcon from "../../ui/AppIcon"; +import { Pressable } from "../../ui/pressable"; +import Paragraph from "../../ui/typography/paragraph"; +export const MenuItemProperties = ({ item }: { item: SideMenuItem }) => { + const { colors } = useThemeColors(); + return ( + + {[ + { + title: strings.setAsHomepage(), + onPress: () => { + SettingsService.setProperty("homepageV2", { + id: item.id, + type: "default" + }); + eSendEvent(eCloseSheet); + }, + icon: "home-outline" + }, + { + title: strings.reorder(), + onPress: () => { + useSideBarDraggingStore.setState({ + dragging: true + }); + eSendEvent(eCloseSheet); + }, + icon: "sort-ascending" + } + ].map((item) => ( + { + item.onPress(); + }} + > + + {item.title} + + ))} + + ); +}; + +MenuItemProperties.present = (item: SideMenuItem) => { + presentSheet({ + component: + }); +}; diff --git a/apps/mobile/app/components/side-menu/index.tsx b/apps/mobile/app/components/side-menu/index.tsx index 801e072ea..2ac6a0174 100644 --- a/apps/mobile/app/components/side-menu/index.tsx +++ b/apps/mobile/app/components/side-menu/index.tsx @@ -55,6 +55,7 @@ import { } from "./stores"; import { useSideBarDraggingStore } from "./dragging-store"; import { Button } from "../ui/button"; +import SettingsService from "../../services/settings"; const renderScene = SceneMap({ home: SideMenuHome, notebooks: SideMenuNotebooks, @@ -65,7 +66,9 @@ const renderScene = SceneMap({ export const SideMenu = React.memo( function SideMenu() { const { colors } = useThemeColors(); - const [index, setIndex] = React.useState(0); + const [index, setIndex] = React.useState( + SettingsService.getProperty("defaultSidebarTab") + ); const [routes] = React.useState([ { key: "home", @@ -113,7 +116,7 @@ const TabBar = ( const dragging = useSideBarDraggingStore((state) => state.dragging); const { colors, isDark } = useThemeColors(); const groupOptions = useGroupOptions( - props.navigationState.index === 1 ? "notebook" : "tags" + props.navigationState.index === 1 ? "notebooks" : "tags" ); const notebookSelectionEnabled = useSideMenuNotebookSelectionStore( (state) => state.enabled @@ -371,7 +374,7 @@ const TabBar = ( { return ( @@ -106,7 +108,10 @@ export function SideMenuHome() { title: strings.routes[ item.title as keyof typeof strings.routes - ]?.() || item.title + ]?.() || item.title, + onLongPress: () => { + MenuItemProperties.present(item); + } }} testID={item.title} index={index} diff --git a/apps/mobile/app/hooks/use-actions.tsx b/apps/mobile/app/hooks/use-actions.tsx index 64d2bc78b..2c30d7a10 100644 --- a/apps/mobile/app/hooks/use-actions.tsx +++ b/apps/mobile/app/hooks/use-actions.tsx @@ -64,6 +64,8 @@ import { eUpdateNoteInEditor } from "../utils/events"; import { deleteItems } from "../utils/functions"; import { convertNoteToText } from "../utils/note-to-text"; import { sleep } from "../utils/time"; +import SettingsService from "../services/settings"; +import { useSettingStore } from "../stores/use-setting-store"; export type ActionId = | "select" @@ -105,7 +107,8 @@ export type ActionId = | "pin-to-notifications" | "favorite" | "remove-from-notebook" - | "trash"; + | "trash" + | "default-homepage"; export type Action = { id: ActionId; @@ -155,6 +158,11 @@ export const useActions = ({ ); const [noteInCurrentNotebook, setNoteInCurrentNotebook] = useState(false); const [locked, setLocked] = useState(false); + const isHomepage = useSettingStore( + (state) => + state.settings.homepageV2?.type === item.type && + state.settings.homepageV2?.id === item.id + ); const isPublished = item.type === "note" && db.monographs.isPublished(item.id); @@ -549,6 +557,31 @@ export const useActions = ({ }); } + if ( + item.type === "notebook" || + item.type === "tag" || + item.type === "color" + ) { + actions.push({ + id: "default-homepage", + title: isHomepage ? strings.unsetAsHomepage() : strings.setAsHomepage(), + icon: "home-outline", + isToggle: true, + checked: isHomepage, + onPress: () => { + SettingsService.setProperty( + "homepageV2", + isHomepage + ? undefined + : { + id: item.id, + type: item.type + } + ); + } + }); + } + if (item.type === "note") { async function openHistory() { presentSheet({ diff --git a/apps/mobile/app/hooks/use-group-options.ts b/apps/mobile/app/hooks/use-group-options.ts index b1384fce3..e6ad2f8f2 100644 --- a/apps/mobile/app/hooks/use-group-options.ts +++ b/apps/mobile/app/hooks/use-group-options.ts @@ -21,12 +21,13 @@ import { db } from "../common/database"; import { eSubscribeEvent, eUnSubscribeEvent } from "../services/event-manager"; import Navigation from "../services/navigation"; import { eGroupOptionsUpdated } from "../utils/events"; +import { useSettingStore } from "../stores/use-setting-store"; export function useGroupOptions(type: any) { + const appLoading = useSettingStore((state) => state.isAppLoading); const [groupOptions, setGroupOptions] = useState( db.settings?.getGroupOptions(type) ); - useEffect(() => { const onUpdate = (groupType: string) => { if (groupType !== type) return; @@ -43,10 +44,15 @@ export function useGroupOptions(type: any) { }; eSubscribeEvent(eGroupOptionsUpdated, onUpdate); + + if (!appLoading) { + onUpdate(type); + } + return () => { eUnSubscribeEvent(eGroupOptionsUpdated, onUpdate); }; - }, [type, groupOptions]); + }, [type, groupOptions, appLoading]); return groupOptions; } diff --git a/apps/mobile/app/navigation/navigation-stack.tsx b/apps/mobile/app/navigation/navigation-stack.tsx index 635d441b8..be7c7bda6 100644 --- a/apps/mobile/app/navigation/navigation-stack.tsx +++ b/apps/mobile/app/navigation/navigation-stack.tsx @@ -29,6 +29,7 @@ import useNavigationStore, { import { useSelectionStore } from "../stores/use-selection-store"; import { useSettingStore } from "../stores/use-setting-store"; import { rootNavigatorRef } from "../utils/global-refs"; +import { db } from "../common/database"; const RootStack = createNativeStackNavigator(); const AppStack = createNativeStackNavigator(); @@ -46,17 +47,97 @@ let ColoredNotes: any = null; const AppNavigation = React.memo( () => { const { colors } = useThemeColors(); - const homepage = SettingsService.get().homepage; - React.useEffect(() => { - setTimeout(() => { - useNavigationStore.getState().update(homepage as keyof RouteParams); - useNavigationStore.getState().setFocusedRouteId(homepage); - }, 300); - }, [homepage]); + const [home, setHome] = React.useState<{ + name: string; + params: any; + }>(); + const homepageV2 = SettingsService.get().homepageV2; + const loading = useSettingStore((state) => state.isAppLoading); - return ( + React.useEffect(() => { + (async () => { + if (loading) return; + if (!homepageV2) { + setHome({ + name: "Notes", + params: undefined + }); + return; + } + + switch (homepageV2.type) { + case "notebook": { + const notebook = await db.notebooks.notebook(homepageV2.id); + if (notebook) { + setHome({ + name: "Notebook", + params: { + item: notebook, + id: notebook.id, + title: notebook.title + } + }); + return; + } + } + + case "color": { + const color = await db.colors.color(homepageV2.id); + if (color) { + setHome({ + name: "ColoredNotes", + params: { + item: color, + id: color.id, + title: color.title + } + }); + return; + } + + break; + } + case "tag": { + const tag = await db.tags.tag(homepageV2.id); + if (tag) { + setHome({ + name: "TaggedNotes", + params: { + item: tag, + id: tag.id, + title: tag.title + } + }); + return; + } + + break; + } + case "default": + { + setHome({ + name: homepageV2.id, + params: undefined + }); + } + return; + } + + setHome({ + name: "Notes", + params: undefined + }); + })(); + }, [homepageV2, loading]); + + React.useEffect(() => { + useNavigationStore.getState().update(home?.name as keyof RouteParams); + useNavigationStore.getState().setFocusedRouteId(home?.params?.id || home); + }, [home]); + + return !home ? null : ( - ) + ), + "sidebar-tab-selector": }; diff --git a/apps/mobile/app/screens/settings/picker/pickers.jsx b/apps/mobile/app/screens/settings/picker/pickers.jsx index bb195d04a..ad60b40b6 100644 --- a/apps/mobile/app/screens/settings/picker/pickers.jsx +++ b/apps/mobile/app/screens/settings/picker/pickers.jsx @@ -64,6 +64,25 @@ export const HomePicker = createSettingsPicker({ premium: true }); +export const SidebarTabPicker = createSettingsPicker({ + getValue: () => useSettingStore.getState().settings.defaultSidebarTab, + updateValue: (item) => { + SettingsService.set({ defaultSidebarTab: item }); + }, + formatValue: (item) => { + const SidebarTabs = [ + strings.routes.Home(), + strings.routes.Notebooks(), + strings.routes.Tags() + ]; + return SidebarTabs[item]; + }, + getItemKey: (item) => item, + options: [0, 1, 2], + compareValue: (current, item) => current === item, + premium: true +}); + export const TrashIntervalPicker = createSettingsPicker({ getValue: () => db.settings.getTrashCleanupInterval(), updateValue: (item) => { diff --git a/apps/mobile/app/screens/settings/settings-data.tsx b/apps/mobile/app/screens/settings/settings-data.tsx index 5d5c67a07..42b81709c 100644 --- a/apps/mobile/app/screens/settings/settings-data.tsx +++ b/apps/mobile/app/screens/settings/settings-data.tsx @@ -30,16 +30,12 @@ import * as RNIap from "react-native-iap"; //@ts-ignore import { enabled } from "react-native-privacy-snapshot"; import ScreenGuardModule from "react-native-screenguard"; -import { DatabaseLogger, db } from "../../common/database"; +import { db } from "../../common/database"; import filesystem from "../../common/filesystem"; import { ChangePassword } from "../../components/auth/change-password"; import { presentDialog } from "../../components/dialog/functions"; import { AppLockPassword } from "../../components/dialogs/applock-password"; -import { - endProgress, - startProgress, - updateProgress -} from "../../components/dialogs/progress"; +import { endProgress, startProgress } from "../../components/dialogs/progress"; import { ChangeEmail } from "../../components/sheets/change-email"; import ExportNotesSheet from "../../components/sheets/export-notes"; import { Issue } from "../../components/sheets/github/issue"; @@ -64,19 +60,15 @@ import Sync from "../../services/sync"; import { useThemeStore } from "../../stores/use-theme-store"; import { useUserStore } from "../../stores/use-user-store"; import { SUBSCRIPTION_STATUS } from "../../utils/constants"; -import { - eCloseSheet, - eCloseSimpleDialog, - eOpenRecoveryKeyDialog -} from "../../utils/events"; +import { eCloseSheet, eOpenRecoveryKeyDialog } from "../../utils/events"; import { NotesnookModule } from "../../utils/notesnook-module"; import { sleep } from "../../utils/time"; import { MFARecoveryCodes, MFASheet } from "./2fa"; import { useDragState } from "./editor/state"; import { verifyUser, verifyUserWithApplock } from "./functions"; +import { logoutUser } from "./logout"; import { SettingSection } from "./types"; import { getTimeLeft } from "./user-section"; -import { logoutUser } from "./logout"; export const settingsGroups: SettingSection[] = [ { @@ -639,11 +631,11 @@ export const settingsGroups: SettingSection[] = [ description: strings.behaviorDesc(), sections: [ { - id: "default-home", + id: "default-sidebar-view", type: "component", - name: strings.homepage(), - description: strings.homepageDesc(), - component: "homeselector" + name: strings.defaultSidebarTab(), + description: strings.defaultSidebarTabDesc(), + component: "sidebar-tab-selector" }, { id: "date-format", diff --git a/apps/mobile/app/stores/use-setting-store.ts b/apps/mobile/app/stores/use-setting-store.ts index b010c6bdc..30b16a8a9 100644 --- a/apps/mobile/app/stores/use-setting-store.ts +++ b/apps/mobile/app/stores/use-setting-store.ts @@ -43,6 +43,10 @@ export type Settings = { fullBackupReminder: "never" | "weekly" | "monthly"; encryptedBackup?: boolean; homepage?: string; + homepageV2?: { + id: string; + type: "notebook" | "tag" | "color" | "default"; + }; sort?: string; sortOrder?: string; screenshotMode?: boolean; @@ -93,6 +97,7 @@ export type Settings = { offlineMode?: boolean; lastFullBackupDate?: number; serverUrls?: Record; + defaultSidebarTab: number; }; type DimensionsType = { @@ -149,6 +154,7 @@ export const defaultSettings: SettingStore["settings"] = { forcePortraitOnTablet: false, useSystemTheme: true, reminder: "off", + defaultSidebarTab: 0, encryptedBackup: false, homepage: "Notes", sort: "default", diff --git a/apps/mobile/app/utils/menu-items.ts b/apps/mobile/app/utils/menu-items.ts index daa79b57a..3d1925903 100644 --- a/apps/mobile/app/utils/menu-items.ts +++ b/apps/mobile/app/utils/menu-items.ts @@ -29,6 +29,7 @@ export type SideMenuItem = { icon: string; onPress?: (item: SideMenuItem) => void; onLongPress?: (item: SideMenuItem) => void; + type: string; }; export const MenuItemsList: SideMenuItem[] = [ @@ -36,7 +37,8 @@ export const MenuItemsList: SideMenuItem[] = [ dataType: "note", id: "Notes", title: "Notes", - icon: "note-outline" + icon: "note-outline", + type: "side-menu-item" }, // { // dataType: "notebook", @@ -48,7 +50,8 @@ export const MenuItemsList: SideMenuItem[] = [ dataType: "note", id: "Favorites", title: "Favorites", - icon: "star-outline" + icon: "star-outline", + type: "side-menu-item" }, // { // dataType: "tag", @@ -60,7 +63,8 @@ export const MenuItemsList: SideMenuItem[] = [ dataType: "reminder", id: "Reminders", title: "Reminders", - icon: "bell" + icon: "bell", + type: "side-menu-item" }, { dataType: "monograph", @@ -70,7 +74,8 @@ export const MenuItemsList: SideMenuItem[] = [ onPress: () => { Navigation.closeDrawer(); Monographs.navigate(); - } + }, + type: "side-menu-item" }, // { // dataType: "note", @@ -82,6 +87,7 @@ export const MenuItemsList: SideMenuItem[] = [ dataType: "note", id: "Trash", title: "Trash", - icon: "delete-outline" + icon: "delete-outline", + type: "side-menu-item" } ]; diff --git a/packages/intl/locale/en.po b/packages/intl/locale/en.po index 97edc865f..397f314c8 100644 --- a/packages/intl/locale/en.po +++ b/packages/intl/locale/en.po @@ -4999,6 +4999,10 @@ msgstr "Reset" msgid "Reset account password" msgstr "Reset account password" +#: src/strings.ts:2467 +msgid "Reset homepage" +msgstr "Reset homepage" + #: src/strings.ts:1806 msgid "Reset selection" msgstr "Reset selection" diff --git a/packages/intl/locale/pseudo-LOCALE.po b/packages/intl/locale/pseudo-LOCALE.po index 6fe388ce7..f67e6d330 100644 --- a/packages/intl/locale/pseudo-LOCALE.po +++ b/packages/intl/locale/pseudo-LOCALE.po @@ -4973,6 +4973,10 @@ msgstr "" msgid "Reset account password" msgstr "" +#: src/strings.ts:2467 +msgid "Reset homepage" +msgstr "" + #: src/strings.ts:1806 msgid "Reset selection" msgstr "" diff --git a/packages/intl/src/strings.ts b/packages/intl/src/strings.ts index 9b4108da0..d2f980ae0 100644 --- a/packages/intl/src/strings.ts +++ b/packages/intl/src/strings.ts @@ -2463,5 +2463,6 @@ Use this if changes from other devices are not appearing on this device. This wi addNotes: () => t`Add notes`, setAsHomepage: () => t`Set as homepage`, defaultSidebarTab: () => t`Default sidebar tab`, - defaultSidebarTabDesc: () => t`Select the default sidebar tab` + defaultSidebarTabDesc: () => t`Select the default sidebar tab`, + unsetAsHomepage: () => t`Reset homepage` };