Skip to content

Commit 03d1762

Browse files
Added open folders to github
1 parent e6d1c41 commit 03d1762

File tree

2 files changed

+119
-3
lines changed

2 files changed

+119
-3
lines changed

src/commons/gitHubOverlay/FileExplorerDialog.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ import {
1818
checkIfFileCanBeSavedAndGetSaveType,
1919
checkIfUserAgreesToOverwriteEditorData,
2020
checkIfUserAgreesToPerformOverwritingSave,
21+
checkIsFile,
2122
openFileInEditor,
23+
openFolderInFolderMode,
2224
performCreatingSave,
2325
performOverwritingSave
2426
} from '../../features/github/GitHubUtils';
@@ -106,7 +108,11 @@ const FileExplorerDialog: React.FC<FileExplorerDialogProps> = props => {
106108
if (props.pickerType === 'Open') {
107109
if (await checkIfFileCanBeOpened(props.octokit, githubLoginID, props.repoName, filePath)) {
108110
if (await checkIfUserAgreesToOverwriteEditorData()) {
109-
openFileInEditor(props.octokit, githubLoginID, props.repoName, filePath);
111+
if (await checkIsFile(props.octokit, githubLoginID, props.repoName, filePath)) {
112+
openFileInEditor(props.octokit, githubLoginID, props.repoName, filePath);
113+
} else {
114+
openFolderInFolderMode(props.octokit, githubLoginID, props.repoName, filePath);
115+
}
110116
}
111117
}
112118
}

src/features/github/GitHubUtils.tsx

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import {
1111
showWarningMessage
1212
} from '../../commons/utils/notifications/NotificationsHelper';
1313
import { store } from '../../pages/createStore';
14+
import { writeFileRecursively, rmFilesInDirRecursively } from '../../commons/fileSystem/FileSystemUtils';
15+
import { FSModule } from 'browserfs/dist/node/core/FS';
16+
import { refreshFileView } from '../../commons/fileSystemView/FileSystemViewList';
1417

1518
/**
1619
* Exchanges the Access Code with the back-end to receive an Auth-Token
@@ -81,8 +84,7 @@ export async function checkIfFileCanBeOpened(
8184
}
8285

8386
if (Array.isArray(files)) {
84-
showWarningMessage("Can't open folder as a file!", 2000);
85-
return false;
87+
true;
8688
}
8789

8890
return true;
@@ -176,6 +178,29 @@ export async function checkIfUserAgreesToPerformOverwritingSave() {
176178
});
177179
}
178180

181+
export async function checkIsFile(
182+
octokit: Octokit,
183+
repoOwner: string,
184+
repoName: string,
185+
filePath: string
186+
) {
187+
const results = await octokit.repos.getContent({
188+
owner: repoOwner,
189+
repo: repoName,
190+
path: filePath
191+
})
192+
193+
const files = results.data;
194+
195+
if (Array.isArray(files)) {
196+
console.log("folder detected");
197+
return false;
198+
}
199+
200+
console.log("file detected");
201+
return true;
202+
}
203+
179204
export async function openFileInEditor(
180205
octokit: Octokit,
181206
repoOwner: string,
@@ -205,6 +230,91 @@ export async function openFileInEditor(
205230
}
206231
}
207232

233+
export async function openFolderInFolderMode(
234+
octokit: Octokit,
235+
repoOwner: string,
236+
repoName: string,
237+
filePath: string
238+
) {
239+
if (octokit === undefined) return;
240+
241+
//In order to get the file paths recursively, we require the tree_sha,
242+
// which is obtained from the most recent commit(any commit works but the most recent)
243+
// is the easiest
244+
245+
const requests = await octokit.request('GET /repos/{owner}/{repo}/branches/master', {
246+
owner: repoOwner,
247+
repo: repoName
248+
});
249+
250+
const tree_sha = requests.data.commit.commit.tree.sha;
251+
252+
const results = await octokit.request('GET /repos/{owner}/{repo}/git/trees/{tree_sha}?recursive=1', {
253+
owner: repoOwner,
254+
repo: repoName,
255+
tree_sha: tree_sha
256+
});
257+
258+
const files_and_folders = results.data.tree;
259+
const files: any[] = [];
260+
261+
262+
//Filters out the files only since the tree returns both file and folder paths
263+
for (let index = 0; index < files_and_folders.length; index++) {
264+
if (files_and_folders[index].type === "blob") {
265+
files[files.length] = files_and_folders[index].path;
266+
}
267+
}
268+
269+
console.log(files);
270+
271+
store.dispatch(actions.setFolderMode('playground', true)); //automatically opens folder mode
272+
const fileSystem: FSModule | null = store.getState().fileSystem.inBrowserFileSystem;
273+
if (fileSystem === null) {
274+
console.log("no filesystem!");
275+
return;
276+
}
277+
278+
// This is a helper function to asynchronously clear the current folder system, then get each
279+
// file and its contents one by one, then finally refresh the file system after all files
280+
// have been recursively created. There may be extra asyncs or promises but this is what works.
281+
const readFile = async (files: Array<string>) => {
282+
console.log(files);
283+
console.log(filePath);
284+
rmFilesInDirRecursively(fileSystem, "/playground");
285+
let promise = Promise.resolve();
286+
type GetContentResponse = GetResponseTypeFromEndpointMethod<typeof octokit.repos.getContent>;
287+
files.forEach((file: string) => {
288+
console.log(file);
289+
promise = promise.then(async () => {
290+
let results = {} as GetContentResponse;
291+
if (file.startsWith(filePath)) {
292+
results = await octokit.repos.getContent({
293+
owner: repoOwner,
294+
repo: repoName,
295+
path: file
296+
});
297+
console.log(results);
298+
const content = (results.data as any)?.content;
299+
300+
if (content) {
301+
const fileContent = Buffer.from(content, 'base64').toString();
302+
console.log(file);
303+
writeFileRecursively(fileSystem, "/playground/" + file, fileContent)
304+
console.log("wrote one file");
305+
}
306+
}
307+
})
308+
})
309+
promise.then(() => {
310+
console.log("promises fulfilled");
311+
refreshFileView();
312+
})
313+
}
314+
315+
readFile(files);
316+
}
317+
208318
export async function performOverwritingSave(
209319
octokit: Octokit,
210320
repoOwner: string,

0 commit comments

Comments
 (0)