diff --git a/CHANGES.md b/CHANGES.md index b43ff50308..495247b50e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ Improvements 🙌: - Ensure users do not accidentally ignore other users (#1890) - Support new config.json format and config.domain.json files (#1682) - Increase Font size on Calling screen (#1643) + - Make the user's Avatar live in the general settings Bugfix 🐛: - Fix incorrect date format for some Asian languages (#1928) diff --git a/vector/src/main/java/im/vector/app/core/preference/RoomAvatarPreference.kt b/vector/src/main/java/im/vector/app/core/preference/RoomAvatarPreference.kt deleted file mode 100644 index 411e23a1c8..0000000000 --- a/vector/src/main/java/im/vector/app/core/preference/RoomAvatarPreference.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2018 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.app.core.preference - -import android.content.Context -import android.util.AttributeSet -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.room.Room - -/** - * Specialized class to target a Room avatar preference. - * Based don the avatar preference class it redefines refreshAvatar() and - * add the new method setConfiguration(). - */ -class RoomAvatarPreference : UserAvatarPreference { - - private var mRoom: Room? = null - - constructor(context: Context) : super(context) - - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - - constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) - - override fun refreshAvatar() { - if (null != mAvatarView && null != mRoom) { - // TODO - // VectorUtils.loadRoomAvatar(context, session, mAvatarView, mRoom) - } - } - - fun setConfiguration(aSession: Session, aRoom: Room) { - mSession = aSession - mRoom = aRoom - refreshAvatar() - } -} diff --git a/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt b/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt index be186377a5..e3b4430fe0 100755 --- a/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt @@ -25,14 +25,11 @@ import androidx.preference.PreferenceViewHolder import im.vector.app.R import im.vector.app.core.extensions.vectorComponent import im.vector.app.features.home.AvatarRenderer -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.util.MatrixItem +import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.api.util.toMatrixItem -open class UserAvatarPreference : Preference { - - internal var mAvatarView: ImageView? = null - internal var mSession: Session? = null +class UserAvatarPreference : Preference { + private var mAvatarView: ImageView? = null private var mLoadingProgressBar: ProgressBar? = null private var avatarRenderer: AvatarRenderer = context.vectorComponent().avatarRenderer() @@ -51,24 +48,11 @@ open class UserAvatarPreference : Preference { override fun onBindViewHolder(holder: PreferenceViewHolder) { super.onBindViewHolder(holder) - mAvatarView = holder.itemView.findViewById(R.id.settings_avatar) mLoadingProgressBar = holder.itemView.findViewById(R.id.avatar_update_progress_bar) - refreshAvatar() } - open fun refreshAvatar() { - val session = mSession ?: return - val view = mAvatarView ?: return - session.getUser(session.myUserId)?.let { - avatarRenderer.render(it.toMatrixItem(), view) - } ?: run { - avatarRenderer.render(MatrixItem.UserItem(session.myUserId), view) - } - } - - fun setSession(session: Session) { - mSession = session - refreshAvatar() + fun refreshAvatar(user: User) { + mAvatarView?.let { avatarRenderer.render(user.toMatrixItem(), it) } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt index a0949e8e21..512545afe2 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt @@ -21,7 +21,6 @@ import android.os.Bundle import android.view.View import androidx.annotation.CallSuper import androidx.preference.PreferenceFragmentCompat -import org.matrix.android.sdk.api.session.Session import im.vector.app.R import im.vector.app.core.di.DaggerScreenComponent import im.vector.app.core.di.HasScreenInjector @@ -29,6 +28,9 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.toast +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.disposables.Disposable +import org.matrix.android.sdk.api.session.Session import timber.log.Timber abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), HasScreenInjector { @@ -74,10 +76,31 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), HasScree mLoadingView = vectorActivity.findViewById(R.id.vector_settings_spinner_views) } + @CallSuper + override fun onDestroyView() { + super.onDestroyView() + uiDisposables.clear() + } + + override fun onDestroy() { + uiDisposables.dispose() + super.onDestroy() + } + abstract fun bindPref() abstract var titleRes: Int + /* ========================================================================================== + * Disposable + * ========================================================================================== */ + + private val uiDisposables = CompositeDisposable() + + protected fun Disposable.disposeOnDestroyView() { + uiDisposables.add(this) + } + /* ========================================================================================== * Protected * ========================================================================================== */ diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt index 127dcc984e..76f6edf3a1 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt @@ -21,6 +21,7 @@ package im.vector.app.features.settings import android.app.Activity import android.content.Intent import android.net.Uri +import android.os.Bundle import android.text.Editable import android.util.Patterns import android.view.View @@ -40,13 +41,6 @@ import com.bumptech.glide.load.engine.cache.DiskCache import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import com.yalantis.ucrop.UCrop -import im.vector.lib.multipicker.MultiPicker -import im.vector.lib.multipicker.entity.MultiPickerImageType -import org.matrix.android.sdk.api.MatrixCallback -import org.matrix.android.sdk.api.NoOpMatrixCallback -import org.matrix.android.sdk.api.failure.isInvalidPassword -import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerConfig -import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService import im.vector.app.R import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.showPassword @@ -68,10 +62,20 @@ import im.vector.app.features.MainActivityArgs import im.vector.app.features.media.createUCropWithDefaultSettings import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.workers.signout.SignOutUiWorker +import im.vector.lib.multipicker.MultiPicker +import im.vector.lib.multipicker.entity.MultiPickerImageType +import io.reactivex.android.schedulers.AndroidSchedulers import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCallback +import org.matrix.android.sdk.api.NoOpMatrixCallback +import org.matrix.android.sdk.api.failure.isInvalidPassword +import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerConfig +import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService +import org.matrix.android.sdk.rx.rx +import org.matrix.android.sdk.rx.unwrap import java.io.File import java.util.UUID @@ -120,10 +124,21 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { } } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + session.rx() + .liveUser(session.myUserId) + .unwrap() + .distinctUntilChanged { user -> user.avatarUrl } + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { mUserAvatarPreference.refreshAvatar(it) } + .disposeOnDestroyView() + } + override fun bindPref() { // Avatar mUserAvatarPreference.let { - it.setSession(session) it.onPreferenceClickListener = Preference.OnPreferenceClickListener { onUpdateAvatarClick() false @@ -447,8 +462,6 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { session.updateAvatar(session.myUserId, uri, getFilenameFromUri(context, uri) ?: UUID.randomUUID().toString(), object : MatrixCallback { override fun onSuccess(data: Unit) { if (!isAdded) return - - mUserAvatarPreference.refreshAvatar() onCommonDone(null) }