Skip to content

Commit fa78e83

Browse files
author
Mukul Mehta
authored
Templated Notes; User Preference Synced with Cloud; Add Last Opened to Preferences (#257)
#257 * Add support for templated notes * User preference store; Add last opened store * Add extra check in getParentPathFromNode in useAnalysis * Add theme to broadcast; Use asyncLocalStorage in extension userPreferenceStore * Add smartCaptureExcludedFields to getUserPreferences store call * Add smartCaptureExcludedFields to API call * Add changeset * Change SidebarListItem defaultItems to array
1 parent 5d3b13f commit fa78e83

39 files changed

+763
-264
lines changed

.changeset/wet-dogs-shave.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'mexit': patch
3+
'mexit-webapp': patch
4+
---
5+
6+
Templated Notes; User Preferences Sync with Cloud

apps/extension/src/Hooks/useRaju.ts

+4-9
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import { useEffect } from 'react'
33
import { addMinutes } from 'date-fns'
44
import { connectToChild, Methods } from 'penpal'
55

6-
import { useAuthStore as useDwindleAuthStore } from '@workduck-io/dwindle'
7-
86
import {
97
Contents,
108
idxKey,
@@ -21,8 +19,7 @@ import {
2119
UserDetails,
2220
WorkspaceDetails,
2321
Link,
24-
Description,
25-
Highlighted
22+
Description
2623
} from '@mexit/core'
2724
import { Theme } from '@mexit/shared'
2825

@@ -34,12 +31,12 @@ import { useLinkStore } from '../Stores/useLinkStore'
3431
import { useRecentsStore } from '../Stores/useRecentsStore'
3532
import { useReminderStore } from '../Stores/useReminderStore'
3633
import { useSputlitStore } from '../Stores/useSputlitStore'
34+
import { useUserPreferenceStore } from '../Stores/userPreferenceStore'
3735
import { getElementById, styleSlot } from '../contentScript'
3836
import { useAuthStore } from './useAuth'
3937
import useInternalAuthStore from './useAuthStore'
4038
import { useReminders } from './useReminders'
4139
import { useSnippets } from './useSnippets'
42-
import useThemeStore from './useThemeStore'
4340

4441
export interface ParentMethods {
4542
SEARCH: (key: idxKey | idxKey[], query: string) => Promise<any>
@@ -64,11 +61,9 @@ export default function useRaju() {
6461
// For some reason, using useState wasn't making dispatch() make use of the new variable
6562
// So added in the context for now
6663
const setChild = useSputlitStore((s) => s.setChild)
67-
const setTheme = useThemeStore((store) => store.setTheme)
64+
const setTheme = useUserPreferenceStore((store) => store.setTheme)
6865
const setAuthenticated = useAuthStore((store) => store.setAuthenticated)
6966
const setInternalAuthStore = useInternalAuthStore((store) => store.setAllStore)
70-
const setUserPool = useDwindleAuthStore((store) => store.setUserPool)
71-
const setUserCred = useDwindleAuthStore((store) => store.setUserCred)
7267
const initContents = useContentStore((store) => store.initContents)
7368
const setIlinks = useDataStore((store) => store.setIlinks)
7469
const setNamespaces = useDataStore((store) => store.setNamespaces)
@@ -121,7 +116,7 @@ export default function useRaju() {
121116
bootAuth(userDetails: UserDetails, workspaceDetails: WorkspaceDetails) {
122117
setAuthenticated(userDetails, workspaceDetails)
123118
},
124-
bootTheme(theme: Theme) {
119+
bootTheme(theme: string) {
125120
setTheme(theme)
126121
},
127122
bootDwindle(authAWS: { userPool; userCred }) {

apps/extension/src/Hooks/useThemeStore.ts

-10
This file was deleted.

apps/extension/src/Stores/userPreferenceStore.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import create from 'zustand'
22
import { devtools, persist } from 'zustand/middleware'
33

4-
import { IDBStorage } from '@mexit/core'
54
import { preferenceStoreConstructor, UserPreferenceStore } from '@mexit/shared'
65

6+
import { asyncLocalStorage } from '../Utils/chromeStorageAdapter'
7+
78
export const USER_PREF_STORE_KEY = 'mex-user-preference-store'
89

910
export const useUserPreferenceStore = create<UserPreferenceStore>(
10-
persist(devtools(preferenceStoreConstructor, { name: 'User Preferences' }), {
11+
persist(devtools(preferenceStoreConstructor, { name: 'User Preferences Extensions' }), {
1112
name: USER_PREF_STORE_KEY,
12-
getStorage: () => IDBStorage,
13+
getStorage: () => asyncLocalStorage,
1314
onRehydrateStorage: () => (state) => {
1415
state?.setHasHydrated(true)
1516
}

apps/extension/src/index.tsx

+15-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react'
1+
import React, { useMemo } from 'react'
22

33
import { ThemeProvider } from 'styled-components'
44

@@ -16,14 +16,23 @@ import { TooltipPortal } from './Components/Tooltip/TooltipPortal'
1616
import { EditorProvider } from './Hooks/useEditorContext'
1717
import { HighlighterProvider } from './Hooks/useHighlighterContext'
1818
import { SputlitProvider } from './Hooks/useSputlitContext'
19-
import useThemeStore from './Hooks/useThemeStore'
19+
import { useUserPreferenceStore } from './Stores/userPreferenceStore'
2020
import { GlobalStyle } from './Styles/GlobalStyle'
2121

22-
export default function Index() {
23-
const theme = useThemeStore((state) => state.theme)
22+
const Providers: React.FC<{ children: React.ReactNode }> = ({ children }) => {
23+
const theme = useUserPreferenceStore((state) => state.theme)
24+
25+
const themeData = useMemo(() => {
26+
const ctheme = defaultThemes.find((t) => t.id === theme)
27+
return ctheme ? ctheme.themeData : defaultThemes[0].themeData
28+
}, [theme])
2429

30+
return <ThemeProvider theme={themeData}>{children}</ThemeProvider>
31+
}
32+
33+
export default function Index() {
2534
return (
26-
<ThemeProvider theme={theme?.themeData ?? defaultThemes[0].themeData}>
35+
<Providers>
2736
<GlobalStyle />
2837
<ReminderArmer />
2938
<SputlitProvider>
@@ -49,6 +58,6 @@ export default function Index() {
4958
</EditorProvider>
5059
</HighlighterProvider>
5160
</SputlitProvider>
52-
</ThemeProvider>
61+
</Providers>
5362
)
5463
}

apps/webapp/src/App.tsx

+15-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect } from 'react'
1+
import React, { useMemo } from 'react'
22

33
import { BrowserRouter as Router } from 'react-router-dom'
44
import { ThemeProvider } from 'styled-components'
@@ -11,16 +11,25 @@ import Init from './Components/Init'
1111
import Main from './Components/Main'
1212
import Modals from './Components/Modals'
1313
import './Stores'
14-
import useThemeStore from './Stores/useThemeStore'
14+
import { useUserPreferenceStore } from './Stores/userPreferenceStore'
1515
import GlobalStyle from './Style/GlobalStyle'
1616
import Switch from './Switch'
1717

18-
function App() {
19-
const theme = useThemeStore((state) => state.theme)
18+
const Providers: React.FC<{ children: React.ReactNode }> = ({ children }) => {
19+
const theme = useUserPreferenceStore((state) => state.theme)
2020

21+
const themeData = useMemo(() => {
22+
const ctheme = defaultThemes.find((t) => t.id === theme)
23+
return ctheme ? ctheme.themeData : defaultThemes[0].themeData
24+
}, [theme])
25+
26+
return <ThemeProvider theme={themeData}>{children}</ThemeProvider>
27+
}
28+
29+
const App = () => {
2130
return (
2231
<Router>
23-
<ThemeProvider theme={theme?.themeData ?? defaultThemes[0].themeData}>
32+
<Providers>
2433
<Init />
2534
<Main>
2635
<Modals />
@@ -29,7 +38,7 @@ function App() {
2938
<FloatingButton />
3039
<Notification />
3140
</Main>
32-
</ThemeProvider>
41+
</Providers>
3342
</Router>
3443
)
3544
}

apps/webapp/src/Components/Chotu.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ import { useLinkStore } from '../Stores/useLinkStore'
1818
import { useRecentsStore } from '../Stores/useRecentsStore'
1919
import { useReminderStore } from '../Stores/useReminderStore'
2020
import { useSnippetStore } from '../Stores/useSnippetStore'
21-
import useThemeStore from '../Stores/useThemeStore'
21+
import { useUserPreferenceStore } from '../Stores/userPreferenceStore'
2222
import { initSearchIndex, searchWorker } from '../Workers/controller'
2323

2424
export default function Chotu() {
2525
const [parent, setParent] = useState<any>(null)
2626
const { userDetails, workspaceDetails } = useAuthStore()
27-
const theme = useThemeStore((state) => state.theme)
27+
const theme = useUserPreferenceStore((store) => store.theme)
2828
const snippets = useSnippetStore((store) => store.snippets)
2929
const reminders = useReminderStore((store) => store.reminders)
3030
const descriptions = useDescriptionStore((store) => store.descriptions)

apps/webapp/src/Components/Editor/ContentEditor.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { useComboboxOpen } from '../../Editor/Hooks/useComboboxOpen'
1414
import { useApi } from '../../Hooks/API/useNodeAPI'
1515
import { useKeyListener } from '../../Hooks/useChangeShortcutListener'
1616
import { useEditorBuffer } from '../../Hooks/useEditorBuffer'
17+
import { useLastOpened } from '../../Hooks/useLastOpened'
1718
import useLayout from '../../Hooks/useLayout'
1819
import useLoad from '../../Hooks/useLoad'
1920
import { usePermissions, isReadonly } from '../../Hooks/usePermissions'
@@ -48,7 +49,7 @@ const ContentEditor = () => {
4849
const infobar = useLayoutStore((store) => store.infobar)
4950

5051
const editorWrapperRef = useRef<HTMLDivElement>(null)
51-
// const { debouncedAddLastOpened } = useLastOpened()
52+
const { debouncedAddLastOpened } = useLastOpened()
5253

5354
const { addOrUpdateValBuffer, getBufferVal, saveAndClearBuffer } = useEditorBuffer()
5455
const nodeid = useParams()?.nodeId
@@ -68,7 +69,7 @@ const ContentEditor = () => {
6869
async (val: any[]) => {
6970
if (val && nodeid !== '__null__') {
7071
addOrUpdateValBuffer(nodeid, val)
71-
// debouncedAddLastOpened(node.nodeid)
72+
debouncedAddLastOpened(nodeid)
7273
}
7374
},
7475
[nodeid]

apps/webapp/src/Components/Init.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useAuth } from '@workduck-io/dwindle'
55
import { addIconsToIconify } from '@mexit/shared'
66

77
import { useInitLoader } from '../Hooks/useInitLoader'
8+
import { useAutoSyncUserPreference } from '../Hooks/useSyncUserPreferences'
89
import config from '../config'
910

1011
const Init = () => {
@@ -30,6 +31,7 @@ const Init = () => {
3031
}, [])
3132

3233
useInitLoader()
34+
useAutoSyncUserPreference()
3335

3436
return null
3537
}

apps/webapp/src/Components/Modals.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import PreviewNoteModal from './PreviewNoteModal'
1010
import Delete from './Refactor/DeleteModal'
1111
import CreateReminderModal from './Reminders/CreateReminderModal'
1212
import TaskViewModal from './TaskViewModal'
13+
import TemplateModal from './Template/TemplateModal'
1314

1415
const Modals = () => {
1516
const isAuthenticated = useAuthStore((store) => store.authenticated)
@@ -28,6 +29,7 @@ const Modals = () => {
2829
<TaskViewModal />
2930
<PreviewNoteModal />
3031
<FleetContainer />
32+
<TemplateModal />
3133
</>
3234
)
3335
}

apps/webapp/src/Components/Sidebar/SharedNotes/index.tsx

+6-6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { useRouting, ROUTE_PATHS, NavigationType } from '../../../Hooks/useRouti
1111
import { useDataStore } from '../../../Stores/useDataStore'
1212
import { useEditorStore } from '../../../Stores/useEditorStore'
1313
import SidebarList, { SidebarListItem } from '../SidebarList'
14+
import { MuteMenuItem } from '../TreeWithContextMenu'
1415

1516
export const ItemContent = styled.div`
1617
cursor: pointer;
@@ -29,11 +30,9 @@ interface SharedNoteContextMenuProps {
2930

3031
const SharedNoteContextMenu = ({ item }: SharedNoteContextMenuProps) => {
3132
return (
32-
<>
33-
<ContextMenuContent>
34-
{/* <MuteMenuItem lastOpenedState={item?.lastOpenedState} nodeid={item.id} /> */}
35-
</ContextMenuContent>
36-
</>
33+
<ContextMenuContent>
34+
<MuteMenuItem lastOpenedState={item?.lastOpenedState} nodeid={item.id} />
35+
</ContextMenuContent>
3736
)
3837
}
3938

@@ -53,6 +52,7 @@ const SharedNotes = () => {
5352

5453
return sharedNodes.length > 0 ? (
5554
<SidebarList
55+
noMargin
5656
items={sharedNodes.map((node) => ({
5757
id: node.nodeid,
5858
label: node.path,
@@ -70,7 +70,7 @@ const SharedNotes = () => {
7070
) : (
7171
<Centered>
7272
<SharedNodeIcon height={64} width={64} fill={theme.colors.text.default} margin="0 0 1rem 0" />
73-
<span>No one has shared Notes with you yet!</span>
73+
<span>No one has shared Notes with you yet HAHAHAHA!</span>
7474
</Centered>
7575
)
7676
}

apps/webapp/src/Components/Sidebar/SidebarList.tsx

+8-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import React, { useEffect, useState } from 'react'
1+
import { useEffect, useRef, useState, ChangeEventHandler } from 'react'
22

33
import searchLine from '@iconify/icons-ri/search-line'
44
import { Icon, IconifyIcon } from '@iconify/react'
55
import Tippy, { useSingleton } from '@tippyjs/react'
66
import { debounce } from 'lodash'
77
import { useTheme } from 'styled-components'
88

9-
import { MexIcon } from '@workduck-io/mex-components'
109
import { tinykeys } from '@workduck-io/tinykeys'
1110

1211
import { fuzzySearch, mog } from '@mexit/core'
@@ -59,6 +58,7 @@ export interface SidebarListProps<T> {
5958
showSearch?: boolean
6059
searchPlaceholder?: string
6160
emptyMessage?: string
61+
noMargin?: boolean
6262
}
6363

6464
const SidebarList = ({
@@ -69,7 +69,8 @@ const SidebarList = ({
6969
defaultItems,
7070
showSearch,
7171
searchPlaceholder,
72-
emptyMessage
72+
emptyMessage,
73+
noMargin
7374
}: SidebarListProps<any>) => {
7475
const [contextOpenViewId, setContextOpenViewId] = useState<string>(null)
7576
const [search, setSearch] = useState('')
@@ -79,11 +80,10 @@ const SidebarList = ({
7980

8081
const [source, target] = useSingleton()
8182

82-
const theme = useTheme()
83-
const inputRef = React.useRef<HTMLInputElement>(null)
83+
const inputRef = useRef<HTMLInputElement>(null)
8484
const expandSidebar = useLayoutStore((store) => store.expandSidebar)
8585

86-
const onSearchChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
86+
const onSearchChange: ChangeEventHandler<HTMLInputElement> = (e) => {
8787
setSearch(e.target.value)
8888
}
8989

@@ -95,7 +95,6 @@ const SidebarList = ({
9595
if (inpEl) inpEl.value = ''
9696
setContextOpenViewId(null)
9797
}
98-
9998
const onSelectItem = (id: string) => {
10099
setSelected(-1)
101100
setContextOpenViewId(null)
@@ -114,7 +113,6 @@ const SidebarList = ({
114113
}
115114
}
116115
}, [search, showSearch, items])
117-
118116
useEffect(() => {
119117
if (inputRef.current) {
120118
const unsubscribe = tinykeys(inputRef.current, {
@@ -173,7 +171,7 @@ const SidebarList = ({
173171
}, [])
174172

175173
return (
176-
<SidebarListWrapper>
174+
<SidebarListWrapper noMargin={noMargin}>
177175
<Tippy theme="mex" placement="right" singleton={source} />
178176

179177
{defaultItems &&
@@ -189,15 +187,14 @@ const SidebarList = ({
189187
))}
190188

191189
{showSearch && items.length > 0 && (
192-
<SidebarListFilter>
190+
<SidebarListFilter noMargin={noMargin}>
193191
<Icon icon={searchLine} />
194192
<Input
195193
placeholder={searchPlaceholder ?? 'Filter items'}
196194
onChange={debounce((e) => onSearchChange(e), 250)}
197195
ref={inputRef}
198196
// onKeyUp={debounce(onKeyUpSearch, 250)}
199197
/>
200-
<MexIcon noHover fontSize="1.2rem" icon="bi:slash-square-fill" color={theme.colors.text.disabled} />
201198
</SidebarListFilter>
202199
)}
203200

0 commit comments

Comments
 (0)