mirror of
https://github.com/SteamFramelyHomebrew/framely.git
synced 2026-10-21 03:01:43 +02:00
16 lines
4.3 KiB
TypeScript
16 lines
4.3 KiB
TypeScript
import {SwitchRow} from './switch';
|
|
import {t} from './i18n';
|
|
import React,{useState} from 'react';
|
|
import {api} from './api';import {runJob} from './store';
|
|
export type Subscription={id:string;name:string;url:string;enabled:boolean;autoRefresh:boolean;lastSuccess?:number;nextRefresh:number;error?:string;entries:{id:string;name:string;url:string}[];pending:{id:string;name:string;url:string}[]};
|
|
export function Subscriptions({subscriptions,refresh}:{subscriptions:Subscription[];refresh:()=>Promise<void>}){
|
|
const[url,setUrl]=useState(''),[preview,setPreview]=useState<any>(null),[busy,setBusy]=useState(false),[error,setError]=useState(''),[confirm,setConfirm]=useState<{sub:Subscription;kind:'remove'|'acceptUrls'}|null>(null);
|
|
async function execute(f:()=>Promise<unknown>){setBusy(true);setError('');try{await f();await refresh();}catch(e){setError(String(e));}finally{setBusy(false);}}
|
|
return <section className="settings-card"><h2>{t("源订阅")}</h2><p className="sub">{t("每天同步订阅中的插件源;不自动安装或更新插件。")}</p>
|
|
{subscriptions.map(s=><article className="source-row" key={s.id}><div><b>{s.name}</b><span className="badge">{s.enabled?t("已启用"):t("已停用")} · {s.entries.length}{t("个源")}</span><p className="source-url">{s.url}</p><small>{s.lastSuccess?t("上次成功:{0}", {"0": new Date(s.lastSuccess).toLocaleString()}):t("尚未成功刷新")} · {s.autoRefresh?t("每天自动刷新"):t("仅手动刷新")}</small>{s.error&&<p className="error">{s.error}{t(",保留上次成功列表。")}</p>}{!!s.pending.length&&<p className="banner">{s.pending.length}{t("个源地址发生变化,等待确认。")}</p>}<details><summary>{t("包含的源")}</summary>{s.entries.map(e=><p key={e.id}>{e.name}<small className="source-url">{e.url}</small></p>)}</details></div><div className="row"><SwitchRow checked={s.enabled} label={t("启用 {0}",{0:s.name})} disabled={busy} onChange={enabled=>void execute(()=>api('subscriptions.change',{id:s.id,enabled}))}/><button disabled={busy||!s.enabled} onClick={()=>void execute(()=>runJob('subscriptions.refresh.start',{id:s.id}))}>{t("立即刷新")}</button><SwitchRow checked={s.autoRefresh} label={t("每天自动刷新")} disabled={busy} onChange={autoRefresh=>void execute(()=>api('subscriptions.change',{id:s.id,autoRefresh}))}/>{!!s.pending.length&&<button onClick={()=>setConfirm({sub:s,kind:'acceptUrls'})}>{t("查看地址变更")}</button>}<button className="danger" onClick={()=>setConfirm({sub:s,kind:'remove'})}>{t("删除订阅")}</button></div></article>)}
|
|
<label>{t("订阅地址")}<input type="url" value={url} onChange={e=>setUrl(e.target.value)} placeholder="https://example.org/subscription.json"/></label><button disabled={busy||!url.trim()} onClick={()=>void execute(async()=>{const v=await runJob('subscriptions.preview.start',{url:url.trim()});setPreview(v.result);})}>{t("预览订阅")}</button>{error&&<p className="error">{error}</p>}
|
|
{preview&&<div className="modal"><h2>{t("添加订阅:")}{preview.document.name}</h2><p>{preview.document.sources.length}{t("个源 · 默认每天刷新")}</p>{preview.document.sources.map((s:any)=><p key={s.id}><b>{s.name}</b><small className="source-url">{s.url}</small></p>)}<button className="primary" disabled={busy} onClick={()=>void execute(async()=>{await api('subscriptions.add',{...preview,approve:true});setPreview(null);setUrl('');})}>{t("确认添加")}</button><button disabled={busy} onClick={()=>setPreview(null)}>{t("取消")}</button></div>}
|
|
{confirm&&<div className="modal"><h2>{confirm.kind==='remove'?t("删除订阅"):t("确认源地址变更")}</h2><p>{confirm.sub.name}</p>{confirm.kind==='remove'?<p>{t("移除此订阅对各源的引用;其他订阅共享的源和手动源会保留。已安装插件保留。")}</p>:confirm.sub.pending.map(next=><div key={next.id}><b>{next.name}</b><p className="source-url">{t("原地址:")}{confirm.sub.entries.find(e=>e.id===next.id)?.url}</p><p className="source-url">{t("新地址:")}{next.url}</p></div>)}<button disabled={busy} className="primary" onClick={()=>void execute(async()=>{await api('subscriptions.change',{id:confirm.sub.id,[confirm.kind]:true,approve:true});setConfirm(null);})}>{t("确认")}</button><button disabled={busy} onClick={()=>setConfirm(null)}>{t("取消")}</button></div>}
|
|
</section>
|
|
}
|