Merge pull request #2915 from nextcloud/refactoring/noid/convInfoAndContactsRemoveConductor

Replace Controller with Activity for conversationInfo and contacts
This commit is contained in:
Marcel Hibbe 2023-03-31 12:59:43 +02:00 committed by GitHub
commit c5d97175d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 422 additions and 356 deletions

View File

@ -210,6 +210,14 @@
android:name=".settings.SettingsActivity" android:name=".settings.SettingsActivity"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity
android:name=".conversation.info.ConversationInfoActivity"
android:theme="@style/AppTheme" />
<activity
android:name=".contacts.ContactsActivity"
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

@ -93,6 +93,19 @@ class MainActivity : BaseActivity(), ActionBarProvider {
router = Conductor.attachRouter(this, binding.controllerContainer, savedInstanceState) router = Conductor.attachRouter(this, binding.controllerContainer, savedInstanceState)
if (intent.getBooleanExtra(BundleKeys.KEY_OPEN_CHAT, false)) {
logRouterBackStack(router!!)
remapChatController(
router!!,
intent.getParcelableExtra<User>(KEY_USER_ENTITY)!!.id!!,
intent.getStringExtra(KEY_ROOM_TOKEN)!!,
intent.extras!!,
true,
true
)
logRouterBackStack(router!!)
}
if (intent.hasExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) { if (intent.hasExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) {
onNewIntent(intent) onNewIntent(intent)
} else if (!router!!.hasRootController()) { } else if (!router!!.hasRootController()) {

View File

@ -21,17 +21,18 @@
* 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.contacts
import android.app.SearchManager import android.app.SearchManager
import android.content.Context import android.content.Context
import android.content.Intent
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.graphics.drawable.ColorDrawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.text.InputType import android.text.InputType
import android.util.Log import android.util.Log
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.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
@ -44,14 +45,13 @@ import androidx.work.WorkManager
import autodagger.AutoInjector import autodagger.AutoInjector
import com.bluelinelabs.logansquare.LoganSquare import com.bluelinelabs.logansquare.LoganSquare
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.activities.MainActivity
import com.nextcloud.talk.adapters.items.ContactItem import com.nextcloud.talk.adapters.items.ContactItem
import com.nextcloud.talk.adapters.items.GenericTextHeaderItem import com.nextcloud.talk.adapters.items.GenericTextHeaderItem
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.bottomsheet.ConversationOperationEnum import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum
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.ControllerContactsRvBinding import com.nextcloud.talk.databinding.ControllerContactsRvBinding
import com.nextcloud.talk.events.OpenConversationEvent import com.nextcloud.talk.events.OpenConversationEvent
@ -66,9 +66,10 @@ import com.nextcloud.talk.models.json.participants.Participant
import com.nextcloud.talk.ui.dialog.ContactsBottomDialog import com.nextcloud.talk.ui.dialog.ContactsBottomDialog
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.bundle.BundleKeys import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_OPEN_CHAT
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import com.nextcloud.talk.utils.remapchat.ConductorRemapping
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.SelectableAdapter
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
@ -78,7 +79,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody import okhttp3.ResponseBody
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import org.parceler.Parcels import org.parceler.Parcels
@ -88,18 +88,15 @@ import java.util.Locale
import javax.inject.Inject import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
class ContactsController(args: Bundle) : class ContactsActivity :
BaseController(R.layout.controller_contacts_rv), BaseActivity(),
SearchView.OnQueryTextListener, SearchView.OnQueryTextListener,
FlexibleAdapter.OnItemClickListener { FlexibleAdapter.OnItemClickListener {
private val binding: ControllerContactsRvBinding? by viewBinding(ControllerContactsRvBinding::bind) private lateinit var binding: ControllerContactsRvBinding
@Inject @Inject
lateinit var userManager: UserManager lateinit var userManager: UserManager
@Inject
lateinit var eventBus: EventBus
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -126,18 +123,29 @@ class ContactsController(args: Bundle) :
private var conversationToken: String? = null private var conversationToken: String? = null
private var contactsBottomDialog: ContactsBottomDialog? = null private var contactsBottomDialog: ContactsBottomDialog? = null
init { override fun onCreate(savedInstanceState: Bundle?) {
setHasOptionsMenu(true) super.onCreate(savedInstanceState)
sharedApplication!!.componentApplication.inject(this) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
binding = ControllerContactsRvBinding.inflate(layoutInflater)
setupActionBar()
setupSystemColors()
setContentView(binding.root)
if (savedInstanceState != null) {
if (adapter != null) {
adapter?.onRestoreInstanceState(savedInstanceState)
}
}
existingParticipants = ArrayList() existingParticipants = ArrayList()
if (args.containsKey(BundleKeys.KEY_NEW_CONVERSATION)) { if (intent.hasExtra(BundleKeys.KEY_NEW_CONVERSATION)) {
isNewConversationView = true isNewConversationView = true
} else if (args.containsKey(BundleKeys.KEY_ADD_PARTICIPANTS)) { } else if (intent.hasExtra(BundleKeys.KEY_ADD_PARTICIPANTS)) {
isAddingParticipantsView = true isAddingParticipantsView = true
conversationToken = args.getString(BundleKeys.KEY_TOKEN) conversationToken = intent.getStringExtra(BundleKeys.KEY_TOKEN)
if (args.containsKey(BundleKeys.KEY_EXISTING_PARTICIPANTS)) { if (intent.hasExtra(BundleKeys.KEY_EXISTING_PARTICIPANTS)) {
existingParticipants = args.getStringArrayList(BundleKeys.KEY_EXISTING_PARTICIPANTS) existingParticipants = intent.getStringArrayListExtra(BundleKeys.KEY_EXISTING_PARTICIPANTS)
} }
} }
selectedUserIds = HashSet() selectedUserIds = HashSet()
@ -146,34 +154,31 @@ class ContactsController(args: Bundle) :
selectedCircleIds = HashSet() selectedCircleIds = HashSet()
} }
override fun onAttach(view: View) { override fun onResume() {
super.onAttach(view) super.onResume()
eventBus.register(this)
if (isNewConversationView) { if (isNewConversationView) {
toggleConversationPrivacyLayout(!isPublicCall) toggleConversationPrivacyLayout(!isPublicCall)
} }
if (isAddingParticipantsView) { if (isAddingParticipantsView) {
binding?.joinConversationViaLink?.joinConversationViaLinkRelativeLayout?.visibility = View.GONE binding.joinConversationViaLink.joinConversationViaLinkRelativeLayout.visibility = View.GONE
binding?.conversationPrivacyToggle?.callHeaderLayout?.visibility = View.GONE binding.conversationPrivacyToggle.callHeaderLayout.visibility = View.GONE
} else { } else {
binding?.joinConversationViaLink?.joinConversationViaLinkRelativeLayout?.setOnClickListener { binding.joinConversationViaLink.joinConversationViaLinkRelativeLayout.setOnClickListener {
joinConversationViaLink() joinConversationViaLink()
} }
binding?.conversationPrivacyToggle?.callHeaderLayout?.setOnClickListener { binding.conversationPrivacyToggle.callHeaderLayout.setOnClickListener {
toggleCallHeader() toggleCallHeader()
} }
} }
}
override fun onViewBound(view: View) {
super.onViewBound(view)
currentUser = userManager.currentUser.blockingGet() currentUser = userManager.currentUser.blockingGet()
if (currentUser != null) { if (currentUser != null) {
credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token) credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
} }
if (adapter == null) { if (adapter == null) {
contactItems = ArrayList<AbstractFlexibleItem<*>>() contactItems = ArrayList<AbstractFlexibleItem<*>>()
adapter = FlexibleAdapter(contactItems, activity, false) adapter = FlexibleAdapter(contactItems, this, false)
if (currentUser != null) { if (currentUser != null) {
fetchData() fetchData()
} }
@ -182,6 +187,91 @@ class ContactsController(args: Bundle) :
prepareViews() prepareViews()
} }
private fun setupActionBar() {
setSupportActionBar(binding.contactsToolbar)
binding.contactsToolbar.setNavigationOnClickListener {
onBackPressed()
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent)))
supportActionBar?.title = when {
isAddingParticipantsView -> {
resources!!.getString(R.string.nc_add_participants)
}
isNewConversationView -> {
resources!!.getString(R.string.nc_select_participants)
}
else -> {
resources!!.getString(R.string.nc_app_product_name)
}
}
}
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 onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
adapter?.onSaveInstanceState(bundle)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.menu_contacts, menu)
searchItem = menu.findItem(R.id.action_search)
doneMenuItem = menu.findItem(R.id.contacts_selection_done)
initSearchView()
return true
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
super.onPrepareOptionsMenu(menu)
if (searchItem != null) {
binding?.titleTextView?.let {
viewThemeUtils.platform.colorToolbarMenuIcon(
it.context,
searchItem!!
)
}
}
checkAndHandleDoneMenuItem()
if (adapter?.hasFilter() == true) {
searchItem!!.expandActionView()
searchView!!.setQuery(adapter!!.getFilter(String::class.java) as CharSequence, false)
}
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.home -> {
finish()
true
}
R.id.contacts_selection_done -> {
selectionDone()
true
}
else -> {
super.onOptionsItemSelected(item)
}
}
}
private fun setupAdapter() { private fun setupAdapter() {
adapter?.setNotifyChangeOfUnfilteredItems(true)?.mode = SelectableAdapter.Mode.MULTI adapter?.setNotifyChangeOfUnfilteredItems(true)?.mode = SelectableAdapter.Mode.MULTI
adapter?.setStickyHeaderElevation(HEADER_ELEVATION) adapter?.setStickyHeaderElevation(HEADER_ELEVATION)
@ -285,13 +375,13 @@ class ContactsController(args: Bundle) :
BundleKeys.KEY_ACTIVE_CONVERSATION, BundleKeys.KEY_ACTIVE_CONVERSATION,
Parcels.wrap(roomOverall.ocs!!.data!!) Parcels.wrap(roomOverall.ocs!!.data!!)
) )
ConductorRemapping.remapChatController(
router, // TODO: go directly to ChatActivity when conductor is removed
currentUser!!.id!!, bundle.putBoolean(KEY_OPEN_CHAT, true)
roomOverall.ocs!!.data!!.token!!, val intent = Intent(context, MainActivity::class.java)
bundle, intent.putExtras(bundle)
true intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
) startActivity(intent)
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
@ -330,72 +420,28 @@ class ContactsController(args: Bundle) :
AddParticipantsToConversation::class.java AddParticipantsToConversation::class.java
).setInputData(data.build()).build() ).setInputData(data.build()).build()
WorkManager.getInstance().enqueue(addParticipantsToConversationWorker) WorkManager.getInstance().enqueue(addParticipantsToConversationWorker)
router.popCurrentController() finish()
} }
private fun initSearchView() { private fun initSearchView() {
if (activity != null) { val searchManager: SearchManager? = getSystemService(Context.SEARCH_SERVICE) as SearchManager?
val searchManager: SearchManager? = activity?.getSystemService(Context.SEARCH_SERVICE) as SearchManager?
if (searchItem != null) {
searchView = MenuItemCompat.getActionView(searchItem) as SearchView
viewThemeUtils.talk.themeSearchView(searchView!!)
searchView!!.maxWidth = Int.MAX_VALUE
searchView!!.inputType = InputType.TYPE_TEXT_VARIATION_FILTER
var imeOptions: Int = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
appPreferences?.isKeyboardIncognito == true
) {
imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
}
searchView!!.imeOptions = imeOptions
searchView!!.queryHint = resources!!.getString(R.string.nc_search)
if (searchManager != null) {
searchView!!.setSearchableInfo(searchManager.getSearchableInfo(activity?.componentName))
}
searchView!!.setOnQueryTextListener(this)
}
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.home -> {
router.popCurrentController()
}
R.id.contacts_selection_done -> {
selectionDone()
true
}
else -> {
super.onOptionsItemSelected(item)
}
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.menu_contacts, menu)
searchItem = menu.findItem(R.id.action_search)
doneMenuItem = menu.findItem(R.id.contacts_selection_done)
initSearchView()
}
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
if (searchItem != null) { if (searchItem != null) {
binding?.titleTextView?.let { searchView = MenuItemCompat.getActionView(searchItem) as SearchView
viewThemeUtils.platform.colorToolbarMenuIcon( viewThemeUtils.talk.themeSearchView(searchView!!)
it.context, searchView!!.maxWidth = Int.MAX_VALUE
searchItem!! searchView!!.inputType = InputType.TYPE_TEXT_VARIATION_FILTER
) var imeOptions: Int = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
appPreferences?.isKeyboardIncognito == true
) {
imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
} }
} searchView!!.imeOptions = imeOptions
searchView!!.queryHint = resources!!.getString(R.string.nc_search)
checkAndHandleDoneMenuItem() if (searchManager != null) {
if (adapter?.hasFilter() == true) { searchView!!.setSearchableInfo(searchManager.getSearchableInfo(componentName))
searchItem!!.expandActionView() }
searchView!!.setQuery(adapter!!.getFilter(String::class.java) as CharSequence, false) searchView!!.setOnQueryTextListener(this)
} }
} }
@ -626,7 +672,7 @@ class ContactsController(args: Bundle) :
} }
private fun prepareViews() { private fun prepareViews() {
layoutManager = SmoothScrollLinearLayoutManager(activity) layoutManager = SmoothScrollLinearLayoutManager(this)
binding?.controllerGenericRv?.recyclerView?.layoutManager = layoutManager binding?.controllerGenericRv?.recyclerView?.layoutManager = layoutManager
binding?.controllerGenericRv?.recyclerView?.setHasFixedSize(true) binding?.controllerGenericRv?.recyclerView?.setHasFixedSize(true)
binding?.controllerGenericRv?.recyclerView?.adapter = adapter binding?.controllerGenericRv?.recyclerView?.adapter = adapter
@ -671,18 +717,6 @@ class ContactsController(args: Bundle) :
} }
} }
override fun onSaveViewState(view: View, outState: Bundle) {
adapter?.onSaveInstanceState(outState)
super.onSaveViewState(view, outState)
}
override fun onRestoreViewState(view: View, savedViewState: Bundle) {
super.onRestoreViewState(view, savedViewState)
if (adapter != null) {
adapter?.onRestoreInstanceState(savedViewState)
}
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
dispose(null) dispose(null)
@ -716,41 +750,33 @@ class ContactsController(args: Bundle) :
} }
} }
override val title: String
get() = when {
isAddingParticipantsView -> {
resources!!.getString(R.string.nc_add_participants)
}
isNewConversationView -> {
resources!!.getString(R.string.nc_select_participants)
}
else -> {
resources!!.getString(R.string.nc_app_product_name)
}
}
private fun prepareAndShowBottomSheetWithBundle(bundle: Bundle) { private fun prepareAndShowBottomSheetWithBundle(bundle: Bundle) {
// 11: create conversation-enter name for new conversation // 11: create conversation-enter name for new conversation
// 10: get&join room when enter link // 10: get&join room when enter link
contactsBottomDialog = ContactsBottomDialog(activity!!, bundle) contactsBottomDialog = ContactsBottomDialog(this, bundle)
contactsBottomDialog?.show() contactsBottomDialog?.show()
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(openConversationEvent: OpenConversationEvent) { fun onMessageEvent(openConversationEvent: OpenConversationEvent) {
ConductorRemapping.remapChatController( // ConductorRemapping.remapChatController(
router, // router,
currentUser!!.id!!, // currentUser!!.id!!,
openConversationEvent.conversation!!.token!!, // openConversationEvent.conversation!!.token!!,
openConversationEvent.bundle!!, // openConversationEvent.bundle!!,
true // true
) // )
contactsBottomDialog?.dismiss()
}
override fun onDetach(view: View) { // TODO: go directly to ChatActivity when conductor is removed
super.onDetach(view)
eventBus.unregister(this) var bundle = openConversationEvent.bundle!!
bundle.putBoolean(KEY_OPEN_CHAT, true)
val intent = Intent(context, MainActivity::class.java)
intent.putExtras(bundle)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)
contactsBottomDialog?.dismiss()
} }
override fun onItemClick(view: View, position: Int): Boolean { override fun onItemClick(view: View, position: Int): Boolean {
@ -812,23 +838,21 @@ class ContactsController(args: Bundle) :
} }
override fun onNext(roomOverall: RoomOverall) { override fun onNext(roomOverall: RoomOverall) {
if (activity != null) { val bundle = Bundle()
val bundle = Bundle() bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, currentUser)
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, currentUser) bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token) bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId) bundle.putParcelable(
bundle.putParcelable( BundleKeys.KEY_ACTIVE_CONVERSATION,
BundleKeys.KEY_ACTIVE_CONVERSATION, Parcels.wrap(roomOverall.ocs!!.data!!)
Parcels.wrap(roomOverall.ocs!!.data!!) )
)
ConductorRemapping.remapChatController( // TODO: go directly to ChatActivity when conductor is removed
router, bundle.putBoolean(KEY_OPEN_CHAT, true)
currentUser!!.id!!, val intent = Intent(context, MainActivity::class.java)
roomOverall.ocs!!.data!!.token!!, intent.putExtras(bundle)
bundle, intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
true startActivity(intent)
)
}
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {

View File

@ -126,6 +126,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.callbacks.MentionAutocompleteCallback import com.nextcloud.talk.callbacks.MentionAutocompleteCallback
import com.nextcloud.talk.controllers.base.BaseController import com.nextcloud.talk.controllers.base.BaseController
import com.nextcloud.talk.controllers.util.viewBinding import com.nextcloud.talk.controllers.util.viewBinding
import com.nextcloud.talk.conversation.info.ConversationInfoActivity
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ControllerChatBinding import com.nextcloud.talk.databinding.ControllerChatBinding
import com.nextcloud.talk.events.UserMentionClickEvent import com.nextcloud.talk.events.UserMentionClickEvent
@ -1778,11 +1779,10 @@ class ChatController(args: Bundle) :
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, conversationUser) bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, conversationUser)
bundle.putString(KEY_ROOM_TOKEN, roomToken) bundle.putString(KEY_ROOM_TOKEN, roomToken)
bundle.putBoolean(BundleKeys.KEY_ROOM_ONE_TO_ONE, isOneToOneConversation()) bundle.putBoolean(BundleKeys.KEY_ROOM_ONE_TO_ONE, isOneToOneConversation())
router.pushController(
RouterTransaction.with(ConversationInfoController(bundle)) val intent = Intent(activity, ConversationInfoActivity::class.java)
.pushChangeHandler(HorizontalChangeHandler()) intent.putExtras(bundle)
.popChangeHandler(HorizontalChangeHandler()) activity!!.startActivity(intent)
)
} }
private fun setupMentionAutocomplete() { private fun setupMentionAutocomplete() {

View File

@ -61,7 +61,6 @@ import coil.request.ImageRequest
import coil.target.Target import coil.target.Target
import coil.transform.CircleCropTransformation import coil.transform.CircleCropTransformation
import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
@ -76,6 +75,7 @@ import com.nextcloud.talk.adapters.items.MessagesTextHeaderItem
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.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.contacts.ContactsActivity
import com.nextcloud.talk.controllers.base.BaseController import com.nextcloud.talk.controllers.base.BaseController
import com.nextcloud.talk.controllers.util.viewBinding import com.nextcloud.talk.controllers.util.viewBinding
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
@ -767,13 +767,9 @@ class ConversationsListController(bundle: Bundle) :
conversation.type === Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL conversation.type === Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
private fun showNewConversationsScreen() { private fun showNewConversationsScreen() {
val bundle = Bundle() val intent = Intent(context, ContactsActivity::class.java)
bundle.putBoolean(KEY_NEW_CONVERSATION, true) intent.putExtra(KEY_NEW_CONVERSATION, true)
router.pushController( startActivity(intent)
RouterTransaction.with(ContactsController(bundle))
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
} }
private fun dispose(disposable: Disposable?) { private fun dispose(disposable: Disposable?) {

View File

@ -5,7 +5,7 @@
* @author Andy Scherzinger * @author Andy Scherzinger
* @author Tim Krüger * @author Tim Krüger
* @author Marcel Hibbe * @author Marcel Hibbe
* Copyright (C) 2022 Marcel Hibbe (dev@mhibbe.de) * Copyright (C) 2022-2023 Marcel Hibbe (dev@mhibbe.de)
* Copyright (C) 2021-2022 Tim Krüger <t@timkrueger.me> * Copyright (C) 2021-2022 Tim Krüger <t@timkrueger.me>
* Copyright (C) 2021 Andy Scherzinger (info@andy-scherzinger.de) * Copyright (C) 2021 Andy Scherzinger (info@andy-scherzinger.de)
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com> * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
@ -24,21 +24,22 @@
* 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.conversation.info
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Intent import android.content.Intent
import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable import android.os.Parcelable
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.MenuItem
import android.view.View import android.view.View
import android.view.View.GONE import android.view.View.GONE
import android.view.View.VISIBLE import android.view.View.VISIBLE
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.SwitchCompat import androidx.appcompat.widget.SwitchCompat
import androidx.core.content.res.ResourcesCompat
import androidx.work.Data import androidx.work.Data
import androidx.work.OneTimeWorkRequest import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager import androidx.work.WorkManager
@ -47,18 +48,16 @@ import com.afollestad.materialdialogs.LayoutMode.WRAP_CONTENT
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.bottomsheets.BottomSheet import com.afollestad.materialdialogs.bottomsheets.BottomSheet
import com.afollestad.materialdialogs.datetime.dateTimePicker import com.afollestad.materialdialogs.datetime.dateTimePicker
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.activities.MainActivity
import com.nextcloud.talk.adapters.items.ParticipantItem import com.nextcloud.talk.adapters.items.ParticipantItem
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.controllers.base.BaseController import com.nextcloud.talk.contacts.ContactsActivity
import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage
import com.nextcloud.talk.controllers.bottomsheet.items.listItemsWithImage import com.nextcloud.talk.controllers.bottomsheet.items.listItemsWithImage
import com.nextcloud.talk.controllers.util.viewBinding
import com.nextcloud.talk.conversation.info.GuestAccessHelper
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ControllerConversationInfoBinding import com.nextcloud.talk.databinding.ControllerConversationInfoBinding
import com.nextcloud.talk.events.EventStatus import com.nextcloud.talk.events.EventStatus
@ -82,6 +81,7 @@ import com.nextcloud.talk.shareditems.activities.SharedItemsActivity
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DateConstants import com.nextcloud.talk.utils.DateConstants
import com.nextcloud.talk.utils.DateUtils import com.nextcloud.talk.utils.DateUtils
import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import com.nextcloud.talk.utils.preferences.preferencestorage.DatabaseStorageModule import com.nextcloud.talk.utils.preferences.preferencestorage.DatabaseStorageModule
@ -91,7 +91,6 @@ import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import java.util.Calendar import java.util.Calendar
@ -100,14 +99,11 @@ import java.util.Locale
import javax.inject.Inject import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
class ConversationInfoController(args: Bundle) : class ConversationInfoActivity :
BaseController( BaseActivity(),
R.layout.controller_conversation_info,
args
),
FlexibleAdapter.OnItemClickListener { FlexibleAdapter.OnItemClickListener {
private val binding: ControllerConversationInfoBinding? by viewBinding(ControllerConversationInfoBinding::bind) private lateinit var binding: ControllerConversationInfoBinding
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -115,16 +111,13 @@ class ConversationInfoController(args: Bundle) :
@Inject @Inject
lateinit var conversationsRepository: ConversationsRepository lateinit var conversationsRepository: ConversationsRepository
@Inject
lateinit var eventBus: EventBus
@Inject @Inject
lateinit var dateUtils: DateUtils lateinit var dateUtils: DateUtils
private val conversationToken: String? private lateinit var conversationToken: String
private val conversationUser: User? private lateinit var conversationUser: User
private val hasAvatarSpacing: Boolean private var hasAvatarSpacing: Boolean = false
private val credentials: String? private lateinit var credentials: String
private var roomDisposable: Disposable? = null private var roomDisposable: Disposable? = null
private var participantsDisposable: Disposable? = null private var participantsDisposable: Disposable? = null
@ -146,68 +139,97 @@ class ConversationInfoController(args: Bundle) :
return null return null
} }
init { override fun onCreate(savedInstanceState: Bundle?) {
setHasOptionsMenu(true) super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
conversationUser = args.getParcelable(BundleKeys.KEY_USER_ENTITY)
conversationToken = args.getString(BundleKeys.KEY_ROOM_TOKEN) binding = ControllerConversationInfoBinding.inflate(layoutInflater)
hasAvatarSpacing = args.getBoolean(BundleKeys.KEY_ROOM_ONE_TO_ONE, false) setupActionBar()
credentials = ApiUtils.getCredentials(conversationUser!!.username, conversationUser.token) setupSystemColors()
setContentView(binding.root)
conversationUser = intent.getParcelableExtra(BundleKeys.KEY_USER_ENTITY)!!
conversationToken = intent.getStringExtra(BundleKeys.KEY_ROOM_TOKEN)!!
hasAvatarSpacing = intent.getBooleanExtra(BundleKeys.KEY_ROOM_ONE_TO_ONE, false)
credentials = ApiUtils.getCredentials(conversationUser.username, conversationUser.token)
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onResume() {
when (item.itemId) { super.onResume()
android.R.id.home -> {
router.popCurrentController()
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
override fun onAttach(view: View) {
super.onAttach(view)
eventBus.register(this)
if (databaseStorageModule == null) { if (databaseStorageModule == null) {
databaseStorageModule = DatabaseStorageModule(conversationUser!!, conversationToken) databaseStorageModule = DatabaseStorageModule(conversationUser, conversationToken)
} }
binding?.notificationSettingsView?.notificationSettings?.setStorageModule(databaseStorageModule) binding.notificationSettingsView.notificationSettings.setStorageModule(databaseStorageModule)
binding?.webinarInfoView?.webinarSettings?.setStorageModule(databaseStorageModule) binding.webinarInfoView.webinarSettings.setStorageModule(databaseStorageModule)
binding?.guestAccessView?.guestAccessSettings?.setStorageModule(databaseStorageModule) binding.guestAccessView.guestAccessSettings.setStorageModule(databaseStorageModule)
binding?.deleteConversationAction?.setOnClickListener { showDeleteConversationDialog() } binding.deleteConversationAction.setOnClickListener { showDeleteConversationDialog() }
binding?.leaveConversationAction?.setOnClickListener { leaveConversation() } binding.leaveConversationAction.setOnClickListener { leaveConversation() }
binding?.clearConversationHistory?.setOnClickListener { showClearHistoryDialog() } binding.clearConversationHistory.setOnClickListener { showClearHistoryDialog() }
binding?.addParticipantsAction?.setOnClickListener { addParticipants() } binding.addParticipantsAction.setOnClickListener { addParticipants() }
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "rich-object-list-media")) { if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "rich-object-list-media")) {
binding?.showSharedItemsAction?.setOnClickListener { showSharedItems() } binding.showSharedItemsAction.setOnClickListener { showSharedItems() }
} else { } else {
binding?.categorySharedItems?.visibility = GONE binding.categorySharedItems.visibility = GONE
} }
fetchRoomInfo() fetchRoomInfo()
themeCategories() themeCategories()
themeSwitchPreferences() themeSwitchPreferences()
binding.addParticipantsAction.visibility = GONE
binding.progressBar.let { viewThemeUtils.platform.colorCircularProgressBar(it) }
}
private fun setupActionBar() {
setSupportActionBar(binding.conversationInfoToolbar)
binding.conversationInfoToolbar.setNavigationOnClickListener {
onBackPressed()
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent)))
supportActionBar?.title = if (hasAvatarSpacing) {
" " + resources!!.getString(R.string.nc_conversation_menu_conversation_info)
} else {
resources!!.getString(R.string.nc_conversation_menu_conversation_info)
}
}
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)
)
} }
private fun themeSwitchPreferences() { private fun themeSwitchPreferences() {
binding?.run { binding.run {
listOf( listOf(
binding?.webinarInfoView?.conversationInfoLobby!!, binding.webinarInfoView.conversationInfoLobby,
binding?.notificationSettingsView?.callNotifications!!, binding.notificationSettingsView.callNotifications,
binding?.notificationSettingsView?.conversationInfoPriorityConversation!!, binding.notificationSettingsView.conversationInfoPriorityConversation,
binding?.guestAccessView?.guestAccessAllowSwitch!!, binding.guestAccessView.guestAccessAllowSwitch,
binding?.guestAccessView?.guestAccessPasswordSwitch!! binding.guestAccessView.guestAccessPasswordSwitch
).forEach(viewThemeUtils.talk::colorSwitchPreference) ).forEach(viewThemeUtils.talk::colorSwitchPreference)
} }
} }
private fun themeCategories() { private fun themeCategories() {
binding?.run { binding.run {
listOf( listOf(
conversationInfoName, conversationInfoName,
conversationDescription, conversationDescription,
@ -216,30 +238,22 @@ class ConversationInfoController(args: Bundle) :
ownOptions, ownOptions,
categorySharedItems, categorySharedItems,
categoryConversationSettings, categoryConversationSettings,
binding?.guestAccessView?.guestAccessCategory!!, binding.guestAccessView.guestAccessCategory,
binding?.webinarInfoView?.conversationInfoWebinar!!, binding.webinarInfoView.conversationInfoWebinar,
binding?.notificationSettingsView?.notificationSettingsCategory!! binding.notificationSettingsView.notificationSettingsCategory
).forEach(viewThemeUtils.talk::colorPreferenceCategory) ).forEach(viewThemeUtils.talk::colorPreferenceCategory)
} }
} }
private fun showSharedItems() { private fun showSharedItems() {
val intent = Intent(activity, SharedItemsActivity::class.java) val intent = Intent(this, SharedItemsActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.putExtra(BundleKeys.KEY_CONVERSATION_NAME, conversation?.displayName) intent.putExtra(BundleKeys.KEY_CONVERSATION_NAME, conversation?.displayName)
intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, conversationToken) intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, conversationToken)
intent.putExtra(BundleKeys.KEY_USER_ENTITY, conversationUser as Parcelable) intent.putExtra(BundleKeys.KEY_USER_ENTITY, conversationUser as Parcelable)
intent.putExtra(SharedItemsActivity.KEY_USER_IS_OWNER_OR_MODERATOR, conversation?.isParticipantOwnerOrModerator) intent.putExtra(SharedItemsActivity.KEY_USER_IS_OWNER_OR_MODERATOR, conversation?.isParticipantOwnerOrModerator)
activity!!.startActivity(intent) startActivity(intent)
}
override fun onViewBound(view: View) {
super.onViewBound(view)
binding?.addParticipantsAction?.visibility = GONE
binding?.progressBar?.let { viewThemeUtils.platform.colorCircularProgressBar(it) }
} }
private fun setupWebinaryView() { private fun setupWebinaryView() {
@ -257,7 +271,7 @@ class ConversationInfoController(args: Bundle) :
reconfigureLobbyTimerView() reconfigureLobbyTimerView()
binding?.webinarInfoView?.startTimePreferences?.setOnClickListener { binding?.webinarInfoView?.startTimePreferences?.setOnClickListener {
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show { MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
val currentTimeCalendar = Calendar.getInstance() val currentTimeCalendar = Calendar.getInstance()
if (conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != 0L) { if (conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != 0L) {
currentTimeCalendar.timeInMillis = conversation!!.lobbyTimer!! * DateConstants.SECOND_DIVIDER currentTimeCalendar.timeInMillis = conversation!!.lobbyTimer!! * DateConstants.SECOND_DIVIDER
@ -345,7 +359,7 @@ class ConversationInfoController(args: Bundle) :
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
ncApi.setLobbyForConversation( ncApi.setLobbyForConversation(
ApiUtils.getCredentials(conversationUser!!.username, conversationUser.token), ApiUtils.getCredentials(conversationUser.username, conversationUser.token),
ApiUtils.getUrlForRoomWebinaryLobby(apiVersion, conversationUser.baseUrl, conversation!!.token), ApiUtils.getUrlForRoomWebinaryLobby(apiVersion, conversationUser.baseUrl, conversation!!.token),
state, state,
conversation!!.lobbyTimer conversation!!.lobbyTimer
@ -376,54 +390,45 @@ class ConversationInfoController(args: Bundle) :
getListOfParticipants() getListOfParticipants()
} }
override fun onDetach(view: View) {
super.onDetach(view)
eventBus.unregister(this)
}
private fun showDeleteConversationDialog() { private fun showDeleteConversationDialog() {
if (activity != null) { binding.conversationInfoName.let {
binding?.conversationInfoName?.let { val dialogBuilder = MaterialAlertDialogBuilder(it.context)
val dialogBuilder = MaterialAlertDialogBuilder(it.context) .setIcon(
.setIcon( viewThemeUtils.dialog.colorMaterialAlertDialogIcon(
viewThemeUtils.dialog.colorMaterialAlertDialogIcon( context,
context, R.drawable.ic_delete_black_24dp
R.drawable.ic_delete_black_24dp
)
) )
.setTitle(R.string.nc_delete_call)
.setMessage(R.string.nc_delete_conversation_more)
.setPositiveButton(R.string.nc_delete) { _, _ ->
deleteConversation()
}
.setNegativeButton(R.string.nc_cancel) { _, _ ->
// unused atm
}
viewThemeUtils.dialog
.colorMaterialAlertDialogBackground(it.context, dialogBuilder)
val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE),
dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
) )
} .setTitle(R.string.nc_delete_call)
.setMessage(R.string.nc_delete_conversation_more)
.setPositiveButton(R.string.nc_delete) { _, _ ->
deleteConversation()
}
.setNegativeButton(R.string.nc_cancel) { _, _ ->
// unused atm
}
viewThemeUtils.dialog
.colorMaterialAlertDialogBackground(it.context, dialogBuilder)
val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE),
dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
)
} }
} }
private fun setupAdapter() { private fun setupAdapter() {
if (activity != null) { if (adapter == null) {
if (adapter == null) { adapter = FlexibleAdapter(userItems, this, true)
adapter = FlexibleAdapter(userItems, activity, true)
}
val layoutManager = SmoothScrollLinearLayoutManager(activity)
binding?.recyclerView?.layoutManager = layoutManager
binding?.recyclerView?.setHasFixedSize(true)
binding?.recyclerView?.adapter = adapter
adapter!!.addListener(this)
} }
val layoutManager = SmoothScrollLinearLayoutManager(this)
binding.recyclerView.layoutManager = layoutManager
binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.adapter = adapter
binding.recyclerView.isNestedScrollingEnabled = false
adapter!!.addListener(this)
} }
private fun handleParticipants(participants: List<Participant>) { private fun handleParticipants(participants: List<Participant>) {
@ -435,7 +440,7 @@ class ConversationInfoController(args: Bundle) :
for (i in participants.indices) { for (i in participants.indices) {
participant = participants[i] participant = participants[i]
userItem = ParticipantItem(router.activity, participant, conversationUser, viewThemeUtils) userItem = ParticipantItem(this, participant, conversationUser, viewThemeUtils)
if (participant.sessionId != null) { if (participant.sessionId != null) {
userItem.isOnline = !participant.sessionId.equals("0") userItem.isOnline = !participant.sessionId.equals("0")
} else { } else {
@ -461,18 +466,10 @@ class ConversationInfoController(args: Bundle) :
setupAdapter() setupAdapter()
binding?.participantsListCategory?.visibility = VISIBLE binding.participantsListCategory?.visibility = VISIBLE
adapter!!.updateDataSet(userItems) adapter!!.updateDataSet(userItems)
} }
override val title: String
get() =
if (hasAvatarSpacing) {
" " + resources!!.getString(R.string.nc_conversation_menu_conversation_info)
} else {
resources!!.getString(R.string.nc_conversation_menu_conversation_info)
}
private fun getListOfParticipants() { private fun getListOfParticipants() {
var apiVersion = 1 var apiVersion = 1
// FIXME Fix API checking with guests? // FIXME Fix API checking with guests?
@ -528,19 +525,9 @@ class ConversationInfoController(args: Bundle) :
bundle.putStringArrayList(BundleKeys.KEY_EXISTING_PARTICIPANTS, existingParticipantsId) bundle.putStringArrayList(BundleKeys.KEY_EXISTING_PARTICIPANTS, existingParticipantsId)
bundle.putString(BundleKeys.KEY_TOKEN, conversation!!.token) bundle.putString(BundleKeys.KEY_TOKEN, conversation!!.token)
router.pushController( val intent = Intent(this, ContactsActivity::class.java)
( intent.putExtras(bundle)
RouterTransaction.with( startActivity(intent)
ContactsController(bundle)
)
.pushChangeHandler(
HorizontalChangeHandler()
)
.popChangeHandler(
HorizontalChangeHandler()
)
)
)
} }
private fun leaveConversation() { private fun leaveConversation() {
@ -551,37 +538,38 @@ class ConversationInfoController(args: Bundle) :
.java .java
).setInputData(it).build() ).setInputData(it).build()
) )
router.popToRoot()
val intent = Intent(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)
} }
} }
private fun showClearHistoryDialog() { private fun showClearHistoryDialog() {
if (activity != null) { binding.conversationInfoName.context.let {
binding?.conversationInfoName?.context?.let { val dialogBuilder = MaterialAlertDialogBuilder(it)
val dialogBuilder = MaterialAlertDialogBuilder(it) .setIcon(
.setIcon( viewThemeUtils.dialog.colorMaterialAlertDialogIcon(
viewThemeUtils.dialog.colorMaterialAlertDialogIcon( context,
context, R.drawable.ic_delete_black_24dp
R.drawable.ic_delete_black_24dp
)
) )
.setTitle(R.string.nc_clear_history)
.setMessage(R.string.nc_clear_history_warning)
.setPositiveButton(R.string.nc_delete_all) { _, _ ->
clearHistory()
}
.setNegativeButton(R.string.nc_cancel) { _, _ ->
// unused atm
}
viewThemeUtils.dialog
.colorMaterialAlertDialogBackground(it, dialogBuilder)
val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE),
dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
) )
} .setTitle(R.string.nc_clear_history)
.setMessage(R.string.nc_clear_history_warning)
.setPositiveButton(R.string.nc_delete_all) { _, _ ->
clearHistory()
}
.setNegativeButton(R.string.nc_cancel) { _, _ ->
// unused atm
}
viewThemeUtils.dialog
.colorMaterialAlertDialogBackground(it, dialogBuilder)
val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE),
dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
)
} }
} }
@ -590,7 +578,7 @@ class ConversationInfoController(args: Bundle) :
ncApi.clearChatHistory( ncApi.clearChatHistory(
credentials, credentials,
ApiUtils.getUrlForChat(apiVersion, conversationUser!!.baseUrl, conversationToken) ApiUtils.getUrlForChat(apiVersion, conversationUser.baseUrl, conversationToken)
) )
?.subscribeOn(Schedulers.io()) ?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread()) ?.observeOn(AndroidSchedulers.mainThread())
@ -622,7 +610,9 @@ class ConversationInfoController(args: Bundle) :
DeleteConversationWorker::class.java DeleteConversationWorker::class.java
).setInputData(it).build() ).setInputData(it).build()
) )
router.popToRoot() val intent = Intent(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)
} }
} }
@ -659,7 +649,7 @@ class ConversationInfoController(args: Bundle) :
binding?.clearConversationHistory?.visibility = GONE binding?.clearConversationHistory?.visibility = GONE
} }
if (isAttached && (!isBeingDestroyed || !isDestroyed)) { if (!isDestroyed) {
binding?.ownOptions?.visibility = VISIBLE binding?.ownOptions?.visibility = VISIBLE
setupWebinaryView() setupWebinaryView()
@ -706,7 +696,7 @@ class ConversationInfoController(args: Bundle) :
binding?.let { binding?.let {
GuestAccessHelper( GuestAccessHelper(
this@ConversationInfoController, this@ConversationInfoActivity,
it, it,
conversation!!, conversation!!,
conversationUser conversationUser
@ -882,7 +872,7 @@ class ConversationInfoController(args: Bundle) :
credentials, credentials,
ApiUtils.getUrlForRoomModerators( ApiUtils.getUrlForRoomModerators(
apiVersion, apiVersion,
conversationUser!!.baseUrl, conversationUser.baseUrl,
conversation!!.token conversation!!.token
), ),
participant.userId participant.userId
@ -895,7 +885,7 @@ class ConversationInfoController(args: Bundle) :
credentials, credentials,
ApiUtils.getUrlForRoomModerators( ApiUtils.getUrlForRoomModerators(
apiVersion, apiVersion,
conversationUser!!.baseUrl, conversationUser.baseUrl,
conversation!!.token conversation!!.token
), ),
participant.userId participant.userId
@ -912,7 +902,7 @@ class ConversationInfoController(args: Bundle) :
credentials, credentials,
ApiUtils.getUrlForAttendees( ApiUtils.getUrlForAttendees(
apiVersion, apiVersion,
conversationUser!!.baseUrl, conversationUser.baseUrl,
conversation!!.token conversation!!.token
), ),
participant.attendeeId participant.attendeeId
@ -944,7 +934,7 @@ class ConversationInfoController(args: Bundle) :
ncApi.removeParticipantFromConversation( ncApi.removeParticipantFromConversation(
credentials, credentials,
ApiUtils.getUrlForRemovingParticipantFromConversation( ApiUtils.getUrlForRemovingParticipantFromConversation(
conversationUser!!.baseUrl, conversationUser.baseUrl,
conversation!!.token, conversation!!.token,
true true
), ),
@ -974,7 +964,7 @@ class ConversationInfoController(args: Bundle) :
ncApi.removeParticipantFromConversation( ncApi.removeParticipantFromConversation(
credentials, credentials,
ApiUtils.getUrlForRemovingParticipantFromConversation( ApiUtils.getUrlForRemovingParticipantFromConversation(
conversationUser!!.baseUrl, conversationUser.baseUrl,
conversation!!.token, conversation!!.token,
false false
), ),
@ -1005,7 +995,7 @@ class ConversationInfoController(args: Bundle) :
} }
override fun onItemClick(view: View?, position: Int): Boolean { override fun onItemClick(view: View?, position: Int): Boolean {
if (!conversation!!.canModerate(conversationUser!!)) { if (!conversation!!.canModerate(conversationUser)) {
return true return true
} }
@ -1022,7 +1012,7 @@ class ConversationInfoController(args: Bundle) :
context.getString(R.string.nc_attendee_pin, participant.attendeePin) context.getString(R.string.nc_attendee_pin, participant.attendeePin)
) )
) )
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show { MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
cornerRadius(res = R.dimen.corner_radius) cornerRadius(res = R.dimen.corner_radius)
title(text = participant.displayName) title(text = participant.displayName)
@ -1048,7 +1038,7 @@ class ConversationInfoController(args: Bundle) :
context.getString(R.string.nc_remove_group_and_members) context.getString(R.string.nc_remove_group_and_members)
) )
) )
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show { MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
cornerRadius(res = R.dimen.corner_radius) cornerRadius(res = R.dimen.corner_radius)
title(text = participant.displayName) title(text = participant.displayName)
@ -1068,7 +1058,7 @@ class ConversationInfoController(args: Bundle) :
context.getString(R.string.nc_remove_circle_and_members) context.getString(R.string.nc_remove_circle_and_members)
) )
) )
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show { MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
cornerRadius(res = R.dimen.corner_radius) cornerRadius(res = R.dimen.corner_radius)
title(text = participant.displayName) title(text = participant.displayName)
@ -1119,7 +1109,7 @@ class ConversationInfoController(args: Bundle) :
} }
if (items.isNotEmpty()) { if (items.isNotEmpty()) {
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show { MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
cornerRadius(res = R.dimen.corner_radius) cornerRadius(res = R.dimen.corner_radius)
title(text = participant.displayName) title(text = participant.displayName)

View File

@ -10,7 +10,6 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.SwitchCompat import androidx.appcompat.widget.SwitchCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.controllers.ConversationInfoController
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ControllerConversationInfoBinding import com.nextcloud.talk.databinding.ControllerConversationInfoBinding
import com.nextcloud.talk.databinding.DialogPasswordBinding import com.nextcloud.talk.databinding.DialogPasswordBinding
@ -24,16 +23,15 @@ import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
class GuestAccessHelper( class GuestAccessHelper(
controller: ConversationInfoController, private val activity: ConversationInfoActivity,
private val binding: ControllerConversationInfoBinding, private val binding: ControllerConversationInfoBinding,
private val conversation: Conversation, private val conversation: Conversation,
private val conversationUser: User private val conversationUser: User
) { ) {
private val activity = controller.activity!! private val conversationsRepository = activity.conversationsRepository
private val conversationsRepository = controller.conversationsRepository private val viewThemeUtils = activity.viewThemeUtils
private val viewThemeUtils = controller.viewThemeUtils private val context = activity.context
private val context = controller.context
fun setupGuestAccess() { fun setupGuestAccess() {
val guestAccessAllowSwitch = ( val guestAccessAllowSwitch = (

View File

@ -86,4 +86,5 @@ object BundleKeys {
const val KEY_DISMISS_RECORDING_URL = "KEY_DISMISS_RECORDING_URL" const val KEY_DISMISS_RECORDING_URL = "KEY_DISMISS_RECORDING_URL"
const val KEY_SHARE_RECORDING_TO_CHAT_URL = "KEY_SHARE_RECORDING_TO_CHAT_URL" const val KEY_SHARE_RECORDING_TO_CHAT_URL = "KEY_SHARE_RECORDING_TO_CHAT_URL"
const val KEY_GEOCODING_RESULT = "KEY_GEOCODING_RESULT" const val KEY_GEOCODING_RESULT = "KEY_GEOCODING_RESULT"
const val KEY_OPEN_CHAT = "KEY_OPEN_CHAT" // just temporarily used until conductor is deleted
} }

View File

@ -19,11 +19,29 @@
--> -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:animateLayoutChanges="true"> android:animateLayoutChanges="true">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/contacts_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/contacts_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_app_product_name" />
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout <LinearLayout
android:id="@+id/loading_content" android:id="@+id/loading_content"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -6,7 +6,7 @@
~ @author Marcel Hibbe ~ @author Marcel Hibbe
~ @author Tim Krüger ~ @author Tim Krüger
~ Copyright (C) 2022 Tim Krüger <t@timkrueger.me> ~ Copyright (C) 2022 Tim Krüger <t@timkrueger.me>
~ Copyright (C) 2022 Marcel Hibbe <dev@mhibbe.de> ~ Copyright (C) 2022-2023 Marcel Hibbe <dev@mhibbe.de>
~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de> ~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com> ~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
~ ~
@ -24,13 +24,31 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:apc="http://schemas.android.com/apk/res-auto" xmlns:apc="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical">
tools:background="@color/white">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/conversation_info_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/conversation_info_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_app_product_name" />
</com.google.android.material.appbar.AppBarLayout>
<ProgressBar <ProgressBar
android:id="@+id/progressBar" android:id="@+id/progressBar"
@ -279,4 +297,4 @@
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
</RelativeLayout> </LinearLayout>