2017-12-10 23:49:20 +00:00
|
|
|
import store from '../../store';
|
|
|
|
import googleHelper from './helpers/googleHelper';
|
|
|
|
import providerRegistry from './providerRegistry';
|
|
|
|
import utils from '../utils';
|
|
|
|
|
|
|
|
export default providerRegistry.register({
|
|
|
|
id: 'googleDriveWorkspace',
|
|
|
|
getToken() {
|
2017-12-17 15:08:52 +00:00
|
|
|
return store.getters['workspace/syncToken'];
|
2017-12-10 23:49:20 +00:00
|
|
|
},
|
|
|
|
initWorkspace() {
|
2017-12-17 15:08:52 +00:00
|
|
|
const makeWorkspaceId = folderId => folderId && Math.abs(utils.hash(utils.serializeObject({
|
|
|
|
providerId: this.id,
|
|
|
|
folderId,
|
|
|
|
}))).toString(36);
|
|
|
|
|
|
|
|
const getWorkspace = folderId => store.getters['data/workspaces'][makeWorkspaceId(folderId)];
|
|
|
|
|
2017-12-10 23:49:20 +00:00
|
|
|
const initFolder = (token, folder) => Promise.resolve({
|
2017-12-17 15:08:52 +00:00
|
|
|
folderId: folder.id,
|
2017-12-10 23:49:20 +00:00
|
|
|
dataFolderId: folder.appProperties.dataFolderId,
|
|
|
|
trashFolderId: folder.appProperties.trashFolderId,
|
|
|
|
})
|
|
|
|
.then((properties) => {
|
|
|
|
// Make sure data folder exists
|
|
|
|
if (properties.dataFolderId) {
|
|
|
|
return properties;
|
|
|
|
}
|
|
|
|
return googleHelper.uploadFile(
|
|
|
|
token,
|
|
|
|
'.stackedit-data',
|
|
|
|
[folder.id],
|
2017-12-17 15:08:52 +00:00
|
|
|
{ folderId: folder.id },
|
2017-12-10 23:49:20 +00:00
|
|
|
undefined,
|
|
|
|
'application/vnd.google-apps.folder',
|
|
|
|
)
|
|
|
|
.then(dataFolder => ({
|
|
|
|
...properties,
|
|
|
|
dataFolderId: dataFolder.id,
|
|
|
|
}));
|
|
|
|
})
|
|
|
|
.then((properties) => {
|
|
|
|
// Make sure trash folder exists
|
|
|
|
if (properties.trashFolderId) {
|
|
|
|
return properties;
|
|
|
|
}
|
|
|
|
return googleHelper.uploadFile(
|
|
|
|
token,
|
|
|
|
'.stackedit-trash',
|
|
|
|
[folder.id],
|
2017-12-17 15:08:52 +00:00
|
|
|
{ folderId: folder.id },
|
2017-12-10 23:49:20 +00:00
|
|
|
undefined,
|
|
|
|
'application/vnd.google-apps.folder',
|
|
|
|
)
|
|
|
|
.then(trashFolder => ({
|
|
|
|
...properties,
|
|
|
|
trashFolderId: trashFolder.id,
|
|
|
|
}));
|
|
|
|
})
|
|
|
|
.then((properties) => {
|
|
|
|
// Update workspace if some properties are missing
|
2017-12-17 15:08:52 +00:00
|
|
|
if (properties.folderId === folder.appProperties.folderId
|
2017-12-10 23:49:20 +00:00
|
|
|
&& properties.dataFolderId === folder.appProperties.dataFolderId
|
|
|
|
&& properties.trashFolderId === folder.appProperties.trashFolderId
|
|
|
|
) {
|
|
|
|
return properties;
|
|
|
|
}
|
|
|
|
return googleHelper.uploadFile(
|
|
|
|
token,
|
|
|
|
undefined,
|
|
|
|
undefined,
|
|
|
|
properties,
|
|
|
|
undefined,
|
|
|
|
'application/vnd.google-apps.folder',
|
|
|
|
folder.id,
|
|
|
|
)
|
|
|
|
.then(() => properties);
|
|
|
|
})
|
|
|
|
.then((properties) => {
|
2017-12-17 15:08:52 +00:00
|
|
|
// Fix the current url hash
|
|
|
|
const hash = `#providerId=${this.id}&folderId=${folder.id}`;
|
|
|
|
if (location.hash !== hash) {
|
|
|
|
location.hash = hash;
|
|
|
|
}
|
|
|
|
|
2017-12-10 23:49:20 +00:00
|
|
|
// Update workspace in the store
|
2017-12-17 15:08:52 +00:00
|
|
|
const workspaceId = makeWorkspaceId(folder.id);
|
2017-12-10 23:49:20 +00:00
|
|
|
store.dispatch('data/patchWorkspaces', {
|
2017-12-17 15:08:52 +00:00
|
|
|
[workspaceId]: {
|
|
|
|
id: workspaceId,
|
2017-12-10 23:49:20 +00:00
|
|
|
sub: token.sub,
|
|
|
|
name: folder.name,
|
|
|
|
providerId: this.id,
|
2017-12-17 15:08:52 +00:00
|
|
|
url: utils.resolveUrl(hash),
|
2017-12-10 23:49:20 +00:00
|
|
|
folderId: folder.id,
|
|
|
|
dataFolderId: properties.dataFolderId,
|
|
|
|
trashFolderId: properties.trashFolderId,
|
|
|
|
},
|
|
|
|
});
|
2017-12-17 15:08:52 +00:00
|
|
|
|
|
|
|
// Return the workspace
|
|
|
|
return getWorkspace(folder.id);
|
2017-12-10 23:49:20 +00:00
|
|
|
});
|
|
|
|
|
2017-12-17 15:08:52 +00:00
|
|
|
const workspace = getWorkspace(utils.queryParams.folderId);
|
|
|
|
return Promise.resolve()
|
|
|
|
.then(() => {
|
|
|
|
// See if we already have a token
|
|
|
|
const googleTokens = store.getters['data/googleTokens'];
|
|
|
|
// Token sub is in the workspace or in the url if workspace is about to be created
|
|
|
|
const token = workspace ? googleTokens[workspace.sub] : googleTokens[utils.queryParams.sub];
|
|
|
|
if (token && token.isDrive) {
|
|
|
|
return token;
|
|
|
|
}
|
|
|
|
// If no token has been found, popup an authorize window and get one
|
|
|
|
return store.dispatch('modal/workspaceGoogleRedirection', {
|
|
|
|
onResolve: () => googleHelper.addDriveAccount(),
|
|
|
|
});
|
|
|
|
})
|
2017-12-10 23:49:20 +00:00
|
|
|
.then(token => Promise.resolve()
|
2017-12-17 15:08:52 +00:00
|
|
|
// If no folderId is provided, create one
|
2017-12-10 23:49:20 +00:00
|
|
|
.then(() => utils.queryParams.folderId || googleHelper.uploadFile(
|
|
|
|
token,
|
|
|
|
'StackEdit workspace',
|
|
|
|
[],
|
|
|
|
undefined,
|
|
|
|
undefined,
|
|
|
|
'application/vnd.google-apps.folder',
|
2017-12-17 15:08:52 +00:00
|
|
|
)
|
|
|
|
.then(folder => initFolder(token, {
|
|
|
|
...folder,
|
|
|
|
appProperties: {},
|
|
|
|
})
|
|
|
|
.then(() => folder.id)))
|
|
|
|
// If workspace does not exist, initialize one
|
|
|
|
.then(folderId => getWorkspace(folderId) || googleHelper.getFile(token, folderId)
|
|
|
|
.then((folder) => {
|
|
|
|
const folderIdProperty = folder.appProperties.folderId;
|
|
|
|
if (folderIdProperty && folderIdProperty !== folderId) {
|
|
|
|
throw new Error(`Google Drive folder ${folderId} is part of another workspace.`);
|
|
|
|
}
|
|
|
|
return initFolder(token, folder);
|
|
|
|
}, () => {
|
|
|
|
throw new Error(`Folder ${folderId} is not accessible. Make sure it's a valid StackEdit workspace folder and you have the right permissions.`);
|
|
|
|
})));
|
2017-12-10 23:49:20 +00:00
|
|
|
},
|
|
|
|
getChanges(token) {
|
2017-12-17 15:08:52 +00:00
|
|
|
const startPageToken = store.getters['data/localSettings'].syncStartPageToken;
|
|
|
|
return googleHelper.getChanges(token, startPageToken, 'appDataFolder')
|
2017-12-10 23:49:20 +00:00
|
|
|
.then((result) => {
|
|
|
|
const changes = result.changes.filter((change) => {
|
|
|
|
if (change.file) {
|
2017-12-17 15:08:52 +00:00
|
|
|
// Parse item from file name
|
2017-12-10 23:49:20 +00:00
|
|
|
try {
|
|
|
|
change.item = JSON.parse(change.file.name);
|
|
|
|
} catch (e) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// Build sync data
|
|
|
|
change.syncData = {
|
|
|
|
id: change.fileId,
|
|
|
|
itemId: change.item.id,
|
|
|
|
type: change.item.type,
|
|
|
|
hash: change.item.hash,
|
|
|
|
};
|
|
|
|
change.file = undefined;
|
|
|
|
}
|
2017-12-17 15:08:52 +00:00
|
|
|
change.syncDataId = change.fileId;
|
2017-12-10 23:49:20 +00:00
|
|
|
return true;
|
|
|
|
});
|
2017-12-17 15:08:52 +00:00
|
|
|
changes.startPageToken = result.startPageToken;
|
2017-12-10 23:49:20 +00:00
|
|
|
return changes;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
});
|