Skip to content

Commit 6508dc7

Browse files
sumomomomomolinedoestrolling
authored andcommitted
Implement save all - barebones writing folders for GDrive
1 parent 76dc9d5 commit 6508dc7

File tree

2 files changed

+113
-15
lines changed

2 files changed

+113
-15
lines changed

src/commons/sagas/PersistenceSaga.tsx

Lines changed: 112 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { AsyncReturnType } from '../utils/TypeHelper';
2929
import { safeTakeEvery as takeEvery, safeTakeLatest as takeLatest } from './SafeEffects';
3030
import { FSModule } from 'browserfs/dist/node/core/FS';
3131
import { retrieveFilesInWorkspaceAsRecord, rmFilesInDirRecursively, writeFileRecursively } from '../fileSystem/FileSystemUtils';
32-
import { refreshFileView } from '../fileSystemView/FileSystemViewList';
32+
import { refreshFileView } from '../fileSystemView/FileSystemViewList'; // TODO broken when folder is open when reading folders
3333

3434
const DISCOVERY_DOCS = ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest'];
3535
const SCOPES =
@@ -91,12 +91,14 @@ export function* persistenceSaga(): SagaIterator {
9191
let toastKey: string | undefined;
9292
try {
9393
yield call(ensureInitialisedAndAuthorised);
94-
const { id, name, mimeType, picked } = yield call(pickFile,
94+
const { id, name, mimeType, picked, parentId } = yield call(pickFile,
9595
'Pick a file/folder to open',
9696
{
9797
pickFolders: true
9898
}
9999
); // id, name, picked gotten here
100+
101+
yield call(console.log, parentId);
100102
if (!picked) {
101103
return;
102104
}
@@ -142,8 +144,6 @@ export function* persistenceSaga(): SagaIterator {
142144
}
143145
yield call(console.log, "there is a filesystem");
144146

145-
yield put(actions.playgroundUpdatePersistenceFolder({ id, name, lastSaved: new Date() }));
146-
147147
// rmdir everything TODO replace everything hardcoded with playground?
148148
yield call(rmFilesInDirRecursively, fileSystem, "/playground");
149149

@@ -173,6 +173,10 @@ export function* persistenceSaga(): SagaIterator {
173173

174174
yield call(showSuccessMessage, `Loaded folder ${name}.`, 1000);
175175

176+
// TODO does not update playground on loading folder
177+
yield call(console.log, "ahfdaskjhfkjsadf", parentId);
178+
yield put(actions.playgroundUpdatePersistenceFolder({ id, name, parentId, lastSaved: new Date() }));
179+
176180
return;
177181
}
178182

@@ -348,10 +352,14 @@ export function* persistenceSaga(): SagaIterator {
348352
yield takeEvery( // TODO work on this
349353
PERSISTENCE_SAVE_ALL,
350354
function* () {
355+
// TODO: when top level folder is renamed, save all just leaves the old folder alone and saves in a new folder if it exists
356+
// Add checking to see if current folder already exists when renamed?
357+
// Some way to keep track of when files/folders are renamed???????????
358+
// TODO: if top level folder already exists in GDrive, to
359+
351360
// Case init: Don't care, delete everything in remote and save again
352361
// Callable only if persistenceObject isFolder
353-
354-
const [currFolderObject] = yield select(
362+
const [currFolderObject] = yield select( // TODO resolve type here?
355363
(state: OverallState) => [
356364
state.playground.persistenceObject
357365
]
@@ -360,6 +368,12 @@ export function* persistenceSaga(): SagaIterator {
360368
yield call(console.log, "no obj!");
361369
return;
362370
}
371+
if (!(currFolderObject as PersistenceObject).isFolder) {
372+
yield call (console.log, "folder not opened!");
373+
return;
374+
}
375+
376+
363377

364378
console.log("currFolderObj", currFolderObject);
365379

@@ -378,6 +392,44 @@ export function* persistenceSaga(): SagaIterator {
378392
// behaviour of open folder for GDrive loads even empty folders
379393
yield call(console.log, "currfiles", currFiles);
380394

395+
const [chapter, variant, external] = yield select(
396+
(state: OverallState) => [
397+
state.workspaces.playground.context.chapter,
398+
state.workspaces.playground.context.variant,
399+
state.workspaces.playground.externalLibrary
400+
]
401+
);
402+
const config: IPlaygroundConfig = {
403+
chapter,
404+
variant,
405+
external
406+
};
407+
408+
// check if top level folder has been renamed
409+
// assuming only 1 top level folder exists, so get 1 file
410+
const testPath = Object.keys(currFiles)[0];
411+
const regexResult = /^(.*[\\\/])?(\.*.*?)(\.[^.]+?|)$/.exec(testPath);
412+
if (regexResult === null) {
413+
yield call(console.log, "Regex null!");
414+
return; // should never come here
415+
}
416+
const topLevelFolderName = regexResult[1].slice(
417+
("/playground/").length, -1).split("/")[0];
418+
419+
if (topLevelFolderName === "") {
420+
yield call(console.log, "no top level folder?");
421+
return;
422+
}
423+
424+
if (topLevelFolderName !== currFolderObject.name) {
425+
// top level folder name has been renamed
426+
yield call(console.log, "TLFN changed from ", currFolderObject.name, " to ", topLevelFolderName);
427+
const newTopLevelFolderId: string = yield call(getContainingFolderIdRecursively, [topLevelFolderName],
428+
currFolderObject.parentId!); // try and find the folder if it exists
429+
currFolderObject.name = topLevelFolderName; // so that the new top level folder will be created below
430+
currFolderObject.id = newTopLevelFolderId; // so that new top level folder will be saved in root of gdrive
431+
}
432+
381433
//const fileNameRegex = new RegExp('@"[^\\]+$"');
382434
for (const currFullFilePath of Object.keys(currFiles)) {
383435
const currFileContent = currFiles[currFullFilePath];
@@ -395,18 +447,34 @@ export function* persistenceSaga(): SagaIterator {
395447
// /fold1/fold2/ becomes ["fold1", "fold2"]
396448
// If in top level folder, becomes [""]
397449

398-
yield call(getContainingFolderIdRecursively, currFileParentFolders,
450+
const currFileParentFolderId: string = yield call(getContainingFolderIdRecursively, currFileParentFolders,
399451
currFolderObject.id);
400452

401-
// yield call(
402-
// createFile,
403-
// fileName,
404-
// currFolderObject.id,
453+
yield call (console.log, "name", currFileName, "content", currFileContent
454+
, "parent folder id", currFileParentFolderId);
405455

406-
// );
456+
const currFileId: string = yield call(getFileFromFolder, currFileParentFolderId, currFileName);
407457

408-
yield call (console.log, "name", currFileName, "content", currFileContent
409-
, "path", currFileParentFolders);
458+
if (currFileId === "") {
459+
// file does not exist, create file
460+
yield call(console.log, "creating ", currFileName);
461+
yield call(createFile, currFileName, currFileParentFolderId, MIME_SOURCE, currFileContent, config);
462+
463+
} else {
464+
// file exists, update file
465+
yield call(console.log, "updating ", currFileName, " id: ", currFileId);
466+
yield call(updateFile, currFileId, currFileName, MIME_SOURCE, currFileContent, config);
467+
}
468+
yield put(actions.playgroundUpdatePersistenceFolder({ id: currFolderObject.id, name: currFolderObject.name, parentId: currFolderObject.parentId, lastSaved: new Date() }));
469+
yield call(showSuccessMessage, `${currFileName} successfully saved to Google Drive.`, 1000);
470+
471+
// TODO: create getFileIdRecursively, that uses currFileParentFolderId
472+
// to query GDrive api to get a particular file's GDrive id OR modify reading func to save each obj's id somewhere
473+
// Then use updateFile like in persistence_save_file to update files that exist
474+
// on GDrive, or createFile if the file doesn't exist
475+
476+
// TODO: lazy loading of files?
477+
// just show the folder structure, then load the file - to turn into an issue
410478
}
411479

412480

@@ -663,6 +731,35 @@ async function getFilesOfFolder( // recursively get files
663731
return ans;
664732
}
665733

734+
async function getFileFromFolder( // returns string id or empty string if failed
735+
parentFolderId: string,
736+
fileName: string
737+
): Promise<string> {
738+
let fileList: gapi.client.drive.File[] | undefined;
739+
740+
await gapi.client.drive.files.list({
741+
q: '\'' + parentFolderId + '\'' + ' in parents and trashed = false and name = \'' + fileName + '\'',
742+
}).then(res => {
743+
fileList = res.result.files
744+
})
745+
746+
console.log(fileList);
747+
748+
if (!fileList || fileList.length === 0) {
749+
// file does not exist
750+
console.log("file not exist: " + fileName);
751+
return "";
752+
}
753+
754+
//check if file is correct
755+
if (fileList![0].name === fileName) {
756+
// file is correct
757+
return fileList![0].id!;
758+
} else {
759+
return "";
760+
}
761+
}
762+
666763
async function getContainingFolderIdRecursively( // TODO memoize?
667764
parentFolders: string[],
668765
topFolderId: string,
@@ -799,7 +896,7 @@ function createFolderAndReturnId(
799896
headers,
800897
body
801898
}).then(res => res.result.id)
802-
};
899+
}
803900

804901
function createMultipartBody(
805902
meta: any,

src/features/persistence/PersistenceTypes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export type PersistenceState = 'INACTIVE' | 'SAVED' | 'DIRTY';
88

99
export type PersistenceObject = {
1010
id: string;
11+
parentId?: string; // only relevant for isFolder = true
1112
name: string;
1213
lastSaved?: Date;
1314
isFolder?: boolean;

0 commit comments

Comments
 (0)