feat: implement browser extension for media publishing and add backend support for media management
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import { browser } from "wxt/browser";
|
||||
|
||||
import { createDefaultPlatformStates, supportedPlatforms, type StoredPlatformState } from "./platforms";
|
||||
|
||||
export interface ExtensionStorageState {
|
||||
installation_key: string;
|
||||
plugin_installation_id: number | null;
|
||||
installation_token: string | null;
|
||||
api_base_url: string | null;
|
||||
platforms: StoredPlatformState[];
|
||||
last_updated_at: string | null;
|
||||
}
|
||||
|
||||
const STORAGE_KEY = "geo.publisher.state";
|
||||
|
||||
function nextInstallationKey(): string {
|
||||
if (typeof crypto !== "undefined" && "randomUUID" in crypto) {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
return `geo-extension-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
||||
}
|
||||
|
||||
function mergePlatformStates(platforms?: StoredPlatformState[]): StoredPlatformState[] {
|
||||
const defaults = createDefaultPlatformStates();
|
||||
if (!platforms?.length) {
|
||||
return defaults;
|
||||
}
|
||||
|
||||
const incoming = new Map(platforms.map((platform) => [platform.platform_id, platform]));
|
||||
return defaults.map((platform) => {
|
||||
const stored = incoming.get(platform.platform_id);
|
||||
return stored ? { ...platform, ...stored } : platform;
|
||||
});
|
||||
}
|
||||
|
||||
async function writeState(nextState: ExtensionStorageState): Promise<void> {
|
||||
await browser.storage.local.set({
|
||||
[STORAGE_KEY]: nextState,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getExtensionState(): Promise<ExtensionStorageState> {
|
||||
const storageValue = await browser.storage.local.get(STORAGE_KEY);
|
||||
const stored = storageValue[STORAGE_KEY] as Partial<ExtensionStorageState> | undefined;
|
||||
|
||||
const nextState: ExtensionStorageState = {
|
||||
installation_key: stored?.installation_key || nextInstallationKey(),
|
||||
plugin_installation_id: stored?.plugin_installation_id ?? null,
|
||||
installation_token: stored?.installation_token ?? null,
|
||||
api_base_url: stored?.api_base_url ?? null,
|
||||
platforms: mergePlatformStates(stored?.platforms),
|
||||
last_updated_at: stored?.last_updated_at ?? null,
|
||||
};
|
||||
|
||||
const shouldPersist =
|
||||
!stored?.installation_key ||
|
||||
!stored?.platforms ||
|
||||
stored.platforms.length !== supportedPlatforms.length;
|
||||
|
||||
if (shouldPersist) {
|
||||
await writeState(nextState);
|
||||
}
|
||||
|
||||
return nextState;
|
||||
}
|
||||
|
||||
export async function patchExtensionState(
|
||||
patch: Partial<Omit<ExtensionStorageState, "platforms">> & { platforms?: StoredPlatformState[] },
|
||||
): Promise<ExtensionStorageState> {
|
||||
const current = await getExtensionState();
|
||||
const nextState: ExtensionStorageState = {
|
||||
...current,
|
||||
...patch,
|
||||
platforms: patch.platforms ? mergePlatformStates(patch.platforms) : current.platforms,
|
||||
last_updated_at: new Date().toISOString(),
|
||||
};
|
||||
await writeState(nextState);
|
||||
return nextState;
|
||||
}
|
||||
|
||||
export async function updatePlatformState(
|
||||
platformId: string,
|
||||
updater: Partial<StoredPlatformState>,
|
||||
): Promise<ExtensionStorageState> {
|
||||
const current = await getExtensionState();
|
||||
const platforms = current.platforms.map((platform) =>
|
||||
platform.platform_id === platformId
|
||||
? {
|
||||
...platform,
|
||||
...updater,
|
||||
}
|
||||
: platform,
|
||||
);
|
||||
return patchExtensionState({ platforms });
|
||||
}
|
||||
|
||||
export async function resetPlatformStates(): Promise<ExtensionStorageState> {
|
||||
return patchExtensionState({ platforms: createDefaultPlatformStates() });
|
||||
}
|
||||
Reference in New Issue
Block a user