soiz1 commited on
Commit
a93bdcd
·
verified ·
1 Parent(s): 33e1ee2

Update src/addons/addons/save-to-google/userscript.js

Browse files
src/addons/addons/save-to-google/userscript.js CHANGED
@@ -1,7 +1,6 @@
1
  import SB3Downloader from "/src/containers/sb3-downloader.jsx";
2
  import { getProjectFilename } from '/src/containers/sb3-downloader.jsx';
3
 
4
- // サムネイル取得関数
5
  const getProjectThumbnail = () => new Promise(resolve => {
6
  window.vm.renderer.requestSnapshot(uri => {
7
  resolve(uri);
@@ -62,75 +61,67 @@ export default async ({ addon, console, msg }) => {
62
  const projectTitle = modal.content.querySelector("#project-title");
63
 
64
  // プロジェクトタイトルの編集機能
65
- if (projectTitle) {
66
- projectTitle.addEventListener("dblclick", () => {
67
- const currentName = projectTitle.textContent;
68
- const input = document.createElement("input");
69
- input.type = "text";
70
- input.value = currentName;
71
- input.style.width = "200px";
72
-
73
- projectTitle.replaceWith(input);
74
- input.focus();
75
-
76
- const handleBlur = () => {
77
- const newName = input.value.trim() || "無題";
78
- window.vm.runtime.projectName = newName;
79
- projectTitle.textContent = newName;
80
- input.replaceWith(projectTitle);
81
- };
82
 
83
- input.addEventListener("blur", handleBlur);
84
- input.addEventListener("keypress", (e) => {
85
- if (e.key === "Enter") {
86
- handleBlur();
87
- }
88
- });
89
  });
90
- }
91
-
92
- if (loginButton) {
93
- loginButton.addEventListener("click", () => {
94
- const messageListener = (event) => {
95
- if (event.origin === "https://soiz1-penguin-upload.hf.space" && event.data.token) {
96
- window.removeEventListener("message", messageListener);
97
- accessToken = event.data.token;
98
-
99
- loginButton.style.display = "none";
100
-
101
- fetchDriveFiles(accessToken)
102
- .then(files => {
103
- displayFileList(files, accessToken, modal, addon);
104
- fileListContainer.style.display = "block";
105
- })
106
- .catch(error => {
107
- console.error("ファイル一覧取得エラー:", error);
108
- showAlert(addon, "error", "ファイル一覧の取得に失敗しました");
109
- });
110
- }
111
- };
112
- window.addEventListener("message", messageListener);
113
-
114
- const authUrl = `https://accounts.google.com/o/oauth2/auth?` +
115
- `client_id=${CLIENT_ID}` +
116
- `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
117
- `&response_type=token` +
118
- `&scope=${encodeURIComponent(SCOPES)}`;
119
-
120
- window.open(authUrl, "_blank", "width=500,height=600");
121
- });
122
- }
123
 
124
- if (newFileButton) {
125
- newFileButton.addEventListener("click", async () => {
126
- try {
127
- await saveToGoogleDrive(null, null, modal.remove, addon);
128
- } catch (error) {
129
- console.error("新規保存エラー:", error);
130
- showAlert(addon, "error", "新規保存に失敗しました");
 
 
 
 
 
 
 
 
 
 
131
  }
132
- });
133
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
 
135
  modal.backdrop.addEventListener("click", modal.remove);
136
  modal.closeButton.addEventListener("click", modal.remove);
@@ -160,7 +151,7 @@ export default async ({ addon, console, msg }) => {
160
  const thumbnailFiles = files.filter(file => file.mimeType === 'image/png');
161
 
162
  if (projectFiles.length === 0) {
163
- fileList.innerHTML = "<p>保存されたファイルが見つかりません</p>";
164
  return;
165
  }
166
 
@@ -176,30 +167,35 @@ export default async ({ addon, console, msg }) => {
176
  fileItem.style.padding = "1rem";
177
  fileItem.style.display = "flex";
178
  fileItem.style.flexDirection = "column";
179
- fileItem.style.gap = "0.5rem";
 
180
 
181
  // サムネイル表示
 
 
 
 
182
  if (thumbnail) {
183
  const thumbnailImg = document.createElement("img");
184
  thumbnailImg.src = `https://drive.google.com/thumbnail?id=${thumbnail.id}&sz=w300`;
185
  thumbnailImg.style.width = "100%";
186
- thumbnailImg.style.height = "auto";
187
  thumbnailImg.style.borderRadius = "4px";
188
  thumbnailImg.style.objectFit = "cover";
189
- thumbnailImg.style.aspectRatio = "4/3";
190
- fileItem.appendChild(thumbnailImg);
191
  } else {
192
  const thumbnailPlaceholder = document.createElement("div");
193
  thumbnailPlaceholder.style.width = "100%";
194
- thumbnailPlaceholder.style.height = "150px";
195
  thumbnailPlaceholder.style.backgroundColor = "#f0f0f0";
196
  thumbnailPlaceholder.style.display = "flex";
197
  thumbnailPlaceholder.style.alignItems = "center";
198
  thumbnailPlaceholder.style.justifyContent = "center";
199
  thumbnailPlaceholder.style.borderRadius = "4px";
200
  thumbnailPlaceholder.textContent = "サムネイルなし";
201
- fileItem.appendChild(thumbnailPlaceholder);
202
  }
 
203
 
204
  // プロジェクト名
205
  const fileName = document.createElement("h3");
@@ -207,6 +203,7 @@ export default async ({ addon, console, msg }) => {
207
  fileName.style.margin = "0";
208
  fileName.style.fontSize = "1rem";
209
  fileName.style.textAlign = "center";
 
210
  fileItem.appendChild(fileName);
211
 
212
  // 共有リンク
@@ -222,6 +219,7 @@ export default async ({ addon, console, msg }) => {
222
  link.target = "_blank";
223
  link.rel = "noopener noreferrer";
224
  link.style.fontSize = "0.9em";
 
225
 
226
  const copyButton = document.createElement("button");
227
  copyButton.textContent = "コピー";
@@ -242,14 +240,14 @@ export default async ({ addon, console, msg }) => {
242
 
243
  // 操作ボタン
244
  const buttonContainer = document.createElement("div");
245
- buttonContainer.style.display = "flex";
 
246
  buttonContainer.style.gap = "0.5rem";
247
- buttonContainer.style.justifyContent = "center";
248
 
249
  const loadButton = document.createElement("button");
250
  loadButton.textContent = "読み込む";
251
  loadButton.className = "button";
252
- loadButton.style.flex = "1";
253
 
254
  loadButton.addEventListener("click", (e) => {
255
  e.stopPropagation();
@@ -262,13 +260,12 @@ export default async ({ addon, console, msg }) => {
262
  const replaceButton = document.createElement("button");
263
  replaceButton.textContent = "上書き";
264
  replaceButton.className = "button";
265
- replaceButton.style.flex = "1";
266
 
267
  replaceButton.addEventListener("click", (e) => {
268
  e.stopPropagation();
269
  if (confirm(`"${project.name}"を現在のプロジェクトで上書きしますか?`)) {
270
  saveToGoogleDrive(project.id, project.name, () => {
271
- // モーダルを閉じずにリストを更新
272
  fetchDriveFiles(accessToken)
273
  .then(files => displayFileList(files, accessToken, modal, addon))
274
  .catch(error => console.error("更新エラー:", error));
@@ -283,7 +280,8 @@ export default async ({ addon, console, msg }) => {
283
  const deleteButton = document.createElement("button");
284
  deleteButton.textContent = "削除";
285
  deleteButton.className = "button";
286
- deleteButton.style.flex = "1";
 
287
  deleteButton.style.backgroundColor = "#ff4444";
288
  deleteButton.style.color = "white";
289
 
@@ -372,7 +370,6 @@ export default async ({ addon, console, msg }) => {
372
  }
373
 
374
  const fileData = await uploadResponse.json();
375
- console.log("プロジェクトファイルがGoogleドライブに保存/更新されました:", fileData);
376
 
377
  // サムネイルを保存
378
  try {
@@ -383,7 +380,6 @@ export default async ({ addon, console, msg }) => {
383
  mimeType: "image/png",
384
  };
385
 
386
- // 既存のサムネイルを探す
387
  const existingThumbnailResponse = await fetch(
388
  `https://www.googleapis.com/drive/v3/files?q=name='${thumbnailMetadata.name}'`,
389
  {
@@ -413,15 +409,12 @@ export default async ({ addon, console, msg }) => {
413
  },
414
  body: thumbnailForm,
415
  });
416
-
417
- console.log("サムネイルがGoogleドライブに保存/更新されました");
418
  } catch (thumbnailError) {
419
- console.warn("サムネイルの保存に失敗しましたが、プロジェクトは保存されました:", thumbnailError);
420
  }
421
 
422
  if (!fileId) {
423
- // 新規保存の場合、公開設定
424
- const permissionResponse = await fetch(`https://www.googleapis.com/drive/v3/files/${fileData.id}/permissions`, {
425
  method: "POST",
426
  headers: {
427
  Authorization: `Bearer ${accessToken}`,
@@ -432,14 +425,9 @@ export default async ({ addon, console, msg }) => {
432
  type: "anyone",
433
  }),
434
  });
435
-
436
- if (!permissionResponse.ok) {
437
- console.warn("権限の設定に失敗しましたが、ファイルは保存されました");
438
- }
439
  }
440
 
441
- const action = fileId ? "上書き保存" : "新規保存";
442
- showAlert(addon, "success", `Googleドライブに${action}しました`);
443
  if (onSuccess) onSuccess();
444
  } catch (error) {
445
  console.error("保存エラー:", error);
 
1
  import SB3Downloader from "/src/containers/sb3-downloader.jsx";
2
  import { getProjectFilename } from '/src/containers/sb3-downloader.jsx';
3
 
 
4
  const getProjectThumbnail = () => new Promise(resolve => {
5
  window.vm.renderer.requestSnapshot(uri => {
6
  resolve(uri);
 
61
  const projectTitle = modal.content.querySelector("#project-title");
62
 
63
  // プロジェクトタイトルの編集機能
64
+ projectTitle?.addEventListener("dblclick", () => {
65
+ const currentName = projectTitle.textContent;
66
+ const input = document.createElement("input");
67
+ input.type = "text";
68
+ input.value = currentName;
69
+ input.style.width = "200px";
70
+
71
+ projectTitle.replaceWith(input);
72
+ input.focus();
73
+
74
+ const handleBlur = () => {
75
+ const newName = input.value.trim() || "無題";
76
+ window.vm.runtime.projectName = newName;
77
+ projectTitle.textContent = newName;
78
+ input.replaceWith(projectTitle);
79
+ };
 
80
 
81
+ input.addEventListener("blur", handleBlur);
82
+ input.addEventListener("keypress", (e) => {
83
+ if (e.key === "Enter") handleBlur();
 
 
 
84
  });
85
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
+ loginButton?.addEventListener("click", () => {
88
+ const messageListener = (event) => {
89
+ if (event.origin === "https://soiz1-penguin-upload.hf.space" && event.data.token) {
90
+ window.removeEventListener("message", messageListener);
91
+ accessToken = event.data.token;
92
+
93
+ loginButton.style.display = "none";
94
+
95
+ fetchDriveFiles(accessToken)
96
+ .then(files => {
97
+ displayFileList(files, accessToken, modal, addon);
98
+ fileListContainer.style.display = "block";
99
+ })
100
+ .catch(error => {
101
+ console.error("ファイル一覧取得エラー:", error);
102
+ showAlert(addon, "error", "ファイル一覧の取得に失敗しました");
103
+ });
104
  }
105
+ };
106
+ window.addEventListener("message", messageListener);
107
+
108
+ const authUrl = `https://accounts.google.com/o/oauth2/auth?` +
109
+ `client_id=${CLIENT_ID}` +
110
+ `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
111
+ `&response_type=token` +
112
+ `&scope=${encodeURIComponent(SCOPES)}`;
113
+
114
+ window.open(authUrl, "_blank", "width=500,height=600");
115
+ });
116
+
117
+ newFileButton?.addEventListener("click", async () => {
118
+ try {
119
+ await saveToGoogleDrive(null, null, modal.remove, addon);
120
+ } catch (error) {
121
+ console.error("新規保存エラー:", error);
122
+ showAlert(addon, "error", "新規保存に失敗しました");
123
+ }
124
+ });
125
 
126
  modal.backdrop.addEventListener("click", modal.remove);
127
  modal.closeButton.addEventListener("click", modal.remove);
 
151
  const thumbnailFiles = files.filter(file => file.mimeType === 'image/png');
152
 
153
  if (projectFiles.length === 0) {
154
+ fileList.innerHTML = "<p style='grid-column: 1 / -1; text-align: center;'>保存されたファイルが見つかりません</p>";
155
  return;
156
  }
157
 
 
167
  fileItem.style.padding = "1rem";
168
  fileItem.style.display = "flex";
169
  fileItem.style.flexDirection = "column";
170
+ fileItem.style.gap = "0.75rem";
171
+ fileItem.style.background = "#fff";
172
 
173
  // サムネイル表示
174
+ const thumbnailContainer = document.createElement("div");
175
+ thumbnailContainer.style.position = "relative";
176
+ thumbnailContainer.style.aspectRatio = "4/3";
177
+
178
  if (thumbnail) {
179
  const thumbnailImg = document.createElement("img");
180
  thumbnailImg.src = `https://drive.google.com/thumbnail?id=${thumbnail.id}&sz=w300`;
181
  thumbnailImg.style.width = "100%";
182
+ thumbnailImg.style.height = "100%";
183
  thumbnailImg.style.borderRadius = "4px";
184
  thumbnailImg.style.objectFit = "cover";
185
+ thumbnailContainer.appendChild(thumbnailImg);
 
186
  } else {
187
  const thumbnailPlaceholder = document.createElement("div");
188
  thumbnailPlaceholder.style.width = "100%";
189
+ thumbnailPlaceholder.style.height = "100%";
190
  thumbnailPlaceholder.style.backgroundColor = "#f0f0f0";
191
  thumbnailPlaceholder.style.display = "flex";
192
  thumbnailPlaceholder.style.alignItems = "center";
193
  thumbnailPlaceholder.style.justifyContent = "center";
194
  thumbnailPlaceholder.style.borderRadius = "4px";
195
  thumbnailPlaceholder.textContent = "サムネイルなし";
196
+ thumbnailContainer.appendChild(thumbnailPlaceholder);
197
  }
198
+ fileItem.appendChild(thumbnailContainer);
199
 
200
  // プロジェクト名
201
  const fileName = document.createElement("h3");
 
203
  fileName.style.margin = "0";
204
  fileName.style.fontSize = "1rem";
205
  fileName.style.textAlign = "center";
206
+ fileName.style.fontWeight = "bold";
207
  fileItem.appendChild(fileName);
208
 
209
  // 共有リンク
 
219
  link.target = "_blank";
220
  link.rel = "noopener noreferrer";
221
  link.style.fontSize = "0.9em";
222
+ link.style.color = "#4d97ff";
223
 
224
  const copyButton = document.createElement("button");
225
  copyButton.textContent = "コピー";
 
240
 
241
  // 操作ボタン
242
  const buttonContainer = document.createElement("div");
243
+ buttonContainer.style.display = "grid";
244
+ buttonContainer.style.gridTemplateColumns = "1fr 1fr";
245
  buttonContainer.style.gap = "0.5rem";
 
246
 
247
  const loadButton = document.createElement("button");
248
  loadButton.textContent = "読み込む";
249
  loadButton.className = "button";
250
+ loadButton.style.width = "100%";
251
 
252
  loadButton.addEventListener("click", (e) => {
253
  e.stopPropagation();
 
260
  const replaceButton = document.createElement("button");
261
  replaceButton.textContent = "上書き";
262
  replaceButton.className = "button";
263
+ replaceButton.style.width = "100%";
264
 
265
  replaceButton.addEventListener("click", (e) => {
266
  e.stopPropagation();
267
  if (confirm(`"${project.name}"を現在のプロジェクトで上書きしますか?`)) {
268
  saveToGoogleDrive(project.id, project.name, () => {
 
269
  fetchDriveFiles(accessToken)
270
  .then(files => displayFileList(files, accessToken, modal, addon))
271
  .catch(error => console.error("更新エラー:", error));
 
280
  const deleteButton = document.createElement("button");
281
  deleteButton.textContent = "削除";
282
  deleteButton.className = "button";
283
+ deleteButton.style.width = "100%";
284
+ deleteButton.style.gridColumn = "1 / -1";
285
  deleteButton.style.backgroundColor = "#ff4444";
286
  deleteButton.style.color = "white";
287
 
 
370
  }
371
 
372
  const fileData = await uploadResponse.json();
 
373
 
374
  // サムネイルを保存
375
  try {
 
380
  mimeType: "image/png",
381
  };
382
 
 
383
  const existingThumbnailResponse = await fetch(
384
  `https://www.googleapis.com/drive/v3/files?q=name='${thumbnailMetadata.name}'`,
385
  {
 
409
  },
410
  body: thumbnailForm,
411
  });
 
 
412
  } catch (thumbnailError) {
413
+ console.warn("サムネイルの保存に失敗しました:", thumbnailError);
414
  }
415
 
416
  if (!fileId) {
417
+ await fetch(`https://www.googleapis.com/drive/v3/files/${fileData.id}/permissions`, {
 
418
  method: "POST",
419
  headers: {
420
  Authorization: `Bearer ${accessToken}`,
 
425
  type: "anyone",
426
  }),
427
  });
 
 
 
 
428
  }
429
 
430
+ showAlert(addon, "success", fileId ? "上書き保存しました" : "新規保存しました");
 
431
  if (onSuccess) onSuccess();
432
  } catch (error) {
433
  console.error("保存エラー:", error);