Replace Controller with Activity for profile

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2023-03-29 15:43:25 +02:00
parent 9e68be74d6
commit bde67eb2bd
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
6 changed files with 198 additions and 158 deletions

View File

@ -202,6 +202,10 @@
android:name=".location.GeocodingActivity" android:name=".location.GeocodingActivity"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity
android:name=".profile.ProfileActivity"
android:theme="@style/AppTheme" />
<receiver android:name=".receivers.PackageReplacedReceiver" <receiver android:name=".receivers.PackageReplacedReceiver"
android:exported="false"> android:exported="false">
<intent-filter> <intent-filter>

View File

@ -78,6 +78,7 @@ import com.nextcloud.talk.jobs.ContactAddressBookWorker.Companion.checkPermissio
import com.nextcloud.talk.jobs.ContactAddressBookWorker.Companion.deleteAll import com.nextcloud.talk.jobs.ContactAddressBookWorker.Companion.deleteAll
import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.models.json.userprofile.UserProfileOverall import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
import com.nextcloud.talk.profile.ProfileActivity
import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DisplayUtils
@ -483,13 +484,8 @@ class SettingsController : BaseController(R.layout.controller_settings) {
setupMessageView() setupMessageView()
binding?.avatarContainer?.setOnClickListener { binding?.avatarContainer?.setOnClickListener {
router val intent = Intent(activity, ProfileActivity::class.java)
.pushController( activity!!.startActivity(intent)
RouterTransaction.with(ProfileController())
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
} }
themeCategories() themeCategories()

View File

@ -21,11 +21,11 @@
*/ */
package com.nextcloud.talk.models.json.userprofile package com.nextcloud.talk.models.json.userprofile
import android.os.Parcelable
import com.bluelinelabs.logansquare.annotation.JsonField import com.bluelinelabs.logansquare.annotation.JsonField
import com.bluelinelabs.logansquare.annotation.JsonObject import com.bluelinelabs.logansquare.annotation.JsonObject
import com.nextcloud.talk.controllers.ProfileController
import com.nextcloud.talk.models.json.converters.ScopeConverter import com.nextcloud.talk.models.json.converters.ScopeConverter
import android.os.Parcelable import com.nextcloud.talk.profile.ProfileActivity
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
@ -76,26 +76,26 @@ data class UserProfileData(
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
constructor() : this(null, null, null, null, null, null, null, null, null, null, null, null, null, null) constructor() : this(null, null, null, null, null, null, null, null, null, null, null, null, null, null)
fun getValueByField(field: ProfileController.Field?): String? { fun getValueByField(field: ProfileActivity.Field?): String? {
return when (field) { return when (field) {
ProfileController.Field.EMAIL -> email ProfileActivity.Field.EMAIL -> email
ProfileController.Field.DISPLAYNAME -> displayName ProfileActivity.Field.DISPLAYNAME -> displayName
ProfileController.Field.PHONE -> phone ProfileActivity.Field.PHONE -> phone
ProfileController.Field.ADDRESS -> address ProfileActivity.Field.ADDRESS -> address
ProfileController.Field.WEBSITE -> website ProfileActivity.Field.WEBSITE -> website
ProfileController.Field.TWITTER -> twitter ProfileActivity.Field.TWITTER -> twitter
else -> "" else -> ""
} }
} }
fun getScopeByField(field: ProfileController.Field?): Scope? { fun getScopeByField(field: ProfileActivity.Field?): Scope? {
return when (field) { return when (field) {
ProfileController.Field.EMAIL -> emailScope ProfileActivity.Field.EMAIL -> emailScope
ProfileController.Field.DISPLAYNAME -> displayNameScope ProfileActivity.Field.DISPLAYNAME -> displayNameScope
ProfileController.Field.PHONE -> phoneScope ProfileActivity.Field.PHONE -> phoneScope
ProfileController.Field.ADDRESS -> addressScope ProfileActivity.Field.ADDRESS -> addressScope
ProfileController.Field.WEBSITE -> websiteScope ProfileActivity.Field.WEBSITE -> websiteScope
ProfileController.Field.TWITTER -> twitterScope ProfileActivity.Field.TWITTER -> twitterScope
else -> null else -> null
} }
} }

View File

@ -19,13 +19,14 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.nextcloud.talk.controllers package com.nextcloud.talk.profile
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.drawable.ColorDrawable
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
@ -34,12 +35,12 @@ import android.text.TextWatcher
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.core.content.res.ResourcesCompat
import androidx.core.net.toFile import androidx.core.net.toFile
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -49,14 +50,12 @@ import com.github.dhaval2404.imagepicker.ImagePicker.Companion.getError
import com.github.dhaval2404.imagepicker.ImagePicker.Companion.with import com.github.dhaval2404.imagepicker.ImagePicker.Companion.with
import com.github.dhaval2404.imagepicker.constant.ImageProvider import com.github.dhaval2404.imagepicker.constant.ImageProvider
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.activities.TakePhotoActivity import com.nextcloud.talk.activities.TakePhotoActivity
import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.controllers.base.BaseController
import com.nextcloud.talk.controllers.util.viewBinding
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ControllerProfileBinding import com.nextcloud.talk.databinding.ActivityProfileBinding
import com.nextcloud.talk.databinding.UserInfoDetailsTableItemBinding import com.nextcloud.talk.databinding.UserInfoDetailsTableItemBinding
import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.models.json.userprofile.Scope import com.nextcloud.talk.models.json.userprofile.Scope
@ -95,8 +94,8 @@ import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
@Suppress("Detekt.TooManyFunctions") @Suppress("Detekt.TooManyFunctions")
class ProfileController : BaseController(R.layout.controller_profile) { class ProfileActivity : BaseActivity() {
private val binding: ControllerProfileBinding? by viewBinding(ControllerProfileBinding::bind) private lateinit var binding: ActivityProfileBinding
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -113,22 +112,119 @@ class ProfileController : BaseController(R.layout.controller_profile) {
private var userInfo: UserProfileData? = null private var userInfo: UserProfileData? = null
private var editableFields = ArrayList<String>() private var editableFields = ArrayList<String>()
override val title: String override fun onCreate(savedInstanceState: Bundle?) {
get() = super.onCreate(savedInstanceState)
resources!!.getString(R.string.nc_profile_personal_info_title) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
binding = ActivityProfileBinding.inflate(layoutInflater)
override fun onViewBound(view: View) { setupActionBar()
super.onViewBound(view) setupSystemColors()
sharedApplication!!.componentApplication.inject(this) setContentView(binding.root)
setHasOptionsMenu(true)
} }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onResume() {
super.onCreateOptionsMenu(menu, inflater) super.onResume()
inflater.inflate(R.menu.menu_profile, menu)
adapter = UserInfoAdapter(null, viewThemeUtils, this)
binding.userinfoList.adapter = adapter
binding.userinfoList.setItemViewCacheSize(DEFAULT_CACHE_SIZE)
currentUser = userManager.currentUser.blockingGet()
val credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
binding.avatarUpload.setOnClickListener { sendSelectLocalFileIntent() }
binding.avatarChoose.setOnClickListener { showBrowserScreen() }
binding.avatarCamera.setOnClickListener { checkPermissionAndTakePicture() }
binding.avatarDelete.setOnClickListener {
ncApi.deleteAvatar(
credentials,
ApiUtils.getUrlForTempAvatar(currentUser!!.baseUrl)
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
override fun onSubscribe(d: Disposable) {
// unused atm
}
override fun onNext(genericOverall: GenericOverall) {
DisplayUtils.loadAvatarImage(
currentUser,
binding.avatarImage,
true
)
}
override fun onError(e: Throwable) {
Log.e(TAG, "Failed to delete avatar", e)
}
override fun onComplete() {
// unused atm
}
})
}
binding.avatarImage.let { ViewCompat.setTransitionName(it, "userAvatar.transitionTag") }
ncApi.getUserProfile(credentials, ApiUtils.getUrlForUserProfile(currentUser!!.baseUrl))
.retry(DEFAULT_RETRIES)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<UserProfileOverall> {
override fun onSubscribe(d: Disposable) {
// unused atm
}
override fun onNext(userProfileOverall: UserProfileOverall) {
userInfo = userProfileOverall.ocs!!.data
showUserProfile()
}
override fun onError(e: Throwable) {
setErrorMessageForMultiList(
getString(R.string.userinfo_no_info_headline),
getString(R.string.userinfo_error_text),
R.drawable.ic_list_empty_error
)
}
override fun onComplete() {
// unused atm
}
})
colorIcons()
} }
override fun onPrepareOptionsMenu(menu: Menu) { private fun setupActionBar() {
setSupportActionBar(binding.profileToolbar)
binding.profileToolbar.setNavigationOnClickListener {
onBackPressed()
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent)))
supportActionBar?.title = context.getString(R.string.nc_profile_personal_info_title)
}
private fun setupSystemColors() {
DisplayUtils.applyColorToStatusBar(
this,
ResourcesCompat.getColor(
resources,
R.color.appbar,
null
)
)
DisplayUtils.applyColorToNavigationBar(
this.window,
ResourcesCompat.getColor(resources, R.color.bg_default, null)
)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.menu_profile, menu)
return true
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
super.onPrepareOptionsMenu(menu) super.onPrepareOptionsMenu(menu)
menu.findItem(R.id.edit).isVisible = editableFields.size > 0 menu.findItem(R.id.edit).isVisible = editableFields.size > 0
if (edit) { if (edit) {
@ -136,6 +232,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
} else { } else {
menu.findItem(R.id.edit).setTitle(R.string.edit) menu.findItem(R.id.edit).setTitle(R.string.edit)
} }
return true
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -146,11 +243,11 @@ class ProfileController : BaseController(R.layout.controller_profile) {
edit = !edit edit = !edit
if (edit) { if (edit) {
item.setTitle(R.string.save) item.setTitle(R.string.save)
binding?.emptyList?.root?.visibility = View.GONE binding.emptyList.root.visibility = View.GONE
binding?.userinfoList?.visibility = View.VISIBLE binding.userinfoList.visibility = View.VISIBLE
if (CapabilitiesUtilNew.isAvatarEndpointAvailable(currentUser!!)) { if (CapabilitiesUtilNew.isAvatarEndpointAvailable(currentUser!!)) {
// TODO later avatar can also be checked via user fields, for now it is in Talk capability // TODO later avatar can also be checked via user fields, for now it is in Talk capability
binding?.avatarButtons?.visibility = View.VISIBLE binding.avatarButtons.visibility = View.VISIBLE
} }
ncApi.getEditableUserProfileFields( ncApi.getEditableUserProfileFields(
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token), ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
@ -179,10 +276,10 @@ class ProfileController : BaseController(R.layout.controller_profile) {
}) })
} else { } else {
item.setTitle(R.string.edit) item.setTitle(R.string.edit)
binding?.avatarButtons?.visibility = View.INVISIBLE binding.avatarButtons.visibility = View.INVISIBLE
if (adapter!!.filteredDisplayList.isEmpty()) { if (adapter!!.filteredDisplayList.isEmpty()) {
binding?.emptyList?.root?.visibility = View.VISIBLE binding.emptyList.root.visibility = View.VISIBLE
binding?.userinfoList?.visibility = View.GONE binding.userinfoList.visibility = View.GONE
} }
} }
adapter!!.notifyDataSetChanged() adapter!!.notifyDataSetChanged()
@ -191,78 +288,8 @@ class ProfileController : BaseController(R.layout.controller_profile) {
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
override fun onAttach(view: View) {
super.onAttach(view)
adapter = UserInfoAdapter(null, viewThemeUtils, this)
binding?.userinfoList?.adapter = adapter
binding?.userinfoList?.setItemViewCacheSize(DEFAULT_CACHE_SIZE)
currentUser = userManager.currentUser.blockingGet()
val credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
binding?.avatarUpload?.setOnClickListener { sendSelectLocalFileIntent() }
binding?.avatarChoose?.setOnClickListener { showBrowserScreen() }
binding?.avatarCamera?.setOnClickListener { checkPermissionAndTakePicture() }
binding?.avatarDelete?.setOnClickListener {
ncApi.deleteAvatar(
credentials,
ApiUtils.getUrlForTempAvatar(currentUser!!.baseUrl)
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
override fun onSubscribe(d: Disposable) {
// unused atm
}
override fun onNext(genericOverall: GenericOverall) {
DisplayUtils.loadAvatarImage(
currentUser,
binding?.avatarImage,
true
)
}
override fun onError(e: Throwable) {
Log.e(TAG, "Failed to delete avatar", e)
}
override fun onComplete() {
// unused atm
}
})
}
binding?.avatarImage?.let { ViewCompat.setTransitionName(it, "userAvatar.transitionTag") }
ncApi.getUserProfile(credentials, ApiUtils.getUrlForUserProfile(currentUser!!.baseUrl))
.retry(DEFAULT_RETRIES)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<UserProfileOverall> {
override fun onSubscribe(d: Disposable) {
// unused atm
}
override fun onNext(userProfileOverall: UserProfileOverall) {
userInfo = userProfileOverall.ocs!!.data
showUserProfile()
}
override fun onError(e: Throwable) {
setErrorMessageForMultiList(
activity!!.getString(R.string.userinfo_no_info_headline),
activity!!.getString(R.string.userinfo_error_text),
R.drawable.ic_list_empty_error
)
}
override fun onComplete() {
// unused atm
}
})
colorIcons()
}
private fun colorIcons() { private fun colorIcons() {
binding?.let { binding.let {
viewThemeUtils.material.themeFAB(it.avatarChoose) viewThemeUtils.material.themeFAB(it.avatarChoose)
viewThemeUtils.material.themeFAB(it.avatarCamera) viewThemeUtils.material.themeFAB(it.avatarCamera)
viewThemeUtils.material.themeFAB(it.avatarUpload) viewThemeUtils.material.themeFAB(it.avatarUpload)
@ -281,17 +308,14 @@ class ProfileController : BaseController(R.layout.controller_profile) {
} }
private fun showUserProfile() { private fun showUserProfile() {
if (activity == null) {
return
}
if (currentUser!!.baseUrl != null) { if (currentUser!!.baseUrl != null) {
binding?.userinfoBaseurl?.text = Uri.parse(currentUser!!.baseUrl).host binding.userinfoBaseurl.text = Uri.parse(currentUser!!.baseUrl).host
} }
DisplayUtils.loadAvatarImage(currentUser, binding?.avatarImage, false) DisplayUtils.loadAvatarImage(currentUser, binding.avatarImage, false)
if (!TextUtils.isEmpty(userInfo?.displayName)) { if (!TextUtils.isEmpty(userInfo?.displayName)) {
binding?.userinfoFullName?.text = userInfo?.displayName binding.userinfoFullName.text = userInfo?.displayName
} }
binding?.loadingContent?.visibility = View.VISIBLE binding.loadingContent.visibility = View.VISIBLE
adapter!!.setData(createUserInfoDetails(userInfo)) adapter!!.setData(createUserInfoDetails(userInfo))
if (isAllEmpty( if (isAllEmpty(
arrayOf( arrayOf(
@ -304,18 +328,18 @@ class ProfileController : BaseController(R.layout.controller_profile) {
) )
) )
) { ) {
binding?.userinfoList?.visibility = View.GONE binding.userinfoList.visibility = View.GONE
binding?.loadingContent?.visibility = View.GONE binding.loadingContent.visibility = View.GONE
binding?.emptyList?.root?.visibility = View.VISIBLE binding.emptyList.root.visibility = View.VISIBLE
setErrorMessageForMultiList( setErrorMessageForMultiList(
activity!!.getString(R.string.userinfo_no_info_headline), getString(R.string.userinfo_no_info_headline),
activity!!.getString(R.string.userinfo_no_info_text), getString(R.string.userinfo_no_info_text),
R.drawable.ic_user R.drawable.ic_user
) )
} else { } else {
binding?.emptyList?.root?.visibility = View.GONE binding.emptyList.root.visibility = View.GONE
binding?.loadingContent?.visibility = View.GONE binding.loadingContent.visibility = View.GONE
binding?.userinfoList?.visibility = View.VISIBLE binding.userinfoList.visibility = View.VISIBLE
} }
// show edit button // show edit button
@ -333,7 +357,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
override fun onNext(userProfileFieldsOverall: UserProfileFieldsOverall) { override fun onNext(userProfileFieldsOverall: UserProfileFieldsOverall) {
editableFields = userProfileFieldsOverall.ocs!!.data!! editableFields = userProfileFieldsOverall.ocs!!.data!!
activity!!.invalidateOptionsMenu() invalidateOptionsMenu()
adapter!!.notifyDataSetChanged() adapter!!.notifyDataSetChanged()
} }
@ -351,17 +375,13 @@ class ProfileController : BaseController(R.layout.controller_profile) {
@Suppress("Detekt.TooGenericExceptionCaught") @Suppress("Detekt.TooGenericExceptionCaught")
private fun setErrorMessageForMultiList(headline: String, message: String, @DrawableRes errorResource: Int) { private fun setErrorMessageForMultiList(headline: String, message: String, @DrawableRes errorResource: Int) {
if (activity == null) { binding.emptyList.emptyListViewHeadline.text = headline
return binding.emptyList.emptyListViewText.text = message
} binding.emptyList.emptyListIcon.setImageResource(errorResource)
binding.emptyList.emptyListIcon.visibility = View.VISIBLE
binding?.emptyList?.emptyListViewHeadline?.text = headline binding.emptyList.emptyListViewText.visibility = View.VISIBLE
binding?.emptyList?.emptyListViewText?.text = message binding.userinfoList.visibility = View.GONE
binding?.emptyList?.emptyListIcon?.setImageResource(errorResource) binding.loadingContent.visibility = View.GONE
binding?.emptyList?.emptyListIcon?.visibility = View.VISIBLE
binding?.emptyList?.emptyListViewText?.visibility = View.VISIBLE
binding?.userinfoList?.visibility = View.GONE
binding?.loadingContent?.visibility = View.GONE
} }
@Suppress("Detekt.LongMethod") @Suppress("Detekt.LongMethod")
@ -483,7 +503,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
} }
private fun sendSelectLocalFileIntent() { private fun sendSelectLocalFileIntent() {
with(activity!!) with(this)
.provider(ImageProvider.GALLERY) .provider(ImageProvider.GALLERY)
.crop() .crop()
.cropSquare() .cropSquare()
@ -496,7 +516,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
val bundle = Bundle() val bundle = Bundle()
bundle.putString(KEY_MIME_TYPE_FILTER, IMAGE_PREFIX) bundle.putString(KEY_MIME_TYPE_FILTER, IMAGE_PREFIX)
val avatarIntent = Intent(activity, RemoteFileBrowserActivity::class.java) val avatarIntent = Intent(this, RemoteFileBrowserActivity::class.java)
avatarIntent.putExtras(bundle) avatarIntent.putExtras(bundle)
startActivityForResult(avatarIntent, REQUEST_CODE_SELECT_REMOTE_FILES) startActivityForResult(avatarIntent, REQUEST_CODE_SELECT_REMOTE_FILES)
@ -580,7 +600,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
} }
private fun openImageWithPicker(file: File) { private fun openImageWithPicker(file: File) {
with(activity!!) with(this)
.provider(ImageProvider.URI) .provider(ImageProvider.URI)
.crop() .crop()
.cropSquare() .cropSquare()
@ -591,6 +611,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
if (requestCode == REQUEST_CODE_IMAGE_PICKER) { if (requestCode == REQUEST_CODE_IMAGE_PICKER) {
val uri: Uri = data?.data!! val uri: Uri = data?.data!!
@ -608,7 +629,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
Log.w(TAG, "Unknown intent request code") Log.w(TAG, "Unknown intent request code")
} }
} else if (resultCode == ImagePicker.RESULT_ERROR) { } else if (resultCode == ImagePicker.RESULT_ERROR) {
Toast.makeText(activity, getError(data), Toast.LENGTH_SHORT).show() Toast.makeText(this, getError(data), Toast.LENGTH_SHORT).show()
} else { } else {
Log.i(TAG, "Task Cancelled") Log.i(TAG, "Task Cancelled")
} }
@ -704,7 +725,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
class UserInfoAdapter( class UserInfoAdapter(
displayList: List<UserInfoDetailsItem>?, displayList: List<UserInfoDetailsItem>?,
private val viewThemeUtils: ViewThemeUtils, private val viewThemeUtils: ViewThemeUtils,
private val controller: ProfileController private val controller: ProfileActivity
) : RecyclerView.Adapter<UserInfoAdapter.ViewHolder>() { ) : RecyclerView.Adapter<UserInfoAdapter.ViewHolder>() {
var displayList: List<UserInfoDetailsItem>? var displayList: List<UserInfoDetailsItem>?
var filteredDisplayList: MutableList<UserInfoDetailsItem> = LinkedList() var filteredDisplayList: MutableList<UserInfoDetailsItem> = LinkedList()
@ -764,7 +785,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
holder.binding.userInfoEditTextEdit.isCursorVisible = true holder.binding.userInfoEditTextEdit.isCursorVisible = true
holder.binding.scope.setOnClickListener { holder.binding.scope.setOnClickListener {
ScopeDialog( ScopeDialog(
controller.activity!!, holder.binding.scope.context,
this, this,
item.field, item.field,
holder.adapterPosition holder.adapterPosition
@ -827,7 +848,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
// nothing // nothing
} }
} }
holder.binding.scope.contentDescription = controller.activity!!.resources.getString( holder.binding.scope.contentDescription = holder.binding.scope.context.getString(
R.string.scope_toggle_description, R.string.scope_toggle_description,
item.hint item.hint
) )

View File

@ -31,17 +31,17 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.controllers.ProfileController
import com.nextcloud.talk.databinding.DialogScopeBinding import com.nextcloud.talk.databinding.DialogScopeBinding
import com.nextcloud.talk.models.json.userprofile.Scope import com.nextcloud.talk.models.json.userprofile.Scope
import com.nextcloud.talk.profile.ProfileActivity
import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.ui.theme.ViewThemeUtils
import javax.inject.Inject import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
class ScopeDialog( class ScopeDialog(
con: Context, con: Context,
private val userInfoAdapter: ProfileController.UserInfoAdapter, private val userInfoAdapter: ProfileActivity.UserInfoAdapter,
private val field: ProfileController.Field, private val field: ProfileActivity.Field,
private val position: Int private val position: Int
) : BottomSheetDialog(con) { ) : BottomSheetDialog(con) {
@ -61,7 +61,7 @@ class ScopeDialog(
viewThemeUtils.platform.themeDialog(dialogScopeBinding.root) viewThemeUtils.platform.themeDialog(dialogScopeBinding.root)
if (field == ProfileController.Field.DISPLAYNAME || field == ProfileController.Field.EMAIL) { if (field == ProfileActivity.Field.DISPLAYNAME || field == ProfileActivity.Field.EMAIL) {
dialogScopeBinding.scopePrivate.visibility = View.GONE dialogScopeBinding.scopePrivate.visibility = View.GONE
} }

View File

@ -25,6 +25,25 @@
android:background="@color/bg_default" android:background="@color/bg_default"
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/profile_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/profile_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/appbar"
android:theme="?attr/actionBarPopupTheme"
app:layout_scrollFlags="scroll|enterAlways"
app:navigationIconTint="@color/fontAppbar"
app:popupTheme="@style/appActionBarPopupMenu"
app:titleTextColor="@color/fontAppbar"
tools:title="@string/nc_profile_personal_info_title" />
</com.google.android.material.appbar.AppBarLayout>
<RelativeLayout <RelativeLayout
android:id="@+id/avatarContainer" android:id="@+id/avatarContainer"
android:layout_width="match_parent" android:layout_width="match_parent"