refactor: sunset Omnivore integration (#1953)
* refactor: remove Omnivore integration and related settings * refactor: remove Omnivore integration from localization files * refactor: remove Omnivore integration from settings and command types * refactor: remove Omnivore entries from localization files
This commit is contained in:
parent
f7eca73f5b
commit
605c3d66b9
|
|
@ -14,11 +14,6 @@ export const createDefaultSettings = (): IntegrationSettings => ({
|
|||
instapaperUsername: "",
|
||||
instapaperPassword: "",
|
||||
|
||||
// omnivore
|
||||
enableOmnivore: false,
|
||||
omnivoreEndpoint: "",
|
||||
omnivoreToken: "",
|
||||
|
||||
// obsidian
|
||||
enableObsidian: false,
|
||||
obsidianVaultPath: "",
|
||||
|
|
|
|||
|
|
@ -104,10 +104,6 @@ export const useEntryActions = ({ entryId, view }: { entryId: string; view?: Fee
|
|||
id: COMMAND_ID.integration.saveToInstapaper,
|
||||
onClick: runCmdFn(COMMAND_ID.integration.saveToInstapaper, [{ entryId }]),
|
||||
},
|
||||
{
|
||||
id: COMMAND_ID.integration.saveToOmnivore,
|
||||
onClick: runCmdFn(COMMAND_ID.integration.saveToOmnivore, [{ entryId }]),
|
||||
},
|
||||
{
|
||||
id: COMMAND_ID.integration.saveToObsidian,
|
||||
onClick: runCmdFn(COMMAND_ID.integration.saveToObsidian, [{ entryId }]),
|
||||
|
|
|
|||
|
|
@ -1,438 +0,0 @@
|
|||
import {
|
||||
SimpleIconsEagle,
|
||||
SimpleIconsInstapaper,
|
||||
SimpleIconsObsidian,
|
||||
SimpleIconsOmnivore,
|
||||
SimpleIconsOutline,
|
||||
SimpleIconsReadwise,
|
||||
} from "@follow/components/ui/platform-icon/icons.js"
|
||||
import type { CombinedEntryModel } from "@follow/models/types"
|
||||
import { IN_ELECTRON } from "@follow/shared/constants"
|
||||
import { useMutation, useQuery } from "@tanstack/react-query"
|
||||
import type { FetchError } from "ofetch"
|
||||
import { ofetch } from "ofetch"
|
||||
import type { ReactNode } from "react"
|
||||
import { useMemo } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { toast } from "sonner"
|
||||
|
||||
import { getReadabilityContent, getReadabilityStatus, ReadabilityStatus } from "~/atoms/readability"
|
||||
import { useIntegrationSettingValue } from "~/atoms/settings/integration"
|
||||
import { tipcClient } from "~/lib/client"
|
||||
import { parseHtml } from "~/lib/parse-html"
|
||||
import type { FlatEntryModel } from "~/store/entry"
|
||||
import { getFeedById, useFeedById } from "~/store/feed"
|
||||
import { useInboxById } from "~/store/inbox"
|
||||
|
||||
export const useIntegrationActions = ({
|
||||
view,
|
||||
entry,
|
||||
}: {
|
||||
view?: number
|
||||
entry?: FlatEntryModel | null
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const feed = useFeedById(entry?.feedId, (feed) => {
|
||||
return {
|
||||
type: feed.type,
|
||||
ownerUserId: feed.ownerUserId,
|
||||
id: feed.id,
|
||||
}
|
||||
})
|
||||
|
||||
const inbox = useInboxById(entry?.inboxId)
|
||||
|
||||
const populatedEntry = useMemo(() => {
|
||||
if (!entry) return null
|
||||
if (!feed?.id && !inbox?.id) return null
|
||||
|
||||
return {
|
||||
...entry,
|
||||
feeds: feed ? getFeedById(feed.id) : undefined,
|
||||
inboxes: inbox,
|
||||
} as CombinedEntryModel
|
||||
}, [entry, feed, inbox])
|
||||
|
||||
const {
|
||||
enableEagle,
|
||||
enableReadwise,
|
||||
enableInstapaper,
|
||||
enableOmnivore,
|
||||
enableObsidian,
|
||||
enableOutline,
|
||||
readwiseToken,
|
||||
instapaperUsername,
|
||||
instapaperPassword,
|
||||
omnivoreToken,
|
||||
omnivoreEndpoint,
|
||||
obsidianVaultPath,
|
||||
outlineToken,
|
||||
outlineEndpoint,
|
||||
outlineCollection,
|
||||
} = useIntegrationSettingValue()
|
||||
const isObsidianEnabled = enableObsidian && !!obsidianVaultPath
|
||||
|
||||
const saveToObsidian = useMutation({
|
||||
mutationKey: ["save-to-obsidian"],
|
||||
mutationFn: async (data: {
|
||||
url: string
|
||||
title: string
|
||||
content: string
|
||||
author: string
|
||||
publishedAt: string
|
||||
vaultPath: string
|
||||
}) => {
|
||||
return await tipcClient?.saveToObsidian(data)
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
if (data?.success) {
|
||||
toast.success(t("entry_actions.saved_to_obsidian"), {
|
||||
duration: 3000,
|
||||
})
|
||||
} else {
|
||||
toast.error(`${t("entry_actions.failed_to_save_to_obsidian")}: ${data?.error}`, {
|
||||
duration: 3000,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const checkEagle = useQuery({
|
||||
queryKey: ["check-eagle"],
|
||||
enabled: ELECTRON && enableEagle && !!entry?.entries.url && view !== undefined,
|
||||
queryFn: async () => {
|
||||
try {
|
||||
await ofetch("http://localhost:41595")
|
||||
return true
|
||||
} catch (error: unknown) {
|
||||
return (error as FetchError).data?.code === 401
|
||||
}
|
||||
},
|
||||
refetchOnMount: false,
|
||||
refetchOnWindowFocus: false,
|
||||
})
|
||||
|
||||
const items = useMemo(() => {
|
||||
if (!populatedEntry || view === undefined) return []
|
||||
|
||||
const getEntryContentAsMarkdown = async () => {
|
||||
const isReadabilityReady =
|
||||
getReadabilityStatus()[populatedEntry.entries.id] === ReadabilityStatus.SUCCESS
|
||||
const content =
|
||||
(isReadabilityReady
|
||||
? getReadabilityContent()[populatedEntry.entries.id].content
|
||||
: populatedEntry.entries.content) || ""
|
||||
|
||||
const [toMarkdown, toMdast, gfmTableToMarkdown] = await Promise.all([
|
||||
import("mdast-util-to-markdown").then((m) => m.toMarkdown),
|
||||
import("hast-util-to-mdast").then((m) => m.toMdast),
|
||||
import("mdast-util-gfm-table").then((m) => m.gfmTableToMarkdown),
|
||||
])
|
||||
|
||||
return toMarkdown(toMdast(parseHtml(content).hastTree), {
|
||||
extensions: [gfmTableToMarkdown()],
|
||||
})
|
||||
}
|
||||
|
||||
const items: {
|
||||
key: string
|
||||
className?: string
|
||||
shortcut?: string
|
||||
name: string
|
||||
icon?: ReactNode
|
||||
hide?: boolean
|
||||
active?: boolean
|
||||
disabled?: boolean
|
||||
onClick: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void
|
||||
}[] = [
|
||||
{
|
||||
name: t("entry_actions.save_media_to_eagle"),
|
||||
icon: <SimpleIconsEagle />,
|
||||
key: "saveToEagle",
|
||||
hide:
|
||||
!enableEagle ||
|
||||
(checkEagle.isLoading ? true : !checkEagle.data) ||
|
||||
!populatedEntry.entries.media?.length,
|
||||
onClick: async () => {
|
||||
if (!populatedEntry.entries.url || !populatedEntry.entries.media?.length) {
|
||||
return
|
||||
}
|
||||
window.analytics?.capture("integration", {
|
||||
type: "eagle",
|
||||
event: "save",
|
||||
})
|
||||
const response = await tipcClient?.saveToEagle({
|
||||
url: populatedEntry.entries.url,
|
||||
mediaUrls: populatedEntry.entries.media.map((m) => m.url),
|
||||
})
|
||||
|
||||
if (response?.status === "success") {
|
||||
toast.success(t("entry_actions.saved_to_eagle"), {
|
||||
duration: 3000,
|
||||
})
|
||||
} else {
|
||||
toast.error(t("entry_actions.failed_to_save_to_eagle"), {
|
||||
duration: 3000,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: t("entry_actions.save_to_readwise"),
|
||||
icon: <SimpleIconsReadwise />,
|
||||
key: "saveToReadwise",
|
||||
hide: !enableReadwise || !readwiseToken || !populatedEntry.entries.url,
|
||||
onClick: async () => {
|
||||
try {
|
||||
window.analytics?.capture("integration", {
|
||||
type: "readwise",
|
||||
event: "save",
|
||||
})
|
||||
const data = await ofetch("https://readwise.io/api/v3/save/", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Token ${readwiseToken}`,
|
||||
},
|
||||
body: {
|
||||
url: populatedEntry.entries.url,
|
||||
html: populatedEntry.entries.content || undefined,
|
||||
title: populatedEntry.entries.title || undefined,
|
||||
author: populatedEntry.entries.author || undefined,
|
||||
summary: populatedEntry.entries.description || undefined,
|
||||
published_date: populatedEntry.entries.publishedAt || undefined,
|
||||
image_url: populatedEntry.entries.media?.[0]?.url || undefined,
|
||||
saved_using: "Follow",
|
||||
},
|
||||
})
|
||||
|
||||
toast.success(
|
||||
<>
|
||||
{t("entry_actions.saved_to_readwise")},{" "}
|
||||
<a target="_blank" className="underline" href={data.url}>
|
||||
view
|
||||
</a>
|
||||
</>,
|
||||
{
|
||||
duration: 3000,
|
||||
},
|
||||
)
|
||||
} catch {
|
||||
toast.error(t("entry_actions.failed_to_save_to_readwise"), {
|
||||
duration: 3000,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: t("entry_actions.save_to_instapaper"),
|
||||
icon: <SimpleIconsInstapaper />,
|
||||
key: "saveToInstapaper",
|
||||
hide:
|
||||
!enableInstapaper ||
|
||||
!instapaperPassword ||
|
||||
!instapaperUsername ||
|
||||
!populatedEntry.entries.url,
|
||||
onClick: async () => {
|
||||
try {
|
||||
window.analytics?.capture("integration", {
|
||||
type: "instapaper",
|
||||
event: "save",
|
||||
})
|
||||
const data = await ofetch("https://www.instapaper.com/api/add", {
|
||||
query: {
|
||||
url: populatedEntry.entries.url,
|
||||
title: populatedEntry.entries.title,
|
||||
},
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Basic ${btoa(`${instapaperUsername}:${instapaperPassword}`)}`,
|
||||
},
|
||||
parseResponse: JSON.parse,
|
||||
})
|
||||
|
||||
toast.success(
|
||||
<>
|
||||
{t("entry_actions.saved_to_instapaper")},{" "}
|
||||
<a
|
||||
target="_blank"
|
||||
className="underline"
|
||||
href={`https://www.instapaper.com/read/${data.bookmark_id}`}
|
||||
>
|
||||
view
|
||||
</a>
|
||||
</>,
|
||||
{
|
||||
duration: 3000,
|
||||
},
|
||||
)
|
||||
} catch {
|
||||
toast.error(t("entry_actions.failed_to_save_to_instapaper"), {
|
||||
duration: 3000,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
window.analytics?.capture("integration", {
|
||||
type: "omnivore",
|
||||
event: "save",
|
||||
})
|
||||
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,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: t("entry_actions.save_to_obsidian"),
|
||||
icon: <SimpleIconsObsidian />,
|
||||
key: "saveToObsidian",
|
||||
hide: !isObsidianEnabled || !populatedEntry?.entries?.url || !IN_ELECTRON,
|
||||
onClick: async () => {
|
||||
if (!isObsidianEnabled || !populatedEntry?.entries?.url || !IN_ELECTRON) return
|
||||
|
||||
const markdownContent = await getEntryContentAsMarkdown()
|
||||
window.analytics?.capture("integration", {
|
||||
type: "obsidian",
|
||||
event: "save",
|
||||
})
|
||||
saveToObsidian.mutate({
|
||||
url: populatedEntry.entries.url,
|
||||
title: populatedEntry.entries.title || "",
|
||||
content: markdownContent,
|
||||
author: populatedEntry.entries.author || "",
|
||||
publishedAt: populatedEntry.entries.publishedAt || "",
|
||||
vaultPath: obsidianVaultPath,
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
name: t("entry_actions.save_to_outline"),
|
||||
icon: <SimpleIconsOutline />,
|
||||
key: "saveToOutline",
|
||||
hide:
|
||||
!IN_ELECTRON ||
|
||||
!enableOutline ||
|
||||
!outlineToken ||
|
||||
!outlineEndpoint ||
|
||||
!outlineCollection ||
|
||||
!populatedEntry.entries.title,
|
||||
onClick: async () => {
|
||||
try {
|
||||
const request = async (method: string, params: Record<string, unknown>) => {
|
||||
return await ofetch(`${outlineEndpoint.replace(/\/$/, "")}/${method}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${outlineToken}`,
|
||||
},
|
||||
body: params,
|
||||
})
|
||||
}
|
||||
let collectionId = outlineCollection
|
||||
if (!/^[a-f\d]{8}(?:-[a-f\d]{4}){3}-[a-f\d]{12}$/i.test(collectionId)) {
|
||||
const collection = await request("collections.info", {
|
||||
id: collectionId,
|
||||
})
|
||||
collectionId = collection.data.id
|
||||
}
|
||||
const markdownContent = await getEntryContentAsMarkdown()
|
||||
await request("documents.create", {
|
||||
title: populatedEntry.entries.title,
|
||||
text: markdownContent,
|
||||
collectionId,
|
||||
publish: true,
|
||||
})
|
||||
toast.success(t("entry_actions.saved_to_outline"), {
|
||||
duration: 3000,
|
||||
})
|
||||
} catch {
|
||||
toast.error(t("entry_actions.failed_to_save_to_outline"), {
|
||||
duration: 3000,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
return items
|
||||
}, [
|
||||
populatedEntry,
|
||||
view,
|
||||
t,
|
||||
enableEagle,
|
||||
checkEagle.isLoading,
|
||||
checkEagle.data,
|
||||
enableReadwise,
|
||||
readwiseToken,
|
||||
enableInstapaper,
|
||||
instapaperPassword,
|
||||
instapaperUsername,
|
||||
enableOmnivore,
|
||||
omnivoreToken,
|
||||
omnivoreEndpoint,
|
||||
isObsidianEnabled,
|
||||
enableOutline,
|
||||
outlineToken,
|
||||
outlineEndpoint,
|
||||
outlineCollection,
|
||||
saveToObsidian,
|
||||
obsidianVaultPath,
|
||||
])
|
||||
|
||||
return {
|
||||
items,
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,6 @@ export const COMMAND_ID = {
|
|||
saveToEagle: "integration:save-to-eagle",
|
||||
saveToReadwise: "integration:save-to-readwise",
|
||||
saveToInstapaper: "integration:save-to-instapaper",
|
||||
saveToOmnivore: "integration:save-to-omnivore",
|
||||
saveToObsidian: "integration:save-to-obsidian",
|
||||
saveToOutline: "integration:save-to-outline",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import {
|
|||
SimpleIconsEagle,
|
||||
SimpleIconsInstapaper,
|
||||
SimpleIconsObsidian,
|
||||
SimpleIconsOmnivore,
|
||||
SimpleIconsOutline,
|
||||
SimpleIconsReadwise,
|
||||
} from "@follow/components/ui/platform-icon/icons.js"
|
||||
|
|
@ -29,7 +28,6 @@ export const useRegisterIntegrationCommands = () => {
|
|||
useRegisterEagleCommands()
|
||||
useRegisterReadwiseCommands()
|
||||
useRegisterInstapaperCommands()
|
||||
useRegisterOmnivoreCommands()
|
||||
useRegisterObsidianCommands()
|
||||
useRegisterOutlineCommands()
|
||||
}
|
||||
|
|
@ -236,90 +234,6 @@ const useRegisterInstapaperCommands = () => {
|
|||
)
|
||||
}
|
||||
|
||||
const useRegisterOmnivoreCommands = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const enableOmnivore = useIntegrationSettingKey("enableOmnivore")
|
||||
const omnivoreToken = useIntegrationSettingKey("omnivoreToken")
|
||||
const omnivoreEndpoint = useIntegrationSettingKey("omnivoreEndpoint")
|
||||
|
||||
const isOmnivoreAvailable = enableOmnivore && !!omnivoreToken && !!omnivoreEndpoint
|
||||
|
||||
useRegisterCommandEffect(
|
||||
!isOmnivoreAvailable
|
||||
? []
|
||||
: defineFollowCommand({
|
||||
id: COMMAND_ID.integration.saveToOmnivore,
|
||||
label: t("entry_actions.save_to_omnivore"),
|
||||
icon: <SimpleIconsOmnivore />,
|
||||
run: async ({ entryId }) => {
|
||||
const entry = useEntryStore.getState().flatMapEntries[entryId]
|
||||
if (!entry) {
|
||||
toast.error("Failed to save to Omnivore: entry is not available", { duration: 3000 })
|
||||
return
|
||||
}
|
||||
const saveUrlQuery = `
|
||||
mutation SaveUrl($input: SaveUrlInput!) {
|
||||
saveUrl(input: $input) {
|
||||
... on SaveSuccess {
|
||||
url
|
||||
clientRequestId
|
||||
}
|
||||
... on SaveError {
|
||||
errorCodes
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
window.analytics?.capture("integration", {
|
||||
type: "omnivore",
|
||||
event: "save",
|
||||
})
|
||||
try {
|
||||
const data = await ofetch(omnivoreEndpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: omnivoreToken,
|
||||
},
|
||||
body: {
|
||||
query: saveUrlQuery,
|
||||
variables: {
|
||||
input: {
|
||||
url: entry.entries.url,
|
||||
source: "Follow",
|
||||
clientRequestId: globalThis.crypto.randomUUID(),
|
||||
publishedAt: new Date(entry.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,
|
||||
})
|
||||
}
|
||||
},
|
||||
}),
|
||||
{
|
||||
deps: [isOmnivoreAvailable],
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
const getEntryContentAsMarkdown = async (entry: FlatEntryModel) => {
|
||||
const isReadabilityReady = getReadabilityStatus()[entry.entries.id] === ReadabilityStatus.SUCCESS
|
||||
const content =
|
||||
|
|
|
|||
|
|
@ -106,11 +106,6 @@ export type SaveToInstapaperCommand = Command<{
|
|||
fn: (payload: { entryId: string }) => void
|
||||
}>
|
||||
|
||||
export type SaveToOmnivoreCommand = Command<{
|
||||
id: typeof COMMAND_ID.integration.saveToOmnivore
|
||||
fn: (payload: { entryId: string }) => void
|
||||
}>
|
||||
|
||||
export type SaveToObsidianCommand = Command<{
|
||||
id: typeof COMMAND_ID.integration.saveToObsidian
|
||||
fn: (payload: { entryId: string }) => void
|
||||
|
|
@ -125,7 +120,6 @@ export type IntegrationCommand =
|
|||
| SaveToEagleCommand
|
||||
| SaveToReadwiseCommand
|
||||
| SaveToInstapaperCommand
|
||||
| SaveToOmnivoreCommand
|
||||
| SaveToObsidianCommand
|
||||
| SaveToOutlineCommand
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import {
|
|||
SimpleIconsEagle,
|
||||
SimpleIconsInstapaper,
|
||||
SimpleIconsObsidian,
|
||||
SimpleIconsOmnivore,
|
||||
SimpleIconsOutline,
|
||||
SimpleIconsReadwise,
|
||||
} from "@follow/components/ui/platform-icon/icons.js"
|
||||
|
|
@ -103,56 +102,6 @@ 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>
|
||||
.
|
||||
</>
|
||||
),
|
||||
}),
|
||||
{
|
||||
type: "title",
|
||||
value: (
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@
|
|||
"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_obsidian": "Failed to save to Obsidian",
|
||||
"entry_actions.failed_to_save_to_omnivore": "Failed to save to Omnivore.",
|
||||
"entry_actions.failed_to_save_to_outline": "Failed to save to Outline.",
|
||||
"entry_actions.failed_to_save_to_readwise": "Failed to save to Readwise.",
|
||||
"entry_actions.mark_as_read": "Mark as Read",
|
||||
|
|
@ -121,13 +120,11 @@
|
|||
"entry_actions.save_media_to_eagle": "Save Media To Eagle",
|
||||
"entry_actions.save_to_instapaper": "Save To Instapaper",
|
||||
"entry_actions.save_to_obsidian": "Save to Obsidian",
|
||||
"entry_actions.save_to_omnivore": "Save To Omnivore",
|
||||
"entry_actions.save_to_outline": "Save To Outline",
|
||||
"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_obsidian": "Saved to Obsidian",
|
||||
"entry_actions.saved_to_omnivore": "Saved To Omnivore.",
|
||||
"entry_actions.saved_to_outline": "Saved To Outline.",
|
||||
"entry_actions.saved_to_readwise": "Saved To Readwise.",
|
||||
"entry_actions.share": "Share",
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@
|
|||
"entry_actions.failed_to_save_to_eagle": "Eagle への保存に失敗しました。",
|
||||
"entry_actions.failed_to_save_to_instapaper": "Instapaper への保存に失敗しました。",
|
||||
"entry_actions.failed_to_save_to_obsidian": "Obsidian への保存に失敗しました。",
|
||||
"entry_actions.failed_to_save_to_omnivore": "Omnivore への保存に失敗しました。",
|
||||
"entry_actions.failed_to_save_to_outline": "Outline への保存に失敗しました。",
|
||||
"entry_actions.failed_to_save_to_readwise": "Readwise への保存に失敗しました。",
|
||||
"entry_actions.mark_as_read": "既読にする",
|
||||
|
|
@ -121,13 +120,11 @@
|
|||
"entry_actions.save_media_to_eagle": "メディアを Eagle に保存",
|
||||
"entry_actions.save_to_instapaper": "Instapaper に保存",
|
||||
"entry_actions.save_to_obsidian": "Obsidian に保存",
|
||||
"entry_actions.save_to_omnivore": "Omnivore に保存",
|
||||
"entry_actions.save_to_outline": "Outline に保存",
|
||||
"entry_actions.save_to_readwise": "Readwise に保存",
|
||||
"entry_actions.saved_to_eagle": "Eagle に保存されました。",
|
||||
"entry_actions.saved_to_instapaper": "Instapaper に保存されました。",
|
||||
"entry_actions.saved_to_obsidian": "Obsidian に保存されました。",
|
||||
"entry_actions.saved_to_omnivore": "Omnivore に保存されました。",
|
||||
"entry_actions.saved_to_outline": "Outline に保存されました。",
|
||||
"entry_actions.saved_to_readwise": "Readwise に保存されました。",
|
||||
"entry_actions.share": "共有",
|
||||
|
|
@ -244,7 +241,7 @@
|
|||
"new_user_guide.step.behavior.unread_question.option2": "バランス: ホバーしたりスクロールが終わると自動で既読にします。",
|
||||
"new_user_guide.step.behavior.unread_question.option3": "コンサバ: クリックしたときのみ既読にします。",
|
||||
"new_user_guide.step.features.actions.description": "アクションルールはフィードごとに違ったアクションを実行できます。\n - AI を使った要約や翻訳 \n - エントリーの読み方の設定 \n - 新着エントリーの通知の有効/無効 \n - 特定のエントリーの書き換えやブロック \n - 新着エントリーの Webhook アドレスへの送信など",
|
||||
"new_user_guide.step.features.integration.description": "統合により、他のサービスにエントリーを保存することができます。現在対応しているサービスは以下のとおりです:\n- Eagle \n- Readwise \n- Instapaper \n- Obsidian \n- Omnivore \n- Outline",
|
||||
"new_user_guide.step.features.integration.description": "統合により、他のサービスにエントリーを保存することができます。現在対応しているサービスは以下のとおりです:\n- Eagle \n- Readwise \n- Instapaper \n- Obsidian \n- Outline",
|
||||
"new_user_guide.step.migrate.profile": "プロファイルをセットアップ",
|
||||
"new_user_guide.step.migrate.title": "OPML ファイルを構成する",
|
||||
"new_user_guide.step.migrate.wallet": "ウォレットをチェック",
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@
|
|||
"entry_actions.failed_to_save_to_eagle": "保存到 Eagle 失败。",
|
||||
"entry_actions.failed_to_save_to_instapaper": "保存到 Instapaper 失败。",
|
||||
"entry_actions.failed_to_save_to_obsidian": "保存到 Obsidian 失败。",
|
||||
"entry_actions.failed_to_save_to_omnivore": "保存到 Omnivore 失败。",
|
||||
"entry_actions.failed_to_save_to_outline": "保存到 Outline 失败。",
|
||||
"entry_actions.failed_to_save_to_readwise": "保存到 Readwise 失败。",
|
||||
"entry_actions.mark_as_read": "标记为已读",
|
||||
|
|
@ -121,13 +120,11 @@
|
|||
"entry_actions.save_media_to_eagle": "保存到 Eagle",
|
||||
"entry_actions.save_to_instapaper": "保存到 Instapaper",
|
||||
"entry_actions.save_to_obsidian": "保存到 Obsidian",
|
||||
"entry_actions.save_to_omnivore": "保存到 Omnivore",
|
||||
"entry_actions.save_to_outline": "保存到 Outline",
|
||||
"entry_actions.save_to_readwise": "保存到 Readwise",
|
||||
"entry_actions.saved_to_eagle": "已保存到 Eagle。",
|
||||
"entry_actions.saved_to_instapaper": "已保存到 Instapaper。",
|
||||
"entry_actions.saved_to_obsidian": "已保存到 Obsidian。",
|
||||
"entry_actions.saved_to_omnivore": "已保存到 Omnivore。",
|
||||
"entry_actions.saved_to_outline": "已保存到 Outline。",
|
||||
"entry_actions.saved_to_readwise": "已保存到 Readwise。",
|
||||
"entry_actions.share": "分享",
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@
|
|||
"entry_actions.failed_to_save_to_eagle": "無法儲存至 Eagle",
|
||||
"entry_actions.failed_to_save_to_instapaper": "無法儲存至 Instapaper",
|
||||
"entry_actions.failed_to_save_to_obsidian": "無法儲存至 Obsidian ",
|
||||
"entry_actions.failed_to_save_to_omnivore": "無法儲存至 Omnivore",
|
||||
"entry_actions.failed_to_save_to_outline": "無法儲存至 Outline",
|
||||
"entry_actions.failed_to_save_to_readwise": "無法儲存至 Readwise",
|
||||
"entry_actions.mark_as_read": "標記為已讀",
|
||||
|
|
@ -121,13 +120,11 @@
|
|||
"entry_actions.save_media_to_eagle": "儲存媒體至 Eagle",
|
||||
"entry_actions.save_to_instapaper": "儲存至 Instapaper",
|
||||
"entry_actions.save_to_obsidian": "儲存至 Obsidian",
|
||||
"entry_actions.save_to_omnivore": "儲存至 Omnivore",
|
||||
"entry_actions.save_to_outline": "儲存至 Outline",
|
||||
"entry_actions.save_to_readwise": "儲存至 Readwise",
|
||||
"entry_actions.saved_to_eagle": "已儲存至 Eagle",
|
||||
"entry_actions.saved_to_instapaper": "已儲存至 Instapaper",
|
||||
"entry_actions.saved_to_obsidian": "已儲存至 Obsidian",
|
||||
"entry_actions.saved_to_omnivore": "已儲存至 Omnivore",
|
||||
"entry_actions.saved_to_outline": "已儲存至 Outline",
|
||||
"entry_actions.saved_to_readwise": "已儲存至 Readwise",
|
||||
"entry_actions.share": "分享",
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@
|
|||
"entry_actions.failed_to_save_to_eagle": "無法儲存到 Eagle。",
|
||||
"entry_actions.failed_to_save_to_instapaper": "無法儲存到 Instapaper。",
|
||||
"entry_actions.failed_to_save_to_obsidian": "儲存到 Obsidian 失敗",
|
||||
"entry_actions.failed_to_save_to_omnivore": "無法儲存到 Omnivore。",
|
||||
"entry_actions.failed_to_save_to_outline": "無法儲存到 Outline。",
|
||||
"entry_actions.failed_to_save_to_readwise": "無法儲存到 Readwise。",
|
||||
"entry_actions.mark_as_read": "標記為已讀",
|
||||
|
|
@ -121,13 +120,11 @@
|
|||
"entry_actions.save_media_to_eagle": "儲存媒體至 Eagle",
|
||||
"entry_actions.save_to_instapaper": "儲存到 Instapaper",
|
||||
"entry_actions.save_to_obsidian": "儲存到 Obsidian",
|
||||
"entry_actions.save_to_omnivore": "儲存到 Omnivore",
|
||||
"entry_actions.save_to_outline": "儲存到 Outline",
|
||||
"entry_actions.save_to_readwise": "儲存到 Readwise",
|
||||
"entry_actions.saved_to_eagle": "已儲存至 Eagle。",
|
||||
"entry_actions.saved_to_instapaper": "已儲存至 Instapaper。",
|
||||
"entry_actions.saved_to_obsidian": "已儲存到 Obsidian",
|
||||
"entry_actions.saved_to_omnivore": "已儲存至 Omnivore。",
|
||||
"entry_actions.saved_to_outline": "已儲存至 Outline。",
|
||||
"entry_actions.saved_to_readwise": "已儲存至 Readwise。",
|
||||
"entry_actions.share": "分享",
|
||||
|
|
|
|||
|
|
@ -175,13 +175,6 @@
|
|||
"integration.obsidian.title": "Obsidian",
|
||||
"integration.obsidian.vaultPath.description": "The path to your Obsidian vault.",
|
||||
"integration.obsidian.vaultPath.label": "Obsidian Vault Path",
|
||||
"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.outline.collection.description": "The UUID or urlId of the collection where the documents is saved.",
|
||||
"integration.outline.collection.label": "Outline Collection",
|
||||
"integration.outline.enable.description": "Display 'Save to Outline' button when available.",
|
||||
|
|
|
|||
|
|
@ -172,13 +172,6 @@
|
|||
"integration.obsidian.title": "Obsidian",
|
||||
"integration.obsidian.vaultPath.description": "Obsidian vaultのパスを指定します",
|
||||
"integration.obsidian.vaultPath.label": "Obsidian Vault パス",
|
||||
"integration.omnivore.enable.description": "利用可能な場合、'Omnivore に保存' ボタンを表示します。",
|
||||
"integration.omnivore.enable.label": "有効化",
|
||||
"integration.omnivore.endpoint.description": "Omnivore の公式 Endpoint",
|
||||
"integration.omnivore.endpoint.label": "Omnivore Endpoint",
|
||||
"integration.omnivore.title": "Omnivore",
|
||||
"integration.omnivore.token.description": "こちらで取得できます:",
|
||||
"integration.omnivore.token.label": "Omnivore API Key",
|
||||
"integration.outline.collection.description": "ドキュメントに保存された UUID または urlId コレクションです。",
|
||||
"integration.outline.collection.label": "Outline コレクション",
|
||||
"integration.outline.enable.description": "利用可能なとき 'Outline に保存' ボタンを表示します。",
|
||||
|
|
|
|||
|
|
@ -172,13 +172,6 @@
|
|||
"integration.obsidian.title": "Obsidian",
|
||||
"integration.obsidian.vaultPath.description": "你的 Obsidian 仓库的路径",
|
||||
"integration.obsidian.vaultPath.label": "Obsidian 仓库路径",
|
||||
"integration.omnivore.enable.description": "显示「保存到 Omnivore」按钮(如果可用)。",
|
||||
"integration.omnivore.enable.label": "启用",
|
||||
"integration.omnivore.endpoint.description": "Omnivore 官方接口",
|
||||
"integration.omnivore.endpoint.label": "Omnivore 访问域名",
|
||||
"integration.omnivore.title": "Omnivore",
|
||||
"integration.omnivore.token.description": "在这里获取 API 密钥",
|
||||
"integration.omnivore.token.label": "Omnivore API 密钥",
|
||||
"integration.outline.collection.description": "保存文档的文档集的 UUID 或 urlId。",
|
||||
"integration.outline.collection.label": "Outline 文档集",
|
||||
"integration.outline.enable.description": "显示「保存到 Outline」按钮(如果可用)。",
|
||||
|
|
|
|||
|
|
@ -168,13 +168,6 @@
|
|||
"integration.obsidian.title": "Obsidian",
|
||||
"integration.obsidian.vaultPath.description": "你的 Obsidian 儲存庫的路徑",
|
||||
"integration.obsidian.vaultPath.label": "Obsidian 儲存庫路徑",
|
||||
"integration.omnivore.enable.description": "顯示「儲存到 Omnivore」按钮(如果可用)",
|
||||
"integration.omnivore.enable.label": "啟用",
|
||||
"integration.omnivore.endpoint.description": "Omnivore 官方端口",
|
||||
"integration.omnivore.endpoint.label": "Omnivore 端口",
|
||||
"integration.omnivore.title": "Omnivore",
|
||||
"integration.omnivore.token.description": "你可以在這裡獲取",
|
||||
"integration.omnivore.token.label": "Omnivore API 密鑰",
|
||||
"integration.outline.collection.description": "儲存文件的集合的 UUID 或 urlId",
|
||||
"integration.outline.collection.label": "Outline Collection",
|
||||
"integration.outline.enable.description": "顯示「儲存到 Outline」按钮(如果可用)",
|
||||
|
|
|
|||
|
|
@ -160,13 +160,6 @@
|
|||
"integration.obsidian.title": "Obsidian",
|
||||
"integration.obsidian.vaultPath.description": "您的 Obsidian 儲存庫的路徑",
|
||||
"integration.obsidian.vaultPath.label": "Obsidian 儲存庫路徑",
|
||||
"integration.omnivore.enable.description": "顯示\"保存到 Omnivore\"按钮(如果可用)。",
|
||||
"integration.omnivore.enable.label": "啟用",
|
||||
"integration.omnivore.endpoint.description": "Omnivore 官方端口",
|
||||
"integration.omnivore.endpoint.label": "Omnivore 端口",
|
||||
"integration.omnivore.title": "Omnivore",
|
||||
"integration.omnivore.token.description": "你可以在這裡獲取",
|
||||
"integration.omnivore.token.label": "Omnivore API 密鑰",
|
||||
"integration.outline.collection.description": "儲存文檔的文檔集的 UUID 或 urlId",
|
||||
"integration.outline.collection.label": "Outline 文檔集",
|
||||
"integration.outline.enable.description": "顯示\"儲存到 Outline\"按鈕(如果可用)",
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
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="currentColor"
|
||||
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,7 +1,6 @@
|
|||
export * from "./collections/eagle"
|
||||
export * from "./collections/instapaper"
|
||||
export * from "./collections/obsidian"
|
||||
export * from "./collections/omnivore"
|
||||
export * from "./collections/outline"
|
||||
export * from "./collections/readwise"
|
||||
export * from "./collections/rss3"
|
||||
|
|
|
|||
|
|
@ -64,11 +64,6 @@ export interface IntegrationSettings {
|
|||
instapaperUsername: string
|
||||
instapaperPassword: string
|
||||
|
||||
// omnivore
|
||||
enableOmnivore: boolean
|
||||
omnivoreEndpoint: string
|
||||
omnivoreToken: string
|
||||
|
||||
// obsidian
|
||||
enableObsidian: boolean
|
||||
obsidianVaultPath: string
|
||||
|
|
|
|||
Loading…
Reference in New Issue