diff --git a/assets/locales/en/messages.json b/assets/locales/en/messages.json index 57e2925..dda79c3 100644 --- a/assets/locales/en/messages.json +++ b/assets/locales/en/messages.json @@ -3,7 +3,7 @@ "message": "Easily find and subscribe to RSS and RSSHub." }, "accessKey": { - "message": "Access key" + "message": "Access key for the current RSSHub instance" }, "about": { "message": "About" @@ -27,7 +27,7 @@ "message": "RSSHub for the current page" }, "customRSSHubDomain": { - "message": "Custom RSSHub domain name" + "message": "RSSHub instance" }, "currentSiteRSSHub": { "message": "RSSHub for the current site" @@ -69,7 +69,7 @@ "message": "Generate access code" }, "hotKey": { - "message": "Hot key" + "message": "Hotkey" }, "joinRSSHub": { "message": "Join RSSHub to make everything RSSible!" @@ -84,7 +84,7 @@ "message": "One-click subscription" }, "notificationsAndReminders": { - "message": "Notifications and reminders" + "message": "Badge reminder" }, "requiredAccessKey": { "message": "Required, please enter the correct access key" @@ -113,6 +113,12 @@ "settings": { "message": "Settings" }, + "RSSHubRelatedSettings": { + "message": "RSSHub Related Settings" + }, + "quickSubscription": { + "message": "Quick Subscriptions" + }, "showCornerBadge": { "message": "Show corner badge" }, diff --git a/assets/locales/zh/messages.json b/assets/locales/zh/messages.json index 766299d..be6cbb8 100644 --- a/assets/locales/zh/messages.json +++ b/assets/locales/zh/messages.json @@ -6,7 +6,7 @@ "message": "关于" }, "accessKey": { - "message": "访问密钥" + "message": "当前 RSSHub 实例的访问密钥" }, "clickToSet": { "message": "点此设置" @@ -27,7 +27,7 @@ "message": "适用于当前页面的 RSSHub" }, "customRSSHubDomain": { - "message": "自定义 RSSHub 域名" + "message": "RSSHub 实例" }, "currentSiteRSSHub": { "message": "适用于当前网站的 RSSHub" @@ -81,7 +81,7 @@ "message": "本地阅读器" }, "notificationsAndReminders": { - "message": "通知与提醒" + "message": "角标提醒" }, "oneclickSubscription": { "message": "一键订阅" @@ -113,6 +113,12 @@ "settings": { "message": "设置" }, + "RSSHubRelatedSettings": { + "message": "RSSHub 相关设置" + }, + "quickSubscription": { + "message": "快速订阅" + }, "showCornerBadge": { "message": "角标提醒" }, diff --git a/package.json b/package.json index ade3ee8..7683045 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "@iconify-json/mingcute": "^1.1.13", "@plasmohq/messaging": "^0.6.1", "@plasmohq/storage": "^1.9.0", + "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-switch": "^1.0.3", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", "lodash": "^4.17.21", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 42d7fac..28dc24b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,15 @@ dependencies: '@plasmohq/storage': specifier: ^1.9.0 version: 1.9.0(react@18.2.0) + '@radix-ui/react-label': + specifier: ^2.0.2 + version: 2.0.2(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-slot': specifier: ^1.0.2 version: 1.0.2(@types/react@18.2.37)(react@18.2.0) + '@radix-ui/react-switch': + specifier: ^1.0.3 + version: 1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) class-variance-authority: specifier: ^0.7.0 version: 0.7.0 @@ -2399,6 +2405,12 @@ packages: config-chain: 1.1.13 dev: false + /@radix-ui/primitive@1.0.1: + resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} + dependencies: + '@babel/runtime': 7.23.5 + dev: false + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.37)(react@18.2.0): resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} peerDependencies: @@ -2413,6 +2425,62 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-context@1.0.1(@types/react@18.2.37)(react@18.2.0): + resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.5 + '@types/react': 18.2.37 + react: 18.2.0 + dev: false + + /@radix-ui/react-label@2.0.2(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.5 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.37 + '@types/react-dom': 18.2.15 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.5 + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.37)(react@18.2.0) + '@types/react': 18.2.37 + '@types/react-dom': 18.2.15 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-slot@1.0.2(@types/react@18.2.37)(react@18.2.0): resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} peerDependencies: @@ -2428,6 +2496,105 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-switch@1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.5 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@types/react': 18.2.37 + '@types/react-dom': 18.2.15 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.37)(react@18.2.0): + resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.5 + '@types/react': 18.2.37 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.37)(react@18.2.0): + resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.5 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@types/react': 18.2.37 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.37)(react@18.2.0): + resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.5 + '@types/react': 18.2.37 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.37)(react@18.2.0): + resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.5 + '@types/react': 18.2.37 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-size@1.0.1(@types/react@18.2.37)(react@18.2.0): + resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.5 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.37)(react@18.2.0) + '@types/react': 18.2.37 + react: 18.2.0 + dev: false + /@remix-run/router@1.13.1: resolution: {integrity: sha512-so+DHzZKsoOcoXrILB4rqDkMDy7NLMErRdOxvzvOKb507YINKUP4Di+shbTZDhSE/pBZ+vr7XGIpcOO0VLSA+Q==} engines: {node: '>=14.0.0'} @@ -2879,7 +3046,6 @@ packages: resolution: {integrity: sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==} dependencies: '@types/react': 18.2.37 - dev: true /@types/react@18.2.37: resolution: {integrity: sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==} diff --git a/src/lib/components/Card.tsx b/src/lib/components/Card.tsx new file mode 100644 index 0000000..aa7019c --- /dev/null +++ b/src/lib/components/Card.tsx @@ -0,0 +1,79 @@ +import * as React from "react" + +import { cn } from "~/lib/utils" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/src/lib/components/Input.tsx b/src/lib/components/Input.tsx new file mode 100644 index 0000000..35e8137 --- /dev/null +++ b/src/lib/components/Input.tsx @@ -0,0 +1,25 @@ +import * as React from "react" + +import { cn } from "~/lib/utils" + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = "Input" + +export { Input } diff --git a/src/lib/components/Label.tsx b/src/lib/components/Label.tsx new file mode 100644 index 0000000..8f40738 --- /dev/null +++ b/src/lib/components/Label.tsx @@ -0,0 +1,26 @@ +"use client" + +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "~/lib/utils" + +const labelVariants = cva( + "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" +) + +const Label = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, ...props }, ref) => ( + +)) +Label.displayName = LabelPrimitive.Root.displayName + +export { Label } diff --git a/src/lib/components/Switch.tsx b/src/lib/components/Switch.tsx new file mode 100644 index 0000000..f53c755 --- /dev/null +++ b/src/lib/components/Switch.tsx @@ -0,0 +1,29 @@ +"use client" + +import * as React from "react" +import * as SwitchPrimitives from "@radix-ui/react-switch" + +import { cn } from "~/lib/utils" + +const Switch = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +Switch.displayName = SwitchPrimitives.Root.displayName + +export { Switch } diff --git a/src/lib/config.ts b/src/lib/config.ts index e23c535..b97ca65 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -47,7 +47,7 @@ export async function getConfig() { return Object.assign({}, defaultConfig, await storage.get("config")); } -export function saveConfig(config: typeof defaultConfig) { +export function setConfig(config: typeof defaultConfig) { if (!config.rsshubDomain) { config.rsshubDomain = defaultConfig.rsshubDomain; } diff --git a/src/lib/quick-subscriptions.ts b/src/lib/quick-subscriptions.ts new file mode 100644 index 0000000..51c2db3 --- /dev/null +++ b/src/lib/quick-subscriptions.ts @@ -0,0 +1,55 @@ +export const quickSubscriptions = [{ + name: "Miniflux", + projectUrl: "https://miniflux.app", + key: "miniflux", + domainKey: "minifluxDomain", +}, { + name: "Inoreader", + projectUrl: "https://www.inoreader.com/", + key: "inoreader", + domainKey: "inoreaderDomain", +}, { + name: "Feedly", + projectUrl: "https://feedly.com/", + key: "feedly", +}, { + name: "FreshRSS", + projectUrl: "https://freshrss.org", + key: "freshrss", + domainKey: "freshrssDomain", +}, { + name: "Tiny Tiny RSS", + projectUrl: "https://tt-rss.org/", + key: "ttrss", + domainKey: "ttrssDomain", +}, { + name: "Nextcloud News", + projectUrl: "https://apps.nextcloud.com/apps/news", + key: "nextcloudnews", + domainKey: "nextcloudnewsDomain", +}, { + name: "Feedbin", + projectUrl: "https://feedbin.com/", + key: "feedbin", + domainKey: "feedbinDomain", +}, { + name: "The Old Reader", + projectUrl: "https://theoldreader.com/", + key: "theoldreader", +}, { + name: "Feeds.Pub", + projectUrl: "https://feeds.pub/", + key: "feedspub", +}, { + name: "BazQux Reader", + projectUrl: "https://bazqux.com/", + key: "bazqux", +}, { + name: "CheckChan", + projectUrl: "https://ckc.ftqq.com", + key: "checkchan", + domainKey: "checkchanBase", +}, { + name: chrome.i18n.getMessage("localReader"), + key: "local", +}] \ No newline at end of file diff --git a/src/options/Siderbar.tsx b/src/options/Siderbar.tsx index b6be536..a6d7943 100644 --- a/src/options/Siderbar.tsx +++ b/src/options/Siderbar.tsx @@ -17,7 +17,7 @@ function Siderbar() { }] return ( -
+
RSSHub Radar diff --git a/src/options/index.tsx b/src/options/index.tsx index 4280b15..4d5ee53 100644 --- a/src/options/index.tsx +++ b/src/options/index.tsx @@ -5,9 +5,9 @@ import Siderbar from "./Siderbar" function Options() { return ( -
+
-
+
diff --git a/src/options/routes/General.tsx b/src/options/routes/General.tsx index 563f9ad..a8dbec1 100644 --- a/src/options/routes/General.tsx +++ b/src/options/routes/General.tsx @@ -1,7 +1,83 @@ +import { useState } from "react" +import { Input } from "~/lib/components/Input" +import { Label } from "~/lib/components/Label" +import { Button } from "~/lib/components/Button" +import { defaultConfig, getConfig, setConfig } from "~/lib/config" +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from "~/lib/components/Card" +import { Switch } from "~/lib/components/Switch" +import { quickSubscriptions } from "~/lib/quick-subscriptions" + function General() { + const [config, setConfig] = useState(defaultConfig) + getConfig().then(setConfig) + return (
-

General

+

{chrome.i18n.getMessage("general")}

+
+ + + {chrome.i18n.getMessage("settings")} + + +
+ + +
+
+ + +
+
+
+ + + {chrome.i18n.getMessage("RSSHubRelatedSettings")} + + +
+ + +
+
+ + +
+
+
+ + + {chrome.i18n.getMessage("quickSubscription")} + + + {quickSubscriptions.map((quickSubscription) => ( +
+ + + {quickSubscription.domainKey ? ( + + ) : ( + + )} +
+ ))} +
+
+
) }