diff --git a/packages/web/components/elements/images/OmnivoreLogoBase.tsx b/packages/web/components/elements/images/OmnivoreLogoBase.tsx
index 7358001f7..94c3fae86 100644
--- a/packages/web/components/elements/images/OmnivoreLogoBase.tsx
+++ b/packages/web/components/elements/images/OmnivoreLogoBase.tsx
@@ -1,6 +1,7 @@
import Link from 'next/link'
import { useRouter } from 'next/router'
import { DEFAULT_HOME_PATH } from '../../../lib/navigations'
+import { Box } from '../LayoutPrimitives'
export type OmnivoreLogoBaseProps = {
color?: string
href?: string
@@ -9,13 +10,8 @@ export type OmnivoreLogoBaseProps = {
}
export function OmnivoreLogoBase(props: OmnivoreLogoBaseProps): JSX.Element {
- const href = props.href || '/home'
- const router = useRouter()
-
return (
-
{props.children}
-
+
)
}
diff --git a/packages/web/components/templates/settings/SettingsTable.tsx b/packages/web/components/templates/settings/SettingsTable.tsx
index 5f81689fd..e651c9294 100644
--- a/packages/web/components/templates/settings/SettingsTable.tsx
+++ b/packages/web/components/templates/settings/SettingsTable.tsx
@@ -8,8 +8,6 @@ import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives'
import { StyledText } from '../../elements/StyledText'
import { styled, theme } from '../../tokens/stitches.config'
import { SettingsLayout } from '../SettingsLayout'
-import { usePersistedState } from '../../../lib/hooks/usePersistedState'
-import { FeatureHelpBox } from '../../elements/FeatureHelpBox'
// Styles
export const Header = styled(Box, {
@@ -26,8 +24,6 @@ type SettingsTableProps = {
createTitle?: string
createAction?: () => void
- suggestionInfo: SuggestionInfo
-
children: React.ReactNode
}
@@ -63,16 +59,6 @@ type MoreOptionsProps = {
onEdit?: () => void
}
-type SuggestionInfo = {
- title: string
- message: string
- docs: string
- key: string
-
- CTAText?: string
- onClickCTA?: () => void
-}
-
const MoreOptions = (props: MoreOptionsProps) => (
{
}
export const SettingsTable = (props: SettingsTableProps): JSX.Element => {
- const [showSuggestion, setShowSuggestion] = usePersistedState({
- key: props.suggestionInfo.key,
- initialValue: !!props.suggestionInfo,
- })
-
return (
{
},
}}
>
- {props.suggestionInfo && showSuggestion && (
- {
- setShowSuggestion(false)
- }}
- helpCTAText={props.suggestionInfo.CTAText}
- onClickCTA={props.suggestionInfo.onClickCTA}
- />
- )}
{
// Don't cache the library items in local storage
const [firstKey] = queryKey
- return firstKey !== 'library-items'
+ return firstKey !== 'library-items' && firstKey !== 'shortcuts'
},
},
})
diff --git a/packages/web/pages/settings/api.tsx b/packages/web/pages/settings/api.tsx
index 721546900..d0b81d812 100644
--- a/packages/web/pages/settings/api.tsx
+++ b/packages/web/pages/settings/api.tsx
@@ -120,21 +120,6 @@ export default function Api(): JSX.Element {
setExpiresAt(neverExpiresDate)
setAddModalOpen(true)
}}
- suggestionInfo={{
- title:
- 'Use API keys to Integrate Omnivore with other apps and services',
- message:
- 'Create API keys to connect Omnivore to other apps such as Logseq and Obsidian or to query the API. Check out the integrations documentation for more info on connecting to Omnivore via the API.',
- docs: 'https://docs.omnivore.app/integrations/api.html',
- key: '--settings-apikeys-show-help',
- CTAText: 'Create an API Key',
- onClickCTA: () => {
- onAdd()
- setName('')
- setExpiresAt(neverExpiresDate)
- setAddModalOpen(true)
- },
- }}
>
{sortedApiKeys.length > 0 ? (
sortedApiKeys.map((apiKey, i) => {
diff --git a/packages/web/pages/settings/discover-feeds/index.tsx b/packages/web/pages/settings/discover-feeds/index.tsx
index c33f344df..ad7753a05 100644
--- a/packages/web/pages/settings/discover-feeds/index.tsx
+++ b/packages/web/pages/settings/discover-feeds/index.tsx
@@ -76,17 +76,6 @@ export default function DiscoverFeedsSettings(): JSX.Element {
createAction={() => {
router.push('/settings/discover-feeds/add')
}}
- suggestionInfo={{
- title: 'Add RSS and Atom feeds to your Omnivore account',
- message:
- 'When you add a new feed the last 24hrs of items, or at least one item will be added to your account. Feeds will be checked for updates every four hours, and new items will be added to your Following. You can also add feeds to your Library by checking the box below.',
- docs: 'https://docs.omnivore.app/using/feeds.html',
- key: '--settings-feeds-show-help',
- CTAText: 'Add a feed',
- onClickCTA: () => {
- router.push('/settings/discover-feeds/add')
- },
- }}
>
{sortedFeeds.length === 0 ? (
diff --git a/packages/web/pages/settings/emails/index.tsx b/packages/web/pages/settings/emails/index.tsx
index f33d6d7ee..35bcbc012 100644
--- a/packages/web/pages/settings/emails/index.tsx
+++ b/packages/web/pages/settings/emails/index.tsx
@@ -80,9 +80,8 @@ function CopyTextButton(props: CopyTextButtonProps): JSX.Element {
export default function EmailsPage(): JSX.Element {
const { emailAddresses, revalidate, isValidating } =
useGetNewsletterEmailsQuery()
- const [confirmDeleteEmailId, setConfirmDeleteEmailId] = useState<
- undefined | string
- >(undefined)
+ const [confirmDeleteEmailId, setConfirmDeleteEmailId] =
+ useState(undefined)
applyStoredTheme()
@@ -121,17 +120,6 @@ export default function EmailsPage(): JSX.Element {
headerTitle="Address"
createTitle="Create a new email address"
createAction={createEmail}
- suggestionInfo={{
- title: 'Subscribe to newsletters with an Omnivore Email Address',
- message:
- 'Create an Omnivore email address and use it to subscribe to newsletters or send yourself documents. Newsletters and documents will be categorized and added to your library when we receive a message. View all received emails with the "Recently Received Emails" link at the bottom of this page.',
- docs: 'https://docs.omnivore.app/using/inbox.html',
- key: '--settings-emails-show-help',
- CTAText: 'Create an email address',
- onClickCTA: () => {
- createEmail()
- },
- }}
>
{sortedEmailAddresses.length > 0 ? (
sortedEmailAddresses.map((email, i) => {
diff --git a/packages/web/pages/settings/emails/recent.tsx b/packages/web/pages/settings/emails/recent.tsx
index 326fa0087..3af53b761 100644
--- a/packages/web/pages/settings/emails/recent.tsx
+++ b/packages/web/pages/settings/emails/recent.tsx
@@ -151,13 +151,11 @@ const ViewRecentEmailModal = (
export default function RecentEmails(): JSX.Element {
const { recentEmails, revalidate, isValidating } = useGetRecentEmailsQuery()
- const [viewingEmailText, setViewingEmailText] = useState<
- RecentEmail | undefined
- >(undefined)
+ const [viewingEmailText, setViewingEmailText] =
+ useState(undefined)
- const [viewingEmailHtml, setViewingEmailHtml] = useState<
- RecentEmail | undefined
- >(undefined)
+ const [viewingEmailHtml, setViewingEmailHtml] =
+ useState(undefined)
applyStoredTheme()
@@ -170,14 +168,6 @@ export default function RecentEmails(): JSX.Element {
pageId="recent-emails"
pageInfoLink="https://docs.omnivore.app/using/inbox.html"
headerTitle="Recently Received Emails"
- suggestionInfo={{
- title:
- 'View original emails that have been recently received in your Omnivore inbox.',
- message:
- "Your 30 most recent emails are stored below. You can click on each email to view its original content or it's text content. If an email was not correctly classified as an article you can mark it as an article and it will be added to your library.",
- docs: 'https://docs.omnivore.app/using/inbox.html',
- key: '--settings-recent-emails-show-help',
- }}
>
{sortedRecentEmails.length > 0 ? (
sortedRecentEmails.map((recentEmail: RecentEmail, i) => {
diff --git a/packages/web/pages/settings/feeds/index.tsx b/packages/web/pages/settings/feeds/index.tsx
index 0876d7631..ebdcb860f 100644
--- a/packages/web/pages/settings/feeds/index.tsx
+++ b/packages/web/pages/settings/feeds/index.tsx
@@ -128,17 +128,6 @@ export default function Rss(): JSX.Element {
createAction={() => {
router.push('/settings/feeds/add')
}}
- suggestionInfo={{
- title: 'Add RSS and Atom feeds to your Omnivore account',
- message:
- 'When you add a new feed the last 24hrs of items, or at least one item will be added to your account. Feeds will be checked for updates every four hours, and new items will be added to your Following. You can also add feeds to your Library by checking the box below.',
- docs: 'https://docs.omnivore.app/using/feeds.html',
- key: '--settings-feeds-show-help',
- CTAText: 'Add a feed',
- onClickCTA: () => {
- router.push('/settings/feeds/add')
- },
- }}
>
{sortedSubscriptions.length === 0 ? (
diff --git a/packages/web/pages/settings/shortcuts.tsx b/packages/web/pages/settings/shortcuts.tsx
index 2d849d9d9..f42b6c792 100644
--- a/packages/web/pages/settings/shortcuts.tsx
+++ b/packages/web/pages/settings/shortcuts.tsx
@@ -10,6 +10,8 @@ import {
import { applyStoredTheme } from '../../lib/themeUpdater'
import { SettingsLayout } from '../../components/templates/SettingsLayout'
+import { NavigationLayout } from '../../components/templates/NavigationLayout'
+
import { Toaster } from 'react-hot-toast'
import {
Box,
@@ -38,185 +40,73 @@ import { useGetLabels } from '../../lib/networking/labels/useLabels'
import { useGetSavedSearches } from '../../lib/networking/savedsearches/useSavedSearches'
import {
Shortcut,
+ useGetShortcuts,
useResetShortcuts,
} from '../../lib/networking/shortcuts/useShortcuts'
-import { ShortcutsTree } from '../../components/templates/ShortcutsTree'
-import { TreeApi } from 'react-arborist'
type ListAction = 'RESET' | 'ADD_ITEM' | 'REMOVE_ITEM'
const SHORTCUTS_KEY = 'library-shortcuts'
-export default function Shortcuts(): JSX.Element {
- applyStoredTheme()
- const [navMenuStyle, setNavMenuStyle] = usePersistedState<
- 'legacy' | 'shortcuts'
- >({
- key: 'library-nav-menu-style',
- initialValue: 'legacy',
- })
+/**
+ * Use this function when you want to fix the "hydration" error in NextJS
+ * @param store
+ * @param callback
+ */
+export const useAsyncStore = (
+ store: (callback: (state: T) => unknown) => unknown,
+ callback: (state: T) => F
+) => {
+ const result = store(callback) as F
+ const [data, setData] = useState()
- const listReducer = (
- state: { state: string; items: Shortcut[] },
- action: {
- type: ListAction
- item?: Shortcut
+ useEffect(() => {
+ setData(typeof result === 'function' ? () => result : result)
+ }, [result])
+
+ return data
+}
+
+/**
+ * Use this function when you want to fix the "hydration" error in NextJS
+ * @param key
+ */
+export const useAsyncStoreValue = (key: K) => {
+ return useAsyncStore(yourContextNameHere, (state) => state[key])
+}
+
+function flattenShortcuts(shortcuts: Shortcut[]): string[] {
+ let result: string[] = []
+
+ for (const shortcut of shortcuts) {
+ if (shortcut.type !== 'folder') {
+ result.push(shortcut.id)
}
- ) => {
- switch (action.type) {
- case 'RESET': {
- const itemStr = window['localStorage'].getItem(SHORTCUTS_KEY)
- if (itemStr) {
- try {
- const parsed = JSON.parse(itemStr)
- if (Array.isArray(parsed)) {
- return { state: 'CURRENT', items: parsed as Shortcut[] }
- }
- } catch (err) {
- console.log('error: ', err)
- }
- }
- return { state: 'CURRENT', items: [] }
- }
- case 'ADD_ITEM': {
- const item = action.item
- if (!item) {
- return state
- }
- const existing = state.items.find(
- (existing) => existing.type == item.type && existing.id == item.id
- )
- if (existing) {
- return state
- }
- state.items.push(item)
- return { state: 'CURRENT', items: [...state.items] }
- }
- case 'REMOVE_ITEM': {
- const item = action.item
- if (!item) {
- return state
- }
- const updated = state.items.filter((existing) => existing.id != item.id)
- return { state: 'CURRENT', items: [...updated] }
- }
- default:
- throw new Error('unknown action')
+ if (shortcut.children && shortcut.children?.length > 0) {
+ result = result.concat(flattenShortcuts(shortcut.children))
}
}
- const [shortcuts, dispatchList] = useReducer(listReducer, {
- state: 'INITIAL',
- items: [],
- })
+ return result
+}
- useEffect(() => {
- try {
- if (shortcuts.state == 'CURRENT') {
- window['localStorage'].setItem(
- SHORTCUTS_KEY,
- JSON.stringify(shortcuts.items)
- )
- }
- } catch (error) {
- console.log('error": ', error)
+export default function Shortcuts(): JSX.Element {
+ const { data: shortcuts, isLoading } = useGetShortcuts()
+ const shortcutIds = useMemo(() => {
+ if (shortcuts) {
+ return flattenShortcuts(shortcuts)
}
+ return []
}, [shortcuts])
- useEffect(() => {
- dispatchList({ type: 'RESET' })
- }, [])
+ console.log('shortcutIds: ', shortcutIds)
return (
-
-
-
-
-
- Shortcuts
-
-
- Use shortcuts to access your most important reads quickly. You can
- create folders for your shortcuts, remove shortcuts, and select
- items from your labels, subscriptions, and saved searches to be
- added to your shortcuts.
-
-
- {
- setNavMenuStyle(
- navMenuStyle == 'shortcuts' ? 'legacy' : 'shortcuts'
- )
- event.preventDefault()
- }}
- >
-
-
-
-
-
-
+ {!isLoading &&
+ shortcutIds.map((shortcutId) => {
+ return {shortcutId}
+ })}
)
}
@@ -228,8 +118,8 @@ export const SectionSeparator = styled(Separator, {
})
type ListProps = {
- shortcuts: Shortcut[]
- dispatchList: (arg: { type: ListAction; item?: Shortcut | undefined }) => void
+ shortcutIds: string[]
+ // dispatchList: (arg: { type: ListAction; item?: Shortcut | undefined }) => void
}
const AvailableItems = (props: ListProps): JSX.Element => {
@@ -266,27 +156,29 @@ const AvailableItems = (props: ListProps): JSX.Element => {
const searchSelected = useCallback(
(search: SavedSearch) => {
- return !!props.shortcuts.find((shortcut) => shortcut.id == search.id)
+ return !!props.shortcutIds.find((shortcutId) => shortcutId == search.id)
},
[props]
)
const labelSelected = useCallback(
(label: Label) => {
- return !!props.shortcuts.find((shortcut) => shortcut.id == label.id)
+ return !!props.shortcutIds.find((shortcutId) => shortcutId == label.id)
},
[props]
)
const subscriptionSelected = useCallback(
(subscription: Subscription) => {
- return !!props.shortcuts.find(
- (shortcut) => shortcut.id == subscription.id
+ return !!props.shortcutIds.find(
+ (shortcutId) => shortcutId == subscription.id
)
},
[props]
)
+ console.log('sortedsavedSearchesL: ', sortedsavedSearches)
+
return (
{
alignment="start"
distribution="start"
>
- Available items
-
- Saved Searches
- {sortedsavedSearches?.map((search) => {
- return (
-
- )
- })}
-
-
+ {/* Available items */}
+
+
+ {/*
Labels
{sortedLabels.map((label) => {
+ console.log('label: ', label)
return (
+ })} */}
)
}
-type AvailableItemButtonProps = {
- shortcut: Shortcut
- isSelected: boolean
- listAction: (arg: { type: ListAction; item?: Shortcut | undefined }) => void
-}
+const SavedSearches = (props: ListProps) => {
+ const { data: savedSearches, isLoading } = useGetSavedSearches()
-const AvailableItemButton = (props: AvailableItemButtonProps): JSX.Element => {
- const shortcutId = `checkbox-search-${props.shortcut.id}`
- return (
-
- {props.shortcut.name}
-
- )
-}
-
-const SelectedItems = (props: ListProps): JSX.Element => {
- const treeRef = useRef | undefined>(undefined)
- const resetShortcuts = useResetShortcuts()
-
- const createNewFolder = useCallback(async () => {
- if (treeRef.current) {
- const result = await treeRef.current.create({
- type: 'internal',
- index: 0,
- })
+ const sortedsavedSearches = useMemo(() => {
+ if (!savedSearches) {
+ return []
}
- }, [treeRef])
-
+ return savedSearches.sort((a, b) =>
+ a.name.toLocaleLowerCase().localeCompare(b.name.toLocaleLowerCase())
+ )
+ }, [savedSearches])
return (
-
- Your shortcuts
-
-
-
-
- )
-}
-
-type CheckboxButtonProps = {
- itemKey: string
- title: string
- isSelected: boolean
- item: Shortcut
-
- listAction: (arg: { type: ListAction; item?: Shortcut | undefined }) => void
- children: ReactNode
-}
-
-function CheckboxButton(props: CheckboxButtonProps): JSX.Element {
- const handleChange = useCallback(
- (selected: boolean) => {
- if (!selected) {
- props.listAction({
- type: 'REMOVE_ITEM',
- item: props.item,
- })
- } else {
- props.listAction({
- type: 'ADD_ITEM',
- item: props.item,
- })
- }
- },
- [props]
- )
- return (
- {
- handleChange(!props.isSelected)
- event.preventDefault()
- }}
- >
- {props.isSelected ? (
-
- ) : (
-
- )}
- {props.children}
-
+ <>
+ {/* Saved Searches */}
+ {/* */}
+ {!isLoading &&
+ (savedSearches ?? []).map((search) => {
+ return (
+
+ {search.name}
+
+ )
+ })}
+ {/* */}
+ >
)
}
diff --git a/packages/web/pages/settings/subscriptions.tsx b/packages/web/pages/settings/subscriptions.tsx
index 321636171..8a46b87fd 100644
--- a/packages/web/pages/settings/subscriptions.tsx
+++ b/packages/web/pages/settings/subscriptions.tsx
@@ -48,13 +48,6 @@ export default function SubscriptionsPage(): JSX.Element {
pageId="settings-subscriptions-tag"
pageInfoLink="https://docs.omnivore.app/using/feeds.html"
headerTitle="Subscriptions"
- suggestionInfo={{
- title: 'View and manage all your Feed and Newsletter subscriptions',
- message:
- 'Use this page to view and manage all the Feeds (RSS & Atom) and Newsletters you have subscribed to.',
- docs: 'https://docs.omnivore.app/using/inbox.html',
- key: '--settings-recent-subscriptions-show-help',
- }}
>
<>
{sortedSubscriptions.length > 0 ? (
diff --git a/yarn.lock b/yarn.lock
index f2580e223..dbc737b2e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7575,6 +7575,13 @@
dependencies:
defer-to-connect "^1.0.1"
+"@tanstack/query-async-storage-persister@^5.51.21":
+ version "5.51.21"
+ resolved "https://registry.yarnpkg.com/@tanstack/query-async-storage-persister/-/query-async-storage-persister-5.51.21.tgz#27e6635d89e0814c65586b8047372349698c7841"
+ integrity sha512-T22f99fDKk+XrT0kCEwETNehn8gjGfdNaaYM0xRA7VvwFKUKNYETOwUQgXV6kZ+xg6LKbZeI22YsTcuYDFOx5w==
+ dependencies:
+ "@tanstack/query-persist-client-core" "5.51.21"
+
"@tanstack/query-core@5.51.21":
version "5.51.21"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.51.21.tgz#a510469c6c30d3de2a8b8798e340169a4b0fd08f"