Support specifying a copy format, e.g. a yt-dlp command (...
Dan Wolff
·
2024-03-02
·
via RSS Minima activity
Commit
89b30bd9
authored
by
Dan Wolff
Browse files
| Original line number |
Diff line number |
Diff line |
|
@@ -13,6 +13,7 @@ import { |
|
|
markFeedAsUnread,
|
|
|
refreshFeed,
|
|
|
removeFeed,
|
|
|
setFeedCopyFormat,
|
|
|
setFeedCustomName,
|
|
|
setFeedEnabled,
|
|
|
setFeedUpdateFrequency,
|
|
@@ -140,6 +141,24 @@ const HighlightFeed: FunctionComponent<HighlightFeedProps> = function ({ |
|
|
}}
|
|
|
/>
|
|
|
</div>
|
|
|
<div>
|
|
|
Copy format:{" "}
|
|
|
<Select
|
|
|
variant="transparent"
|
|
|
value={feed.copyFormat}
|
|
|
options={[
|
|
|
{ value: undefined, label: "URL" },
|
|
|
{ value: "yt-dlp", label: "yt-dlp downloader" },
|
|
|
{
|
|
|
value: "yt-dlp-sound",
|
|
|
label: "yt-dlp downloader (sound only)",
|
|
|
},
|
|
|
] as const}
|
|
|
onOptionChange={(value) => {
|
|
|
dispatch(setFeedCopyFormat, feedId, value);
|
|
|
}}
|
|
|
/>
|
|
|
</div>
|
|
|
<div>
|
|
|
Feed added: <RelativeTime time={feed.addedDateTime} />
|
|
|
</div>
|
|
@@ -210,7 +229,7 @@ const HighlightFeed: FunctionComponent<HighlightFeedProps> = function ({ |
|
|
{items.map((x) => (
|
|
|
<li key={x.feedItemId}>
|
|
|
<ListFeedEntry
|
|
|
feedId={feedId}
|
|
|
feed={feed}
|
|
|
feedEntry={x}
|
|
|
keyboardNavY={keyboardNavY++}
|
|
|
/>
|
|
|
| Original line number |
Diff line number |
Diff line |
|
@@ -128,25 +128,25 @@ const DetailsButton = forwardRef<HTMLAnchorElement, { |
|
|
});
|
|
|
|
|
|
const EntriesList: FunctionComponent<{
|
|
|
feedId: number;
|
|
|
feed: Feed;
|
|
|
text?: string;
|
|
|
entries?: FeedItem[];
|
|
|
showMoreText?: string;
|
|
|
onShowMore?(): void;
|
|
|
keyboardNavY: number;
|
|
|
}> = ({ feedId, text, entries, showMoreText, onShowMore, keyboardNavY }) => {
|
|
|
}> = ({ feed, text, entries, showMoreText, onShowMore, keyboardNavY }) => {
|
|
|
const keyboardNav = useKeyboardNav();
|
|
|
let localKeyboardNavY = 0;
|
|
|
return (
|
|
|
<>
|
|
|
{text && <p class="italic opacity-50 pl-4 mb-1">{text}</p>}
|
|
|
|
|
|
{entries && feedId !== undefined && (
|
|
|
{entries && feed.feedId !== undefined && (
|
|
|
<ul class="mb-2">
|
|
|
{entries.map((x) => (
|
|
|
<li key={x.feedItemId} class="ml-8">
|
|
|
<ListFeedEntry
|
|
|
feedId={feedId}
|
|
|
feed={feed}
|
|
|
feedEntry={x}
|
|
|
keyboardNavY={[keyboardNavY, localKeyboardNavY++]}
|
|
|
/>
|
|
@@ -250,7 +250,7 @@ const ListFeed: FunctionComponent<ListFeedProps> = ({ feed, keyboardNavY }) => { |
|
|
|
|
|
const entriesList = enabled && expanded && (
|
|
|
<EntriesList
|
|
|
feedId={feedId}
|
|
|
feed={feed}
|
|
|
text={items.length === 0 && displayEntries === "all"
|
|
|
? "No entries"
|
|
|
: undefined}
|
|
|
| Original line number |
Diff line number |
Diff line |
|
@@ -9,7 +9,7 @@ import { |
|
|
markAsRead,
|
|
|
markAsUnread,
|
|
|
} from "../state/operations.ts";
|
|
|
import { FeedItem } from "../state/State.ts";
|
|
|
import { Feed, FeedItem } from "../state/State.ts";
|
|
|
import useAppState from "../state/useAppState.ts";
|
|
|
import CopyButton from "./CopyButton.tsx";
|
|
|
import IconButton from "./IconButton.tsx";
|
|
@@ -19,13 +19,13 @@ import listDisplayContext from "../lib/listDisplayContext.ts"; |
|
|
import useKeyboardNav from "../lib/useKeyboardNav.tsx";
|
|
|
|
|
|
interface ListFeedEntryProps {
|
|
|
feedId: number;
|
|
|
feed: Feed;
|
|
|
feedEntry: FeedItem;
|
|
|
keyboardNavY?: number | number[];
|
|
|
}
|
|
|
|
|
|
const ListFeedEntry: FunctionComponent<ListFeedEntryProps> = ({
|
|
|
feedId,
|
|
|
feed: { feedId, copyFormat },
|
|
|
feedEntry,
|
|
|
keyboardNavY = 0,
|
|
|
}) => {
|
|
@@ -39,6 +39,19 @@ const ListFeedEntry: FunctionComponent<ListFeedEntryProps> = ({ |
|
|
const keyboardNav = useKeyboardNav({ y: keyboardNavY });
|
|
|
let keyboardNavX = 0;
|
|
|
|
|
|
let copyText: string, copyTitle: string;
|
|
|
|
|
|
if (copyFormat === "yt-dlp" || copyFormat === "yt-dlp-sound") {
|
|
|
const escapedUrl = url.replace(/[\\"]/g, "\\$&");
|
|
|
copyText = copyFormat === "yt-dlp"
|
|
|
? `yt-dlp "${escapedUrl}"`
|
|
|
: `yt-dlp -x "${escapedUrl}"`;
|
|
|
copyTitle = `Copy command: ${copyText}`;
|
|
|
} else {
|
|
|
copyText = url;
|
|
|
copyTitle = `Copy URL: ${url}`;
|
|
|
}
|
|
|
|
|
|
return (
|
|
|
<div
|
|
|
class={`flex gap-2 ${
|
|
@@ -48,8 +61,8 @@ const ListFeedEntry: FunctionComponent<ListFeedEntryProps> = ({ |
|
|
<div class="whitespace-pre">
|
|
|
<CopyButton
|
|
|
ref={keyboardNav.add({ x: keyboardNavX++ })}
|
|
|
title={`Copy URL: ${url}`}
|
|
|
text={url}
|
|
|
title={copyTitle}
|
|
|
text={copyText}
|
|
|
/>
|
|
|
|
|
|
{toggleRead.node}
|
|
|
| Original line number |
Diff line number |
Diff line |
|
@@ -9,6 +9,7 @@ import { |
|
|
import { upsertFeedItems } from "./db/feedItem.ts";
|
|
|
import { updateUser } from "./db/user.ts";
|
|
|
import {
|
|
|
CopyFormat,
|
|
|
deleteUserFeed,
|
|
|
getUserFeedByUrl,
|
|
|
insertUserFeed,
|
|
@@ -180,6 +181,14 @@ export default class BackEndApi { |
|
|
updateUserFeed({ userId: this.#userId, feedId, updateFrequencyMinutes });
|
|
|
}
|
|
|
|
|
|
setFeedCopyFormat(feedId: number, copyFormat?: CopyFormat) {
|
|
|
updateUserFeed({
|
|
|
userId: this.#userId,
|
|
|
feedId,
|
|
|
copyFormat: copyFormat ?? null,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
setFeedEnabled(feedId: number, enabled: boolean) {
|
|
|
updateUserFeed({ userId: this.#userId, feedId, enabled });
|
|
|
}
|
|
|
| Original line number |
Diff line number |
Diff line |
|
|
export default {
|
|
|
id: "11_add_userFeed.copyFormat",
|
|
|
sql: `
|
|
|
ALTER TABLE userFeed
|
|
|
ADD COLUMN copyFormat TEXT NULL;
|
|
|
`,
|
|
|
}; |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。