mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-08-28 17:21:05 +00:00
fix(cloud PFP): Not pulling from cloud on page load
This commit is contained in:
@@ -1,25 +1,34 @@
|
||||
<script lang="ts">
|
||||
import localforage from 'localforage'
|
||||
import { onMount } from 'svelte'
|
||||
import browser from 'webextension-polyfill'
|
||||
import CloudPfpAvatar from '@/interface/components/CloudPfpAvatar.svelte'
|
||||
import { cloudAuth } from '@/seqta/utils/CloudAuth'
|
||||
import {
|
||||
clearCloudProfilePicture,
|
||||
isUseCloudPfpEnabled,
|
||||
notifyProfilePictureChanged,
|
||||
pullCloudProfilePictureFromServer,
|
||||
syncLocalProfilePictureToCloud,
|
||||
} from '@/seqta/utils/cloudPfpSync'
|
||||
|
||||
let value = $state<string | undefined>(undefined)
|
||||
let fileInput = $state<HTMLInputElement | undefined>(undefined)
|
||||
let dragging = $state(false)
|
||||
let blobUrl = $state<string | undefined>(undefined)
|
||||
let useCloudPfp = $state(false)
|
||||
let refreshingCloud = $state(false)
|
||||
let cloudRefreshError = $state<string | undefined>(undefined)
|
||||
|
||||
// Setup localforage instance
|
||||
const store = localforage.createInstance({
|
||||
name: 'profile-picture-store',
|
||||
storeName: 'profilePicture',
|
||||
})
|
||||
|
||||
async function load() {
|
||||
useCloudPfp = await isUseCloudPfpEnabled()
|
||||
const blob = await store.getItem<Blob>('profile-picture')
|
||||
if (blob && blob instanceof Blob) {
|
||||
// Revoke old blobUrl if any
|
||||
if (blobUrl) URL.revokeObjectURL(blobUrl)
|
||||
blobUrl = URL.createObjectURL(blob)
|
||||
value = blobUrl
|
||||
@@ -28,7 +37,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
load()
|
||||
onMount(() => {
|
||||
void load()
|
||||
const onStorage = (
|
||||
changes: Record<string, browser.Storage.StorageChange>,
|
||||
areaName: string,
|
||||
) => {
|
||||
if (areaName === 'local' && changes['plugin.profile-picture.settings']) {
|
||||
void load()
|
||||
}
|
||||
}
|
||||
browser.storage.onChanged.addListener(onStorage)
|
||||
return () => browser.storage.onChanged.removeListener(onStorage)
|
||||
})
|
||||
|
||||
async function afterProfilePictureChange() {
|
||||
window.dispatchEvent(new Event('profile-picture-updated'))
|
||||
@@ -38,6 +59,16 @@
|
||||
await notifyProfilePictureChanged()
|
||||
}
|
||||
|
||||
async function refreshCloudPfp() {
|
||||
cloudRefreshError = undefined
|
||||
refreshingCloud = true
|
||||
const result = await pullCloudProfilePictureFromServer()
|
||||
refreshingCloud = false
|
||||
if (!result.success) {
|
||||
cloudRefreshError = result.error ?? 'Could not refresh cloud photo'
|
||||
}
|
||||
}
|
||||
|
||||
function triggerSelect() {
|
||||
fileInput?.click()
|
||||
}
|
||||
@@ -46,12 +77,10 @@
|
||||
const file = files?.[0]
|
||||
if (!file) return
|
||||
|
||||
// Revoke old blob URL if it exists
|
||||
if (blobUrl) {
|
||||
URL.revokeObjectURL(blobUrl)
|
||||
}
|
||||
|
||||
// Store the blob in localforage
|
||||
await store.setItem('profile-picture', file)
|
||||
const newBlobUrl = URL.createObjectURL(file)
|
||||
value = newBlobUrl
|
||||
@@ -76,42 +105,64 @@
|
||||
}
|
||||
value = undefined
|
||||
await store.removeItem('profile-picture')
|
||||
if (await isUseCloudPfpEnabled()) {
|
||||
await clearCloudProfilePicture()
|
||||
}
|
||||
await afterProfilePictureChange()
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="flex relative justify-center items-center rounded-lg cursor-pointer select-none border-zinc-300 dark:border-zinc-600 bg-white/20 dark:bg-zinc-800/30"
|
||||
onclick={() => value ? null : triggerSelect()}
|
||||
ondragover={(e) => { e.stopPropagation(); dragging = true }}
|
||||
ondragleave={() => dragging = false}
|
||||
ondrop={onDrop}
|
||||
onkeydown={(e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault()
|
||||
triggerSelect()
|
||||
}
|
||||
}}
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
{#if value}
|
||||
<img src={value} alt="Profile" class="object-cover rounded-full size-10" />
|
||||
<button
|
||||
class="flex justify-center items-center m-1 text-lg dark:text-white size-7"
|
||||
onclick={(e) => {
|
||||
e.stopPropagation()
|
||||
removeImage()
|
||||
}}
|
||||
>×</button>
|
||||
{:else}
|
||||
<div class="flex gap-2 items-center px-3 py-1 text-xs rounded-lg border border-dashed transition border-zinc-300 dark:border-zinc-600 text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300">
|
||||
<span class="text-lg font-IconFamily">{'\ued47'}</span>
|
||||
<span>Upload</span>
|
||||
<div class="flex flex-col gap-2 items-end">
|
||||
{#if useCloudPfp}
|
||||
<div class="flex gap-2 items-center">
|
||||
<CloudPfpAvatar user={cloudAuth.state.user} class="object-cover rounded-full size-10" />
|
||||
<button
|
||||
type="button"
|
||||
class="px-2 py-1 text-xs rounded-md bg-zinc-200 dark:bg-zinc-700 hover:bg-zinc-300 dark:hover:bg-zinc-600 disabled:opacity-50"
|
||||
disabled={refreshingCloud}
|
||||
onclick={() => refreshCloudPfp()}
|
||||
>
|
||||
{refreshingCloud ? 'Refreshing…' : 'Refresh from cloud'}
|
||||
</button>
|
||||
</div>
|
||||
{#if cloudRefreshError}
|
||||
<p class="text-xs text-red-500">{cloudRefreshError}</p>
|
||||
{/if}
|
||||
{/if}
|
||||
<input type="file" accept="image/*" class="hidden" bind:this={fileInput} onchange={onFileChange} />
|
||||
{#if dragging}
|
||||
<div class="absolute inset-0 rounded-full bg-zinc-200/40 dark:bg-zinc-700/40"></div>
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class="flex relative justify-center items-center rounded-lg cursor-pointer select-none border-zinc-300 dark:border-zinc-600 bg-white/20 dark:bg-zinc-800/30"
|
||||
onclick={() => value ? null : triggerSelect()}
|
||||
ondragover={(e) => { e.stopPropagation(); dragging = true }}
|
||||
ondragleave={() => dragging = false}
|
||||
ondrop={onDrop}
|
||||
onkeydown={(e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault()
|
||||
triggerSelect()
|
||||
}
|
||||
}}
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
{#if value}
|
||||
<img src={value} alt="Profile" class="object-cover rounded-full size-10" />
|
||||
<button
|
||||
class="flex justify-center items-center m-1 text-lg dark:text-white size-7"
|
||||
onclick={(e) => {
|
||||
e.stopPropagation()
|
||||
removeImage()
|
||||
}}
|
||||
>×</button>
|
||||
{:else}
|
||||
<div class="flex gap-2 items-center px-3 py-1 text-xs rounded-lg border border-dashed transition border-zinc-300 dark:border-zinc-600 text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300">
|
||||
<span class="text-lg font-IconFamily">{'\ued47'}</span>
|
||||
<span>Upload</span>
|
||||
</div>
|
||||
{/if}
|
||||
<input type="file" accept="image/*" class="hidden" bind:this={fileInput} onchange={onFileChange} />
|
||||
{#if dragging}
|
||||
<div class="absolute inset-0 rounded-full bg-zinc-200/40 dark:bg-zinc-700/40"></div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@ import ProfilePictureSetting from "./ProfilePictureSetting.svelte";
|
||||
import { waitForElm } from "@/seqta/utils/waitForElm";
|
||||
import browser from "webextension-polyfill";
|
||||
import { cloudAuth } from "@/seqta/utils/CloudAuth";
|
||||
import { resolveCloudPfp } from "@/seqta/utils/cloudPfpCache";
|
||||
import { resolveCloudPfp, defaultAccountsPfpUrl } from "@/seqta/utils/cloudPfpCache";
|
||||
import styles from "./styles.css?inline";
|
||||
import localforage from "localforage";
|
||||
|
||||
@@ -64,10 +64,13 @@ const profilePicturePlugin: Plugin<typeof settings> = {
|
||||
}
|
||||
|
||||
const useCloud = api.settings.useCloudPfp;
|
||||
const pfpUrl = cloudAuth.state.user?.pfpUrl;
|
||||
const userId = cloudAuth.state.user?.id;
|
||||
const pfpUrl =
|
||||
cloudAuth.state.user?.pfpUrl ??
|
||||
(userId ? defaultAccountsPfpUrl(userId) : undefined);
|
||||
|
||||
if (useCloud && pfpUrl && cloudAuth.state.user?.id) {
|
||||
const resolved = await resolveCloudPfp(cloudAuth.state.user.id, pfpUrl);
|
||||
if (useCloud && pfpUrl && userId) {
|
||||
const resolved = await resolveCloudPfp(userId, pfpUrl);
|
||||
if (resolved) {
|
||||
currentBlobUrl = resolved.src;
|
||||
img = document.createElement("img");
|
||||
@@ -92,6 +95,13 @@ const profilePicturePlugin: Plugin<typeof settings> = {
|
||||
}
|
||||
}
|
||||
|
||||
if (api.settings.useCloudPfp && cloudAuth.state.isLoggedIn) {
|
||||
const { pullCloudProfilePictureFromServer } = await import(
|
||||
"@/seqta/utils/cloudPfpSync"
|
||||
);
|
||||
await pullCloudProfilePictureFromServer();
|
||||
}
|
||||
|
||||
await applyProfileImage();
|
||||
|
||||
const onLocalPictureUpdated = () => {
|
||||
@@ -114,11 +124,9 @@ const profilePicturePlugin: Plugin<typeof settings> = {
|
||||
});
|
||||
|
||||
const useCloudUnreg = api.settings.onChange("useCloudPfp", (enabled: boolean) => {
|
||||
if (enabled) {
|
||||
void import("@/seqta/utils/cloudPfpSync").then(({ syncLocalProfilePictureToCloud }) =>
|
||||
syncLocalProfilePictureToCloud(),
|
||||
);
|
||||
}
|
||||
void import("@/seqta/utils/cloudPfpSync").then(({ onUseCloudPfpToggled }) =>
|
||||
onUseCloudPfpToggled(enabled),
|
||||
);
|
||||
void applyProfileImage();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user