Fixed workspace ID dependency

This commit is contained in:
benweet 2017-12-11 00:53:46 +00:00
parent 9596339684
commit 8263e14bcc
9 changed files with 117 additions and 116 deletions

View File

@ -14,6 +14,8 @@ import Modal from './Modal';
import Notification from './Notification';
import SplashScreen from './SplashScreen';
import syncSvc from '../services/syncSvc';
import networkSvc from '../services/networkSvc';
import sponsorSvc from '../services/sponsorSvc';
import timeSvc from '../services/timeSvc';
import store from '../store';
@ -77,6 +79,8 @@ export default {
created() {
syncSvc.init()
.then(() => {
networkSvc.init();
sponsorSvc.init();
this.ready = true;
});
},

View File

@ -4,7 +4,6 @@ import store from '../store';
import welcomeFile from '../data/welcomeFile.md';
const dbVersion = 1;
const dbVersionKey = `${utils.workspaceId}/localDbVersion`;
const dbStoreName = 'objects';
const exportBackup = utils.queryParams.exportBackup;
if (exportBackup) {
@ -15,11 +14,18 @@ const deleteMarkerMaxAge = 1000;
const checkSponsorshipAfter = (5 * 60 * 1000) + (30 * 1000); // tokenExpirationMargin + 30 sec
class Connection {
constructor(dbName) {
constructor() {
this.getTxCbs = [];
// Make the DB name
const workspaceId = store.getters['workspace/currentWorkspace'].id;
this.dbName = 'stackedit-db';
if (workspaceId !== 'main') {
this.dbName += `-${workspaceId}`;
}
// Init connection
const request = indexedDB.open(dbName, dbVersion);
const request = indexedDB.open(this.dbName, dbVersion);
request.onerror = () => {
throw new Error("Can't connect to IndexedDB.");
@ -27,7 +33,6 @@ class Connection {
request.onsuccess = (event) => {
this.db = event.target.result;
localStorage[dbVersionKey] = this.db.version; // Safari does not support onversionchange
this.db.onversionchange = () => window.location.reload();
this.getTxCbs.forEach(({ onTx, onError }) => this.createTx(onTx, onError));
@ -67,11 +72,6 @@ class Connection {
return this.getTxCbs.push({ onTx, onError });
}
// If DB version has changed (Safari support)
if (parseInt(localStorage[dbVersionKey], 10) !== this.db.version) {
return window.location.reload();
}
// Open transaction in read/write will prevent conflict with other tabs
const tx = this.db.transaction(this.db.objectStoreNames, 'readwrite');
tx.onerror = onError;
@ -102,7 +102,7 @@ const localDbSvc = {
*/
init() {
// Create the connection
this.connection = new Connection(store.getters['data/dbName']);
this.connection = new Connection();
// Load the DB
return localDbSvc.sync()
@ -131,7 +131,7 @@ const localDbSvc = {
// If app was last opened 7 days ago and synchronization is off
if (!store.getters['data/loginToken'] &&
(utils.lastOpened + utils.cleanTrashAfter < Date.now())
(store.getters['workspace/lastFocus'] + utils.cleanTrashAfter < Date.now())
) {
// Clean files
store.getters['file/items']
@ -447,7 +447,6 @@ const localDbSvc = {
request.onsuccess = resolve;
})
.then(() => {
localStorage.removeItem(dbVersionKey);
window.location.reload();
}, () => store.dispatch('notification/error', 'Could not delete local database.'));
},

View File

@ -5,8 +5,88 @@ const scriptLoadingPromises = Object.create(null);
const oauth2AuthorizationTimeout = 120 * 1000; // 2 minutes
const networkTimeout = 30 * 1000; // 30 sec
let isConnectionDown = false;
const userInactiveAfter = 2 * 60 * 1000; // 2 minutes
export default {
init() {
// Keep track of the last user activity
this.lastActivity = 0;
const setLastActivity = () => {
this.lastActivity = Date.now();
};
window.document.addEventListener('mousedown', setLastActivity);
window.document.addEventListener('keydown', setLastActivity);
window.document.addEventListener('touchstart', setLastActivity);
// Keep track of the last window focus
this.lastFocus = 0;
const setLastFocus = () => {
this.lastFocus = Date.now();
localStorage.setItem(store.getters['workspace/lastFocusKey'], this.lastFocus);
setLastActivity();
};
if (document.hasFocus()) {
setLastFocus();
}
window.addEventListener('focus', setLastFocus);
// Check browser is online periodically
const checkOffline = () => {
const isBrowserOffline = window.navigator.onLine === false;
if (!isBrowserOffline &&
store.state.lastOfflineCheck + networkTimeout + 5000 < Date.now() &&
this.isUserActive()
) {
store.commit('updateLastOfflineCheck');
new Promise((resolve, reject) => {
const script = document.createElement('script');
let timeout;
let clean = (cb) => {
clearTimeout(timeout);
document.head.removeChild(script);
clean = () => {}; // Prevent from cleaning several times
cb();
};
script.onload = () => clean(resolve);
script.onerror = () => clean(reject);
script.src = `https://apis.google.com/js/api.js?${Date.now()}`;
try {
document.head.appendChild(script); // This can fail with bad network
timeout = setTimeout(() => clean(reject), networkTimeout);
} catch (e) {
reject(e);
}
})
.then(() => {
isConnectionDown = false;
}, () => {
isConnectionDown = true;
});
}
const offline = isBrowserOffline || isConnectionDown;
if (store.state.offline !== offline) {
store.commit('setOffline', offline);
if (offline) {
store.dispatch('notification/error', 'You are offline.');
} else {
store.dispatch('notification/info', 'You are back online!');
}
}
};
utils.setInterval(checkOffline, 1000);
window.addEventListener('online', () => {
isConnectionDown = false;
checkOffline();
});
window.addEventListener('offline', checkOffline);
},
isWindowFocused() {
return parseInt(localStorage.getItem(this.lastFocusKey), 10) === this.lastFocus;
},
isUserActive() {
return this.lastActivity > Date.now() - userInactiveAfter && this.isWindowFocused();
},
loadScript(url) {
if (!scriptLoadingPromises[url]) {
scriptLoadingPromises[url] = new Promise((resolve, reject) => {
@ -217,53 +297,3 @@ export default {
return attempt();
},
};
function checkOffline() {
const isBrowserOffline = window.navigator.onLine === false;
if (!isBrowserOffline &&
store.state.lastOfflineCheck + networkTimeout + 5000 < Date.now() &&
utils.isUserActive()
) {
store.commit('updateLastOfflineCheck');
new Promise((resolve, reject) => {
const script = document.createElement('script');
let timeout;
let clean = (cb) => {
clearTimeout(timeout);
document.head.removeChild(script);
clean = () => {}; // Prevent from cleaning several times
cb();
};
script.onload = () => clean(resolve);
script.onerror = () => clean(reject);
script.src = `https://apis.google.com/js/api.js?${Date.now()}`;
try {
document.head.appendChild(script); // This can fail with bad network
timeout = setTimeout(() => clean(reject), networkTimeout);
} catch (e) {
reject(e);
}
})
.then(() => {
isConnectionDown = false;
}, () => {
isConnectionDown = true;
});
}
const offline = isBrowserOffline || isConnectionDown;
if (store.state.offline !== offline) {
store.commit('setOffline', offline);
if (offline) {
store.dispatch('notification/error', 'You are offline.');
} else {
store.dispatch('notification/info', 'You are back online!');
}
}
}
utils.setInterval(checkOffline, 1000);
window.addEventListener('online', () => {
isConnectionDown = false;
checkOffline();
});
window.addEventListener('offline', checkOffline);

View File

@ -1,6 +1,7 @@
import localDbSvc from './localDbSvc';
import store from '../store';
import utils from './utils';
import networkSvc from './networkSvc';
import exportSvc from './exportSvc';
import providerRegistry from './providers/providerRegistry';
@ -114,7 +115,7 @@ function requestPublish() {
let intervalId;
const attempt = () => {
// Only start publishing when these conditions are met
if (utils.isUserActive()) {
if (networkSvc.isUserActive()) {
clearInterval(intervalId);
if (!hasCurrentFilePublishLocations()) {
// Cancel sync

View File

@ -23,7 +23,7 @@ const isGoogleSponsor = () => {
const checkPayment = () => {
const currentDate = Date.now();
if (!isGoogleSponsor() && utils.isUserActive() && !store.state.offline &&
if (!isGoogleSponsor() && networkSvc.isUserActive() && !store.state.offline &&
lastCheck + checkPaymentEvery < currentDate
) {
lastCheck = currentDate;
@ -39,9 +39,10 @@ const checkPayment = () => {
}
};
utils.setInterval(checkPayment, 2000);
export default {
init: () => {
utils.setInterval(checkPayment, 2000);
},
getToken() {
if (isGoogleSponsor() || store.state.offline) {
return Promise.resolve();

View File

@ -2,6 +2,7 @@ import localDbSvc from './localDbSvc';
import store from '../store';
import utils from './utils';
import diffUtils from './diffUtils';
import networkSvc from './networkSvc';
import providerRegistry from './providers/providerRegistry';
import googleDriveAppDataProvider from './providers/googleDriveAppDataProvider';
@ -14,9 +15,9 @@ let workspaceProvider;
/**
* Use a lock in the local storage to prevent multiple windows concurrency.
*/
const lastSyncActivityKey = `${utils.workspaceId}/lastSyncActivity`;
let lastSyncActivity;
const getLastStoredSyncActivity = () => parseInt(localStorage[lastSyncActivityKey], 10) || 0;
const getLastStoredSyncActivity = () =>
parseInt(localStorage.getItem(store.getters['workspace/lastSyncActivityKey']), 10) || 0;
/**
* Return true if workspace sync is possible.
@ -51,7 +52,7 @@ function isSyncWindow() {
}
/**
* Return true if auto sync can start, ie that lastSyncActivity is old enough.
* Return true if auto sync can start, ie if lastSyncActivity is old enough.
*/
function isAutoSyncReady() {
const storedLastSyncActivity = getLastStoredSyncActivity();
@ -64,7 +65,7 @@ function isAutoSyncReady() {
function setLastSyncActivity() {
const currentDate = Date.now();
lastSyncActivity = currentDate;
localStorage[lastSyncActivityKey] = currentDate;
localStorage.setItem(store.getters['workspace/lastSyncActivityKey'], currentDate);
}
/**
@ -626,7 +627,7 @@ function requestSync() {
let intervalId;
const attempt = () => {
// Only start syncing when these conditions are met
if (utils.isUserActive() && isSyncWindow()) {
if (networkSvc.isUserActive() && isSyncWindow()) {
clearInterval(intervalId);
if (!isSyncPossible()) {
// Cancel sync
@ -704,7 +705,7 @@ export default {
// Sync periodically
utils.setInterval(() => {
if (isSyncPossible() &&
utils.isUserActive() &&
networkSvc.isUserActive() &&
isSyncWindow() &&
isAutoSyncReady()
) {

View File

@ -2,7 +2,6 @@ import yaml from 'js-yaml';
import '../libs/clunderscore';
import defaultProperties from '../data/defaultFileProperties.yml';
const workspaceId = 'main';
const origin = `${location.protocol}//${location.host}`;
// For uid()
@ -12,30 +11,6 @@ const alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
const radix = alphabet.length;
const array = new Uint32Array(uidLength);
// For isUserActive
const inactiveAfter = 2 * 60 * 1000; // 2 minutes
let lastActivity;
const setLastActivity = () => {
lastActivity = Date.now();
};
window.document.addEventListener('mousedown', setLastActivity);
window.document.addEventListener('keydown', setLastActivity);
window.document.addEventListener('touchstart', setLastActivity);
// For isWindowFocused
let lastFocus;
const lastFocusKey = `${workspaceId}/lastWindowFocus`;
const lastOpened = parseInt(localStorage[lastFocusKey], 10) || 0;
const setLastFocus = () => {
lastFocus = Date.now();
localStorage[lastFocusKey] = lastFocus;
setLastActivity();
};
if (document.hasFocus()) {
setLastFocus();
}
window.addEventListener('focus', setLastFocus);
// For parseQueryParams()
const parseQueryParams = (params) => {
const result = {};
@ -50,11 +25,9 @@ const parseQueryParams = (params) => {
const urlParser = window.document.createElement('a');
export default {
workspaceId,
origin,
queryParams: parseQueryParams(location.hash.slice(1)),
oauth2RedirectUri: `${origin}/oauth2/callback`,
lastOpened,
cleanTrashAfter: 7 * 24 * 60 * 60 * 1000, // 7 days
types: [
'contentState',
@ -147,12 +120,6 @@ export default {
setInterval(func, interval) {
return setInterval(() => func(), this.randomize(interval));
},
isWindowFocused() {
return parseInt(localStorage[lastFocusKey], 10) === lastFocus;
},
isUserActive() {
return lastActivity > Date.now() - inactiveAfter && this.isWindowFocused();
},
parseQueryParams,
addQueryParams(url = '', params = {}) {
const keys = Object.keys(params).filter(key => params[key] != null);

View File

@ -131,17 +131,6 @@ export default {
});
return result;
},
dbName: (state, getters) => {
let dbName;
Object.keys(getters.workspaces).some((id) => {
dbName = 'stackedit-db';
if (id !== 'main') {
dbName += `-${id}`;
}
return dbName;
});
return dbName;
},
settings: getter('settings'),
computedSettings: (state, getters) => {
const customSettings = yaml.safeLoad(getters.settings);

View File

@ -23,6 +23,15 @@ export default {
const workspaces = rootGetters['data/workspaces'];
return workspaces[state.currentWorkspaceId] || workspaces.main;
},
lastSyncActivityKey: (state, getters) => {
const workspaceId = getters.currentWorkspace.id;
return `${workspaceId}/lastSyncActivity`;
},
lastFocusKey: (state, getters) => {
const workspaceId = getters.currentWorkspace.id;
return `${workspaceId}/lastWindowFocus`;
},
lastFocus: (state, getters) => parseInt(localStorage.getItem(getters.lastFocusKey), 10) || 0,
},
actions: {
},