Skip to content

Commit ebe1f37

Browse files
committed
Initial commit for google drive - instantaneous deletion/file renaming
1 parent 096cec4 commit ebe1f37

File tree

4 files changed

+143
-17
lines changed

4 files changed

+143
-17
lines changed

src/commons/fileSystem/FileSystemActions.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import {
1010
DELETE_ALL_PERSISTENCE_FILES, DELETE_GITHUB_SAVE_INFO,
1111
DELETE_PERSISTENCE_FILE,
1212
SET_IN_BROWSER_FILE_SYSTEM,
13-
UPDATE_GITHUB_SAVE_INFO,
1413
SET_PERSISTENCE_FILE_LAST_EDIT_BY_PATH,
14+
UPDATE_PERSISTENCE_FILE_PATH_AND_NAME_BY_PATH,
1515
UPDATE_LAST_EDITED_FILE_PATH,
16-
UPDATE_REFRESH_FILE_VIEW_KEY} from './FileSystemTypes';
16+
UPDATE_REFRESH_FILE_VIEW_KEY } from './FileSystemTypes';
1717

1818
export const setInBrowserFileSystem = createAction(
1919
SET_IN_BROWSER_FILE_SYSTEM,
@@ -34,12 +34,6 @@ export const deleteAllGithubSaveInfo = createAction(
3434
DELETE_ALL_GITHUB_SAVE_INFO,
3535
() => ({ payload: {} })
3636
);
37-
export const updateGithubSaveInfo = createAction(
38-
UPDATE_GITHUB_SAVE_INFO,
39-
(repoName: string,
40-
filePath: string,
41-
lastSaved: Date) => ({ payload: {repoName, filePath, lastSaved} })
42-
);
4337

4438
export const addPersistenceFile = createAction(
4539
ADD_PERSISTENCE_FILE,
@@ -48,7 +42,12 @@ export const addPersistenceFile = createAction(
4842

4943
export const deletePersistenceFile = createAction(
5044
DELETE_PERSISTENCE_FILE,
51-
(persistenceFile: PersistenceFile) => ({ payload: persistenceFile })
45+
( persistenceFile: PersistenceFile ) => ({ payload: persistenceFile })
46+
);
47+
48+
export const updatePersistenceFilePathAndNameByPath = createAction(
49+
UPDATE_PERSISTENCE_FILE_PATH_AND_NAME_BY_PATH,
50+
(oldPath: string, newPath: string, newFileName: string) => ({ payload: {oldPath, newPath, newFileName}})
5251
);
5352

5453
export const deleteAllPersistenceFiles = createAction(

src/commons/fileSystem/FileSystemReducer.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
setPersistenceFileLastEditByPath,
1414
updateLastEditedFilePath,
1515
updateRefreshFileViewKey,
16+
updatePersistenceFilePathAndNameByPath,
1617
} from './FileSystemActions';
1718
import { FileSystemState } from './FileSystemTypes';
1819

@@ -23,7 +24,7 @@ export const FileSystemReducer: Reducer<FileSystemState, SourceActionType> = cre
2324
.addCase(setInBrowserFileSystem, (state, action) => {
2425
state.inBrowserFileSystem = action.payload.inBrowserFileSystem;
2526
})
26-
.addCase(addGithubSaveInfo, (state, action) => {
27+
.addCase(addGithubSaveInfo, (state, action) => { // TODO rewrite
2728
const githubSaveInfoPayload = action.payload.githubSaveInfo;
2829
const persistenceFileArray = state['persistenceFileArray'];
2930

@@ -51,7 +52,7 @@ export const FileSystemReducer: Reducer<FileSystemState, SourceActionType> = cre
5152
}
5253
state.persistenceFileArray = persistenceFileArray;
5354
})
54-
.addCase(deleteGithubSaveInfo, (state, action) => {
55+
.addCase(deleteGithubSaveInfo, (state, action) => { // TODO rewrite - refer to deletePersistenceFile below
5556
const newPersistenceFileArray = state['persistenceFileArray'].filter(e => {
5657
return e.path != action.payload.githubSaveInfo.filePath &&
5758
e.lastSaved != action.payload.githubSaveInfo.lastSaved &&
@@ -62,7 +63,7 @@ export const FileSystemReducer: Reducer<FileSystemState, SourceActionType> = cre
6263
.addCase(deleteAllGithubSaveInfo, (state, action) => {
6364
state.persistenceFileArray = [];
6465
})
65-
.addCase(addPersistenceFile, (state, action) => {
66+
.addCase(addPersistenceFile, (state, action) => { // TODO rewrite
6667
const persistenceFilePayload = action.payload;
6768
const persistenceFileArray = state['persistenceFileArray'];
6869
const persistenceFileIndex = persistenceFileArray.findIndex(e => e.id === persistenceFilePayload.id);
@@ -75,11 +76,28 @@ export const FileSystemReducer: Reducer<FileSystemState, SourceActionType> = cre
7576
})
7677
.addCase(deletePersistenceFile, (state, action) => {
7778
const newPersistenceFileArray = state['persistenceFileArray'].filter(e => e.id !== action.payload.id);
78-
state.persistenceFileArray = newPersistenceFileArray;
79+
const isGitHubSyncing = action.payload.repoName ? true : false;
80+
if (isGitHubSyncing) {
81+
const newPersFile = {id: '', name: '', repoName: action.payload.repoName, path: action.payload.path};
82+
const newPersFileArray = newPersistenceFileArray.concat(newPersFile);
83+
state.persistenceFileArray = newPersFileArray;
84+
} else {
85+
state.persistenceFileArray = newPersistenceFileArray;
86+
}
7987
})
8088
.addCase(deleteAllPersistenceFiles, (state, action) => {
8189
state.persistenceFileArray = [];
8290
})
91+
.addCase(updatePersistenceFilePathAndNameByPath, (state, action) => {
92+
const filesState = state['persistenceFileArray'];
93+
const persistenceFileFindIndex = filesState.findIndex(e => e.path === action.payload.oldPath);
94+
if (persistenceFileFindIndex === -1) {
95+
return;
96+
}
97+
const newPersistenceFile = {...filesState[persistenceFileFindIndex], path: action.payload.newPath, name: action.payload.newFileName};
98+
filesState[persistenceFileFindIndex] = newPersistenceFile;
99+
state.persistenceFileArray = filesState;
100+
})
83101
.addCase(setPersistenceFileLastEditByPath, (state, action) => {
84102
const filesState = state['persistenceFileArray'];
85103
const persistenceFileFindIndex = filesState.findIndex(e => e.path === action.payload.path);

src/commons/fileSystem/FileSystemTypes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ export const ADD_PERSISTENCE_FILE = 'ADD_PERSISTENCE_FILE';
77
export const DELETE_GITHUB_SAVE_INFO = 'DELETE_GITHUB_SAVE_INFO';
88
export const DELETE_PERSISTENCE_FILE = 'DELETE_PERSISTENCE_FILE';
99
export const DELETE_ALL_GITHUB_SAVE_INFO = 'DELETE_ALL_GITHUB_SAVE_INFO';
10-
export const UPDATE_GITHUB_SAVE_INFO = 'UPDATE_GITHUB_SAVE_INFO';
1110
export const DELETE_ALL_PERSISTENCE_FILES = 'DELETE_ALL_PERSISTENCE_FILES';
11+
export const UPDATE_PERSISTENCE_FILE_PATH_AND_NAME_BY_PATH = 'UPDATE_PERSISTENCE_FILE_PATH_AND_NAME_BY_PATH';
1212
export const SET_PERSISTENCE_FILE_LAST_EDIT_BY_PATH = 'SET_PERSISTENCE_FILE_LAST_EDIT_BY_PATH';
1313
export const UPDATE_LAST_EDITED_FILE_PATH = 'UPDATE_LAST_EDITED_FILE_PATH';
1414
export const UPDATE_REFRESH_FILE_VIEW_KEY = 'UPDATE_REFRESH_FILE_VIEW_KEY';

src/commons/sagas/PersistenceSaga.tsx

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import { OverallState } from '../application/ApplicationTypes';
2424
import { ExternalLibraryName } from '../application/types/ExternalTypes';
2525
import { LOGIN_GOOGLE, LOGOUT_GOOGLE } from '../application/types/SessionTypes';
2626
import { retrieveFilesInWorkspaceAsRecord, rmFilesInDirRecursively, writeFileRecursively } from '../fileSystem/FileSystemUtils';
27-
import { refreshFileView } from '../fileSystemView/FileSystemViewList'; // TODO broken when folder is open when reading folders
2827
import { actions } from '../utils/ActionsHelper';
2928
import Constants from '../utils/Constants';
3029
import { showSimpleConfirmDialog, showSimplePromptDialog } from '../utils/DialogHelper';
@@ -196,7 +195,7 @@ export function* persistenceSaga(): SagaIterator {
196195
// TODO find a file to open instead of deleting all active tabs?
197196
// TODO without modifying WorkspaceReducer in one function this would cause errors - called by onChange of Playground.tsx?
198197
// TODO change behaviour of WorkspaceReducer to not create program.js every time folder mode changes with 0 tabs existing?
199-
yield call(refreshFileView); // refreshes folder view TODO super jank?
198+
yield call(store.dispatch, actions.updateRefreshFileViewKey()); // refreshes folder view TODO super jank?
200199

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

@@ -533,6 +532,9 @@ export function* persistenceSaga(): SagaIterator {
533532
// Turn on folder mode TODO enable folder mode
534533
//yield call (store.dispatch, actions.setFolderMode("playground", true));
535534
yield call(store.dispatch, actions.enableFileSystemContextMenus());
535+
yield call(store.dispatch, actions.updateRefreshFileViewKey());
536+
537+
yield call(showSuccessMessage, `${currFolderObject.name} successfully saved to Google Drive.`, 1000);
536538

537539

538540
// Case 1: Open picker to select location for saving, similar to save all
@@ -609,7 +611,8 @@ export function* persistenceSaga(): SagaIterator {
609611
yield call(console.log, "parent not found ", newFilePath);
610612
return;
611613
}
612-
const newFileName = regexResult![2];
614+
const newFileName = regexResult![2] + regexResult![3];
615+
yield call(console.log, regexResult, "regexresult!!!!!!!!!!!!!!!!!");
613616
const persistenceFileArray: PersistenceFile[] = yield select((state: OverallState) => state.fileSystem.persistenceFileArray);
614617
const parentFolderPersistenceFile = persistenceFileArray.find(e => e.path === parentFolderPath);
615618
if (!parentFolderPersistenceFile) {
@@ -648,6 +651,37 @@ export function* persistenceSaga(): SagaIterator {
648651
function* ({ payload }: ReturnType<typeof actions.persistenceCreateFolder>) {
649652
const newFolderPath = payload;
650653
yield call(console.log, "create folder ", newFolderPath);
654+
655+
656+
// const persistenceFileArray: PersistenceFile[] = yield select((state: OverallState) => state.fileSystem.persistenceFileArray);
657+
658+
// look for parent folder persistenceFile
659+
const regexResult = /^(.*[\\\/])?(\.*.*?)(\.[^.]+?|)$/.exec(newFolderPath);
660+
const parentFolderPath = regexResult ? regexResult[1].slice(0, -1) : undefined;
661+
if (!parentFolderPath) {
662+
yield call(console.log, "parent not found ", newFolderPath);
663+
return;
664+
}
665+
const newFolderName = regexResult![2];
666+
const persistenceFileArray: PersistenceFile[] = yield select((state: OverallState) => state.fileSystem.persistenceFileArray);
667+
const parentFolderPersistenceFile = persistenceFileArray.find(e => e.path === parentFolderPath);
668+
if (!parentFolderPersistenceFile) {
669+
yield call(console.log, "parent pers file not found ", newFolderPath, " parent path ", parentFolderPath, " persArr ", persistenceFileArray, " reg res ", regexResult);
670+
return;
671+
}
672+
673+
yield call(console.log, "parent found ", parentFolderPersistenceFile, " for file ", newFolderPath);
674+
675+
// create folder
676+
const parentFolderId = parentFolderPersistenceFile.id;
677+
678+
const newFolderId: string = yield call(createFolderAndReturnId, parentFolderId, newFolderName);
679+
yield put(actions.addPersistenceFile({ lastSaved: new Date(), path: newFolderPath, id: newFolderId, name: newFolderName, parentId: parentFolderId }));
680+
yield call(
681+
showSuccessMessage,
682+
`Folder ${newFolderName} successfully saved to Google Drive.`,
683+
1000
684+
);
651685
}
652686
);
653687

@@ -656,6 +690,21 @@ export function* persistenceSaga(): SagaIterator {
656690
function* ({ payload }: ReturnType<typeof actions.persistenceDeleteFile>) {
657691
const filePath = payload;
658692
yield call(console.log, "delete file ", filePath);
693+
694+
// look for file
695+
const persistenceFileArray: PersistenceFile[] = yield select((state: OverallState) => state.fileSystem.persistenceFileArray);
696+
const persistenceFile = persistenceFileArray.find(e => e.path === filePath);
697+
if (!persistenceFile) {
698+
yield call(console.log, "cannot find pers file for ", filePath);
699+
return;
700+
}
701+
yield call(deleteFileOrFolder, persistenceFile.id); // assume this succeeds all the time
702+
yield put(actions.deletePersistenceFile(persistenceFile));
703+
yield call(
704+
showSuccessMessage,
705+
`${persistenceFile.name} successfully deleted from Google Drive.`,
706+
1000
707+
);
659708
}
660709
);
661710

@@ -664,13 +713,55 @@ export function* persistenceSaga(): SagaIterator {
664713
function* ({ payload }: ReturnType<typeof actions.persistenceDeleteFolder>) {
665714
const folderPath = payload;
666715
yield call(console.log, "delete folder ", folderPath);
716+
717+
// identical to delete file
718+
const persistenceFileArray: PersistenceFile[] = yield select((state: OverallState) => state.fileSystem.persistenceFileArray);
719+
const persistenceFile = persistenceFileArray.find(e => e.path === folderPath);
720+
if (!persistenceFile) {
721+
yield call(console.log, "cannot find pers file for ", folderPath);
722+
return;
723+
}
724+
yield call(deleteFileOrFolder, persistenceFile.id); // assume this succeeds all the time
725+
yield put(actions.deletePersistenceFile(persistenceFile));
726+
yield call(
727+
showSuccessMessage,
728+
`Folder ${persistenceFile.name} successfully deleted from Google Drive.`,
729+
1000
730+
);
667731
}
668732
)
669733

670734
yield takeEvery(
671735
PERSISTENCE_RENAME_FILE,
672736
function* ({ payload : {oldFilePath, newFilePath} }: ReturnType<typeof actions.persistenceRenameFile>) {
673737
yield call(console.log, "rename file ", oldFilePath, " to ", newFilePath);
738+
739+
// look for file
740+
const persistenceFileArray: PersistenceFile[] = yield select((state: OverallState) => state.fileSystem.persistenceFileArray);
741+
const persistenceFile = persistenceFileArray.find(e => e.path === oldFilePath);
742+
if (!persistenceFile) {
743+
yield call(console.log, "cannot find pers file for ", oldFilePath);
744+
return;
745+
}
746+
747+
// new name
748+
const regexResult = /^(.*[\\\/])?(\.*.*?)(\.[^.]+?|)$/.exec(newFilePath);
749+
if (!regexResult) {
750+
yield call(console.log, "regex fail ", newFilePath);
751+
return;
752+
}
753+
const newFileName = regexResult[2] + regexResult[3];
754+
755+
// call gapi
756+
yield call(renameFileOrFolder, persistenceFile.id, newFileName);
757+
758+
// handle pers file
759+
yield put(actions.updatePersistenceFilePathAndNameByPath(oldFilePath, newFilePath, newFileName));
760+
yield call(
761+
showSuccessMessage,
762+
`${newFileName} successfully renamed in Google Drive.`,
763+
1000
764+
);
674765
}
675766
);
676767

@@ -912,6 +1003,24 @@ async function getFileFromFolder( // returns string id or empty string if failed
9121003
}
9131004
*/
9141005

1006+
function deleteFileOrFolder(
1007+
id: string
1008+
): Promise<any> {
1009+
return gapi.client.drive.files.delete({
1010+
fileId: id
1011+
});
1012+
}
1013+
1014+
function renameFileOrFolder(
1015+
id: string,
1016+
newName: string,
1017+
): Promise<any> {
1018+
return gapi.client.drive.files.update({
1019+
fileId: id,
1020+
resource: { name: newName }
1021+
});
1022+
}
1023+
9151024
async function getContainingFolderIdRecursively( // TODO memoize?
9161025
parentFolders: string[],
9171026
topFolderId: string,

0 commit comments

Comments
 (0)