Skip to content

Commit 9e22cb0

Browse files
authored
Merge pull request #8 from MuShare/develop/update-user
Upload avatar
2 parents 6ada2f3 + 74f2ccc commit 9e22cb0

File tree

6 files changed

+162
-20
lines changed

6 files changed

+162
-20
lines changed

demoapp/build.gradle

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
apply plugin: 'com.android.application'
22
apply plugin: 'kotlin-android'
33
apply plugin: 'kotlin-android-extensions'
4+
apply plugin: "kotlin-kapt"
45

56
android {
67
compileSdkVersion 29
@@ -13,7 +14,7 @@ android {
1314

1415
defaultConfig {
1516
applicationId "com.mushare.demoapp"
16-
minSdkVersion 16
17+
minSdkVersion 19
1718
targetSdkVersion 29
1819
versionCode 1
1920
versionName "1.0"
@@ -30,6 +31,11 @@ android {
3031

3132
}
3233

34+
repositories {
35+
jcenter()
36+
maven { url "https://jitpack.io" } //Make sure to add this in your project for uCrop
37+
}
38+
3339
dependencies {
3440
implementation fileTree(dir: 'libs', include: ['*.jar'])
3541
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
@@ -39,6 +45,10 @@ dependencies {
3945
implementation 'androidx.annotation:annotation:1.1.0'
4046
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
4147
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
48+
implementation 'com.github.dhaval2404:imagepicker:1.7.5'
49+
implementation 'com.github.florent37:inline-activity-result-kotlin:1.0.4'
50+
implementation 'com.github.bumptech.glide:glide:4.11.0'
51+
kapt 'com.github.bumptech.glide:compiler:4.11.0'
4252
testImplementation 'junit:junit:4.13'
4353
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
4454
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

demoapp/src/main/AndroidManifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
android:label="@string/app_name"
1111
android:roundIcon="@mipmap/ic_launcher_round"
1212
android:supportsRtl="true"
13-
android:theme="@style/AppTheme">
13+
android:theme="@style/AppTheme"
14+
android:requestLegacyExternalStorage="true">
1415
<activity
1516
android:name=".ui.login.LoginActivity"
1617
android:label="@string/app_name">
Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
package com.mushare.demoapp.ui.login;
22

3+
import android.app.Activity
34
import android.os.Bundle
45
import android.util.Log
5-
import android.widget.Button
6-
import android.widget.EditText
7-
import android.widget.TextView
8-
import android.widget.Toast
6+
import android.widget.*
97
import androidx.appcompat.app.AppCompatActivity
8+
import com.bumptech.glide.Glide
9+
import com.github.dhaval2404.imagepicker.ImagePicker
1010
import com.mushare.demoapp.R
11-
import com.mushare.plutosdk.Pluto
12-
import com.mushare.plutosdk.getToken
13-
import com.mushare.plutosdk.myInfo
14-
import com.mushare.plutosdk.updateName
11+
import com.mushare.plutosdk.*
1512
import java.lang.ref.WeakReference
1613

1714
class ProfileActivity : AppCompatActivity() {
@@ -21,30 +18,70 @@ class ProfileActivity : AppCompatActivity() {
2118
}
2219

2320
private lateinit var nameEditText: WeakReference<EditText>
21+
private lateinit var avatarImageView: WeakReference<ImageView>
2422

2523
override fun onCreate(savedInstanceState: Bundle?) {
2624
super.onCreate(savedInstanceState)
2725

2826
setContentView(R.layout.activity_profile)
2927

30-
nameEditText = WeakReference(findViewById<EditText>(R.id.profile_name))
28+
nameEditText = WeakReference(findViewById(R.id.profile_name))
29+
avatarImageView = WeakReference(findViewById(R.id.profile_avatar))
3130

32-
Pluto.getInstance()?.myInfo(success = {
33-
nameEditText.get()?.setText(it.name)
34-
})
31+
updateUserInfo()
3532

3633
Pluto.getInstance()?.getToken(completion = {
3734
findViewById<TextView>(R.id.profile_access_token).text = it ?: "Refresh failed"
3835
})
3936

37+
findViewById<Button>(R.id.profile_upload_avatar).setOnClickListener {
38+
ImagePicker.with(this)
39+
.crop()
40+
.compress(64)
41+
.maxResultSize(480, 480)
42+
.start { resultCode, data ->
43+
when (resultCode) {
44+
Activity.RESULT_OK -> {
45+
Pluto.getInstance()?.uploadAvatar(
46+
imageFile = ImagePicker.getFile(data) ?: return@start,
47+
success = {
48+
updateUserInfo {
49+
Toast
50+
.makeText(
51+
this,
52+
"Avatar uploaded",
53+
Toast.LENGTH_SHORT
54+
)
55+
.show()
56+
}
57+
},
58+
error = {
59+
Log.d(TAG, "Error uploading avatar $it")
60+
}
61+
)
62+
}
63+
ImagePicker.RESULT_ERROR -> {
64+
Toast
65+
.makeText(this, ImagePicker.getError(data), Toast.LENGTH_SHORT)
66+
.show()
67+
}
68+
else -> {
69+
Toast
70+
.makeText(this, "Task Cancelled", Toast.LENGTH_SHORT)
71+
.show()
72+
}
73+
}
74+
}
75+
}
76+
4077
findViewById<Button>(R.id.profile_update_name).setOnClickListener {
4178
val name = nameEditText.get()?.text.toString() ?: return@setOnClickListener
4279
Pluto.getInstance()?.updateName(
4380
name = name,
4481
success = {
45-
Pluto.getInstance()?.myInfo(success = {
82+
updateUserInfo {
4683
Toast.makeText(this, "Name updated", Toast.LENGTH_SHORT).show()
47-
})
84+
}
4885
},
4986
error = {
5087
Log.d(TAG, "Error updating username $it")
@@ -58,4 +95,15 @@ class ProfileActivity : AppCompatActivity() {
5895
})
5996
}
6097
}
98+
99+
private fun updateUserInfo(completion: (() -> Unit)? = null) {
100+
Pluto.getInstance()?.myInfo(success = { user ->
101+
nameEditText.get()?.setText(user.name)
102+
avatarImageView.get()?.let {
103+
Glide.with(this).load(user.avatar).into(it)
104+
}
105+
completion?.let { it() }
106+
})
107+
108+
}
61109
}

demoapp/src/main/res/layout/activity_profile.xml

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,22 @@
44
android:layout_height="match_parent"
55
xmlns:app="http://schemas.android.com/apk/res-auto">
66

7+
<ImageView
8+
android:id="@+id/profile_avatar"
9+
android:layout_width="50dp"
10+
android:layout_height="50dp"
11+
app:layout_constraintTop_toTopOf="parent"
12+
app:layout_constraintLeft_toLeftOf="parent"
13+
android:layout_marginStart="20dp"
14+
android:layout_marginTop="20dp"
15+
android:background="@color/colorAccent"/>
16+
717
<EditText
818
android:id="@+id/profile_name"
919
android:layout_width="match_parent"
1020
android:layout_height="wrap_content"
1121
app:layout_constraintTop_toTopOf="parent"
12-
android:layout_marginStart="20dp"
22+
android:layout_marginStart="90dp"
1323
android:layout_marginTop="20dp"
1424
android:layout_marginEnd="20dp"
1525
android:hint="Username"/>
@@ -20,19 +30,30 @@
2030
android:layout_height="wrap_content"
2131
app:layout_constraintTop_toBottomOf="@id/profile_name"
2232
android:layout_marginStart="20dp"
23-
android:layout_marginTop="10dp"
33+
android:layout_marginTop="20dp"
2434
android:layout_marginEnd="20dp"
2535
android:text="Update Username"
2636
/>
2737

2838
<Button
29-
android:id="@+id/profile_refresh_token"
39+
android:id="@+id/profile_upload_avatar"
3040
android:layout_width="match_parent"
3141
android:layout_height="wrap_content"
3242
app:layout_constraintTop_toBottomOf="@id/profile_update_name"
3343
android:layout_marginStart="20dp"
3444
android:layout_marginTop="10dp"
3545
android:layout_marginEnd="20dp"
46+
android:text="Upload Avatar"
47+
/>
48+
49+
<Button
50+
android:id="@+id/profile_refresh_token"
51+
android:layout_width="match_parent"
52+
android:layout_height="wrap_content"
53+
app:layout_constraintTop_toBottomOf="@id/profile_upload_avatar"
54+
android:layout_marginStart="20dp"
55+
android:layout_marginTop="10dp"
56+
android:layout_marginEnd="20dp"
3657
android:text="Refresh Token"/>
3758

3859
<TextView

pluto-kotlin-client-sdk/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ apply plugin: 'maven-publish'
55

66
buildscript {
77
ext.versionCode = 11
8-
ext.versionName = '0.2.4'
8+
ext.versionName = '0.3'
99
}
1010

1111
android {

pluto-kotlin-client-sdk/src/main/java/com/mushare/plutosdk/Pluto+User.kt

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package com.mushare.plutosdk
22

3+
import android.graphics.Bitmap
4+
import android.graphics.BitmapFactory
5+
import android.util.Base64
36
import retrofit2.Call
47
import retrofit2.Callback
58
import retrofit2.Response
9+
import java.io.ByteArrayOutputStream
10+
import java.io.File
611

712
fun Pluto.myInfo(
813
success: (PlutoUser) -> Unit,
@@ -110,3 +115,60 @@ fun Pluto.updateName(
110115
handler = handler
111116
)
112117
}
118+
119+
fun Pluto.uploadAvatar(
120+
imageFile: File,
121+
success: () -> Unit,
122+
error: ((PlutoError) -> Unit)? = null,
123+
handler: Pluto.PlutoRequestHandler? = null
124+
) {
125+
val bitmap = BitmapFactory.decodeFile(imageFile.absolutePath)
126+
val outputStream = ByteArrayOutputStream()
127+
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
128+
val base64 = Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT)
129+
getAuthorizationHeader(
130+
completion = { header ->
131+
if (header == null) {
132+
handler?.setCall(null)
133+
error?.invoke(PlutoError.notSignin)
134+
return@getAuthorizationHeader
135+
}
136+
137+
val body = UpdateUserInfoPutData(null, base64)
138+
plutoService.updateUserInfo(body, header).apply {
139+
enqueue(object : Callback<PlutoResponse> {
140+
override fun onFailure(call: Call<PlutoResponse>, t: Throwable) {
141+
t.printStackTrace()
142+
error?.invoke(PlutoError.badRequest)
143+
}
144+
145+
override fun onResponse(
146+
call: Call<PlutoResponse>,
147+
response: Response<PlutoResponse>
148+
) {
149+
val plutoResponse = response.body()
150+
if (plutoResponse != null) {
151+
if (plutoResponse.statusOK()) {
152+
success()
153+
} else {
154+
error?.invoke(plutoResponse.errorCode())
155+
}
156+
} else {
157+
error?.invoke(
158+
parseErrorCodeFromErrorBody(
159+
response.errorBody(),
160+
gson
161+
)
162+
)
163+
}
164+
}
165+
})
166+
}.also {
167+
handler?.setCall(it)
168+
}
169+
},
170+
handler = handler
171+
)
172+
}
173+
174+

0 commit comments

Comments
 (0)