From 9754e26e5f87f72d30f5e3ade404c4095576933f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 22 Jun 2020 20:50:31 +0200 Subject: [PATCH 1/2] Add capability to change the display name (#1529) --- .idea/dictionaries/bmarty.xml | 1 + CHANGES.md | 1 + .../api/session/profile/ProfileService.kt | 9 +++- .../session/profile/DefaultProfileService.kt | 11 ++++- .../internal/session/profile/ProfileAPI.kt | 7 +++ .../internal/session/profile/ProfileModule.kt | 3 ++ .../session/profile/SetDisplayNameBody.kt | 28 ++++++++++++ .../session/profile/SetDisplayNameTask.kt | 43 +++++++++++++++++++ .../features/settings/VectorPreferences.kt | 1 - .../settings/VectorSettingsGeneralFragment.kt | 39 ++++------------- .../main/res/xml/vector_settings_general.xml | 1 + 11 files changed, 111 insertions(+), 33 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/SetDisplayNameBody.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/SetDisplayNameTask.kt diff --git a/.idea/dictionaries/bmarty.xml b/.idea/dictionaries/bmarty.xml index 93ac86f417..9d601bff14 100644 --- a/.idea/dictionaries/bmarty.xml +++ b/.idea/dictionaries/bmarty.xml @@ -7,6 +7,7 @@ ciphertext coroutine decryptor + displayname emoji emojis fdroid diff --git a/CHANGES.md b/CHANGES.md index 903880fa27..9fde9949ac 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ Changes in RiotX 0.23.0 (2020-XX-XX) Features ✨: - Call with WebRTC support (##611) + - Add capability to change the display name (#1529) Improvements 🙌: - "Add Matrix app" menu is now always visible (#1495) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/profile/ProfileService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/profile/ProfileService.kt index 92f9359e34..3d084336e3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/profile/ProfileService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/profile/ProfileService.kt @@ -35,12 +35,19 @@ interface ProfileService { } /** - * Return the current dispayname for this user + * Return the current display name for this user * @param userId the userId param to look for * */ fun getDisplayName(userId: String, matrixCallback: MatrixCallback>): Cancelable + /** + * Update the display name for this user + * @param userId the userId to update the display name of + * @param newDisplayName the new display name of the user + */ + fun setDisplayName(userId: String, newDisplayName: String, matrixCallback: MatrixCallback): Cancelable + /** * Return the current avatarUrl for this user. * @param userId the userId param to look for diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/DefaultProfileService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/DefaultProfileService.kt index a981e8e930..88f0dfc25c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/DefaultProfileService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/DefaultProfileService.kt @@ -34,7 +34,8 @@ import javax.inject.Inject internal class DefaultProfileService @Inject constructor(private val taskExecutor: TaskExecutor, private val monarchy: Monarchy, private val refreshUserThreePidsTask: RefreshUserThreePidsTask, - private val getProfileInfoTask: GetProfileInfoTask) : ProfileService { + private val getProfileInfoTask: GetProfileInfoTask, + private val setDisplayNameTask: SetDisplayNameTask) : ProfileService { override fun getDisplayName(userId: String, matrixCallback: MatrixCallback>): Cancelable { val params = GetProfileInfoTask.Params(userId) @@ -54,6 +55,14 @@ internal class DefaultProfileService @Inject constructor(private val taskExecuto .executeBy(taskExecutor) } + override fun setDisplayName(userId: String, newDisplayName: String, matrixCallback: MatrixCallback): Cancelable { + return setDisplayNameTask + .configureWith(SetDisplayNameTask.Params(userId = userId, newDisplayName = newDisplayName)) { + callback = matrixCallback + } + .executeBy(taskExecutor) + } + override fun getAvatarUrl(userId: String, matrixCallback: MatrixCallback>): Cancelable { val params = GetProfileInfoTask.Params(userId) return getProfileInfoTask diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/ProfileAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/ProfileAPI.kt index 717497e582..b3b726a315 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/ProfileAPI.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/ProfileAPI.kt @@ -23,6 +23,7 @@ import retrofit2.Call import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.POST +import retrofit2.http.PUT import retrofit2.http.Path internal interface ProfileAPI { @@ -42,6 +43,12 @@ internal interface ProfileAPI { @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "account/3pid") fun getThreePIDs(): Call + /** + * Change user display name + */ + @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "profile/{userId}/displayname") + fun setDisplayName(@Path("userId") userId: String, @Body body: SetDisplayNameBody): Call + /** * Bind a threePid * Ref: https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-account-3pid-bind diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/ProfileModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/ProfileModule.kt index 0d7ebe5b62..d83c305c10 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/ProfileModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/ProfileModule.kt @@ -51,4 +51,7 @@ internal abstract class ProfileModule { @Binds abstract fun bindUnbindThreePidsTask(task: DefaultUnbindThreePidsTask): UnbindThreePidsTask + + @Binds + abstract fun bindSetDisplayNameTask(task: DefaultSetDisplayNameTask): SetDisplayNameTask } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/SetDisplayNameBody.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/SetDisplayNameBody.kt new file mode 100644 index 0000000000..c9bcbff688 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/SetDisplayNameBody.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.matrix.android.internal.session.profile + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class SetDisplayNameBody( + /** + * The new display name for this user. + */ + @Json(name = "displayname") + val displayName: String +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/SetDisplayNameTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/SetDisplayNameTask.kt new file mode 100644 index 0000000000..bca2f73f26 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/profile/SetDisplayNameTask.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.profile + +import im.vector.matrix.android.internal.network.executeRequest +import im.vector.matrix.android.internal.task.Task +import org.greenrobot.eventbus.EventBus +import javax.inject.Inject + +internal abstract class SetDisplayNameTask : Task { + data class Params( + val userId: String, + val newDisplayName: String + ) +} + +internal class DefaultSetDisplayNameTask @Inject constructor( + private val profileAPI: ProfileAPI, + private val eventBus: EventBus) : SetDisplayNameTask() { + + override suspend fun execute(params: Params) { + return executeRequest(eventBus) { + val body = SetDisplayNameBody( + displayName = params.newDisplayName + ) + apiCall = profileAPI.setDisplayName(params.userId, body) + } + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt index beae0a623e..5f245c883d 100755 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt @@ -74,7 +74,6 @@ class VectorPreferences @Inject constructor(private val context: Context) { const val SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY = "SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY" // user - const val SETTINGS_DISPLAY_NAME_PREFERENCE_KEY = "SETTINGS_DISPLAY_NAME_PREFERENCE_KEY" const val SETTINGS_PROFILE_PICTURE_PREFERENCE_KEY = "SETTINGS_PROFILE_PICTURE_PREFERENCE_KEY" // contacts diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt index 926d285f7b..d20f6c0684 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt @@ -79,7 +79,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { findPreference(VectorPreferences.SETTINGS_PROFILE_PICTURE_PREFERENCE_KEY)!! } private val mDisplayNamePreference by lazy { - findPreference(VectorPreferences.SETTINGS_DISPLAY_NAME_PREFERENCE_KEY)!! + findPreference("SETTINGS_DISPLAY_NAME_PREFERENCE_KEY")!! } private val mPasswordPreference by lazy { findPreference(VectorPreferences.SETTINGS_CHANGE_PASSWORD_PREFERENCE_KEY)!! @@ -858,44 +858,23 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { * Update the displayname. */ private fun onDisplayNameClick(value: String?) { - notImplemented() - /* TODO - if (!TextUtils.equals(session.myUser.displayname, value)) { + value ?: return + val currentDisplayName = session.getUser(session.myUserId)?.displayName ?: "" + if (currentDisplayName != value) { displayLoadingView() - session.myUser.updateDisplayName(value, object : MatrixCallback { - override fun onSuccess(info: Void?) { + session.setDisplayName(session.myUserId, value, object : MatrixCallback { + override fun onSuccess(data: Unit) { // refresh the settings value - PreferenceManager.getDefaultSharedPreferences(activity).edit { - putString(VectorPreferences.SETTINGS_DISPLAY_NAME_PREFERENCE_KEY, value) - } - + mDisplayNamePreference.summary = value onCommonDone(null) - - refreshDisplay() } - override fun onNetworkError(e: Exception) { - onCommonDone(e.localizedMessage) - } - - override fun onMatrixError(e: MatrixError) { - if (MatrixError.M_CONSENT_NOT_GIVEN == e.errcode) { - activity?.runOnUiThread { - hideLoadingView() - (activity as VectorAppCompatActivity).consentNotGivenHelper.displayDialog(e) - } - } else { - onCommonDone(e.localizedMessage) - } - } - - override fun onUnexpectedError(e: Exception) { - onCommonDone(e.localizedMessage) + override fun onFailure(failure: Throwable) { + onCommonDone(failure.localizedMessage) } }) } - */ } companion object { diff --git a/vector/src/main/res/xml/vector_settings_general.xml b/vector/src/main/res/xml/vector_settings_general.xml index 7248280e37..f79fbc71e2 100644 --- a/vector/src/main/res/xml/vector_settings_general.xml +++ b/vector/src/main/res/xml/vector_settings_general.xml @@ -14,6 +14,7 @@ From 35fed2676a5c3935710ed99125db8b54b94e3f00 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 23 Jun 2020 11:21:00 +0200 Subject: [PATCH 2/2] Cleanup after Onuray's review and improve wording when removing display name --- matrix-sdk-android/src/main/res/values/strings.xml | 4 ++-- .../features/settings/VectorSettingsGeneralFragment.kt | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values/strings.xml b/matrix-sdk-android/src/main/res/values/strings.xml index fe62a19b8e..4e8e5abc96 100644 --- a/matrix-sdk-android/src/main/res/values/strings.xml +++ b/matrix-sdk-android/src/main/res/values/strings.xml @@ -33,8 +33,8 @@ You set your display name to %1$s %1$s changed their display name from %2$s to %3$s You changed your display name from %1$s to %2$s - %1$s removed their display name (%2$s) - You removed your display name (%1$s) + %1$s removed their display name (it was %2$s) + You removed your display name (it was %1$s) %1$s changed the topic to: %2$s You changed the topic to: %1$s %1$s changed the room name to: %2$s diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt index d20f6c0684..6d73abf873 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt @@ -122,7 +122,9 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { it.summary = session.getUser(session.myUserId)?.displayName ?: "" it.text = it.summary.toString() it.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> - onDisplayNameClick(newValue?.let { (it as String).trim() }) + newValue + ?.let { value -> (value as? String)?.trim() } + ?.let { value -> onDisplayNameChanged(value) } false } } @@ -857,20 +859,21 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { /** * Update the displayname. */ - private fun onDisplayNameClick(value: String?) { - value ?: return + private fun onDisplayNameChanged(value: String) { val currentDisplayName = session.getUser(session.myUserId)?.displayName ?: "" if (currentDisplayName != value) { displayLoadingView() session.setDisplayName(session.myUserId, value, object : MatrixCallback { override fun onSuccess(data: Unit) { + if (!isAdded) return // refresh the settings value mDisplayNamePreference.summary = value onCommonDone(null) } override fun onFailure(failure: Throwable) { + if (!isAdded) return onCommonDone(failure.localizedMessage) } })