mirror of
https://github.com/DIYgod/RSSHub-Radar.git
synced 2026-08-30 16:41:08 +08:00
Merge branch 'pr/hyoban/890' into dev
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
"async-lock": "^1.4.1",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.0",
|
||||
"foxact": "^0.2.31",
|
||||
"he": "1.2.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lucide-react": "^0.324.0",
|
||||
|
||||
Generated
+28
-4
@@ -1,9 +1,5 @@
|
||||
lockfileVersion: '6.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@iconify-json/mingcute':
|
||||
specifier: ^1.1.16
|
||||
@@ -35,6 +31,9 @@ dependencies:
|
||||
clsx:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
foxact:
|
||||
specifier: ^0.2.31
|
||||
version: 0.2.31(react@18.2.0)
|
||||
he:
|
||||
specifier: 1.2.0
|
||||
version: 1.2.0
|
||||
@@ -3863,6 +3862,10 @@ packages:
|
||||
engines: {node: '>= 12'}
|
||||
dev: false
|
||||
|
||||
/client-only@0.0.1:
|
||||
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
|
||||
dev: false
|
||||
|
||||
/clone@1.0.4:
|
||||
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
|
||||
engines: {node: '>=0.8'}
|
||||
@@ -4496,6 +4499,19 @@ packages:
|
||||
fetch-blob: 3.2.0
|
||||
dev: true
|
||||
|
||||
/foxact@0.2.31(react@18.2.0):
|
||||
resolution: {integrity: sha512-NxO/aw7e7wFf+xp8JQi8lDrfrKtIDsWwiFHRBajCO+2oLLgupxSqZV++/amOzxC9dmanDHBN3O2YHGv2LJsJrA==}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
optional: true
|
||||
dependencies:
|
||||
client-only: 0.0.1
|
||||
react: 18.2.0
|
||||
server-only: 0.0.1
|
||||
dev: false
|
||||
|
||||
/fraction.js@4.3.7:
|
||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
||||
dev: true
|
||||
@@ -6606,6 +6622,10 @@ packages:
|
||||
dependencies:
|
||||
lru-cache: 6.0.0
|
||||
|
||||
/server-only@0.0.1:
|
||||
resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==}
|
||||
dev: false
|
||||
|
||||
/set-function-length@1.1.1:
|
||||
resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -7372,3 +7392,7 @@ packages:
|
||||
/zod@3.22.4:
|
||||
resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
|
||||
dev: true
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { useDark } from "~/lib/hooks/use-dark"
|
||||
|
||||
export function AppearanceSwitch({ className = "" }: { className?: string }) {
|
||||
const { toggleDark } = useDark()
|
||||
|
||||
return (
|
||||
<button type="button" onClick={toggleDark} className={"flex " + className}>
|
||||
<div className="i-mingcute-sun-2-line scale-100 dark:scale-0 transition-transform duration-500 rotate-0 dark:-rotate-90" />
|
||||
<div className="i-mingcute-moon-line absolute scale-0 dark:scale-100 transition-transform duration-500 rotate-90 dark:rotate-0" />
|
||||
<span className="sr-only">Toggle theme</span>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
@@ -19,7 +19,7 @@ const buttonVariants = cva(
|
||||
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
rss: "border border-orange-500 text-orange-500 bg-background hover:bg-orange-500 hover:text-white",
|
||||
rss: "border border-primary text-primary bg-background hover:bg-primary hover:text-white",
|
||||
},
|
||||
size: {
|
||||
default: "h-10 px-4 py-2",
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import { useLocalStorage } from "foxact/use-local-storage"
|
||||
import { useEffect, useMemo, useSyncExternalStore } from "react"
|
||||
|
||||
const query = "(prefers-color-scheme: dark)"
|
||||
|
||||
function getSnapshot() {
|
||||
return window.matchMedia(query).matches
|
||||
}
|
||||
|
||||
function getServerSnapshot(): undefined {
|
||||
return undefined
|
||||
}
|
||||
|
||||
function subscribe(callback: () => void) {
|
||||
const matcher = window.matchMedia(query)
|
||||
matcher.addEventListener("change", callback)
|
||||
return () => {
|
||||
matcher.removeEventListener("change", callback)
|
||||
}
|
||||
}
|
||||
|
||||
function useSystemDark() {
|
||||
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)
|
||||
}
|
||||
|
||||
const themeOptions = ["system", "light", "dark"] as const
|
||||
export type Theme = (typeof themeOptions)[number]
|
||||
|
||||
function isDarkMode(setting?: Theme | null, isSystemDark?: boolean) {
|
||||
return setting === "dark" || (isSystemDark && setting !== "light")
|
||||
}
|
||||
|
||||
export function useDark(themeKey = "use-dark") {
|
||||
const [theme, setTheme] = useLocalStorage<Theme>(themeKey, "system")
|
||||
const isSystemDark = useSystemDark()
|
||||
|
||||
const isDark = useMemo(
|
||||
() => isDarkMode(theme, isSystemDark),
|
||||
[isSystemDark, theme],
|
||||
)
|
||||
|
||||
const toggleDark = () => {
|
||||
if (theme === "system") {
|
||||
setTheme(isSystemDark ? "light" : "dark")
|
||||
} else {
|
||||
setTheme("system")
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const isDark = isDarkMode(theme, isSystemDark)
|
||||
if (isDark) {
|
||||
document.documentElement.classList.toggle("dark", true)
|
||||
} else {
|
||||
document.documentElement.classList.toggle("dark", false)
|
||||
}
|
||||
|
||||
if (
|
||||
(theme === "dark" && isSystemDark) ||
|
||||
(theme === "light" && !isSystemDark)
|
||||
) {
|
||||
setTheme("system")
|
||||
}
|
||||
}, [theme, isSystemDark, setTheme])
|
||||
|
||||
return { isDark, toggleDark }
|
||||
}
|
||||
+56
-56
@@ -2,62 +2,62 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 20 14.3% 4.1%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 20 14.3% 4.1%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 20 14.3% 4.1%;
|
||||
--primary: 24.6 95% 53.1%;
|
||||
--primary-foreground: 60 9.1% 97.8%;
|
||||
--secondary: 60 4.8% 95.9%;
|
||||
--secondary-foreground: 24 9.8% 10%;
|
||||
--muted: 60 4.8% 95.9%;
|
||||
--muted-foreground: 25 5.3% 44.7%;
|
||||
--accent: 60 4.8% 95.9%;
|
||||
--accent-foreground: 24 9.8% 10%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
--border: 20 5.9% 90%;
|
||||
--input: 20 5.9% 90%;
|
||||
--ring: 24.6 95% 53.1%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--foreground: 60 9.1% 97.8%;
|
||||
--card: 20 14.3% 4.1%;
|
||||
--card-foreground: 60 9.1% 97.8%;
|
||||
--popover: 20 14.3% 4.1%;
|
||||
--popover-foreground: 60 9.1% 97.8%;
|
||||
--primary: 20.5 90.2% 48.2%;
|
||||
--primary-foreground: 60 9.1% 97.8%;
|
||||
--secondary: 12 6.5% 15.1%;
|
||||
--secondary-foreground: 60 9.1% 97.8%;
|
||||
--muted: 12 6.5% 15.1%;
|
||||
--muted-foreground: 24 5.4% 63.9%;
|
||||
--accent: 12 6.5% 15.1%;
|
||||
--accent-foreground: 60 9.1% 97.8%;
|
||||
--destructive: 0 72.2% 50.6%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
--border: 12 6.5% 15.1%;
|
||||
--input: 12 6.5% 15.1%;
|
||||
--ring: 20.5 90.2% 48.2%;
|
||||
}
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 20 14.3% 4.1%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 20 14.3% 4.1%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 20 14.3% 4.1%;
|
||||
--primary: 24.6 95% 53.1%;
|
||||
--primary-foreground: 60 9.1% 97.8%;
|
||||
--secondary: 60 4.8% 95.9%;
|
||||
--secondary-foreground: 24 9.8% 10%;
|
||||
--muted: 60 4.8% 95.9%;
|
||||
--muted-foreground: 25 5.3% 44.7%;
|
||||
--accent: 60 4.8% 95.9%;
|
||||
--accent-foreground: 24 9.8% 10%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
--border: 20 5.9% 90%;
|
||||
--input: 20 5.9% 90%;
|
||||
--ring: 24.6 95% 53.1%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
|
||||
.content a {
|
||||
@apply underline text-orange-500;
|
||||
}
|
||||
.dark {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--foreground: 60 9.1% 97.8%;
|
||||
--card: 20 14.3% 4.1%;
|
||||
--card-foreground: 60 9.1% 97.8%;
|
||||
--popover: 20 14.3% 4.1%;
|
||||
--popover-foreground: 60 9.1% 97.8%;
|
||||
--primary: 20.5 90.2% 48.2%;
|
||||
--primary-foreground: 60 9.1% 97.8%;
|
||||
--secondary: 12 6.5% 15.1%;
|
||||
--secondary-foreground: 60 9.1% 97.8%;
|
||||
--muted: 12 6.5% 15.1%;
|
||||
--muted-foreground: 24 5.4% 63.9%;
|
||||
--accent: 12 6.5% 15.1%;
|
||||
--accent-foreground: 60 9.1% 97.8%;
|
||||
--destructive: 0 72.2% 50.6%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
--border: 12 6.5% 15.1%;
|
||||
--input: 12 6.5% 15.1%;
|
||||
--ring: 20.5 90.2% 48.2%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
|
||||
.content a {
|
||||
@apply underline text-primary;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import RSSHubIcon from "data-base64:~/assets/icon.png"
|
||||
import { Link, useLocation } from "react-router-dom"
|
||||
|
||||
import { AppearanceSwitch } from "~/lib/components/AppearanceSwitch"
|
||||
import { cn } from "~/lib/utils"
|
||||
|
||||
import info from "../../package.json"
|
||||
@@ -28,7 +29,7 @@ function Siderbar() {
|
||||
return (
|
||||
<div className="flex flex-col h-[calc(100vh-80px)] sticky top-10">
|
||||
<div>
|
||||
<div className="px-4 flex items-center space-x-2 text-orange-500 text-xl font-bold mb-8">
|
||||
<div className="px-4 flex items-center space-x-2 text-primary text-xl font-bold mb-8">
|
||||
<img className="w-10 h-10" src={RSSHubIcon} />
|
||||
<span>RSSHub Radar</span>
|
||||
</div>
|
||||
@@ -40,9 +41,9 @@ function Siderbar() {
|
||||
to={link.path}
|
||||
className={cn(
|
||||
location.pathname === link.path
|
||||
? "bg-orange-50 text-orange-500"
|
||||
? "bg-primary/10 text-primary"
|
||||
: "",
|
||||
"px-4 py-3 hover:bg-orange-50 transition-colors rounded-lg flex items-center space-x-2",
|
||||
"px-4 py-3 hover:bg-primary/10 transition-colors rounded-lg flex items-center space-x-2",
|
||||
)}
|
||||
>
|
||||
<i className={link.icon + " w-5 h-5"}></i>
|
||||
@@ -52,10 +53,11 @@ function Siderbar() {
|
||||
))}
|
||||
</ul>
|
||||
<footer className="text-zinc-500 text-center text-sm">
|
||||
<AppearanceSwitch className="mx-auto mb-2 text-2xl" />
|
||||
<p>Version v{info.version}</p>
|
||||
<p>
|
||||
Made with <span className="text-red-500">♥</span> by{" "}
|
||||
<a className="underline text-orange-500" href="https://diygod.cc/">
|
||||
<a className="underline text-primary" href="https://diygod.cc/">
|
||||
DIYgod
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { MemoryRouter } from "react-router-dom"
|
||||
|
||||
import { Routing } from "~/options/routes"
|
||||
|
||||
import "~/lib/style.css"
|
||||
|
||||
import { Toaster } from "react-hot-toast"
|
||||
import { MemoryRouter } from "react-router-dom"
|
||||
|
||||
import { Routing } from "~/options/routes"
|
||||
|
||||
import Siderbar from "./Siderbar"
|
||||
|
||||
function Options() {
|
||||
return (
|
||||
<div className="max-w-screen-lg mx-auto text-base py-10">
|
||||
<Toaster />
|
||||
<Toaster
|
||||
toastOptions={{
|
||||
className: "!bg-secondary !text-secondary-foreground",
|
||||
}}
|
||||
/>
|
||||
<MemoryRouter>
|
||||
<div className="flex space-x-20 h-full">
|
||||
<Siderbar />
|
||||
|
||||
@@ -12,12 +12,12 @@ function About() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-3xl font-medium leading-10 mb-6 text-orange-500 border-b pb-4">
|
||||
<h1 className="text-3xl font-medium leading-10 mb-6 text-primary border-b pb-4">
|
||||
{chrome.i18n.getMessage("about")}
|
||||
</h1>
|
||||
<div className="space-y-4">
|
||||
<Card>
|
||||
<CardContent className="space-y-4 content text-zinc-700 py-10">
|
||||
<CardContent className="space-y-4 content text-zinc-700 dark:text-zinc-300 py-10">
|
||||
<p
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: chrome.i18n.getMessage("RSSHubRadarInfo"),
|
||||
@@ -60,10 +60,7 @@ function About() {
|
||||
<p> </p>
|
||||
<p>
|
||||
Made with <span className="text-red-500">♥</span> by{" "}
|
||||
<a
|
||||
className="underline text-orange-500"
|
||||
href="https://diygod.cc/"
|
||||
>
|
||||
<a className="underline text-primary" href="https://diygod.cc/">
|
||||
DIYgod
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -39,7 +39,7 @@ function General() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-3xl font-medium leading-10 mb-6 text-orange-500 border-b pb-4">
|
||||
<h1 className="text-3xl font-medium leading-10 mb-6 text-primary border-b pb-4">
|
||||
{chrome.i18n.getMessage("general")}
|
||||
</h1>
|
||||
<div className="space-y-4">
|
||||
|
||||
@@ -112,7 +112,7 @@ function RulesList({
|
||||
<div key={key + item + index}>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="flex-1">
|
||||
<p className="text-sm text-zinc-700">
|
||||
<p className="text-sm text-foreground/70">
|
||||
{subdomainRule.title}
|
||||
</p>
|
||||
</div>
|
||||
@@ -153,7 +153,7 @@ function Rules() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-3xl font-medium leading-10 mb-6 text-orange-500 border-b pb-4">
|
||||
<h1 className="text-3xl font-medium leading-10 mb-6 text-primary border-b pb-4">
|
||||
{chrome.i18n.getMessage("rules")}
|
||||
</h1>
|
||||
<div className="content mb-6 space-y-2">
|
||||
|
||||
@@ -52,7 +52,7 @@ function RSSItem({
|
||||
<a
|
||||
target="_blank"
|
||||
href={url}
|
||||
className="w-48 cursor-pointer flex flex-col justify-between text-black flex-1"
|
||||
className="w-48 cursor-pointer flex flex-col justify-between text-black dark:text-white flex-1"
|
||||
>
|
||||
<span className="text-[13px] truncate">{item.title}</span>
|
||||
<span className="text-xs truncate text-zinc-400">
|
||||
|
||||
+6
-3
@@ -1,14 +1,17 @@
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import "~/lib/style.css"
|
||||
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import { sendToBackground } from "@plasmohq/messaging"
|
||||
|
||||
import { useDark } from "~/lib/hooks/use-dark"
|
||||
import report from "~/lib/report"
|
||||
|
||||
import RSSList from "./RSSList"
|
||||
|
||||
function IndexPopup() {
|
||||
useDark()
|
||||
|
||||
const [data, setData] = useState({
|
||||
pageRSS: [],
|
||||
pageRSSHub: [],
|
||||
@@ -50,7 +53,7 @@ function IndexPopup() {
|
||||
href="/options.html"
|
||||
target="_blank"
|
||||
>
|
||||
<i className="i-mingcute-settings-3-line w-5 h-5 text-slate-600 hover:text-black transition-colors"></i>
|
||||
<i className="i-mingcute-settings-3-line w-5 h-5 text-slate-600 dark:text-slate-400 hover:text-black dark:hover:text-white transition-colors"></i>
|
||||
</a>
|
||||
{!data.pageRSS.length &&
|
||||
!data.pageRSSHub.length &&
|
||||
|
||||
Reference in New Issue
Block a user