2021-12-07 15:48:09 +01:00
|
|
|
// @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';
|
2022-05-26 04:44:26 +02:00
|
|
|
import { isLocalStorageAvailable, LocalStorage, LS } from 'util/storage';
|
2021-12-07 15:48:09 +01:00
|
|
|
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) {
|
2022-05-26 04:44:26 +02:00
|
|
|
const storedValue = LocalStorage.getItem(LS.TUS_LOCKED_UPLOADS);
|
2021-12-07 15:48:09 +01:00
|
|
|
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();
|
2022-05-26 04:44:26 +02:00
|
|
|
LocalStorage.setItem(LS.TUS_LOCKED_UPLOADS, JSON.stringify(lockedUploads));
|
2021-12-07 15:48:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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) {
|
2022-05-26 04:44:26 +02:00
|
|
|
LocalStorage.setItem(LS.TUS_LOCKED_UPLOADS, JSON.stringify(lockedUploads));
|
2021-12-07 15:48:09 +01:00
|
|
|
} else {
|
2022-05-26 04:44:26 +02:00
|
|
|
LocalStorage.removeItem(LS.TUS_LOCKED_UPLOADS);
|
2021-12-07 15:48:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ****************************************************************************
|
|
|
|
// Removed
|
|
|
|
// ****************************************************************************
|
|
|
|
|
|
|
|
function getRemovedUploads() {
|
|
|
|
if (localStorageAvailable) {
|
2022-05-26 04:44:26 +02:00
|
|
|
const storedValue = LocalStorage.getItem(LS.TUS_REMOVED_UPLOADS);
|
2021-12-07 15:48:09 +01:00
|
|
|
return storedValue ? storedValue.split(',') : [];
|
|
|
|
}
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
export function tusRemoveAndNotify(guid: string) {
|
|
|
|
if (!localStorageAvailable) return;
|
|
|
|
const removedUploads = getRemovedUploads();
|
|
|
|
removedUploads.push(guid);
|
2022-05-26 04:44:26 +02:00
|
|
|
LocalStorage.setItem(LS.TUS_REMOVED_UPLOADS, removedUploads.join(','));
|
2021-12-07 15:48:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export function tusClearRemovedUploads() {
|
|
|
|
if (!localStorageAvailable) return;
|
2022-05-26 04:44:26 +02:00
|
|
|
LocalStorage.removeItem(LS.TUS_REMOVED_UPLOADS);
|
2021-12-07 15:48:09 +01:00
|
|
|
}
|
|
|
|
|
2022-01-03 08:30:44 +01:00
|
|
|
export function tusClearLockedUploads() {
|
|
|
|
if (!localStorageAvailable) return;
|
2022-05-26 04:44:26 +02:00
|
|
|
LocalStorage.removeItem(LS.TUS_LOCKED_UPLOADS);
|
|
|
|
LocalStorage.setItem(LS.TUS_REFRESH_LOCK, String(Math.random()));
|
2022-01-03 08:30:44 +01:00
|
|
|
}
|
|
|
|
|
2021-12-07 15:48:09 +01:00
|
|
|
// ****************************************************************************
|
|
|
|
// Respond to changes from other tabs.
|
|
|
|
// ****************************************************************************
|
|
|
|
|
|
|
|
export function tusHandleTabUpdates(storageKey: string) {
|
|
|
|
switch (storageKey) {
|
2022-05-26 04:44:26 +02:00
|
|
|
case LS.TUS_LOCKED_UPLOADS:
|
2021-12-07 15:48:09 +01:00
|
|
|
// 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;
|
|
|
|
|
2022-05-26 04:44:26 +02:00
|
|
|
case LS.TUS_REFRESH_LOCK:
|
2022-01-03 08:30:44 +01:00
|
|
|
window.store.dispatch(doUpdateUploadProgress({ guid: 'refresh--lock' }));
|
|
|
|
break;
|
|
|
|
|
2022-05-26 04:44:26 +02:00
|
|
|
case LS.TUS_REMOVED_UPLOADS:
|
2021-12-07 15:48:09 +01:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
}
|