feat(settings): enhance data export functionality and UI improvements

- Updated the data control settings to include a new export data feature with improved UI elements.
- Refactored the modal dialog to utilize the new `useDialog` hook for confirmation prompts.
- Enhanced localization strings for clarity and consistency in export-related descriptions.
- Added success feedback for cache cleaning actions to improve user experience.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei 2025-06-07 01:48:03 +08:00
parent e05fc74ca3
commit e0ff343ac0
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
7 changed files with 61 additions and 55 deletions

View File

@ -166,8 +166,8 @@ export const useDialog = (): DialogInstance => {
</div>
),
content: ({ dismiss }) => (
<div className="flex max-w-[75ch] flex-col gap-3">
{options.message}
<div className="flex max-w-prose flex-col gap-3">
<div className="whitespace-pre">{options.message}</div>
<div className="flex items-center justify-end gap-3">
<Button

View File

@ -19,10 +19,11 @@ import { zodResolver } from "@hookform/resolvers/zod"
import { useQuery } from "@tanstack/react-query"
import { useForm } from "react-hook-form"
import { useTranslation } from "react-i18next"
import { toast } from "sonner"
import { z } from "zod"
import { setGeneralSetting, useGeneralSettingValue } from "~/atoms/settings/general"
import { useModalStack } from "~/components/ui/modal/stacked/hooks"
import { useDialog, useModalStack } from "~/components/ui/modal/stacked/hooks"
import { exportDB } from "~/database"
import { ipcServices } from "~/lib/client"
import { queryClient } from "~/lib/query-client"
@ -36,59 +37,32 @@ const { defineSettingItem, SettingBuilder } = createSetting(
useGeneralSettingValue,
setGeneralSetting,
)
export const SettingDataControl = () => {
const { t } = useTranslation("settings")
const { present } = useModalStack()
const { ask } = useDialog()
return (
<div className="mt-4">
{/* Top Level - Most Important */}
<SettingBuilder
settings={[
{
type: "title",
value: t("general.data"),
},
defineSettingItem("dataPersist", {
label: t("general.data_persist.label"),
description: t("general.data_persist.description"),
}),
{
label: t("general.rebuild_database.label"),
action: () => {
present({
title: t("general.rebuild_database.title"),
clickOutsideToDismiss: true,
content: () => (
<div className="text-sm">
<p>{t("general.rebuild_database.warning.line1")}</p>
<p>{t("general.rebuild_database.warning.line2")}</p>
<div className="mt-4 flex justify-end">
<Button
buttonClassName="bg-red-500 px-3 text-white"
onClick={async () => {
await clearLocalPersistStoreData()
window.location.reload()
}}
>
{t("ok", { ns: "common" })}
</Button>
</div>
</div>
),
})
},
description: t("general.rebuild_database.description"),
buttonText: t("general.rebuild_database.button"),
},
{
label: t("general.export_database.label"),
description: t("general.export_database.description"),
buttonText: t("general.export_database.button"),
action: () => {
exportDB()
},
type: "title",
value: t("general.export_data.title"),
},
{
label: t("general.export.label"),
description: t("general.export.description"),
@ -101,16 +75,37 @@ export const SettingDataControl = () => {
})
},
},
ELECTRON_BUILD && {
type: "title",
value: t("general.cache"),
{
label: t("general.export_database.label"),
description: t("general.export_database.description"),
buttonText: t("general.export_database.button"),
action: () => {
exportDB()
},
},
ELECTRON_BUILD && AppCacheLimit,
ELECTRON_BUILD ? CleanElectronCache : CleanCacheStorage,
ELECTRON_BUILD && {
{
type: "title",
value: t("general.data_file.label"),
value: t("general.maintenance.title"),
},
ELECTRON_BUILD ? CleanElectronCache : CleanCacheStorage,
ELECTRON_BUILD && AppCacheLimit,
{
label: t("general.rebuild_database.label"),
action: () => {
ask({
title: t("general.rebuild_database.title"),
variant: "danger",
message: `${t("general.rebuild_database.warning.line1")}\n${t("general.rebuild_database.warning.line2")}`,
confirmText: t("ok", { ns: "common" }),
onConfirm: async () => {
await clearLocalPersistStoreData()
window.location.reload()
},
})
},
description: t("general.rebuild_database.description"),
buttonText: t("general.rebuild_database.button"),
},
ELECTRON_BUILD && {
label: t("general.log_file.label"),
@ -227,7 +222,9 @@ const CleanCacheStorage = () => {
if (key.startsWith("workbox-precache-")) return null
return caches.delete(key)
}),
)
).then(() => {
toast.success(t("data_control.clean_cache.success"))
})
}}
buttonText={t("data_control.clean_cache.button")}
/>

View File

@ -48,7 +48,7 @@ export const StepPreferences = () => {
>
<View className="flex flex-row items-center justify-between">
<Text className="text-text text-base font-medium">
{t("general.language", { ns: "settings" })}
{t("general.language.title", { ns: "settings" })}
</Text>
<View className="w-[150px]">
<LanguageSelect settingKey="language" />

View File

@ -157,6 +157,7 @@
"data_control.clean_cache.clear": "Clear",
"data_control.clean_cache.description": "Clean the app cache to free up space.",
"data_control.clean_cache.description_web": "Clean the web app service worker cache to free up space.",
"data_control.clean_cache.success": "Cache cleaned successfully.",
"data_control.data_sources": "Data Sources",
"data_control.export_local_database.label": "Export local database",
"data_control.import_opml.label": "Import subscriptions from OPML",
@ -200,17 +201,18 @@
"general.enhanced.enabled.tip": "Enhanced settings are enabled, you can disable them in the General settings - Advanced.",
"general.enhanced.label": "Enhanced Settings",
"general.export.button": "Export",
"general.export.description": "Export your feeds to an OPML file.",
"general.export.description": "Export your list of feed subscriptions.",
"general.export.folder_mode.description": "Decide how you want to organize your export folders.",
"general.export.folder_mode.label": "Folder Mode",
"general.export.folder_mode.option.category": "Category",
"general.export.folder_mode.option.view": "View",
"general.export.label": "Export Feeds",
"general.export.label": "Export Feeds (OPML)",
"general.export.rsshub_url.description": "Default base URL for RSSHub route, leave it empty to use https://rsshub.app.",
"general.export.rsshub_url.label": "RSSHub URL",
"general.export_data.title": "Export Data",
"general.export_database.button": "Export",
"general.export_database.description": "Export your database to a JSON file.",
"general.export_database.label": "Export Database",
"general.export_database.description": "Export all your data, including articles (Full Backup).",
"general.export_database.label": "Export Database (JSON)",
"general.group_by_date.description": "Group entries by date.",
"general.group_by_date.label": "Group by date",
"general.hide_all_read_subscriptions.description": "Hide subscriptions without unread entries in the subscription list.",
@ -223,6 +225,7 @@
"general.log_file.button": "Reveal",
"general.log_file.description": "Reveal the log file in the system.",
"general.log_file.label": "Log File",
"general.maintenance.title": "Maintenance",
"general.mark_as_read.hover.description": "Automatically mark entries as read when hovered.",
"general.mark_as_read.hover.label": "When hovering over article",
"general.mark_as_read.render.description": "Mark items like social posts or images as read immediately.",

View File

@ -201,6 +201,7 @@
"general.export.label": "フィードをエクスポート",
"general.export.rsshub_url.description": "RSSHub ルートの基準となるデフォルト URL を指定します、空欄だと https://rsshub.app で設定します。",
"general.export.rsshub_url.label": "RSSHub URL",
"general.export_data.title": "データをエクスポート",
"general.export_database.button": "エクスポート",
"general.export_database.description": "データベースを JSON ファイルでエクスポート",
"general.export_database.label": "データベースをエクスポート",
@ -216,6 +217,7 @@
"general.log_file.button": "ログ",
"general.log_file.description": "システムにログファイルがあると表示します。",
"general.log_file.label": "ログファイル",
"general.maintenance.title": "メンテナンス",
"general.mark_as_read.hover.description": "ホバー時にエントリを自動的に既読にします。",
"general.mark_as_read.hover.label": "記事にホバーしたとき",
"general.mark_as_read.render.description": "ソーシャルメディアの投稿や画像などの単一項目を即座に既読にマークします。",

View File

@ -193,17 +193,18 @@
"general.enhanced.enabled.tip": "增强设置已启用,你可以在「通用」设置的「高级」选项中将其停用。",
"general.enhanced.label": "增强设置",
"general.export.button": "导出",
"general.export.description": "将你的订阅源导出到 OPML 文件。",
"general.export.description": "导出你的订阅源列表。",
"general.export.folder_mode.description": "决定你想要如何组织导出文件夹。",
"general.export.folder_mode.label": "文件夹模式",
"general.export.folder_mode.option.category": "分类",
"general.export.folder_mode.option.view": "视图",
"general.export.label": "导出订阅源",
"general.export.label": "导出订阅源 (OPML)",
"general.export.rsshub_url.description": "RSSHub 路由的默认根 URL留空则使用 https://rsshub.app。",
"general.export.rsshub_url.label": "RSSHub URL",
"general.export_data.title": "导出数据",
"general.export_database.button": "导出",
"general.export_database.description": "将你的数据库导出到 JSON 文件。",
"general.export_database.label": "导出数据库",
"general.export_database.description": "导出你的所有数据,包括文章(完整备份)。",
"general.export_database.label": "导出数据库 (JSON)",
"general.group_by_date.description": "按日期对条目进行分组。",
"general.group_by_date.label": "按日期分组",
"general.hide_all_read_subscriptions.description": "在订阅列表中隐藏没有未读条目的订阅。",
@ -216,6 +217,7 @@
"general.log_file.button": "显示",
"general.log_file.description": "在系统中显示日志文件。",
"general.log_file.label": "日志文件",
"general.maintenance.title": "维护",
"general.mark_as_read.hover.description": "当鼠标悬停在条目时自动将其标记为已读。",
"general.mark_as_read.hover.label": "悬停在文章上时",
"general.mark_as_read.render.description": "将社交媒体贴文或图片等单项内容立即标记为已读。",

View File

@ -201,6 +201,7 @@
"general.export.label": "匯出 RSS 摘要",
"general.export.rsshub_url.description": "RSSHub 路由的預設基礎 URL留空則使用 https://rsshub.app。",
"general.export.rsshub_url.label": "RSSHub URL",
"general.export_data.title": "匯出資料",
"general.export_database.button": "匯出",
"general.export_database.description": "將你的資料庫匯出成 JSON 檔案。",
"general.export_database.label": "匯出資料庫",
@ -216,6 +217,7 @@
"general.log_file.button": "顯示",
"general.log_file.description": "在系統中顯示記錄檔案。",
"general.log_file.label": "記錄檔案",
"general.maintenance.title": "維護",
"general.mark_as_read.hover.description": "游標懸停時自動將條目標記為已讀。",
"general.mark_as_read.hover.label": "滑鼠懸停在文章上時",
"general.mark_as_read.render.description": "將社群媒體貼文或圖片等單項內容立即標記為已讀。",