forked from scratchfoundation/scratch-gui
-
-
Notifications
You must be signed in to change notification settings - Fork 16
Add Google Drive file loading functionality #427
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Implements the ability to load Scratch 3.0 projects (.sb3) directly from Google Drive. Key features: - Dynamic loading of Google API scripts (improves initial page load) - OAuth 2.0 authentication with Google Identity Services - Google Picker API integration for file selection - Seamless project loading from Google Drive Implementation details: - Created dynamic script loader (src/lib/google-script-loader.js) to load Google APIs on demand - Implemented Google Drive API module (src/lib/google-drive-api.js) for authentication and file operations - Added Google Drive loader HOC container (src/containers/google-drive-loader.jsx) - Added "Load from Google Drive" menu item to File menu - Created comprehensive setup documentation (docs/google-drive-setup.md) - Added environment variable configuration (.env.example) - Updated .gitignore to exclude .env files - Added cspell.json for custom dictionary words Configuration: - Requires GOOGLE_CLIENT_ID and GOOGLE_API_KEY environment variables - See docs/google-drive-setup.md for detailed GCP setup instructions Closes #426 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Fix environment variable handling in webpack for Google API credentials - Remove MIME type filter to show all files in Google Picker - Fix LoadingStates import and usage in google-drive-loader - Wrap picker callback in try-catch to prevent error propagation - Add comprehensive debug logging throughout download process - Update Japanese translations for Google Drive features - Fix COOP/COEP headers configuration in webpack - Update documentation for Docker environment setup This commit resolves the issues preventing Google Drive file loading from working properly. The main fixes include: 1. Correcting the requestProjectUpload call to pass loadingState 2. Using fetch API for reliable binary file downloads 3. Proper error handling in callback invocations Fixes #426 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Fixed React warning about openUrlLoaderModal prop on DOM elements - Added openUrlLoaderModal to prop filtering in GUIComponent (gui.jsx) - Added openUrlLoaderModal to prop filtering in GoogleDriveLoaderComponent - Removed timing measurement logs from google-drive-loader.jsx Changes: - src/components/gui/gui.jsx: Filter out openUrlLoaderModal using underscore prefix - src/containers/google-drive-loader.jsx: Filter out openUrlLoaderModal, remove timing logs 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- File menu now closes immediately when user selects "Load from Google Drive" - Improves UX by clearing the menu before showing Google Picker dialog - Previously, menu stayed open until file loading completed Changes: - Import closeFileMenu action from reducers/menus - Call closeFileMenu() in handleStartSelectingGoogleDrive method - Add closeFileMenu to mapDispatchToProps and PropTypes - Filter closeFileMenu prop in render to prevent passing to DOM 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Google Picker now displays in the same language as the application - Added locale parameter to showPicker method in google-drive-api.js - Set PickerBuilder locale using .setLocale() method - Get current locale from Redux state (state.locales.locale) - Pass locale from google-drive-loader to showPicker Additional fixes: - Removed unused mimeType variable (lint error) - Fixed max-len error in console.error statement 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
…name to HOC Loading modal timing improvements: - Show loading modal immediately before vm.loadProject() (matching sb-file-uploader-hoc.jsx) - Changed onLoadingStarted to dispatch openLoadingProject() instead of requestProjectUpload() - Removed early onShowLoadingProject() call that caused delayed modal display - Removed unused requestProjectUpload import File naming consistency: - Renamed google-drive-loader.jsx to google-drive-loader-hoc.jsx to match exported name - Updated import in menu-bar.jsx to use new file name This ensures Google Drive loader behaves identically to the existing file upload flow. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Improved UX by showing loading screen before file download starts: - Modified handlePickerResponse to call callback twice: 1. Immediately when file is selected (selected: true, fileName) 2. After download completes (success: true, fileName, fileData) - Updated handlePickerCallback to handle both stages: 1. On file selected: Set project title and show loading modal 2. On download complete: Convert to Uint8Array and load project This eliminates the delay between file selection and loading screen display, providing immediate visual feedback during the download process. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Changed OAuth 2.0 scope from drive.readonly to drive.file to enable upload functionality: Changes to src/lib/google-drive-api.js: - Updated SCOPES constant from 'drive.readonly' to 'drive.file' - Added comments explaining the scope capabilities: - Reading files selected via Picker - Uploading new files to Google Drive Changes to docs/google-drive-setup.md: - Updated recommended scope to 'drive.file' - Added detailed explanation of scope capabilities - Added note that 'drive.readonly' prevents upload functionality Required GCP configuration: - Users must update OAuth consent screen to add 'drive.file' scope - Existing auth tokens will be invalidated after scope change - Users will need to re-authenticate with new permissions This resolves the "Server rejected" error when uploading files via Google Picker. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Removed all development/debugging console.log statements while keeping essential error logging (console.error) for production diagnostics. Changes to src/containers/google-drive-loader-hoc.jsx: - Removed debug logs from handlePickerCallback: - Picker callback details (cancelled, hasError, hasSuccess, etc.) - User cancelled picker notification - File selected notification - Project title setting notification - Loading modal display notification - File download details (fileName, fileDataType, constructor, byteLength) - Uint8Array conversion logs (2 occurrences) - Kept error logging for picker errors Changes to src/lib/google-drive-api.js: - Removed debug logs from downloadFile method: - Download start notification - gapi.client.drive.files.get call notification - Response details (status, bodyType, bodyLength, etc.) - Binary string to ArrayBuffer conversion notification - Download success notification - Removed debug log from handlePickerResponse (file download success) - Kept error logging for download failures and callback errors All functionality remains unchanged - only logging statements were removed. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Use .setQuery('.sb3') to filter files in Google Picker
- Add internationalization for picker dialog title
- Add Japanese translation for picker title: "Google ドライブから Scratch 3.0 プロジェクト (.sb3) を選択"
- Pass localized title from HOC to Google Drive API
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
11 tasks
github-actions bot
pushed a commit
that referenced
this pull request
Dec 14, 2025
…e-drive-loader Add Google Drive file loading functionality
takaokouji
added a commit
that referenced
this pull request
Dec 14, 2025
This commit implements the ability to save Scratch 3.0 projects (.sb3) to Google Drive with a custom dialog for specifying the filename and save location, complementing the existing "Load from Google Drive" functionality. ## New Features - **Menu Integration**: Added "Save to Google Drive" menu item in File menu - **Save Dialog**: Custom dialog with filename input and save location selection - **Folder Selection**: Users can save to My Drive root or select a specific folder - **File Upload**: Multipart upload using Google Drive Files API v3 ## Implementation ### New Components 1. **google-drive-saver-hoc.jsx**: HOC for Google Drive save functionality - Manages save dialog state and upload process - Converts Ruby code to blocks before saving - Provides error handling and user feedback 2. **google-drive-save-dialog.jsx**: Custom save dialog component - Filename input with .sb3 extension validation - Save location dropdown (My Drive or folder selection) - Cancel, Reset, and Save buttons 3. **google-drive-save-dialog.css**: Dialog styling ### Modified Files 1. **google-drive-api.js**: Added upload functionality - uploadFile(): Multipart upload to Google Drive - showFolderPicker(): Folder selection via Google Picker - handleFolderPickerResponse(): Handle folder picker callback 2. **menu-bar.jsx**: Integrated save functionality - Added "Save to Google Drive" menu item - Integrated GoogleDriveSaverHOC - Added GoogleDriveSaveDialog component 3. **ja.js**: Added Japanese translations for all new UI elements ## Technical Details - Uses existing OAuth 2.0 authentication from GoogleDriveLoaderHOC - Leverages drive.file scope (already configured) - Multipart upload with metadata and file content - Base64 encoding for binary file data - Folder picker using Google Picker API ## Testing - ✅ Lint checks pass: npm run test:lint - Dialog UI follows app.diagrams.net design patterns - Supports both My Drive root and folder selection ## Related - Implements feature request from Issue #428 - Built on top of PR #427 (Google Drive load functionality) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
This was referenced Dec 14, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Implements the ability to load Scratch 3.0 projects (.sb3) directly from
Google Drive, addressing issue #426.
Key Features
user first clicks "Load from Google Drive", improving initial page load
performance
Services
Implementation Details
New Files
src/lib/google-script-loader.jssrc/lib/google-drive-api.jssrc/containers/google-drive-loader.jsxdocs/google-drive-setup.md.env.examplecspell.jsonModified Files
src/components/menu-bar/menu-bar.jsx.gitignore.envto prevent accidental commits of sensitive credentialsConfiguration
Environment Variables
Two environment variables are required:
GOOGLE_CLIENT_ID: OAuth 2.0 Client ID from Google Cloud ConsoleGOOGLE_API_KEY: API Key for Google Picker APISetup Instructions
See
docs/google-drive-setup.mdfor detailed setup instructions including:Technical Approach
Why Dynamic Script Loading?
Instead of including Google API scripts in
index.html, we use dynamicloading because:
loading unnecessary scripts
by the user
initial bundle size
Error Handling
Testing
Manual Testing Steps
npm run buildLint and Build
npm run test:lintnpm run buildBreaking Changes
None. This is a new feature that doesn't affect existing functionality.
Future Enhancements
Possible improvements for future PRs:
Related Issues
Closes #426
🤖 Generated with Claude Code
Co-Authored-By: Claude [email protected]