Fixed location synchronization
This commit is contained in:
parent
0a2d8396d6
commit
cbb44f4ea6
@ -209,8 +209,8 @@ export default {
|
|||||||
color: #de2c00;
|
color: #de2c00;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal__tip {
|
.modal__info {
|
||||||
background-color: transparentize(#ffd600, 0.85);
|
background-color: $info-bg;
|
||||||
border-radius: $border-radius-base;
|
border-radius: $border-radius-base;
|
||||||
margin: 1.2em 0;
|
margin: 1.2em 0;
|
||||||
padding: 0.75em 1.25em;
|
padding: 0.75em 1.25em;
|
||||||
|
@ -143,11 +143,10 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-bar__warning {
|
.side-bar__info {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin: 0 -10px;
|
margin: 0 -10px;
|
||||||
color: darken($error-color, 10);
|
background-color: $info-bg;
|
||||||
background-color: transparentize($error-color, 0.925);
|
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
|
@ -4,6 +4,7 @@ $line-height-base: 1.67;
|
|||||||
$line-height-title: 1.33;
|
$line-height-title: 1.33;
|
||||||
$font-size-monospace: 0.85em;
|
$font-size-monospace: 0.85em;
|
||||||
$code-bg: rgba(0, 0, 0, 0.05);
|
$code-bg: rgba(0, 0, 0, 0.05);
|
||||||
|
$info-bg: transparentize(#ffb000, 0.85);
|
||||||
$code-border-radius: 2px;
|
$code-border-radius: 2px;
|
||||||
$link-color: #0c93e4;
|
$link-color: #0c93e4;
|
||||||
$error-color: #f20;
|
$error-color: #f20;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<menu-entry @click.native="exportMarkdown">
|
<menu-entry @click.native="exportMarkdown">
|
||||||
<icon-download slot="icon"></icon-download>
|
<icon-download slot="icon"></icon-download>
|
||||||
<div>Export as Markdown</div>
|
<div>Export as Markdown</div>
|
||||||
<span>Save file as plain text.</span>
|
<span>Save plain text file.</span>
|
||||||
</menu-entry>
|
</menu-entry>
|
||||||
<menu-entry @click.native="exportHtml">
|
<menu-entry @click.native="exportHtml">
|
||||||
<icon-download slot="icon"></icon-download>
|
<icon-download slot="icon"></icon-download>
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="side-bar__panel side-bar__panel--menu">
|
<div class="side-bar__panel side-bar__panel--menu">
|
||||||
<div class="side-bar__warning" v-if="publishLocations.length">
|
<div class="side-bar__info" v-if="publishLocations.length">
|
||||||
<p><b>{{currentFileName}}</b> is already published.</p>
|
<p><b>{{currentFileName}}</b> is already published.</p>
|
||||||
<menu-entry v-if="!offline" @click.native="requestPublish">
|
<menu-entry @click.native="requestPublish">
|
||||||
<icon-upload slot="icon"></icon-upload>
|
<icon-upload slot="icon"></icon-upload>
|
||||||
<div>Publish now</div>
|
<div>Publish now</div>
|
||||||
<span>Upload current file to its publication locations.</span>
|
<span>Update current file publications.</span>
|
||||||
</menu-entry>
|
</menu-entry>
|
||||||
<menu-entry @click.native="managePublish">
|
<menu-entry @click.native="managePublish">
|
||||||
<icon-view-list slot="icon"></icon-view-list>
|
<icon-view-list slot="icon"></icon-view-list>
|
||||||
@ -120,9 +120,6 @@ export default {
|
|||||||
MenuEntry,
|
MenuEntry,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([
|
|
||||||
'offline',
|
|
||||||
]),
|
|
||||||
...mapState('queue', [
|
...mapState('queue', [
|
||||||
'isPublishRequested',
|
'isPublishRequested',
|
||||||
]),
|
]),
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="side-bar__panel side-bar__panel--menu">
|
<div class="side-bar__panel side-bar__panel--menu">
|
||||||
<div class="side-bar__warning" v-if="syncLocations.length">
|
<div class="side-bar__info" v-if="syncLocations.length">
|
||||||
<p><b>{{currentFileName}}</b> is already synchronized.</p>
|
<p><b>{{currentFileName}}</b> is already synchronized.</p>
|
||||||
<menu-entry v-if="!offline && isSyncPossible" @click.native="requestSync">
|
<menu-entry v-if="isSyncPossible" @click.native="requestSync">
|
||||||
<icon-sync slot="icon"></icon-sync>
|
<icon-sync slot="icon"></icon-sync>
|
||||||
<div>Synchronize now</div>
|
<div>Synchronize now</div>
|
||||||
<span>Download, merge and upload file changes.</span>
|
<span>Download / upload file changes.</span>
|
||||||
</menu-entry>
|
</menu-entry>
|
||||||
<menu-entry @click.native="manageSync">
|
<menu-entry @click.native="manageSync">
|
||||||
<icon-view-list slot="icon"></icon-view-list>
|
<icon-view-list slot="icon"></icon-view-list>
|
||||||
@ -13,13 +13,11 @@
|
|||||||
<span>Manage current file synchronized locations.</span>
|
<span>Manage current file synchronized locations.</span>
|
||||||
</menu-entry>
|
</menu-entry>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="!offline && isSyncPossible">
|
<menu-entry v-else-if="isSyncPossible" @click.native="requestSync">
|
||||||
<menu-entry @click.native="requestSync">
|
<icon-sync slot="icon"></icon-sync>
|
||||||
<icon-sync slot="icon"></icon-sync>
|
<div>Synchronize now</div>
|
||||||
<div>Synchronize now</div>
|
<span>Download / upload file changes.</span>
|
||||||
<span>Download, merge and upload file changes.</span>
|
</menu-entry>
|
||||||
</menu-entry>
|
|
||||||
</div>
|
|
||||||
<hr>
|
<hr>
|
||||||
<div v-for="token in googleDriveTokens" :key="token.sub">
|
<div v-for="token in googleDriveTokens" :key="token.sub">
|
||||||
<menu-entry @click.native="openGoogleDrive(token)">
|
<menu-entry @click.native="openGoogleDrive(token)">
|
||||||
@ -99,9 +97,6 @@ export default {
|
|||||||
MenuEntry,
|
MenuEntry,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([
|
|
||||||
'offline',
|
|
||||||
]),
|
|
||||||
...mapState('queue', [
|
...mapState('queue', [
|
||||||
'isSyncRequested',
|
'isSyncRequested',
|
||||||
]),
|
]),
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
||||||
</div>
|
</div>
|
||||||
</form-entry>
|
</form-entry>
|
||||||
<div class="modal__tip">
|
<div class="modal__info">
|
||||||
<b>ProTip:</b> You can provide a value for <code>title</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
<b>ProTip:</b> You can provide a value for <code>title</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
||||||
</div>
|
</div>
|
||||||
<div class="modal__button-bar">
|
<div class="modal__button-bar">
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
||||||
</div>
|
</div>
|
||||||
</form-entry>
|
</form-entry>
|
||||||
<div class="modal__tip">
|
<div class="modal__info">
|
||||||
<b>ProTip:</b> You can provide values for <code>title</code>, <code>tags</code>,
|
<b>ProTip:</b> You can provide values for <code>title</code>, <code>tags</code>,
|
||||||
<code>status</code> and <code>date</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
<code>status</code> and <code>date</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
||||||
</div>
|
</div>
|
||||||
</form-entry>
|
</form-entry>
|
||||||
<div class="modal__tip">
|
<div class="modal__info">
|
||||||
<b>ProTip:</b> You can provide a value for <code>title</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
<b>ProTip:</b> You can provide a value for <code>title</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
||||||
</div>
|
</div>
|
||||||
<div class="modal__button-bar">
|
<div class="modal__button-bar">
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
||||||
</div>
|
</div>
|
||||||
</form-entry>
|
</form-entry>
|
||||||
<div class="modal__tip">
|
<div class="modal__info">
|
||||||
<b>ProTip:</b> You can provide a value for <code>title</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
<b>ProTip:</b> You can provide a value for <code>title</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
||||||
</div>
|
</div>
|
||||||
<div class="modal__button-bar">
|
<div class="modal__button-bar">
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
||||||
</div>
|
</div>
|
||||||
</form-entry>
|
</form-entry>
|
||||||
<div class="modal__tip">
|
<div class="modal__info">
|
||||||
<b>ProTip:</b> You can provide values for <code>title</code>, <code>tags</code>,
|
<b>ProTip:</b> You can provide values for <code>title</code>, <code>tags</code>,
|
||||||
<code>categories</code>, <code>excerpt</code>, <code>author</code>, <code>featuredImage</code>,
|
<code>categories</code>, <code>excerpt</code>, <code>author</code>, <code>featuredImage</code>,
|
||||||
<code>status</code> and <code>date</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
<code>status</code> and <code>date</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
<a href="javascript:void(0)" @click="configureTemplates">Configure templates</a>
|
||||||
</div>
|
</div>
|
||||||
</form-entry>
|
</form-entry>
|
||||||
<div class="modal__tip">
|
<div class="modal__info">
|
||||||
<b>ProTip:</b> You can provide values for <code>title</code>, <code>tags</code> and
|
<b>ProTip:</b> You can provide values for <code>title</code>, <code>tags</code> and
|
||||||
<code>status</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
<code>status</code> in the <a href="javascript:void(0)" @click="openFileProperties">file properties</a>.
|
||||||
</div>
|
</div>
|
||||||
|
@ -264,5 +264,8 @@ function checkOffline() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
utils.setInterval(checkOffline, 1000);
|
utils.setInterval(checkOffline, 1000);
|
||||||
window.addEventListener('online', checkOffline);
|
window.addEventListener('online', () => {
|
||||||
|
isConnectionDown = false;
|
||||||
|
checkOffline();
|
||||||
|
});
|
||||||
window.addEventListener('offline', checkOffline);
|
window.addEventListener('offline', checkOffline);
|
||||||
|
@ -84,10 +84,10 @@ export default providerRegistry.register({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
uploadContent(token, content, syncLocation, ifNotTooLate) {
|
uploadContent(token, content, syncLocation, ifNotTooLate) {
|
||||||
return this.uploadData(token, undefined, content, `${syncLocation.fileId}/content`, ifNotTooLate)
|
return this.uploadData(token, content, `${syncLocation.fileId}/content`, ifNotTooLate)
|
||||||
.then(() => syncLocation);
|
.then(() => syncLocation);
|
||||||
},
|
},
|
||||||
uploadData(token, sub, item, dataId, ifNotTooLate) {
|
uploadData(token, item, dataId, ifNotTooLate) {
|
||||||
const syncData = store.getters['data/syncDataByItemId'][dataId];
|
const syncData = store.getters['data/syncDataByItemId'][dataId];
|
||||||
if (syncData && syncData.hash === item.hash) {
|
if (syncData && syncData.hash === item.hash) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
@ -98,7 +98,6 @@ export default providerRegistry.register({
|
|||||||
id: item.id,
|
id: item.id,
|
||||||
type: item.type,
|
type: item.type,
|
||||||
hash: item.hash,
|
hash: item.hash,
|
||||||
sub,
|
|
||||||
}),
|
}),
|
||||||
['appDataFolder'],
|
['appDataFolder'],
|
||||||
JSON.stringify(item),
|
JSON.stringify(item),
|
||||||
|
@ -54,37 +54,33 @@ function cleanSyncedContent(syncedContent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function applyChanges(changes) {
|
function applyChanges(changes) {
|
||||||
const token = mainProvider.getToken();
|
|
||||||
const storeItemMap = { ...store.getters.allItemMap };
|
const storeItemMap = { ...store.getters.allItemMap };
|
||||||
const syncData = { ...store.getters['data/syncData'] };
|
const syncData = { ...store.getters['data/syncData'] };
|
||||||
let syncDataChanged = false;
|
let syncDataChanged = false;
|
||||||
|
|
||||||
changes.forEach((change) => {
|
changes.forEach((change) => {
|
||||||
// Ignore items that belong to another user (like settings)
|
const existingSyncData = syncData[change.fileId];
|
||||||
if (!change.item || !change.item.sub || change.item.sub === token.sub) {
|
const existingItem = existingSyncData && storeItemMap[existingSyncData.itemId];
|
||||||
const existingSyncData = syncData[change.fileId];
|
if (change.removed && existingSyncData) {
|
||||||
const existingItem = existingSyncData && storeItemMap[existingSyncData.itemId];
|
if (existingItem) {
|
||||||
if (change.removed && existingSyncData) {
|
// Remove object from the store
|
||||||
if (existingItem) {
|
store.commit(`${existingItem.type}/deleteItem`, existingItem.id);
|
||||||
// Remove object from the store
|
delete storeItemMap[existingItem.id];
|
||||||
store.commit(`${existingItem.type}/deleteItem`, existingItem.id);
|
|
||||||
delete storeItemMap[existingItem.id];
|
|
||||||
}
|
|
||||||
delete syncData[change.fileId];
|
|
||||||
syncDataChanged = true;
|
|
||||||
} else if (!change.removed && change.item && change.item.hash) {
|
|
||||||
if (!existingSyncData || (existingSyncData.hash !== change.item.hash && (
|
|
||||||
!existingItem || existingItem.hash !== change.item.hash
|
|
||||||
))) {
|
|
||||||
// Put object in the store
|
|
||||||
if (change.item.type !== 'content') { // Merge contents later
|
|
||||||
store.commit(`${change.item.type}/setItem`, change.item);
|
|
||||||
storeItemMap[change.item.id] = change.item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
syncData[change.fileId] = change.syncData;
|
|
||||||
syncDataChanged = true;
|
|
||||||
}
|
}
|
||||||
|
delete syncData[change.fileId];
|
||||||
|
syncDataChanged = true;
|
||||||
|
} else if (!change.removed && change.item && change.item.hash) {
|
||||||
|
if (!existingSyncData || (existingSyncData.hash !== change.item.hash && (
|
||||||
|
!existingItem || existingItem.hash !== change.item.hash
|
||||||
|
))) {
|
||||||
|
// Put object in the store
|
||||||
|
if (change.item.type !== 'content') { // Merge contents later
|
||||||
|
store.commit(`${change.item.type}/setItem`, change.item);
|
||||||
|
storeItemMap[change.item.id] = change.item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
syncData[change.fileId] = change.syncData;
|
||||||
|
syncDataChanged = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -374,7 +370,6 @@ function syncDataItem(dataId) {
|
|||||||
}
|
}
|
||||||
return mainProvider.uploadData(
|
return mainProvider.uploadData(
|
||||||
token,
|
token,
|
||||||
dataId === 'settings' ? token.sub : undefined,
|
|
||||||
mergedItem,
|
mergedItem,
|
||||||
dataId,
|
dataId,
|
||||||
);
|
);
|
||||||
|
@ -60,6 +60,10 @@ export default {
|
|||||||
resolveText: 'Yes, delete',
|
resolveText: 'Yes, delete',
|
||||||
rejectText: 'No',
|
rejectText: 'No',
|
||||||
}),
|
}),
|
||||||
|
trashDeletion: ({ dispatch }) => dispatch('open', {
|
||||||
|
content: '<p>Files in the trash are automatically deleted after 7 days of inactivity.</p>',
|
||||||
|
resolveText: 'Ok',
|
||||||
|
}),
|
||||||
reset: ({ dispatch }) => dispatch('open', {
|
reset: ({ dispatch }) => dispatch('open', {
|
||||||
content: '<p>This will clean your local files and settings. Are you sure?</p>',
|
content: '<p>This will clean your local files and settings. Are you sure?</p>',
|
||||||
resolveText: 'Yes, clean',
|
resolveText: 'Yes, clean',
|
||||||
|
Loading…
Reference in New Issue
Block a user