mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-09-03 03:38:52 +00:00
ADD - animate factory reset progress
This commit is contained in:
@@ -332,6 +332,9 @@ const defaultLocales: LocaleTree = {
|
||||
factoryReset: 'Erase All Content and Settings',
|
||||
factoryResetBody:
|
||||
'This removes the account and all local data from this phone. Cloud data and the IMEI remain.',
|
||||
factoryResetProgress: 'Erasing iFruit Phone',
|
||||
factoryResetWarning:
|
||||
'Do not turn off this phone. This takes 60 seconds.',
|
||||
accountErrors: {
|
||||
invalid_email: 'Choose a valid 3–32 character iFruit address.',
|
||||
invalid_password: 'Password must be 6–64 characters.',
|
||||
|
||||
@@ -32,7 +32,13 @@ import {
|
||||
UserRound,
|
||||
Volume2,
|
||||
} from 'lucide-vue-next'
|
||||
import { computed, nextTick, ref, type ComponentPublicInstance } from 'vue'
|
||||
import {
|
||||
computed,
|
||||
nextTick,
|
||||
onBeforeUnmount,
|
||||
ref,
|
||||
type ComponentPublicInstance,
|
||||
} from 'vue'
|
||||
|
||||
import { PHONE_FRAME_IMAGES } from '@/config/appearance'
|
||||
import { PHONE_APPS } from '@/config/apps'
|
||||
@@ -66,6 +72,9 @@ type SettingsView =
|
||||
type RootToggleKey = 'airplaneMode' | 'streamerMode'
|
||||
type SubmenuView = Exclude<SettingsView, 'root' | 'notification-detail'>
|
||||
|
||||
const FACTORY_RESET_DURATION_MS = 60_000
|
||||
const FACTORY_RESET_CIRCUMFERENCE = 2 * Math.PI * 48
|
||||
|
||||
const phone = usePhoneStore()
|
||||
const account = useAccountStore()
|
||||
const query = ref('')
|
||||
@@ -82,6 +91,13 @@ const removeDeviceImei = ref('')
|
||||
const removeDevicePassword = ref('')
|
||||
const removeDeviceOpened = ref(false)
|
||||
const resetOpened = ref(false)
|
||||
const factoryResetting = ref(false)
|
||||
const factoryResetProgress = ref(0)
|
||||
const factoryResetDashOffset = computed(
|
||||
() =>
|
||||
FACTORY_RESET_CIRCUMFERENCE * (1 - factoryResetProgress.value / 100),
|
||||
)
|
||||
let factoryResetAnimationFrame: number | undefined
|
||||
|
||||
const toggleRows = [
|
||||
{
|
||||
@@ -293,8 +309,42 @@ async function confirmRemoveDevice(): Promise<void> {
|
||||
|
||||
async function confirmFactoryReset(): Promise<void> {
|
||||
resetOpened.value = false
|
||||
if (!(await account.factoryReset())) accountToast.value = accountError()
|
||||
factoryResetting.value = true
|
||||
factoryResetProgress.value = 0
|
||||
const startedAt = performance.now()
|
||||
|
||||
const animateProgress = (now: number): void => {
|
||||
factoryResetProgress.value = Math.min(
|
||||
100,
|
||||
((now - startedAt) / FACTORY_RESET_DURATION_MS) * 100,
|
||||
)
|
||||
if (factoryResetProgress.value < 100) {
|
||||
factoryResetAnimationFrame = requestAnimationFrame(animateProgress)
|
||||
}
|
||||
}
|
||||
factoryResetAnimationFrame = requestAnimationFrame(animateProgress)
|
||||
|
||||
const [success] = await Promise.all([
|
||||
account.factoryReset(),
|
||||
new Promise<void>((resolve) =>
|
||||
window.setTimeout(resolve, FACTORY_RESET_DURATION_MS),
|
||||
),
|
||||
])
|
||||
|
||||
if (factoryResetAnimationFrame !== undefined) {
|
||||
cancelAnimationFrame(factoryResetAnimationFrame)
|
||||
factoryResetAnimationFrame = undefined
|
||||
}
|
||||
factoryResetProgress.value = 100
|
||||
factoryResetting.value = false
|
||||
if (!success) accountToast.value = accountError()
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (factoryResetAnimationFrame !== undefined) {
|
||||
cancelAnimationFrame(factoryResetAnimationFrame)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -888,6 +938,57 @@ async function confirmFactoryReset(): Promise<void> {
|
||||
</template>
|
||||
</k-page>
|
||||
|
||||
<div
|
||||
v-if="factoryResetting"
|
||||
class="fixed inset-0 z-[100] flex flex-col items-center justify-center bg-black px-8 text-center text-white"
|
||||
>
|
||||
<div
|
||||
class="relative flex h-28 w-28 items-center justify-center"
|
||||
role="progressbar"
|
||||
:aria-label="phone.t('Apps.settings.factoryResetProgress')"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
:aria-valuenow="Math.floor(factoryResetProgress)"
|
||||
>
|
||||
<svg
|
||||
class="h-28 w-28 -rotate-90"
|
||||
viewBox="0 0 112 112"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<circle
|
||||
cx="56"
|
||||
cy="56"
|
||||
r="48"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="6"
|
||||
class="text-white/15"
|
||||
/>
|
||||
<circle
|
||||
cx="56"
|
||||
cy="56"
|
||||
r="48"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="6"
|
||||
stroke-linecap="round"
|
||||
:stroke-dasharray="FACTORY_RESET_CIRCUMFERENCE"
|
||||
:stroke-dashoffset="factoryResetDashOffset"
|
||||
class="text-white"
|
||||
/>
|
||||
</svg>
|
||||
<span class="absolute text-xl font-semibold tabular-nums">
|
||||
{{ Math.floor(factoryResetProgress) }}%
|
||||
</span>
|
||||
</div>
|
||||
<h2 class="mt-8 text-xl font-semibold">
|
||||
{{ phone.t('Apps.settings.factoryResetProgress') }}
|
||||
</h2>
|
||||
<p class="mt-3 max-w-64 text-sm leading-5 text-white/55">
|
||||
{{ phone.t('Apps.settings.factoryResetWarning') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<k-dialog
|
||||
:opened="removeDeviceOpened"
|
||||
@backdropclick="removeDeviceOpened = false"
|
||||
|
||||
@@ -133,6 +133,7 @@ Locales["en"] = {
|
||||
imei = "IMEI", linkedDevices = "Linked Devices", thisDevice = "This Phone", removeDevice = "Remove Device",
|
||||
removeDeviceBody = "Enter your iFruit password to remove this device from the account.", signOut = "Sign Out",
|
||||
factoryReset = "Erase All Content and Settings", factoryResetBody = "This removes the account and all local data from this phone. Cloud data and the IMEI remain.",
|
||||
factoryResetProgress = "Erasing iFruit Phone", factoryResetWarning = "Do not turn off this phone. This takes 60 seconds.",
|
||||
accountErrors = {
|
||||
invalid_email = "Choose a valid 3–32 character iFruit address.", invalid_password = "Password must be 6–64 characters.",
|
||||
invalid_credentials = "Email or password is incorrect.", email_taken = "That iFruit address is already registered.",
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Sky Phone</title>
|
||||
<script type="module" crossorigin src="./assets/sky-index-BOG1PqIF.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/sky-index-CFphfAe0.css">
|
||||
<script type="module" crossorigin src="./assets/sky-index-BgUSnAVU.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/sky-index-CsEJ7-yo.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
Reference in New Issue
Block a user