From 68e6585d39fe5aee2a7f17d49763e825212a47fd Mon Sep 17 00:00:00 2001 From: colmugx Date: Tue, 15 Oct 2024 10:27:16 +0800 Subject: [PATCH] feat(integration): add omnivore support (#909) --- .../src/atoms/settings/integration.ts | 10 +++ .../ui/platform-icon/collections/omnivore.tsx | 12 ++++ .../src/components/ui/platform-icon/icons.ts | 1 + .../src/hooks/biz/useEntryActions.tsx | 62 +++++++++++++++++++ .../src/modules/settings/tabs/integration.tsx | 51 +++++++++++++++ locales/app/en.json | 3 + locales/settings/en.json | 7 +++ packages/shared/src/interface/settings.ts | 10 +++ 8 files changed, 156 insertions(+) create mode 100644 apps/renderer/src/components/ui/platform-icon/collections/omnivore.tsx diff --git a/apps/renderer/src/atoms/settings/integration.ts b/apps/renderer/src/atoms/settings/integration.ts index 2e671909ff..dff5ec8dac 100644 --- a/apps/renderer/src/atoms/settings/integration.ts +++ b/apps/renderer/src/atoms/settings/integration.ts @@ -3,12 +3,22 @@ import type { IntegrationSettings } from "@follow/shared/interface/settings" import { createSettingAtom } from "./helper" export const createDefaultSettings = (): IntegrationSettings => ({ + // eagle enableEagle: true, + + // readwise enableReadwise: false, readwiseToken: "", + + // instapaper enableInstapaper: false, instapaperUsername: "", instapaperPassword: "", + + // omnivore + enableOmnivore: false, + omnivoreEndpoint: "", + omnivoreToken: "", }) export const { diff --git a/apps/renderer/src/components/ui/platform-icon/collections/omnivore.tsx b/apps/renderer/src/components/ui/platform-icon/collections/omnivore.tsx new file mode 100644 index 0000000000..f668f4ad31 --- /dev/null +++ b/apps/renderer/src/components/ui/platform-icon/collections/omnivore.tsx @@ -0,0 +1,12 @@ +import type { SVGProps } from "react" + +export function SimpleIconsOmnivore(props: SVGProps) { + return ( + + + + ) +} diff --git a/apps/renderer/src/components/ui/platform-icon/icons.ts b/apps/renderer/src/components/ui/platform-icon/icons.ts index 1b8a6e63c6..a6aa151f77 100644 --- a/apps/renderer/src/components/ui/platform-icon/icons.ts +++ b/apps/renderer/src/components/ui/platform-icon/icons.ts @@ -1,4 +1,5 @@ export * from "./collections/eagle" export * from "./collections/instapaper" +export * from "./collections/omnivore" export * from "./collections/readwise" export * from "./collections/rss3" diff --git a/apps/renderer/src/hooks/biz/useEntryActions.tsx b/apps/renderer/src/hooks/biz/useEntryActions.tsx index b9673fd5ac..d4d9dc0c27 100644 --- a/apps/renderer/src/hooks/biz/useEntryActions.tsx +++ b/apps/renderer/src/hooks/biz/useEntryActions.tsx @@ -25,6 +25,7 @@ import { mountLottie } from "~/components/ui/lottie-container" import { SimpleIconsEagle, SimpleIconsInstapaper, + SimpleIconsOmnivore, SimpleIconsReadwise, } from "~/components/ui/platform-icon/icons" import { shortcuts } from "~/constants/shortcuts" @@ -167,6 +168,9 @@ export const useEntryActions = ({ const enableInstapaper = useIntegrationSettingKey("enableInstapaper") const instapaperUsername = useIntegrationSettingKey("instapaperUsername") const instapaperPassword = useIntegrationSettingKey("instapaperPassword") + const enableOmnivore = useIntegrationSettingKey("enableOmnivore") + const omnivoreToken = useIntegrationSettingKey("omnivoreToken") + const omnivoreEndpoint = useIntegrationSettingKey("omnivoreEndpoint") const checkEagle = useQuery({ queryKey: ["check-eagle"], @@ -308,6 +312,64 @@ export const useEntryActions = ({ } }, }, + { + name: t("entry_actions.save_to_omnivore"), + icon: , + key: "saveToomnivore", + hide: !enableOmnivore || !omnivoreToken || !omnivoreEndpoint || !populatedEntry.entries.url, + onClick: async () => { + const saveUrlQuery = ` + mutation SaveUrl($input: SaveUrlInput!) { + saveUrl(input: $input) { + ... on SaveSuccess { + url + clientRequestId + } + ... on SaveError { + errorCodes + message + } + } + } +` + + try { + const data = await ofetch(omnivoreEndpoint, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: omnivoreToken, + }, + body: { + query: saveUrlQuery, + variables: { + input: { + url: populatedEntry.entries.url, + source: "Follow", + clientRequestId: globalThis.crypto.randomUUID(), + publishedAt: new Date(populatedEntry.entries.publishedAt), + }, + }, + }, + }) + toast.success( + <> + {t("entry_actions.saved_to_omnivore")},{" "} + + view + + , + { + duration: 3000, + }, + ) + } catch { + toast.error(t("entry_actions.failed_to_save_to_omnivore"), { + duration: 3000, + }) + } + }, + }, { key: "tip", shortcut: shortcuts.entry.tip.key, diff --git a/apps/renderer/src/modules/settings/tabs/integration.tsx b/apps/renderer/src/modules/settings/tabs/integration.tsx index ff7a92516b..0d54800235 100644 --- a/apps/renderer/src/modules/settings/tabs/integration.tsx +++ b/apps/renderer/src/modules/settings/tabs/integration.tsx @@ -7,6 +7,7 @@ import { Divider } from "~/components/ui/divider" import { SimpleIconsEagle, SimpleIconsInstapaper, + SimpleIconsOmnivore, SimpleIconsReadwise, } from "~/components/ui/platform-icon/icons" @@ -100,6 +101,56 @@ export const SettingIntegration = () => { labelClassName: "w-[150px]", }, }), + { + type: "title", + value: ( + + + {t("integration.omnivore.title")} + + ), + }, + defineSettingItem("enableOmnivore", { + label: t("integration.omnivore.enable.label"), + description: t("integration.omnivore.enable.description"), + }), + defineSettingItem("omnivoreEndpoint", { + label: t("integration.omnivore.endpoint.label"), + vertical: true, + description: ( + <> + {t("integration.omnivore.endpoint.description")}{" "} + + https://api-prod.omnivore.app/api/graphql + + . + + ), + }), + defineSettingItem("omnivoreToken", { + label: t("integration.omnivore.token.label"), + vertical: true, + type: "password", + description: ( + <> + {t("integration.omnivore.token.description")}{" "} + + omnivore.app/settings/api + + . + + ), + }), BottomTip, ]} diff --git a/locales/app/en.json b/locales/app/en.json index d6969931d7..c5795ae412 100644 --- a/locales/app/en.json +++ b/locales/app/en.json @@ -56,6 +56,7 @@ "entry_actions.copy_title": "Copy Title", "entry_actions.failed_to_save_to_eagle": "Failed to save to Eagle.", "entry_actions.failed_to_save_to_instapaper": "Failed to save to Instapaper.", + "entry_actions.failed_to_save_to_omnivore": "Failed to save to Omnivore.", "entry_actions.failed_to_save_to_readwise": "Failed to save to Readwise.", "entry_actions.mark_as_read": "Mark as Read", "entry_actions.mark_as_unread": "Mark as Unread", @@ -63,9 +64,11 @@ "entry_actions.recent_reader": "Recent reader:", "entry_actions.save_media_to_eagle": "Save Media To Eagle", "entry_actions.save_to_instapaper": "Save To Instapaper", + "entry_actions.save_to_omnivore": "Save To Omnivore", "entry_actions.save_to_readwise": "Save To Readwise", "entry_actions.saved_to_eagle": "Saved To Eagle.", "entry_actions.saved_to_instapaper": "Saved To Instapaper.", + "entry_actions.saved_to_omnivore": "Saved To Omnivore.", "entry_actions.saved_to_readwise": "Saved To Readwise.", "entry_actions.share": "Share", "entry_actions.star": "Star", diff --git a/locales/settings/en.json b/locales/settings/en.json index c432afdc10..295c6c5a8d 100644 --- a/locales/settings/en.json +++ b/locales/settings/en.json @@ -128,6 +128,13 @@ "integration.instapaper.password.label": "Instapaper Password", "integration.instapaper.title": "Instapaper", "integration.instapaper.username.label": "Instapaper Username", + "integration.omnivore.enable.description": "Display 'Save to Omnivore' button when available.", + "integration.omnivore.enable.label": "Enable", + "integration.omnivore.endpoint.description": "Omnivore Official Endpoint is: ", + "integration.omnivore.endpoint.label": "Omnivore Endpoint", + "integration.omnivore.title": "Omnivore", + "integration.omnivore.token.description": "You can get it here: ", + "integration.omnivore.token.label": "Omnivore API Key", "integration.readwise.enable.description": "Display 'Save to Readwise' button when available.", "integration.readwise.enable.label": "Enable", "integration.readwise.title": "Readwise", diff --git a/packages/shared/src/interface/settings.ts b/packages/shared/src/interface/settings.ts index a613d695bb..397cc831c0 100644 --- a/packages/shared/src/interface/settings.ts +++ b/packages/shared/src/interface/settings.ts @@ -40,10 +40,20 @@ export interface UISettings { } export interface IntegrationSettings { + // eagle enableEagle: boolean + + // readwise enableReadwise: boolean readwiseToken: string + + // instapaper enableInstapaper: boolean instapaperUsername: string instapaperPassword: string + + // omnivore + enableOmnivore: boolean + omnivoreEndpoint: string + omnivoreToken: string }