feature: bili-toy cloud fallback local

This commit is contained in:
Vick Scarlet
2026-08-16 20:06:16 +08:00
committed by 神戸小鳥
parent 907d0e7d09
commit 2d53a6ca33
4 changed files with 67 additions and 16 deletions
+12 -3
View File
@@ -40,6 +40,13 @@
width: 100%; width: 100%;
> button { flex: 1 0; } > button { flex: 1 0; }
} }
&.loading {
display: flex;
justify-content: center;
align-items: center;
> * { width: auto; }
animation: pulse 1.8s ease-in-out infinite;
}
} }
.saving { .saving {
position: fixed; position: fixed;
@@ -47,9 +54,11 @@
left: 0; left: 0;
opacity: 0; opacity: 0;
user-select: none; user-select: none;
transition: opacity 0.3s;
&.active { &.active {
opacity: 1; animation: pulse 1.8s ease-in-out infinite;
transition: opacity 0.1s;
} }
}
@keyframes pulse {
0%, 100% { opacity: 0.5; }
50% { opacity: 1; }
} }
+7 -4
View File
@@ -1,10 +1,13 @@
import { toastMsg } from '@/toast'
import './Github.css' import './Github.css'
const repo = 'https://github.com/VickScarlet/remake'
export function Github() { export function Github() {
const handleClick = () => {
if (import.meta.env.VITE_CHANNEL === 'bili') toastMsg(repo, 'github')
else window.open(repo)
}
return ( return (
<button <button className="github-btn" onClick={handleClick}>
className="github-btn"
onClick={() => window.open('https://github.com/VickScarlet/remake')}
>
<svg <svg
fill="currentColor" fill="currentColor"
width="800px" width="800px"
-1
View File
@@ -62,7 +62,6 @@ export default function Summary() {
const handleEnd = () => { const handleEnd = () => {
const achievements = end() const achievements = end()
toastAchvs(achievements) toastAchvs(achievements)
console.log('Achievements', achievements)
} }
return ( return (
<div className="screen summary"> <div className="screen summary">
+48 -8
View File
@@ -1,6 +1,7 @@
const PREFIX = 'bili-toy-remake'
const storage = { const storage = {
get: async (keys: string[]) => { get: async (keys: string[]) => {
var result = await toy.getCloudStorage(keys) const result = await toy.getCloudStorage(keys)
if (result && result.data && typeof result.data === 'object') { if (result && result.data && typeof result.data === 'object') {
return result.data return result.data
} }
@@ -24,19 +25,58 @@ export async function init() {
} }
} }
export async function get(key: string) { function getCloudInstance(key: string) {
if (!cloudMap.has(key)) { if (!cloudMap.has(key)) {
const cloud = ToyCloudSaveCore.createCloudSave({ storage, prefix: key }) const cloud = ToyCloudSaveCore.createCloudSave({ storage, prefix: key })
cloudMap.set(key, cloud) cloudMap.set(key, cloud)
} }
return await cloudMap.get(key)!.load() return cloudMap.get(key) || null
} }
export async function set(key: string, value: string) { export async function get(key: string): Promise<string | null> {
if (!cloudMap.has(key)) { const localKey = `${PREFIX}-${key}`
const cloud = ToyCloudSaveCore.createCloudSave({ storage, prefix: key }) const localData = localStorage.getItem(localKey)
cloudMap.set(key, cloud)
const cloud = getCloudInstance(key)
if (!cloud) return localData
try {
const cloudData = await cloud.load()
if (cloudData !== null) {
localStorage.setItem(localKey, cloudData)
return cloudData
}
} catch (error) {
console.error(
`[Bili Storage] 业务 Key '${key}' 云端拉取失败,降级使用本地档:`,
error,
)
}
return localData
}
export async function set(key: string, value: string): Promise<boolean> {
const localKey = `${PREFIX}-${key}`
try {
localStorage.setItem(localKey, value)
} catch (localError) {
console.error(
`[Bili Storage] 本地 LocalStorage 写入崩溃(可能满 5MB 额度):`,
localError,
)
}
const cloud = getCloudInstance(key)
if (!cloud) return true
try {
await cloud.save(value)
} catch (cloudError) {
console.error(
`[Bili Storage] 业务 Key '${key}' 本地已保存,但同步至 B 站云端失败:`,
cloudError,
)
} }
await cloudMap.get(key)!.save(value)
return true return true
} }