Skip to content

Commit 7b91715

Browse files
authored
Merge pull request #425 from Automattic/hamorillo/424-qe-activity
QuickEditor: Implement GravatarQuickEditorActivity
2 parents b43126e + 40f7500 commit 7b91715

File tree

17 files changed

+451
-13
lines changed

17 files changed

+451
-13
lines changed

demo-app/src/main/AndroidManifest.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@
5656
<!-- </intent-filter>-->
5757
</activity>
5858

59+
<!-- Gravatar QE Activity -->
60+
<!-- <activity-->
61+
<!-- android:name="com.gravatar.quickeditor.ui.GravatarQuickEditorActivity"-->
62+
<!-- tools:node="merge">-->
63+
64+
<!-- <intent-filter>-->
65+
<!-- <action android:name="android.intent.action.VIEW" />-->
66+
67+
<!-- <category android:name="android.intent.category.DEFAULT" />-->
68+
<!-- <category android:name="android.intent.category.BROWSABLE" />-->
69+
70+
<!-- <data-->
71+
<!-- android:host="${DEMO_OAUTH_REDIRECT_URI_HOST}"-->
72+
<!-- android:scheme="${DEMO_OAUTH_REDIRECT_URI_SCHEME}" />-->
73+
<!-- </intent-filter>-->
74+
<!-- </activity>-->
75+
76+
5977
<!-- Lib activities -->
6078
<activity
6179
android:name="com.yalantis.ucrop.UCropActivity"

demo-app/src/main/java/com/gravatar/demoapp/ui/activity/QuickEditorTestActivity.kt

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,25 @@ import android.widget.Toast
77
import androidx.appcompat.app.AppCompatActivity
88
import androidx.compose.foundation.layout.fillMaxWidth
99
import androidx.compose.foundation.layout.padding
10+
import androidx.compose.foundation.shape.CircleShape
1011
import androidx.compose.runtime.Composable
1112
import androidx.compose.runtime.LaunchedEffect
1213
import androidx.compose.runtime.getValue
14+
import androidx.compose.runtime.key
1315
import androidx.compose.runtime.mutableStateOf
1416
import androidx.compose.runtime.neverEqualPolicy
1517
import androidx.compose.runtime.remember
1618
import androidx.compose.runtime.setValue
1719
import androidx.compose.ui.Modifier
20+
import androidx.compose.ui.draw.clip
1821
import androidx.compose.ui.platform.ComposeView
1922
import androidx.compose.ui.unit.dp
2023
import com.gravatar.demoapp.BuildConfig
2124
import com.gravatar.demoapp.R
2225
import com.gravatar.quickeditor.GravatarQuickEditor
26+
import com.gravatar.quickeditor.ui.GetQuickEditorResult
27+
import com.gravatar.quickeditor.ui.GravatarQuickEditorActivity
28+
import com.gravatar.quickeditor.ui.GravatarQuickEditorResult
2329
import com.gravatar.quickeditor.ui.editor.AuthenticationMethod
2430
import com.gravatar.quickeditor.ui.editor.AvatarPickerContentLayout
2531
import com.gravatar.quickeditor.ui.editor.GravatarQuickEditorParams
@@ -30,8 +36,27 @@ import com.gravatar.services.ProfileService
3036
import com.gravatar.types.Email
3137
import com.gravatar.ui.components.ComponentState
3238
import com.gravatar.ui.components.ProfileSummary
39+
import com.gravatar.ui.components.atomic.Avatar
3340

3441
class QuickEditorTestActivity : AppCompatActivity() {
42+
private var profileChanges by mutableStateOf(0)
43+
private val getQEResult = registerForActivityResult(GetQuickEditorResult()) { quickEditorResult ->
44+
when (quickEditorResult) {
45+
GravatarQuickEditorResult.AVATAR_SELECTED -> {
46+
profileChanges++
47+
Toast.makeText(this, "Avatar selected", Toast.LENGTH_SHORT).show()
48+
}
49+
50+
GravatarQuickEditorResult.DISMISSED -> {
51+
Toast.makeText(this, "Dismissed", Toast.LENGTH_SHORT).show()
52+
}
53+
54+
else -> {
55+
Toast.makeText(this, "Unexpected...", Toast.LENGTH_SHORT).show()
56+
}
57+
}
58+
}
59+
3560
override fun onCreate(savedInstanceState: Bundle?) {
3661
super.onCreate(savedInstanceState)
3762
setContentView(R.layout.activity_quick_editor_test)
@@ -41,9 +66,12 @@ class QuickEditorTestActivity : AppCompatActivity() {
4166
private fun setupViews() {
4267
val profileCard = findViewById<ComposeView>(R.id.profile_card)
4368
val btnUpdateAvatar = findViewById<Button>(R.id.btn_update_avatar)
69+
val btnUpdateAvatarWithQEActivity = findViewById<Button>(R.id.btn_update_avatar_qe_activity)
4470

4571
profileCard.setContent {
46-
GravatarProfileSummary(emailAddress = BuildConfig.DEMO_EMAIL)
72+
key(profileChanges) {
73+
GravatarProfileSummary(emailAddress = BuildConfig.DEMO_EMAIL)
74+
}
4775
}
4876

4977
btnUpdateAvatar.setOnClickListener {
@@ -67,6 +95,23 @@ class QuickEditorTestActivity : AppCompatActivity() {
6795
},
6896
)
6997
}
98+
99+
btnUpdateAvatarWithQEActivity.setOnClickListener {
100+
getQEResult.launch(
101+
GravatarQuickEditorActivity.GravatarEditorActivityArguments(
102+
GravatarQuickEditorParams {
103+
email = Email(BuildConfig.DEMO_EMAIL)
104+
avatarPickerContentLayout = AvatarPickerContentLayout.Horizontal
105+
},
106+
AuthenticationMethod.OAuth(
107+
OAuthParams {
108+
clientId = BuildConfig.DEMO_OAUTH_CLIENT_ID
109+
redirectUri = BuildConfig.DEMO_OAUTH_REDIRECT_URI
110+
},
111+
),
112+
),
113+
)
114+
}
70115
}
71116
}
72117

@@ -98,5 +143,13 @@ fun GravatarProfileSummary(emailAddress: String = "[email protected]") {
98143
modifier = Modifier
99144
.fillMaxWidth()
100145
.padding(16.dp),
146+
avatar = {
147+
Avatar(
148+
state = profileState,
149+
size = 72.dp,
150+
modifier = Modifier.clip(CircleShape),
151+
forceRefresh = true,
152+
)
153+
},
101154
)
102155
}

demo-app/src/main/res/layout/activity_quick_editor_test.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@
3535
app:layout_constraintStart_toStartOf="parent"
3636
app:layout_constraintTop_toBottomOf="@id/profile_container" />
3737

38+
<Button
39+
android:id="@+id/btn_update_avatar_qe_activity"
40+
android:layout_width="wrap_content"
41+
android:layout_height="wrap_content"
42+
android:layout_marginTop="12dp"
43+
android:text="Update Avatar with QuickEditor Activity"
44+
app:layout_constraintEnd_toEndOf="parent"
45+
app:layout_constraintStart_toStartOf="parent"
46+
app:layout_constraintTop_toBottomOf="@id/btn_update_avatar" />
47+
3848
<TextView
3949
android:layout_width="match_parent"
4050
android:layout_height="wrap_content"

docs/get-started/get-started.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ To do that the QuickEditor needs an authorization token to perform requests on b
244244

245245
### 1. Let the Quick Editor handle the OAuth flow
246246

247+
#### 1.1 Using you own activity with `android:launchMode="singleTask"` (Recommended)
248+
247249
Quick Editor can handle the heavy lifting of running the full OAuth flow, so you don't have to do that. We will still need a few things from you.
248250
First, you have to go to [OAuth docs](https://docs.gravatar.com/oauth/) and create your Application. Define the `Redirect URLs`.
249251

@@ -311,6 +313,61 @@ When the user logs out form the app, make sure to run:
311313
GravatarQuickEditor.logout(Email("{USER_EMAIL}"))
312314
```
313315

316+
#### 1.2 Using the provided activity
317+
318+
If using an activity with `android:launchMode="singleTask"` is not an option, you can use the provided activity. With this option, you don't need to modify how your activities are set up.
319+
320+
You need to add the provided activity to your `AndroidManifest.xml`:
321+
322+
```xml
323+
<activity
324+
android:name="com.gravatar.quickeditor.ui.GravatarQuickEditorActivity"
325+
tools:node="merge">
326+
327+
<intent-filter>
328+
<action android:name="android.intent.action.VIEW" />
329+
330+
<category android:name="android.intent.category.DEFAULT" />
331+
<category android:name="android.intent.category.BROWSABLE" />
332+
333+
<data
334+
android:scheme="https"
335+
android:host="yourhost.com"
336+
android:pathPrefix="/redirect-url"
337+
/>
338+
</intent-filter>
339+
</activity>
340+
```
341+
342+
_Note the important difference here: the `tools:node="merge"` attribute. This is necessary to merge the intent filter with the one defined in the library._
343+
344+
The `GravatarQuickEditorActivity` defines an Activity Result contract that you can use to launch the Quick Editor and handle the result. Here's an example of how you can use it:
345+
346+
```kotlin
347+
private val getQEResult = registerForActivityResult(GetQuickEditorResult()) { quickEditorResult ->
348+
when (quickEditorResult) {
349+
GravatarQuickEditorResult.AVATAR_SELECTED -> { ... }
350+
351+
GravatarQuickEditorResult.DISMISSED -> { ... }
352+
353+
else -> { ... }
354+
}
355+
}
356+
357+
getQEResult.launch(
358+
GravatarQuickEditorActivity.GravatarEditorActivityArguments(
359+
GravatarQuickEditorParams { ... },
360+
AuthenticationMethod.OAuth(
361+
OAuthParams { ... },
362+
),
363+
),
364+
)
365+
```
366+
367+
It's important to note that using the `GravatarQuickEditorActivity` you'll only receive the result of the Quick Editor when it's dismissed not instantly as with using the `@Composable` component from your `singleTask` activity (see [Section 1.1](#11-using-you-own-activity-with-androidlaunchmodesingletask-recommended)).
368+
369+
In the `demo-app` you can find a detailed implementation showing how to use the provided activity. See `QuickEditorTestActivity`.
370+
314371
#### Exclude Data Store files from Android backup (optional, but recommended)
315372

316373
Data Store files are subject to Android backups. Encrypted files from the backup won't work when restored on a different device so we have to exclude those files.

gradle/libs.versions.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,6 @@ dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
9090
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
9191
ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" }
9292
openapi-generator = { id = "org.openapi.generator", version.ref = "openapi" }
93+
parcelize = { id = "kotlin-parcelize" }
9394
publish-to-s3 = { id = "com.automattic.android.publish-to-s3", version.ref = "publishToS3" }
9495
roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" }

0 commit comments

Comments
 (0)