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