soiz1 commited on
Commit
0e14d86
·
verified ·
1 Parent(s): 91f2f42

Update src/containers/sb3-downloader.jsx

Browse files
Files changed (1) hide show
  1. src/containers/sb3-downloader.jsx +46 -1
src/containers/sb3-downloader.jsx CHANGED
@@ -69,7 +69,8 @@ class SB3Downloader extends React.Component {
69
  'downloadProject',
70
  'saveAsNew',
71
  'saveToLastFile',
72
- 'saveToLastFileOrNew'
 
73
  ]);
74
  }
75
  startedSaving () {
@@ -108,6 +109,26 @@ class SB3Downloader extends React.Component {
108
  this.handleSaveError(e);
109
  }
110
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  async saveToLastFile () {
112
  try {
113
  await this.saveToHandle(this.props.fileHandle);
@@ -226,6 +247,30 @@ class SB3Downloader extends React.Component {
226
  });
227
  });
228
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  handleSaveError (e) {
230
  // AbortError can happen when someone cancels the file selector dialog
231
  if (e && e.name === 'AbortError') {
 
69
  'downloadProject',
70
  'saveAsNew',
71
  'saveToLastFile',
72
+ 'saveToLastFileOrNew',
73
+ 'saveAsFolder'
74
  ]);
75
  }
76
  startedSaving () {
 
109
  this.handleSaveError(e);
110
  }
111
  }
112
+ async saveAsFolder() {
113
+ if (!this.props.canSaveProject) {
114
+ return;
115
+ }
116
+ try {
117
+ const handle = await FileSystemAPI.showDirectoryPicker("pm-project-folder", "documents");
118
+
119
+ this.startedSaving();
120
+ const jsZip = this.props.saveProjectZip();
121
+ this.extractJSZipToHandle(jsZip, handle);
122
+ this.finishedSaving();
123
+
124
+ const title = handle.name;
125
+ if (title) {
126
+ this.props.onSetProjectTitle(title);
127
+ }
128
+ } catch (e) {
129
+ this.handleSaveError(e);
130
+ }
131
+ }
132
  async saveToLastFile () {
133
  try {
134
  await this.saveToHandle(this.props.fileHandle);
 
247
  });
248
  });
249
  }
250
+ async extractJSZipToHandle (zip, handle) {
251
+ // Not sure how memory management works but im hoping this is fine
252
+ for (const [relativePath, zipEntry] of Object.entries(zip.files)) {
253
+ // files will be able to make directories
254
+ if (zipEntry.dir) continue;
255
+
256
+ const pathParts = relativePath.split("/");
257
+ const fileName = pathParts.pop();
258
+
259
+ // NOTE: Right now there's no reason to preserve directories, but the future save file format will use them.
260
+ // See here for more info: https://docs.penguinmod.com/save-format/
261
+ // make a directory for each file within one
262
+ let currentDir = handle;
263
+ for (const part of pathParts) {
264
+ currentDir = await currentDir.getDirectoryHandle(part, { create: true });
265
+ }
266
+
267
+ const fileHandle = await currentDir.getFileHandle(fileName, { create: true });
268
+ const writable = await fileHandle.createWritable();
269
+ const content = await zipEntry.async("arraybuffer");
270
+ await writable.write(content);
271
+ await writable.close();
272
+ }
273
+ }
274
  handleSaveError (e) {
275
  // AbortError can happen when someone cancels the file selector dialog
276
  if (e && e.name === 'AbortError') {