130 lines
4.1 KiB
JavaScript
130 lines
4.1 KiB
JavaScript
|
// @flow
|
||
|
|
||
|
/**
|
||
|
* This serves a bridge between tabs using localStorage to indicate whether an
|
||
|
* upload is currently in progress (locked) or removed.
|
||
|
*
|
||
|
* An alternative is to sync the redux's 'publish::currentUploads' through the
|
||
|
* wallet's sync process, but let's not pollute the wallet for now.
|
||
|
*/
|
||
|
|
||
|
import { v4 as uuid } from 'uuid';
|
||
|
import { TUS_LOCKED_UPLOADS, TUS_REMOVED_UPLOADS } from 'constants/storage';
|
||
|
import { isLocalStorageAvailable } from 'util/storage';
|
||
|
import { doUpdateUploadRemove, doUpdateUploadProgress } from 'redux/actions/publish';
|
||
|
|
||
|
const localStorageAvailable = isLocalStorageAvailable();
|
||
|
|
||
|
let gTabId: string = '';
|
||
|
|
||
|
function getTabId() {
|
||
|
if (!gTabId) {
|
||
|
// We want to maximize bootup speed, so only initialize
|
||
|
// the tab ID on first use instead when declared.
|
||
|
gTabId = uuid();
|
||
|
}
|
||
|
return gTabId;
|
||
|
}
|
||
|
|
||
|
// ****************************************************************************
|
||
|
// Locked
|
||
|
// ****************************************************************************
|
||
|
|
||
|
function getLockedUploads() {
|
||
|
if (localStorageAvailable) {
|
||
|
const storedValue = window.localStorage.getItem(TUS_LOCKED_UPLOADS);
|
||
|
return storedValue ? JSON.parse(storedValue) : {};
|
||
|
}
|
||
|
return {};
|
||
|
}
|
||
|
|
||
|
export function tusIsSessionLocked(guid: string) {
|
||
|
const lockedUploads = getLockedUploads();
|
||
|
return lockedUploads[guid] && lockedUploads[guid] !== getTabId();
|
||
|
}
|
||
|
|
||
|
export function tusLockAndNotify(guid: string) {
|
||
|
const lockedUploads = getLockedUploads();
|
||
|
if (!lockedUploads[guid] && localStorageAvailable) {
|
||
|
lockedUploads[guid] = getTabId();
|
||
|
window.localStorage.setItem(TUS_LOCKED_UPLOADS, JSON.stringify(lockedUploads));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* tusUnlockAndNotify
|
||
|
*
|
||
|
* @param guid The upload session to unlock and notify other tabs of.
|
||
|
* Passing 'undefined' will clear all sessions locked by this tab.
|
||
|
*/
|
||
|
export function tusUnlockAndNotify(guid?: string) {
|
||
|
if (!localStorageAvailable) return;
|
||
|
|
||
|
const lockedUploads = getLockedUploads();
|
||
|
|
||
|
if (guid) {
|
||
|
delete lockedUploads[guid];
|
||
|
} else {
|
||
|
const ourTabId = getTabId();
|
||
|
const lockedUploadsEntries = Object.entries(lockedUploads);
|
||
|
lockedUploadsEntries.forEach(([lockedGuid, tabId]) => {
|
||
|
if (tabId === ourTabId) {
|
||
|
delete lockedUploads[lockedGuid];
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if (Object.keys(lockedUploads).length > 0) {
|
||
|
window.localStorage.setItem(TUS_LOCKED_UPLOADS, JSON.stringify(lockedUploads));
|
||
|
} else {
|
||
|
window.localStorage.removeItem(TUS_LOCKED_UPLOADS);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ****************************************************************************
|
||
|
// Removed
|
||
|
// ****************************************************************************
|
||
|
|
||
|
function getRemovedUploads() {
|
||
|
if (localStorageAvailable) {
|
||
|
const storedValue = window.localStorage.getItem(TUS_REMOVED_UPLOADS);
|
||
|
return storedValue ? storedValue.split(',') : [];
|
||
|
}
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
export function tusRemoveAndNotify(guid: string) {
|
||
|
if (!localStorageAvailable) return;
|
||
|
const removedUploads = getRemovedUploads();
|
||
|
removedUploads.push(guid);
|
||
|
window.localStorage.setItem(TUS_REMOVED_UPLOADS, removedUploads.join(','));
|
||
|
}
|
||
|
|
||
|
export function tusClearRemovedUploads() {
|
||
|
if (!localStorageAvailable) return;
|
||
|
window.localStorage.removeItem(TUS_REMOVED_UPLOADS);
|
||
|
}
|
||
|
|
||
|
// ****************************************************************************
|
||
|
// Respond to changes from other tabs.
|
||
|
// ****************************************************************************
|
||
|
|
||
|
export function tusHandleTabUpdates(storageKey: string) {
|
||
|
switch (storageKey) {
|
||
|
case TUS_LOCKED_UPLOADS:
|
||
|
// The locked IDs are in localStorage, but related GUI is unaware.
|
||
|
// Send a redux update to force an update.
|
||
|
window.store.dispatch(doUpdateUploadProgress({ guid: 'force--update' }));
|
||
|
break;
|
||
|
|
||
|
case TUS_REMOVED_UPLOADS:
|
||
|
// The other tab's store has removed this upload, so it's safe to do the
|
||
|
// same without affecting rehydration.
|
||
|
if (localStorageAvailable) {
|
||
|
const removedUploads = getRemovedUploads();
|
||
|
removedUploads.forEach((guid) => window.store.dispatch(doUpdateUploadRemove(guid)));
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|