Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(integration): add omnivore support #909

Merged
merged 6 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions apps/renderer/src/atoms/settings/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { SVGProps } from "react"

export function SimpleIconsOmnivore(props: SVGProps<SVGSVGElement>) {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16" {...props}>
<path
fill="#3D3D3D"
d="M15.9 7.801c0 .507-.123 1.12-.248 1.656v.004l-.001.003a2.87 2.87 0 0 1-2.793 2.186h-.036c-1.625 0-2.649-1.334-2.649-2.828v-2.14l-1.21 1.794-.067.055a1.404 1.404 0 0 1-1.793 0l-.065-.053-1.248-1.82v4.414H4.6V6.268c0-.91 1.078-1.439 1.794-.802l.055.048 1.46 2.13a.21.21 0 0 0 .179 0l1.43-2.119.065-.054c.68-.567 1.78-.138 1.78.815v2.536c0 .971.619 1.638 1.46 1.638h.035c.78 0 1.45-.527 1.636-1.277.125-.534.216-1.026.216-1.378-.017-3.835-3.262-6.762-7.188-6.498-3.311.23-5.986 2.905-6.216 6.216A6.705 6.705 0 0 0 8 14.693v1.19a7.895 7.895 0 0 1-7.882-8.44C.39 3.536 3.536.39 7.44.118 12.017-.19 15.88 3.242 15.9 7.8z"
/>
</svg>
)
}
1 change: 1 addition & 0 deletions apps/renderer/src/components/ui/platform-icon/icons.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./collections/eagle"
export * from "./collections/instapaper"
export * from "./collections/omnivore"
export * from "./collections/readwise"
export * from "./collections/rss3"
62 changes: 62 additions & 0 deletions apps/renderer/src/hooks/biz/useEntryActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"],
Expand Down Expand Up @@ -308,6 +312,64 @@ export const useEntryActions = ({
}
},
},
{
name: t("entry_actions.save_to_omnivore"),
icon: <SimpleIconsOmnivore />,
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")},{" "}
<a target="_blank" className="underline" href={data.data.saveUrl.url}>
view
</a>
</>,
{
duration: 3000,
},
)
} catch {
toast.error(t("entry_actions.failed_to_save_to_omnivore"), {
duration: 3000,
})
}
},
},
{
key: "tip",
shortcut: shortcuts.entry.tip.key,
Expand Down
51 changes: 51 additions & 0 deletions apps/renderer/src/modules/settings/tabs/integration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Divider } from "~/components/ui/divider"
import {
SimpleIconsEagle,
SimpleIconsInstapaper,
SimpleIconsOmnivore,
SimpleIconsReadwise,
} from "~/components/ui/platform-icon/icons"

Expand Down Expand Up @@ -100,6 +101,56 @@ export const SettingIntegration = () => {
labelClassName: "w-[150px]",
},
}),
{
type: "title",
value: (
<span className="flex items-center gap-2 font-bold">
<SimpleIconsOmnivore />
{t("integration.omnivore.title")}
</span>
),
},
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")}{" "}
<a
target="_blank"
className="underline"
rel="noreferrer noopener"
href="https://api-prod.omnivore.app/api/graphql"
>
https://api-prod.omnivore.app/api/graphql
</a>
.
</>
),
}),
defineSettingItem("omnivoreToken", {
label: t("integration.omnivore.token.label"),
vertical: true,
type: "password",
description: (
<>
{t("integration.omnivore.token.description")}{" "}
<a
target="_blank"
className="underline"
rel="noreferrer noopener"
href="https://omnivore.app/settings/api"
>
omnivore.app/settings/api
</a>
.
</>
),
}),

BottomTip,
]}
Expand Down
3 changes: 3 additions & 0 deletions locales/app/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,19 @@
"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",
"entry_actions.open_in_browser": "Open In {{which}}",
"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",
Expand Down
7 changes: 7 additions & 0 deletions locales/settings/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
10 changes: 10 additions & 0 deletions packages/shared/src/interface/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Loading