Skip to content

Commit

Permalink
feat(gDriveSync): prompt before saving if there is a remote update
Browse files Browse the repository at this point in the history
  • Loading branch information
johannesjo committed Mar 9, 2018
1 parent dacbe58 commit 8b3e99a
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 61 deletions.
6 changes: 3 additions & 3 deletions app-src/scripts/constants.js
Expand Up @@ -132,9 +132,9 @@
},
config: {
googleDriveSync: {
isAutoLogin: undefined,
isAutoSyncToRemote: false,
isAutoSyncFromRemote: false,
isAutoLogin: false,
isLoadRemoteDataOnStartup: false,
isAutoSync: false,
syncInterval: moment.duration(1, 'minutes'),
},
automaticBackups: {
Expand Down
3 changes: 2 additions & 1 deletion app-src/scripts/main/global-services/app-storage-s.js
Expand Up @@ -226,7 +226,8 @@
this.saveLsItem(val, key);
});

// reload page completely afterwards
// unset handlers for unload to prevent current app state from overwriting the imports
window.onbeforeunload = window.onunload = undefined;
window.location.reload(true);
}

Expand Down
18 changes: 13 additions & 5 deletions app-src/scripts/main/global-services/google-api-s.js
Expand Up @@ -14,7 +14,7 @@
' https://www.googleapis.com/auth/drive.install' +
' https://www.googleapis.com/auth/drive';

const DEFAULT_FIELDS_FOR_DRIVE = 'id,title,mimeType,userPermission,editable,copyable,shared,fileSize';
const DEFAULT_FIELDS_FOR_DRIVE = 'id,title,mimeType,userPermission,editable,modifiedDate,shared,createdDate,fileSize';

/**
* Helper for building multipart requests for uploading to Drive.
Expand Down Expand Up @@ -277,13 +277,13 @@
return defer.promise;
}

loadFile(fileId) {
getFileInfo(fileId) {
if (!fileId) {
this.SimpleToast('ERROR', 'GoogleApi: No file id specified');
return this.$q.reject('No file id given');
}

const metaData = this.$http({
return this.$http({
method: 'GET',
url: `https://content.googleapis.com/drive/v2/files/${encodeURIComponent(fileId)}`,
params: {
Expand All @@ -295,8 +295,16 @@
'Authorization': `Bearer ${this.accessToken}`,
},
});
}

loadFile(fileId) {
if (!fileId) {
this.SimpleToast('ERROR', 'GoogleApi: No file id specified');
return this.$q.reject('No file id given');
}

const fileData = this.$http({
const metaData = this.getFileInfo(fileId);
const fileContents = this.$http({
method: 'GET',
url: `https://content.googleapis.com/drive/v2/files/${encodeURIComponent(fileId)}`,
params: {
Expand All @@ -309,7 +317,7 @@
},
});

return this.$q.all([this.$q.when(metaData), this.$q.when(fileData)])
return this.$q.all([this.$q.when(metaData), this.$q.when(fileContents)])
.then((res) => {
return this.$q.when({
backup: res[1].data,
Expand Down
125 changes: 115 additions & 10 deletions app-src/scripts/main/global-services/google-drive-sync-s.js
Expand Up @@ -13,43 +13,148 @@

class GoogleDriveSync {
/* @ngInject */
constructor(AppStorage, GoogleApi, $rootScope, SimpleToast, $q) {
constructor(AppStorage, GoogleApi, $rootScope, SimpleToast, $mdDialog, $q) {
this.AppStorage = AppStorage;
this.GoogleApi = GoogleApi;
this.$rootScope = $rootScope;
this.SimpleToast = SimpleToast;
this.$mdDialog = $mdDialog;
this.$q = $q;

if (this.$rootScope.r.config.googleDriveSync.isAutoLogin) {
this.data = this.$rootScope.r.googleDriveSync;
this.config = this.$rootScope.r.config.googleDriveSync;

if (this.config.isAutoLogin) {
GoogleApi.login();
}
if (this.config.isAutoSync) {

}
if (this.config.isLoadRemoteDataOnStartup) {

}
}

_isRemoteUpdate() {

}

_isNewerThan(strDate1, strDate2) {
const d1 = new Date(strDate1);
const d2 = new Date(strDate2);
return (d1.getTime() > d2.getTime());
}

_isValidData(data) {
return data.tasks && data.backlogTasks && data.config;
}

getLocalAppData() {
_getLocalAppData() {
return this.AppStorage.getCompleteBackupData();
}

saveTo() {
return this.GoogleApi.saveFile(this.getLocalAppData(), {
_confirmSaveDialog(remoteModified) {
const confirm = this.$mdDialog.confirm()
.title('Overwrite unsaved data on Google Drive?')
.textContent(`
There seem to be some changes on Google Drive, that you don\'t have locally. Do you want to overwrite them anyway?
\nRemote data last saved change: ${remoteModified};
\nLast sync to remote from this app instance: ${this.data.lastSyncToRemote}.`)
.ok('Please do it!')
.cancel('No');

return this.$mdDialog.show(confirm);
}

_confirmLoadDialog(remoteChanged) {
const confirm = this.$mdDialog.confirm()
.title('Overwrite unsaved local changes?')
.textContent(`
All data will be lost forever.
Remote data last change: ${remoteChanged};
Local data last changed: ${this.data.lastSyncToRemote}`)
.ok('Please do it!')
.cancel('No');

return this.$mdDialog.show(confirm);
}

_save() {
const completeData = this._getLocalAppData();

return this.GoogleApi.saveFile(completeData, {
title: SYNC_FILE_NAME,
id: this.$rootScope.r.googleDriveSync.backupDocId,
id: this.data.backupDocId,
editable: true
})
.then((res) => {
if (res && res.data) {
this.$rootScope.r.googleDriveSync.backupDocId = res.data.id;
this.data.backupDocId = res.data.id;
this.data.lastSyncToRemote = res.data.modifiedDate;
}
});
}

loadFrom() {
return this.GoogleApi.loadFile(this.$rootScope.r.googleDriveSync.backupDocId)
_load() {
return this.GoogleApi.loadFile(this.data.backupDocId)
.then((res) => {
console.log(res);
this.data.lastLocalUpdate = res.meta.modifiedDate;
return this.$q.when(res);
});
}

saveTo() {
const defer = this.$q.defer();

this.GoogleApi.getFileInfo(this.data.backupDocId)
.then((res) => {
const lastModifiedRemote = res.data.modifiedDate;

if (this._isNewerThan(lastModifiedRemote, this.data.lastSyncToRemote)) {
// remote has an update so prompt what to do
this._confirmSaveDialog(lastModifiedRemote)
.then(() => {
this._save().then(defer.resolve);
}, defer.reject);
} else {
// all clear just save
this._save().then(defer.resolve);
}
})
.catch(defer.reject);

return defer.promise;
}

loadFrom() {
const defer = this.$q.defer();
this.GoogleApi.getFileInfo(this.data.backupDocId)
.then((res) => {
const lastModifiedRemote = res.data.modifiedDate;

if (this._isNewerThan(this.data.lastSyncToRemote, lastModifiedRemote)) {
// local data is newer so prompt
this._confirmLoadDialog().then(() => {
this._load().then(defer.resolve);
}, defer.reject);
} else {
// all clear just load
this._load().then((res) => {
console.log('loadFrom', res);
defer.resolve(res);
});
}
});

return defer.promise;
}

sync() {
this.loadFrom()
.then(() => {

});
}
}

angular
Expand Down
84 changes: 42 additions & 42 deletions app-src/scripts/settings/backup-settings/backup-settings-d.html
Expand Up @@ -17,22 +17,42 @@ <h2 class="md-title">
</section>
</help-section>

<h3 class="md-caption">File import/export</h3>
<a class="md-raised md-button md-ink-ripple"
type="button"
download-backup>
<ng-md-icon icon="file_download"
aria-label="download settings"></ng-md-icon>
Export your tasks and settings
<div class="md-ripple-container"></div>
</a>
<md-button
class="md-raised"
ng-click="vm.showUploadForm=!vm.showUploadForm;">
<ng-md-icon icon="file_upload"
aria-label="import settings"></ng-md-icon>
Import Settings
</md-button>
<section>
<h3 class="md-caption">File import/export</h3>
<a class="md-raised md-button md-ink-ripple"
type="button"
download-backup>
<ng-md-icon icon="file_download"
aria-label="download settings"></ng-md-icon>
Export your tasks and settings
<div class="md-ripple-container"></div>
</a>
<md-button
class="md-raised"
ng-click="vm.showUploadForm=!vm.showUploadForm;">
<ng-md-icon icon="file_upload"
aria-label="import settings"></ng-md-icon>
Import Settings
</md-button>

<form ng-if="vm.showUploadForm"
ng-submit="vm.importSettings(vm.uploadSettingsTextarea)">
<md-input-container class="md-block"
flex-gt-sm>
<label>Copy and paste the contents of the saved JSON file here</label>
<textarea ng-model="vm.uploadSettingsTextarea"
md-auto-focus
rows="3"></textarea>
</md-input-container>

<div><strong>NOTE: Once you hit the import button all your current settings and data will be overwritten!</strong>
</div>

<md-button type="submit"
class="md-raised md-primary">Import settings
</md-button>
</form>
</section>

<section>
<h3 class="md-caption">Sync via Google Drive</h3>
Expand Down Expand Up @@ -82,15 +102,15 @@ <h3 class="md-caption">Sync via Google Drive</h3>
</md-switch>
</div>
<div>
<md-switch ng-model="vm.settings.googleDriveSync.isAutoSyncToRemote"
aria-label="Auto sync to remote">
Auto sync to remote
<md-switch ng-model="vm.settings.googleDriveSync.isLoadRemoteDataOnStartup"
aria-label="Load remote data on startup">
Load remote data on startup
</md-switch>
</div>
<div>
<md-switch ng-model="vm.settings.googleDriveSync.isAutoSyncFromRemote"
aria-label="Auto sync from remote">
Auto sync from remote
<md-switch ng-model="vm.settings.googleDriveSync.isAutoSync"
aria-label="Auto sync data">
Auto sync data
</md-switch>
</div>
<!-- todo add sync doc id -->
Expand All @@ -107,26 +127,6 @@ <h3 class="md-caption">Sync via Google Drive</h3>

</section>


<form ng-if="vm.showUploadForm"
ng-submit="vm.importSettings(vm.uploadSettingsTextarea)">
<md-input-container class="md-block"
flex-gt-sm>
<label>Copy and paste the contents of the saved JSON file here</label>
<textarea ng-model="vm.uploadSettingsTextarea"
md-auto-focus
rows="3"></textarea>
</md-input-container>

<div><strong>NOTE: Once you hit the import button all your current settings and data will be overwritten!</strong>
</div>

<md-button type="submit"
class="md-raised md-primary">Import settings
</md-button>
</form>


<section ng-if="vm.IS_ELECTRON">
<h3 class="md-caption">Automatic Backups</h3>
<div>
Expand Down

0 comments on commit 8b3e99a

Please sign in to comment.