Files
paseo/packages/app/src/components/quitting-overlay.tsx
T
chyendongnhanh338andGitHub 08ebe5e7e1 Complete client UI i18n migration
Adds client-side i18n support, language settings, translated UI copy, and locale parity coverage.
2026-06-11 14:15:35 +08:00

70 lines
1.7 KiB
TypeScript

import { useEffect, useState } from "react";
import { Text, View } from "react-native";
import { useTranslation } from "react-i18next";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
import { LoadingSpinner } from "@/components/ui/loading-spinner";
import { getIsElectronRuntime } from "@/constants/layout";
import { listenToDesktopEvent } from "@/desktop/electron/events";
export function QuittingOverlay() {
const { t } = useTranslation();
const { theme } = useUnistyles();
const [quitting, setQuitting] = useState(false);
useEffect(() => {
if (!getIsElectronRuntime()) return;
let cancelled = false;
let unlisten: (() => void) | null = null;
void listenToDesktopEvent("quitting", () => {
if (!cancelled) setQuitting(true);
}).then((fn) => {
if (cancelled) {
fn();
} else {
unlisten = fn;
}
return undefined;
});
return () => {
cancelled = true;
unlisten?.();
};
}, []);
if (!quitting) return null;
return (
<View style={styles.overlay}>
<LoadingSpinner size="large" color={theme.colors.foregroundMuted} />
<Text style={styles.title}>{t("desktop.quitting.title")}</Text>
<Text style={styles.detail}>{t("desktop.quitting.detail")}</Text>
</View>
);
}
const styles = StyleSheet.create((theme) => ({
overlay: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: theme.colors.surface1,
alignItems: "center",
justifyContent: "center",
gap: theme.spacing[3],
zIndex: 9999,
},
title: {
color: theme.colors.foreground,
fontSize: theme.fontSize.base,
},
detail: {
color: theme.colors.foregroundMuted,
fontSize: theme.fontSize.sm,
},
}));