Stackedit/src/services/providers/googleDriveWorkspaceProvider.js

176 lines
5.9 KiB
JavaScript
Raw Normal View History

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;
});
},
});