alert before clean browsers

This commit is contained in:
Julian Freeman
2026-04-17 12:05:33 -04:00
parent ab1da1ff0e
commit 8764af1a56
7 changed files with 109 additions and 8 deletions

View File

@@ -19,7 +19,7 @@ fn get_fast_cleaning_configs() -> Vec<CleaningConfig> {
Some(10),
true,
));
configs.push(CleaningConfig::new("回收站", "C:\\$Recycle.Bin", None, false));
configs.push(CleaningConfig::new("回收站", "C:\\$Recycle.Bin", None, true));
configs.push(CleaningConfig::new(
"内核转储文件",
"C:\\Windows\\LiveKernelReports",

View File

@@ -8,7 +8,14 @@ import DiskAnalysisPage from "./pages/DiskAnalysisPage.vue";
import FastCleanPage from "./pages/FastCleanPage.vue";
import MemoryCleanPage from "./pages/MemoryCleanPage.vue";
import { openInExplorer, openSearch } from "./services/tauri/cleaner";
import type { AlertOptions, FileNode, ModalType, Tab } from "./types/cleaner";
import type {
AlertOptions,
ConfirmOptions,
FileNode,
ModalMode,
ModalType,
Tab,
} from "./types/cleaner";
const activeTab = ref<Tab>("clean-c-fast");
const isCMenuOpen = ref(true);
@@ -18,6 +25,10 @@ const showModal = ref(false);
const modalTitle = ref("");
const modalMessage = ref("");
const modalType = ref<ModalType>("info");
const modalMode = ref<ModalMode>("alert");
const modalConfirmText = ref("确定");
const modalCancelText = ref("取消");
let modalResolver: ((confirmed: boolean) => void) | null = null;
const contextMenu = ref({
show: false,
@@ -27,14 +38,53 @@ const contextMenu = ref({
});
function showAlert({ title, message, type = "info" }: AlertOptions) {
modalMode.value = "alert";
modalTitle.value = title;
modalMessage.value = message;
modalType.value = type;
modalConfirmText.value = "确定";
showModal.value = true;
}
function requestConfirm({
title,
message,
type = "info",
confirmText = "确定",
cancelText = "取消",
}: ConfirmOptions) {
if (modalResolver) {
modalResolver(false);
modalResolver = null;
}
modalMode.value = "confirm";
modalTitle.value = title;
modalMessage.value = message;
modalType.value = type;
modalConfirmText.value = confirmText;
modalCancelText.value = cancelText;
showModal.value = true;
return new Promise<boolean>((resolve) => {
modalResolver = resolve;
});
}
function closeModal() {
showModal.value = false;
if (modalResolver) {
modalResolver(false);
modalResolver = null;
}
}
function confirmModal() {
showModal.value = false;
if (modalResolver) {
modalResolver(true);
modalResolver = null;
}
}
function handleContextMenu(event: MouseEvent, node: FileNode) {
@@ -95,11 +145,13 @@ async function searchNode(provider: "google" | "perplexity") {
v-else-if="activeTab === 'clean-browser-chrome'"
browser="chrome"
:show-alert="showAlert"
:request-confirm="requestConfirm"
/>
<BrowserCleanPage
v-else-if="activeTab === 'clean-browser-edge'"
browser="edge"
:show-alert="showAlert"
:request-confirm="requestConfirm"
/>
<DiskAnalysisPage
v-else-if="activeTab === 'clean-c-deep'"
@@ -148,7 +200,11 @@ async function searchNode(provider: "google" | "perplexity") {
:title="modalTitle"
:message="modalMessage"
:type="modalType"
:mode="modalMode"
:confirm-text="modalConfirmText"
:cancel-text="modalCancelText"
@close="closeModal"
@confirm="confirmModal"
/>
</div>
</template>

View File

@@ -1,15 +1,19 @@
<script setup lang="ts">
import type { ModalType } from "../../types/cleaner";
import type { ModalMode, ModalType } from "../../types/cleaner";
defineProps<{
open: boolean;
title: string;
message: string;
type: ModalType;
mode?: ModalMode;
confirmText?: string;
cancelText?: string;
}>();
const emit = defineEmits<{
close: [];
confirm: [];
}>();
</script>
@@ -27,8 +31,13 @@ const emit = defineEmits<{
<div class="modal-body">
<p>{{ message }}</p>
</div>
<div class="modal-footer">
<button class="btn-primary" @click="emit('close')">确定</button>
<div class="modal-footer" :class="{ 'is-confirm': mode === 'confirm' }">
<button v-if="mode === 'confirm'" class="btn-secondary modal-btn" @click="emit('close')">
{{ cancelText || "取消" }}
</button>
<button class="btn-primary modal-btn" @click="mode === 'confirm' ? emit('confirm') : emit('close')">
{{ mode === "confirm" ? confirmText || "确定清理" : confirmText || "确定" }}
</button>
</div>
</div>
</div>

View File

@@ -3,7 +3,12 @@ import {
startBrowserClean as runBrowserCleanCommand,
startBrowserScan as runBrowserScanCommand,
} from "../services/tauri/cleaner";
import type { AlertOptions, BrowserScanResult, CleanResult } from "../types/cleaner";
import type {
AlertOptions,
BrowserScanResult,
CleanResult,
ConfirmOptions,
} from "../types/cleaner";
import { formatItemSize } from "../utils/format";
interface BrowserState {
@@ -17,6 +22,7 @@ interface BrowserState {
export function useBrowserClean(
browser: "chrome" | "edge",
showAlert: (options: AlertOptions) => void,
requestConfirm: (options: ConfirmOptions) => Promise<boolean>,
) {
const state = ref<BrowserState>({
isScanning: false,
@@ -83,6 +89,19 @@ export function useBrowserClean(
return;
}
const browserName = browser === "chrome" ? "谷歌浏览器" : "微软浏览器";
const confirmed = await requestConfirm({
title: "确认清理浏览器缓存",
message: `即将清理 ${browserName} 的缓存和临时文件。\n\n建议先关闭浏览器以避免部分文件被占用导致清理不完整。\n\n是否继续`,
type: "info",
confirmText: "继续清理",
cancelText: "暂不清理",
});
if (!confirmed) {
return;
}
current.isCleaning = true;
try {
current.cleanResult = await runBrowserCleanCommand(browser, selectedProfiles);

View File

@@ -1,15 +1,16 @@
<script setup lang="ts">
import { useBrowserClean } from "../composables/useBrowserClean";
import type { AlertOptions } from "../types/cleaner";
import type { AlertOptions, ConfirmOptions } from "../types/cleaner";
import { splitSize } from "../utils/format";
const props = defineProps<{
browser: "chrome" | "edge";
showAlert: (options: AlertOptions) => void;
requestConfirm: (options: ConfirmOptions) => Promise<boolean>;
}>();
const { state, selectedStats, startScan, startClean, toggleAllProfiles, invertProfiles, reset } =
useBrowserClean(props.browser, props.showAlert);
useBrowserClean(props.browser, props.showAlert, props.requestConfirm);
const browserName = props.browser === "chrome" ? "谷歌浏览器" : "微软浏览器";
</script>

View File

@@ -462,11 +462,21 @@
color: var(--text-sec);
font-size: 15px;
line-height: 1.6;
white-space: pre-line;
}
.modal-footer {
display: flex;
justify-content: center;
gap: 12px;
}
.modal-footer.is-confirm {
justify-content: center;
}
.modal-btn {
min-width: 120px;
}
.context-menu {

View File

@@ -65,9 +65,15 @@ export interface ScanProgressPayload {
}
export type ModalType = "info" | "success" | "error";
export type ModalMode = "alert" | "confirm";
export interface AlertOptions {
title: string;
message: string;
type?: ModalType;
}
export interface ConfirmOptions extends AlertOptions {
confirmText?: string;
cancelText?: string;
}