-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add Google Drive support #13
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
base: main
Are you sure you want to change the base?
Conversation
…rieval for Google Drive
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds Google Drive integration to the multiplatform application, enabling cloud storage and synchronization capabilities. The implementation includes platform-specific clients for Android and JVM (desktop), with stub implementations for Web and a missing iOS implementation.
Changes:
- Added a multiplatform
CloudDriveClientinterface with platform-specific implementations - Integrated Google Drive SDK dependencies for Android and JVM targets
- Updated SettingsScreen UI to support Google Drive authorization and account management
- Updated application namespace and package identifiers to
io.github.smiling_pixel.mark_day
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| gradle/libs.versions.toml | Added Google Drive and OAuth client library dependencies |
| composeApp/src/commonMain/kotlin/io/github/smiling_pixel/client/CloudDriveClient.kt | Defined common CloudDriveClient interface with DriveFile and UserInfo models |
| composeApp/src/androidMain/kotlin/io/github/smiling_pixel/client/GoogleDriveClient.kt | Android implementation using Google Play Services Auth and Drive API |
| composeApp/src/androidMain/kotlin/io/github/smiling_pixel/client/GoogleSignInHelper.kt | Helper object for managing Google Sign-In flow via ActivityResult API |
| composeApp/src/jvmMain/kotlin/io/github/smiling_pixel/client/GoogleDriveClient.kt | JVM implementation using OAuth2 with browser-based authorization |
| composeApp/src/wasmJsMain/kotlin/io/github/smiling_pixel/client/GoogleDriveClient.kt | Stub implementation with NotImplementedError responses |
| composeApp/src/commonMain/kotlin/io/github/smiling_pixel/SettingsScreen.kt | Added Google Drive authorization UI with sign-in/sign-out functionality |
| composeApp/src/androidMain/kotlin/io/github/smiling_pixel/MainActivity.kt | Registered ActivityResultLauncher for Google Sign-In flow |
| composeApp/src/androidMain/AndroidManifest.xml | Updated activity name to use fully qualified package |
| composeApp/build.gradle.kts | Added Google Drive dependencies and updated namespace/applicationId |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| private val CREDENTIALS_FILE_PATH = "/credentials.json" | ||
|
|
||
| private fun getFlow(httpTransport: NetHttpTransport): GoogleAuthorizationCodeFlow { | ||
| val inputStream = GoogleDriveClient::class.java.getResourceAsStream(CREDENTIALS_FILE_PATH) | ||
| ?: throw FileNotFoundException("Resource not found: $CREDENTIALS_FILE_PATH. Please obtain credentials.json from Google Cloud Console.") |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The JVM implementation requires a credentials.json file in the resources directory to function, but this dependency is not documented. Consider adding documentation (in comments, README, or error messages) explaining how to obtain and configure this file from the Google Cloud Console, or the application will fail at runtime for JVM users.
| val result = GoogleSignInHelper.launchSignIn(signInIntent) | ||
|
|
||
| if (result != null && result.resultCode == android.app.Activity.RESULT_OK) { | ||
| val task = GoogleSignIn.getSignedInAccountFromIntent(result.data) |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is inconsistent indentation on line 86. The line uses an extra space before the val keyword, while lines 87-95 have proper indentation. This should be aligned with the surrounding code for consistency.
| val task = GoogleSignIn.getSignedInAccountFromIntent(result.data) | |
| val task = GoogleSignIn.getSignedInAccountFromIntent(result.data) |
| try { | ||
| val account = task.getResult(ApiException::class.java) | ||
| if (account != null) { | ||
| val email = account.email | ||
| if (email != null) { | ||
| initService(email) | ||
| return@withContext true | ||
| } | ||
| } | ||
| } catch (e: Exception) { | ||
| e.printStackTrace() | ||
| } |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is inconsistent indentation on lines 87-88 and 96-97. These lines use an extra space before the keywords, while surrounding code has proper indentation. The indentation should be aligned consistently with the rest of the code block.
| e.printStackTrace() | ||
| false |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is inconsistent indentation on line 213. The line uses an extra space before the e.printStackTrace() statement. This should be aligned with the surrounding code for consistency.
| e.printStackTrace() | |
| false | |
| e.printStackTrace() | |
| false |
| import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential | ||
| import com.google.api.client.extensions.android.http.AndroidHttp | ||
| import com.google.api.client.http.ByteArrayContent | ||
| import com.google.api.client.http.javanet.NetHttpTransport |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import com.google.api.client.http.javanet.NetHttpTransport is unused in the Android implementation. This import is only relevant for JVM-based implementations. Consider removing it to keep the imports clean.
| import com.google.api.client.http.javanet.NetHttpTransport |
| suspend fun launchSignIn(intent: Intent): ActivityResult? { | ||
| val l = launcher ?: return null | ||
| val deferred = CompletableDeferred<ActivityResult>() | ||
| authDeferred = deferred | ||
| l.launch(intent) | ||
| return deferred.await() | ||
| } |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The GoogleSignInHelper object has a potential race condition. If multiple coroutines call launchSignIn simultaneously, the second call will overwrite authDeferred before the first completes, causing the first caller to never receive its result. Consider using a thread-safe queue or mutex to handle concurrent authorization requests.
| import android.content.Intent | ||
| import androidx.activity.result.ActivityResult | ||
| import androidx.activity.result.ActivityResultLauncher | ||
| import androidx.activity.result.IntentSenderRequest |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import androidx.activity.result.IntentSenderRequest is unused in this file. Consider removing it to keep the imports clean.
| import androidx.activity.result.IntentSenderRequest |
| @@ -0,0 +1,30 @@ | |||
| package io.github.smiling_pixel.client | |||
|
|
|||
| import android.app.Activity | |||
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import android.app.Activity is unused in this file. Consider removing it to keep the imports clean.
| import android.app.Activity |
| driveService = null | ||
| deferred.complete(Unit) |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is inconsistent indentation on lines 108-110. These lines use an extra space before the keywords, while surrounding code has proper indentation. The indentation should be aligned consistently with the rest of the code block.
| driveService = null | |
| deferred.complete(Unit) | |
| driveService = null | |
| deferred.complete(Unit) |
| expect fun getCloudDriveClient(): CloudDriveClient | ||
|
|
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The iOS target is missing an implementation of the getCloudDriveClient() expected function. The common code defines expect fun getCloudDriveClient(): CloudDriveClient, and while Android, JVM, and wasmJs provide actual implementations, iOS does not. This will cause a compilation error for iOS targets. You need to add an iOS-specific implementation file similar to the wasmJs stub implementation.
This pull request introduces Google Drive integration into the application, enabling users to authorize, access, and manage their files in Google Drive from within the app. The changes include new client interfaces, Android implementation, UI updates for authorization, and necessary dependency and configuration updates.
Google Drive Integration
CloudDriveClientinterface, including models forDriveFileandUserInfo, to abstract cloud drive operations (composeApp/src/commonMain/kotlin/io/github/smiling_pixel/client/CloudDriveClient.kt).GoogleDriveClientwith full support for authorization, file/folder management, and user info retrieval, using Google APIs (composeApp/src/androidMain/kotlin/io/github/smiling_pixel/client/GoogleDriveClient.kt).GoogleSignInHelperto handle Google Sign-In flows and activity result management on Android (composeApp/src/androidMain/kotlin/io/github/smiling_pixel/client/GoogleSignInHelper.kt).UI Enhancements
SettingsScreento allow users to authorize Google Drive, view account info, and revoke access, reflecting authorization state and user details in the UI (composeApp/src/commonMain/kotlin/io/github/smiling_pixel/SettingsScreen.kt). [1] [2] [3]MainActivityto support the authorization flow (composeApp/src/androidMain/kotlin/io/github/smiling_pixel/MainActivity.kt).Dependency and Configuration Updates
build.gradle.kts(composeApp/build.gradle.kts). [1] [2]io.github.smiling_pixel.mark_dayfor consistency across Android and desktop builds (composeApp/build.gradle.kts,AndroidManifest.xml). [1] [2] [3]