WIP. Replace Controller with Activity for ConversationList

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2023-04-06 14:47:51 +02:00 committed by Andy Scherzinger
parent b975e8e4bd
commit aa1e93db05
No known key found for this signature in database
GPG Key ID: 6CADC7E3523C308B
12 changed files with 621 additions and 544 deletions

View File

@ -224,6 +224,10 @@
android:launchMode="singleInstance"
android:screenOrientation="portrait" />
<activity
android:name=".conversationlist.ConversationsListActivity"
android:theme="@style/AppTheme" />
<receiver android:name=".receivers.PackageReplacedReceiver"
android:exported="false">
<intent-filter>

View File

@ -48,6 +48,10 @@ import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
open class BaseActivity : AppCompatActivity() {
enum class AppBarLayoutType {
TOOLBAR, SEARCH_BAR, EMPTY
}
@Inject
lateinit var eventBus: EventBus
@ -60,6 +64,9 @@ open class BaseActivity : AppCompatActivity() {
@Inject
lateinit var context: Context
open val appBarLayoutType: AppBarLayoutType
get() = AppBarLayoutType.TOOLBAR
override fun onCreate(savedInstanceState: Bundle?) {
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
super.onCreate(savedInstanceState)

View File

@ -40,15 +40,14 @@ import com.nextcloud.talk.R
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.chat.ChatActivity
import com.nextcloud.talk.controllers.ConversationsListController
import com.nextcloud.talk.controllers.LockedController
import com.nextcloud.talk.controllers.ServerSelectionController
import com.nextcloud.talk.controllers.WebViewLoginController
import com.nextcloud.talk.controllers.base.providers.ActionBarProvider
import com.nextcloud.talk.conversationlist.ConversationsListActivity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ActivityMainBinding
import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.settings.SettingsActivity
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.SecurityUtils
@ -165,11 +164,10 @@ class MainActivity : BaseActivity(), ActionBarProvider {
}
private fun setDefaultRootController() {
router!!.setRoot(
RouterTransaction.with(ConversationsListController(Bundle()))
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
val intent = Intent(this, ConversationsListActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.putExtras(Bundle())
startActivity(intent)
}
fun resetConversationsList() {
@ -192,11 +190,6 @@ class MainActivity : BaseActivity(), ActionBarProvider {
})
}
fun openSettings() {
val intent = Intent(this, SettingsActivity::class.java)
startActivity(intent)
}
fun addAccount() {
router!!.pushController(
RouterTransaction.with(ServerSelectionController())

View File

@ -121,8 +121,8 @@ import com.nextcloud.talk.adapters.messages.VoiceMessageInterface
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.callbacks.MentionAutocompleteCallback
import com.nextcloud.talk.controllers.ConversationsListController
import com.nextcloud.talk.conversation.info.ConversationInfoActivity
import com.nextcloud.talk.conversationlist.ConversationsListActivity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ControllerChatBinding
import com.nextcloud.talk.events.UserMentionClickEvent
@ -1763,7 +1763,7 @@ class ChatActivity :
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == UploadAndShareFilesWorker.REQUEST_PERMISSION) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(ConversationsListController.TAG, "upload starting after permissions were granted")
Log.d(ConversationsListActivity.TAG, "upload starting after permissions were granted")
if (filesToUpload.isNotEmpty()) {
uploadFiles(filesToUpload)
}
@ -3154,12 +3154,9 @@ class ChatActivity :
bundle.putString(BundleKeys.KEY_FORWARD_MSG_TEXT, message?.text)
bundle.putString(BundleKeys.KEY_FORWARD_HIDE_SOURCE_ROOM, roomId)
// TODO
// router.pushController(
// RouterTransaction.with(ConversationsListController(bundle))
// .pushChangeHandler(HorizontalChangeHandler())
// .popChangeHandler(HorizontalChangeHandler())
// )
val intent = Intent(this, ConversationsListActivity::class.java)
intent.putExtras(bundle)
startActivity(intent)
}
fun markAsUnread(message: IMessage?) {

View File

@ -22,6 +22,7 @@
package com.nextcloud.talk.controllers
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.os.Handler
@ -42,6 +43,7 @@ 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.conversationlist.ConversationsListActivity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ControllerAccountVerificationBinding
import com.nextcloud.talk.events.EventStatus
@ -457,11 +459,8 @@ class AccountVerificationController(args: Bundle? = null) :
if (activity != null) {
activity!!.runOnUiThread {
if (userManager.users.blockingGet().size == 1) {
router.setRoot(
RouterTransaction.with(ConversationsListController(Bundle()))
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
val intent = Intent(context, ConversationsListActivity::class.java)
startActivity(intent)
} else {
if (isAccountImport) {
ApplicationWideMessageHolder.getInstance().messageType =
@ -517,11 +516,8 @@ class AccountVerificationController(args: Bundle? = null) :
}
} else {
if (userManager.users.blockingGet().isNotEmpty()) {
router.setRoot(
RouterTransaction.with(ConversationsListController(Bundle()))
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
val intent = Intent(context, ConversationsListActivity::class.java)
startActivity(intent)
} else {
router.setRoot(
RouterTransaction.with(ServerSelectionController())

View File

@ -22,10 +22,7 @@
*/
package com.nextcloud.talk.controllers.base
import android.animation.AnimatorInflater
import android.app.Activity
import android.content.Context
import android.content.res.Resources
import android.os.Build
import android.os.Bundle
import android.util.Log
@ -39,12 +36,10 @@ import android.widget.EditText
import androidx.annotation.LayoutRes
import androidx.annotation.RequiresApi
import androidx.appcompat.app.ActionBar
import androidx.core.content.res.ResourcesCompat
import autodagger.AutoInjector
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType
import com.google.android.material.appbar.AppBarLayout
import com.nextcloud.talk.R
import com.nextcloud.talk.activities.MainActivity
import com.nextcloud.talk.application.NextcloudTalkApplication
@ -54,9 +49,7 @@ import com.nextcloud.talk.controllers.ServerSelectionController
import com.nextcloud.talk.controllers.SwitchAccountController
import com.nextcloud.talk.controllers.WebViewLoginController
import com.nextcloud.talk.controllers.base.providers.ActionBarProvider
import com.nextcloud.talk.databinding.ActivityMainBinding
import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.preferences.AppPreferences
import javax.inject.Inject
import kotlin.jvm.internal.Intrinsics
@ -120,12 +113,12 @@ abstract class BaseController(@LayoutRes var layoutRes: Int, args: Bundle? = nul
protected open fun onViewBound(view: View) {
var activity: MainActivity? = null
if (getActivity() != null && getActivity() is MainActivity) {
activity = getActivity() as MainActivity?
viewThemeUtils.material.themeCardView(activity!!.binding.searchToolbar)
viewThemeUtils.material.themeToolbar(activity.binding.toolbar)
viewThemeUtils.material.themeSearchBarText(activity.binding.searchText)
}
// if (getActivity() != null && getActivity() is MainActivity) {
// activity = getActivity() as MainActivity?
// viewThemeUtils.material.themeCardView(activity!!.binding.searchToolbar)
// viewThemeUtils.material.themeToolbar(activity.binding.toolbar)
// viewThemeUtils.material.themeSearchBarText(activity.binding.searchText)
// }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences.isKeyboardIncognito) {
disableKeyboardPersonalisedLearning((view as ViewGroup))
@ -136,7 +129,7 @@ abstract class BaseController(@LayoutRes var layoutRes: Int, args: Bundle? = nul
}
override fun onAttach(view: View) {
showSearchOrToolbar()
// showSearchOrToolbar()
setTitle()
if (actionBar != null) {
actionBar!!.setDisplayHomeAsUpEnabled(parentController != null || router.backstackSize >= 1)
@ -144,93 +137,93 @@ abstract class BaseController(@LayoutRes var layoutRes: Int, args: Bundle? = nul
super.onAttach(view)
}
open fun showSearchOrToolbar() {
if (isValidActivity(activity)) {
val showSearchBar = appBarLayoutType == AppBarLayoutType.SEARCH_BAR
val activity = activity as MainActivity
if (appBarLayoutType == AppBarLayoutType.EMPTY) {
hideBars(activity.binding)
} else {
if (showSearchBar) {
showSearchBar(activity.binding)
} else {
showToolbar(activity.binding)
}
colorizeStatusBar(showSearchBar, activity, resources)
}
colorizeNavigationBar(activity, resources)
}
}
private fun isValidActivity(activity: Activity?): Boolean {
return activity != null && activity is MainActivity
}
private fun showSearchBar(binding: ActivityMainBinding) {
val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
binding.searchToolbar.visibility = View.VISIBLE
binding.searchText.hint = searchHint
binding.toolbar.visibility = View.GONE
// layoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout
// .LayoutParams.SCROLL_FLAG_SNAP | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
layoutParams.scrollFlags = 0
binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
binding.appBar.context,
R.animator.appbar_elevation_off
)
binding.searchToolbar.layoutParams = layoutParams
}
private fun showToolbar(binding: ActivityMainBinding) {
val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
binding.searchToolbar.visibility = View.GONE
binding.toolbar.visibility = View.VISIBLE
viewThemeUtils.material.colorToolbarOverflowIcon(binding.toolbar)
layoutParams.scrollFlags = 0
binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
binding.appBar.context,
R.animator.appbar_elevation_on
)
binding.searchToolbar.layoutParams = layoutParams
}
private fun hideBars(binding: ActivityMainBinding) {
binding.toolbar.visibility = View.GONE
binding.searchToolbar.visibility = View.GONE
}
fun hideSearchBar() {
val activity = activity as MainActivity?
val layoutParams = activity!!.binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
activity.binding.searchToolbar.visibility = View.GONE
activity.binding.toolbar.visibility = View.VISIBLE
layoutParams.scrollFlags = 0
activity.binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
activity.binding.appBar.context,
R.animator.appbar_elevation_on
)
}
private fun colorizeStatusBar(showSearchBar: Boolean, activity: Activity?, resources: Resources?) {
if (activity != null && resources != null) {
if (showSearchBar) {
view?.let { viewThemeUtils.platform.resetStatusBar(activity) }
} else {
view?.let { viewThemeUtils.platform.themeStatusBar(activity, it) }
}
}
}
private fun colorizeNavigationBar(activity: Activity?, resources: Resources?) {
if (activity != null && resources != null) {
DisplayUtils.applyColorToNavigationBar(
activity.window,
ResourcesCompat.getColor(resources, R.color.bg_default, null)
)
}
}
// open fun showSearchOrToolbar() {
// if (isValidActivity(activity)) {
// val showSearchBar = appBarLayoutType == AppBarLayoutType.SEARCH_BAR
// val activity = activity as MainActivity
//
// if (appBarLayoutType == AppBarLayoutType.EMPTY) {
// hideBars(activity.binding)
// } else {
// if (showSearchBar) {
// showSearchBar(activity.binding)
// } else {
// showToolbar(activity.binding)
// }
// colorizeStatusBar(showSearchBar, activity, resources)
// }
//
// colorizeNavigationBar(activity, resources)
// }
// }
//
// private fun isValidActivity(activity: Activity?): Boolean {
// return activity != null && activity is MainActivity
// }
//
// private fun showSearchBar(binding: ActivityMainBinding) {
// val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
// binding.searchToolbar.visibility = View.VISIBLE
// binding.searchText.hint = searchHint
// binding.toolbar.visibility = View.GONE
// // layoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout
// // .LayoutParams.SCROLL_FLAG_SNAP | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
// layoutParams.scrollFlags = 0
// binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
// binding.appBar.context,
// R.animator.appbar_elevation_off
// )
// binding.searchToolbar.layoutParams = layoutParams
// }
//
// private fun showToolbar(binding: ActivityMainBinding) {
// val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
// binding.searchToolbar.visibility = View.GONE
// binding.toolbar.visibility = View.VISIBLE
// viewThemeUtils.material.colorToolbarOverflowIcon(binding.toolbar)
// layoutParams.scrollFlags = 0
// binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
// binding.appBar.context,
// R.animator.appbar_elevation_on
// )
// binding.searchToolbar.layoutParams = layoutParams
// }
//
// private fun hideBars(binding: ActivityMainBinding) {
// binding.toolbar.visibility = View.GONE
// binding.searchToolbar.visibility = View.GONE
// }
//
// fun hideSearchBar() {
// val activity = activity as MainActivity?
// val layoutParams = activity!!.binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
// activity.binding.searchToolbar.visibility = View.GONE
// activity.binding.toolbar.visibility = View.VISIBLE
// layoutParams.scrollFlags = 0
// activity.binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
// activity.binding.appBar.context,
// R.animator.appbar_elevation_on
// )
// }
//
// private fun colorizeStatusBar(showSearchBar: Boolean, activity: Activity?, resources: Resources?) {
// if (activity != null && resources != null) {
// if (showSearchBar) {
// view?.let { viewThemeUtils.platform.resetStatusBar(activity) }
// } else {
// view?.let { viewThemeUtils.platform.themeStatusBar(activity, it) }
// }
// }
// }
//
// private fun colorizeNavigationBar(activity: Activity?, resources: Resources?) {
// if (activity != null && resources != null) {
// DisplayUtils.applyColorToNavigationBar(
// activity.window,
// ResourcesCompat.getColor(resources, R.color.bg_default, null)
// )
// }
// }
override fun onDetach(view: View) {
super.onDetach(view)

View File

@ -23,14 +23,17 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.controllers
package com.nextcloud.talk.conversationlist
import android.animation.AnimatorInflater
import android.annotation.SuppressLint
import android.app.Activity
import android.app.SearchManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Resources
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
@ -40,7 +43,6 @@ import android.text.InputType
import android.text.TextUtils
import android.util.Log
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.MotionEvent
import android.view.View
@ -49,6 +51,7 @@ import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.SearchView
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.MenuItemCompat
import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.RecyclerView
@ -60,13 +63,12 @@ import coil.imageLoader
import coil.request.ImageRequest
import coil.target.Target
import coil.transform.CircleCropTransformation
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.activities.CallActivity
import com.nextcloud.talk.activities.MainActivity
import com.nextcloud.talk.adapters.items.ConversationItem
import com.nextcloud.talk.adapters.items.GenericTextHeaderItem
import com.nextcloud.talk.adapters.items.LoadMoreResultsItem
@ -74,11 +76,8 @@ import com.nextcloud.talk.adapters.items.MessageResultItem
import com.nextcloud.talk.adapters.items.MessagesTextHeaderItem
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.chat.ChatActivity
import com.nextcloud.talk.contacts.ContactsActivity
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.databinding.ControllerConversationsRvBinding
import com.nextcloud.talk.events.ConversationsListFetchDataEvent
@ -100,6 +99,7 @@ import com.nextcloud.talk.ui.dialog.ConversationsListBottomDialog
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.ClosedInterfaceImpl
import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.FileUtils
import com.nextcloud.talk.utils.Mimetype
import com.nextcloud.talk.utils.ParticipantPermissions
@ -130,7 +130,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.apache.commons.lang3.builder.CompareToBuilder
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.parceler.Parcels
@ -140,19 +139,17 @@ import java.util.concurrent.TimeUnit
import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class ConversationsListController(bundle: Bundle) :
BaseController(R.layout.controller_conversations_rv, bundle),
class ConversationsListActivity :
BaseActivity(),
FlexibleAdapter.OnItemClickListener,
FlexibleAdapter.OnItemLongClickListener,
ConversationMenuInterface {
private val bundle: Bundle
private lateinit var binding: ControllerConversationsRvBinding
@Inject
lateinit var userManager: UserManager
@Inject
lateinit var eventBus: EventBus
@Inject
lateinit var ncApi: NcApi
@ -162,11 +159,6 @@ class ConversationsListController(bundle: Bundle) :
@Inject
lateinit var platformPermissionUtil: PlatformPermissionUtil
private val binding: ControllerConversationsRvBinding? by viewBinding(ControllerConversationsRvBinding::bind)
override val title: String
get() = resources!!.getString(R.string.nc_app_product_name)
override val appBarLayoutType: AppBarLayoutType
get() = AppBarLayoutType.SEARCH_BAR
@ -190,7 +182,7 @@ class ConversationsListController(bundle: Bundle) :
private var selectedConversation: Conversation? = null
private var textToPaste: String? = ""
private var selectedMessageId: String? = null
private var forwardMessage: Boolean
private var forwardMessage: Boolean = false
private var nextUnreadConversationScrollPosition = 0
private var layoutManager: SmoothScrollLinearLayoutManager? = null
private val callHeaderItems = HashMap<String, GenericTextHeaderItem>()
@ -198,23 +190,88 @@ class ConversationsListController(bundle: Bundle) :
private var searchHelper: MessageSearchHelper? = null
private var searchViewDisposable: Disposable? = null
override fun onViewBound(view: View) {
super.onViewBound(view)
sharedApplication!!.componentApplication.inject(this)
actionBar?.show()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
binding = ControllerConversationsRvBinding.inflate(layoutInflater)
setupActionBar()
setupSystemColors()
setContentView(binding.root)
forwardMessage = intent.getBooleanExtra(KEY_FORWARD_MSG_FLAG, false)
}
override fun onResume() {
super.onResume()
// actionBar?.show()
if (adapter == null) {
adapter = FlexibleAdapter(conversationItems, activity, true)
adapter = FlexibleAdapter(conversationItems, this, true)
} else {
binding?.loadingContent?.visibility = View.GONE
}
adapter!!.addListener(this)
prepareViews()
showShareToScreen = hasActivityActionSendIntent()
ClosedInterfaceImpl().setUpPushTokenRegistration()
if (!eventBus.isRegistered(this)) {
eventBus.register(this)
}
currentUser = userManager.currentUser.blockingGet()
if (currentUser != null) {
if (isServerEOL(currentUser!!)) {
showServerEOLDialog()
return
}
if (isUnifiedSearchAvailable(currentUser!!)) {
searchHelper = MessageSearchHelper(unifiedSearchRepository)
}
credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
loadUserAvatar(binding.switchAccountButton)
viewThemeUtils.material.colorMaterialTextButton(binding.switchAccountButton)
fetchRooms()
} else {
Log.e(TAG, "userManager.currentUser.blockingGet() returned null")
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
}
showSearchOrToolbar()
}
private fun setupActionBar() {
setSupportActionBar(binding.conversationListToolbar)
binding.conversationListToolbar.setNavigationOnClickListener {
onBackPressed()
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent)))
supportActionBar?.title = 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)
)
}
private fun loadUserAvatar(
target: Target
) {
if (activity != null) {
if (currentUser != null) {
val url = ApiUtils.getUrlForAvatar(
currentUser!!.baseUrl,
@ -239,7 +296,6 @@ class ConversationsListController(bundle: Bundle) :
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
}
}
}
private fun loadUserAvatar(button: MaterialButton) {
val target = object : Target {
@ -268,55 +324,8 @@ class ConversationsListController(bundle: Bundle) :
loadUserAvatar(target)
}
override fun onAttach(view: View) {
Log.d(
TAG,
"onAttach: Controller: " + System.identityHashCode(this) +
" Activity: " + System.identityHashCode(activity)
)
super.onAttach(view)
showShareToScreen = hasActivityActionSendIntent()
ClosedInterfaceImpl().setUpPushTokenRegistration()
if (!eventBus.isRegistered(this)) {
eventBus.register(this)
}
currentUser = userManager.currentUser.blockingGet()
if (currentUser != null) {
if (isServerEOL(currentUser!!)) {
showServerEOLDialog()
return
}
if (isUnifiedSearchAvailable(currentUser!!)) {
searchHelper = MessageSearchHelper(unifiedSearchRepository)
}
credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
if (activity != null && activity is MainActivity) {
loadUserAvatar((activity as MainActivity?)!!.binding.switchAccountButton)
viewThemeUtils.material
.colorMaterialTextButton((activity as MainActivity?)!!.binding.switchAccountButton)
}
fetchRooms()
} else {
Log.e(TAG, "userManager.currentUser.blockingGet() returned null")
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
}
}
override fun onDetach(view: View) {
Log.d(
TAG,
"onDetach: Controller: " + System.identityHashCode(this) +
" Activity: " + System.identityHashCode(activity)
)
super.onDetach(view)
eventBus.unregister(this)
}
private fun initSearchView() {
if (activity != null) {
val searchManager = activity!!.getSystemService(Context.SEARCH_SERVICE) as SearchManager?
val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager?
if (searchItem != null) {
searchView = MenuItemCompat.getActionView(searchItem) as SearchView
viewThemeUtils.talk.themeSearchView(searchView!!)
@ -327,9 +336,9 @@ class ConversationsListController(bundle: Bundle) :
imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
}
searchView!!.imeOptions = imeOptions
searchView!!.queryHint = searchHint
searchView!!.queryHint = getString(R.string.appbar_search_in, getString(R.string.nc_app_product_name))
if (searchManager != null) {
searchView!!.setSearchableInfo(searchManager.getSearchableInfo(activity!!.componentName))
searchView!!.setSearchableInfo(searchManager.getSearchableInfo(componentName))
}
searchViewDisposable = observeSearchView(searchView!!)
.debounce { query: String? ->
@ -348,12 +357,11 @@ class ConversationsListController(bundle: Bundle) :
.subscribe { newText: String? -> onQueryTextChange(newText) }
}
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
inflater.inflate(R.menu.menu_conversation_plus_filter, menu)
menuInflater.inflate(R.menu.menu_conversation_plus_filter, menu)
searchItem = menu.findItem(R.id.action_search)
chooseAccountItem = menu.findItem(R.id.action_choose_account)
loadUserAvatar(chooseAccountItem!!)
@ -362,17 +370,19 @@ class ConversationsListController(bundle: Bundle) :
if (resources != null && resources!!.getBoolean(R.bool.multiaccount_support)) {
val newFragment: DialogFragment = ChooseAccountShareToDialogFragment.newInstance()
newFragment.show(
(activity as MainActivity?)!!.supportFragmentManager,
supportFragmentManager,
ChooseAccountShareToDialogFragment.TAG
)
}
true
}
initSearchView()
return true
}
override fun onPrepareOptionsMenu(menu: Menu) {
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
super.onPrepareOptionsMenu(menu)
searchView = MenuItemCompat.getActionView(searchItem) as SearchView
val moreAccountsAvailable = userManager.users.blockingGet().size > 1
@ -385,24 +395,19 @@ class ConversationsListController(bundle: Bundle) :
hideSearchBar()
actionBar?.setTitle(R.string.nc_forward_to_three_dots)
} else {
val activity = activity as MainActivity?
searchItem!!.isVisible = conversationItems.size > 0
if (activity != null) {
if (adapter!!.hasFilter()) {
showSearchView(activity, searchView, searchItem)
showSearchView(searchView, searchItem)
searchView!!.setQuery(adapter!!.getFilter(String::class.java), false)
}
activity.binding.searchText.setOnClickListener {
showSearchView(activity, searchView, searchItem)
viewThemeUtils.platform.themeStatusBar(activity, searchView!!)
}
binding.searchText.setOnClickListener {
showSearchView(searchView, searchItem)
viewThemeUtils.platform.themeStatusBar(this, searchView!!)
}
searchView!!.setOnCloseListener {
if (TextUtils.isEmpty(searchView!!.query.toString())) {
searchView!!.onActionViewCollapsed()
if (activity != null) {
viewThemeUtils.platform.resetStatusBar(activity)
}
viewThemeUtils.platform.resetStatusBar(this)
} else {
searchView!!.post { searchView!!.setQuery(TAG, true) }
}
@ -428,48 +433,118 @@ class ConversationsListController(bundle: Bundle) :
}
binding?.swipeRefreshLayoutView?.isEnabled = true
searchView!!.onActionViewCollapsed()
val mainActivity = getActivity() as MainActivity?
if (mainActivity != null) {
mainActivity.binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
mainActivity.binding.appBar.context,
binding.conversationListAppbar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
binding.conversationListAppbar.context,
R.animator.appbar_elevation_off
)
mainActivity.binding.toolbar.visibility = View.GONE
mainActivity.binding.searchToolbar.visibility = View.VISIBLE
binding.conversationListToolbar.visibility = View.GONE
binding.searchToolbar.visibility = View.VISIBLE
if (resources != null) {
viewThemeUtils.platform
.resetStatusBar(mainActivity)
}
viewThemeUtils.platform.resetStatusBar(this@ConversationsListActivity)
}
val layoutManager = binding?.recyclerView?.layoutManager as SmoothScrollLinearLayoutManager?
layoutManager?.scrollToPositionWithOffset(0, 0)
return true
}
})
}
return true
}
private fun showSearchOrToolbar() {
if (TextUtils.isEmpty(searchQuery)) {
val showSearchBar = appBarLayoutType == AppBarLayoutType.SEARCH_BAR
if (appBarLayoutType == AppBarLayoutType.EMPTY) {
hideBars()
} else {
if (showSearchBar) {
showSearchBar()
} else {
showToolbar()
}
colorizeStatusBar(showSearchBar, this, resources)
}
colorizeNavigationBar(this, resources)
}
}
private fun showSearchBar() {
val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
binding.searchToolbar.visibility = View.VISIBLE
binding.searchText.hint = getString(R.string.appbar_search_in, getString(R.string.nc_app_product_name))
binding.conversationListToolbar.visibility = View.GONE
// layoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout
// .LayoutParams.SCROLL_FLAG_SNAP | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
layoutParams.scrollFlags = 0
binding.conversationListAppbar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
binding.conversationListAppbar.context,
R.animator.appbar_elevation_off
)
binding.searchToolbar.layoutParams = layoutParams
}
private fun showToolbar() {
val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
binding.searchToolbar.visibility = View.GONE
binding.searchToolbar.visibility = View.VISIBLE
viewThemeUtils.material.colorToolbarOverflowIcon(binding.conversationListToolbar)
layoutParams.scrollFlags = 0
binding.conversationListAppbar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
binding.conversationListAppbar.context,
R.animator.appbar_elevation_on
)
binding.conversationListToolbar.layoutParams = layoutParams
}
private fun hideBars() {
binding.conversationListToolbar.visibility = View.GONE
binding.searchToolbar.visibility = View.GONE
}
private fun hideSearchBar() {
val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
binding.searchToolbar.visibility = View.GONE
binding.conversationListToolbar.visibility = View.VISIBLE
layoutParams.scrollFlags = 0
binding.conversationListAppbar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
binding.conversationListAppbar.context,
R.animator.appbar_elevation_on
)
}
private fun colorizeStatusBar(showSearchBar: Boolean, activity: Activity?, resources: Resources?) {
if (activity != null && resources != null) {
if (showSearchBar) {
viewThemeUtils.platform.resetStatusBar(activity)
} else {
viewThemeUtils.platform.themeStatusBar(activity, binding.root)
}
}
}
private fun colorizeNavigationBar(activity: Activity?, resources: Resources?) {
if (activity != null && resources != null) {
DisplayUtils.applyColorToNavigationBar(
activity.window,
ResourcesCompat.getColor(resources, R.color.bg_default, null)
)
}
}
private fun hasActivityActionSendIntent(): Boolean {
return if (activity != null) {
Intent.ACTION_SEND == activity!!.intent.action || Intent.ACTION_SEND_MULTIPLE == activity!!.intent.action
} else {
false
}
return Intent.ACTION_SEND == intent.action || Intent.ACTION_SEND_MULTIPLE == intent.action
}
override fun showSearchOrToolbar() {
if (TextUtils.isEmpty(searchQuery)) {
super.showSearchOrToolbar()
}
}
private fun showSearchView(activity: MainActivity, searchView: SearchView?, searchItem: MenuItem?) {
activity.binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
activity.binding.appBar.context,
private fun showSearchView(searchView: SearchView?, searchItem: MenuItem?) {
binding.conversationListAppbar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
binding.conversationListAppbar.context,
R.animator.appbar_elevation_on
)
activity.binding.toolbar.visibility = View.VISIBLE
activity.binding.searchToolbar.visibility = View.GONE
binding.conversationListToolbar.visibility = View.VISIBLE
binding.searchToolbar.visibility = View.GONE
searchItem!!.expandActionView()
}
@ -499,10 +574,11 @@ class ConversationsListController(bundle: Bundle) :
// This is invoked asynchronously, when server returns a response the view might have been
// unbound in the meantime. Check if the view is still there.
// FIXME - does it make sense to update internal data structures even when view has been unbound?
if (view == null) {
Log.d(TAG, "fetchData - getRooms - view is not bound: $startNanoTime")
return@subscribe
}
// if (view == null) {
// Log.d(TAG, "fetchData - getRooms - view is not bound: $startNanoTime")
// return@subscribe
// }
if (adapterWasNull) {
adapterWasNull = false
binding?.loadingContent?.visibility = View.GONE
@ -548,8 +624,8 @@ class ConversationsListController(bundle: Bundle) :
}
private fun addToConversationItems(conversation: Conversation) {
if (bundle.containsKey(KEY_FORWARD_HIDE_SOURCE_ROOM) && conversation.roomId ==
bundle.getString(KEY_FORWARD_HIDE_SOURCE_ROOM)
if (intent.getStringExtra(KEY_FORWARD_HIDE_SOURCE_ROOM) != null &&
intent.getStringExtra(KEY_FORWARD_HIDE_SOURCE_ROOM) == conversation.roomId
) {
return
}
@ -566,24 +642,23 @@ class ConversationsListController(bundle: Bundle) :
genericTextHeaderItem = GenericTextHeaderItem(headerTitle, viewThemeUtils)
callHeaderItems[headerTitle] = genericTextHeaderItem
}
if (activity != null) {
val conversationItem = ConversationItem(
conversation,
currentUser!!,
activity!!,
this,
viewThemeUtils
)
conversationItems.add(conversationItem)
val conversationItemWithHeader = ConversationItem(
conversation,
currentUser!!,
activity!!,
this,
callHeaderItems[headerTitle],
viewThemeUtils
)
conversationItemsWithHeader.add(conversationItemWithHeader)
}
}
private fun showErrorDialog() {
binding?.floatingActionButton?.let {
@ -639,7 +714,7 @@ class ConversationsListController(bundle: Bundle) :
val conversationItem = ConversationItem(
conversation,
currentUser!!,
activity!!,
this,
callHeaderItems[headerTitle],
viewThemeUtils
)
@ -659,30 +734,18 @@ class ConversationsListController(bundle: Bundle) :
private fun handleHttpExceptions(throwable: Throwable) {
if (throwable is HttpException) {
when (throwable.code()) {
HTTP_UNAUTHORIZED -> if (parentController != null && parentController!!.router != null) {
Log.d(TAG, "Starting reauth webview via getParentController()")
parentController!!.router.pushController(
RouterTransaction.with(
WebViewLoginController(
currentUser!!.baseUrl,
true
)
)
.pushChangeHandler(VerticalChangeHandler())
.popChangeHandler(VerticalChangeHandler())
)
} else {
Log.d(TAG, "Starting reauth webview via ConversationsListController")
showUnauthorizedDialog()
HTTP_UNAUTHORIZED -> showUnauthorizedDialog()
else -> {
Log.e(TAG, "Http exception in ConversationListActivity", throwable)
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
}
else -> {}
}
}
}
@SuppressLint("ClickableViewAccessibility")
private fun prepareViews() {
layoutManager = SmoothScrollLinearLayoutManager(Objects.requireNonNull(activity))
layoutManager = SmoothScrollLinearLayoutManager(this)
binding?.recyclerView?.layoutManager = layoutManager
binding?.recyclerView?.setHasFixedSize(true)
binding?.recyclerView?.adapter = adapter
@ -695,8 +758,8 @@ class ConversationsListController(bundle: Bundle) :
}
})
binding?.recyclerView?.setOnTouchListener { v: View, _: MotionEvent? ->
if (isAttached && (!isBeingDestroyed || !isDestroyed)) {
val imm = activity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
if (!isDestroyed) {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(v.windowToken, 0)
}
false
@ -709,21 +772,17 @@ class ConversationsListController(bundle: Bundle) :
showNewConversationsScreen()
}
binding?.floatingActionButton?.let { viewThemeUtils.material.themeFAB(it) }
if (activity != null && activity is MainActivity) {
val activity = activity as MainActivity?
activity!!.binding.switchAccountButton.setOnClickListener {
binding.switchAccountButton.setOnClickListener {
if (resources != null && resources!!.getBoolean(R.bool.multiaccount_support)) {
val newFragment: DialogFragment = ChooseAccountDialogFragment.newInstance()
newFragment.show(
(getActivity() as MainActivity?)!!.supportFragmentManager,
ChooseAccountDialogFragment.TAG
)
newFragment.show(supportFragmentManager, ChooseAccountDialogFragment.TAG)
} else {
val intent = Intent(context, SettingsActivity::class.java)
startActivity(intent)
}
}
}
binding?.newMentionPopupBubble?.hide()
binding?.newMentionPopupBubble?.setPopupBubbleListener {
binding?.recyclerView?.smoothScrollToPosition(
@ -786,17 +845,19 @@ class ConversationsListController(bundle: Bundle) :
}
}
public override fun onSaveViewState(view: View, outState: Bundle) {
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
if (searchView != null && !TextUtils.isEmpty(searchView!!.query)) {
outState.putString(KEY_SEARCH_QUERY, searchView!!.query.toString())
bundle.putString(KEY_SEARCH_QUERY, searchView!!.query.toString())
}
super.onSaveViewState(view, outState)
}
public override fun onRestoreViewState(view: View, savedViewState: Bundle) {
super.onRestoreViewState(view, savedViewState)
if (savedViewState.containsKey(KEY_SEARCH_QUERY)) {
searchQuery = savedViewState.getString(KEY_SEARCH_QUERY, "")
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
if (savedInstanceState.containsKey(KEY_SEARCH_QUERY)) {
searchQuery = savedInstanceState.getString(KEY_SEARCH_QUERY, "")
}
}
@ -906,7 +967,7 @@ class ConversationsListController(bundle: Bundle) :
@Suppress("Detekt.ComplexMethod")
private fun handleConversation(conversation: Conversation?) {
selectedConversation = conversation
if (selectedConversation != null && activity != null) {
if (selectedConversation != null) {
val hasChatPermission = ParticipantPermissions(currentUser!!, selectedConversation!!).hasChatPermission()
if (showShareToScreen) {
if (hasChatPermission &&
@ -919,7 +980,7 @@ class ConversationsListController(bundle: Bundle) :
}
} else if (forwardMessage) {
if (hasChatPermission && !isReadOnlyConversation(selectedConversation!!)) {
openConversation(bundle.getString(KEY_FORWARD_MSG_TEXT))
openConversation(intent.getStringExtra(KEY_FORWARD_MSG_TEXT))
forwardMessage = false
} else {
Toast.makeText(context, R.string.send_to_forbidden, Toast.LENGTH_LONG).show()
@ -1001,7 +1062,7 @@ class ConversationsListController(bundle: Bundle) :
}
private fun clearIntentAction() {
activity!!.intent.action = ""
intent.action = ""
}
override fun onItemLongClick(position: Int) {
@ -1012,7 +1073,7 @@ class ConversationsListController(bundle: Bundle) :
if (clickedItem != null) {
val conversation = (clickedItem as ConversationItem).model
conversationsListBottomDialog = ConversationsListBottomDialog(
activity!!,
this,
this,
userManager.currentUser.blockingGet(),
conversation
@ -1025,8 +1086,7 @@ class ConversationsListController(bundle: Bundle) :
@Suppress("Detekt.TooGenericExceptionCaught")
private fun collectDataFromIntent() {
filesToShare = ArrayList()
if (activity != null && activity!!.intent != null) {
val intent = activity!!.intent
if (intent != null) {
if (Intent.ACTION_SEND == intent.action || Intent.ACTION_SEND_MULTIPLE == intent.action) {
try {
val mimeType = intent.type
@ -1099,6 +1159,7 @@ class ConversationsListController(bundle: Bundle) :
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == UploadAndShareFilesWorker.REQUEST_PERMISSION &&
grantResults.isNotEmpty() &&
grantResults[0] == PackageManager.PERMISSION_GRANTED
@ -1132,13 +1193,6 @@ class ConversationsListController(bundle: Bundle) :
bundle.putString(BundleKeys.KEY_MESSAGE_ID, selectedMessageId)
selectedMessageId = null
}
// remapChatController(
// router,
// currentUser!!.id!!,
// selectedConversation!!.token!!,
// bundle,
// false
// )
val intent = Intent(context, ChatActivity::class.java)
intent.putExtras(bundle)
@ -1171,8 +1225,7 @@ class ConversationsListController(bundle: Bundle) :
override fun showDeleteConversationDialog(bundle: Bundle) {
conversationMenuBundle = bundle
if (activity != null &&
conversationMenuBundle != null &&
if (conversationMenuBundle != null &&
isInternalUserEqualsCurrentUser(currentUser, conversationMenuBundle)
) {
val conversation = Parcels.unwrap<Conversation>(conversationMenuBundle!!.getParcelable(KEY_ROOM))
@ -1216,7 +1269,6 @@ class ConversationsListController(bundle: Bundle) :
}
private fun showUnauthorizedDialog() {
if (activity != null) {
binding?.floatingActionButton?.let {
val dialogBuilder = MaterialAlertDialogBuilder(it.context)
.setIcon(
@ -1234,29 +1286,25 @@ class ConversationsListController(bundle: Bundle) :
.blockingGet()
val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java).build()
WorkManager.getInstance().enqueue(accountRemovalWork)
if (otherUserExists && view != null) {
onViewBound(view!!)
onAttach(view!!)
if (otherUserExists) {
finish()
startActivity(intent)
} else if (!otherUserExists) {
router.setRoot(
RouterTransaction.with(ServerSelectionController())
.pushChangeHandler(VerticalChangeHandler())
.popChangeHandler(VerticalChangeHandler())
)
Log.d(TAG, "No other users found. AccountRemovalWorker will restart the app.")
}
}
.setNegativeButton(R.string.nc_settings_reauthorize) { _, _ ->
router.pushController(
RouterTransaction.with(
WebViewLoginController(currentUser!!.baseUrl, true)
)
.pushChangeHandler(VerticalChangeHandler())
.popChangeHandler(VerticalChangeHandler())
)
// TODO
// router.pushController(
// RouterTransaction.with(
// WebViewLoginController(currentUser!!.baseUrl, true)
// )
// .pushChangeHandler(VerticalChangeHandler())
// .popChangeHandler(VerticalChangeHandler())
// )
}
viewThemeUtils.dialog
.colorMaterialAlertDialogBackground(it.context, dialogBuilder)
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(it.context, dialogBuilder)
val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE),
@ -1264,7 +1312,6 @@ class ConversationsListController(bundle: Bundle) :
)
}
}
}
private fun showServerEOLDialog() {
binding?.floatingActionButton?.let {
@ -1279,25 +1326,20 @@ class ConversationsListController(bundle: Bundle) :
.blockingGet()
val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java).build()
WorkManager.getInstance().enqueue(accountRemovalWork)
if (otherUserExists && view != null) {
onViewBound(view!!)
onAttach(view!!)
if (otherUserExists) {
finish()
startActivity(intent)
} else if (!otherUserExists) {
router.setRoot(
RouterTransaction.with(
ServerSelectionController()
)
.pushChangeHandler(VerticalChangeHandler())
.popChangeHandler(VerticalChangeHandler())
)
restartApp(this)
}
}
.setNegativeButton(R.string.nc_cancel) { _, _ ->
if (userManager.users.blockingGet().isNotEmpty()) {
router.pushController(RouterTransaction.with(SwitchAccountController()))
// TODO
// router.pushController(RouterTransaction.with(SwitchAccountController()))
} else {
activity!!.finishAffinity()
activity!!.finish()
finishAffinity()
finish()
}
}
@ -1310,6 +1352,15 @@ class ConversationsListController(bundle: Bundle) :
}
}
fun restartApp(context: Context) {
val packageManager = context.packageManager
val intent = packageManager.getLaunchIntentForPackage(context.packageName)
val componentName = intent!!.component
val mainIntent = Intent.makeRestartActivityTask(componentName)
context.startActivity(mainIntent)
Runtime.getRuntime().exit(0)
}
private fun deleteConversation(data: Data) {
val deleteConversationWorker =
OneTimeWorkRequest.Builder(DeleteConversationWorker::class.java).setInputData(data).build()
@ -1351,6 +1402,13 @@ class ConversationsListController(bundle: Bundle) :
showErrorDialog()
}
override fun onBackPressed() {
super.onBackPressed()
// TODO: replace this when conductor is removed. For now it avoids to load the MainActiviy which has no UI.
finishAffinity()
}
companion object {
const val TAG = "ConvListController"
const val UNREAD_BUBBLE_DELAY = 2500
@ -1360,10 +1418,4 @@ class ConversationsListController(bundle: Bundle) :
const val SEARCH_MIN_CHARS = 2
const val HTTP_UNAUTHORIZED = 401
}
init {
setHasOptionsMenu(true)
forwardMessage = bundle.getBoolean(KEY_FORWARD_MSG_FLAG)
this.bundle = bundle
}
}

View File

@ -38,7 +38,7 @@ import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.adapters.items.LoadMoreResultsItem
import com.nextcloud.talk.adapters.items.MessageResultItem
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.controllers.ConversationsListController
import com.nextcloud.talk.conversationlist.ConversationsListActivity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ActivityMessageSearchBinding
import com.nextcloud.talk.utils.DisplayUtils
@ -241,7 +241,7 @@ class MessageSearchActivity : BaseActivity() {
when {
TextUtils.isEmpty(query) -> Observable.empty()
else -> Observable.timer(
ConversationsListController.SEARCH_DEBOUNCE_INTERVAL_MS.toLong(),
ConversationsListActivity.SEARCH_DEBOUNCE_INTERVAL_MS.toLong(),
TimeUnit.MILLISECONDS
)
}

View File

@ -26,6 +26,7 @@ package com.nextcloud.talk.ui.dialog;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
@ -34,16 +35,17 @@ import android.view.View;
import android.view.ViewGroup;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.nextcloud.talk.activities.MainActivity;
import com.nextcloud.talk.adapters.items.AdvancedUserItem;
import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.conversationlist.ConversationsListActivity;
import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.databinding.DialogChooseAccountBinding;
import com.nextcloud.talk.extensions.ImageViewExtensionsKt;
import com.nextcloud.talk.models.json.participants.Participant;
import com.nextcloud.talk.models.json.status.Status;
import com.nextcloud.talk.models.json.status.StatusOverall;
import com.nextcloud.talk.settings.SettingsActivity;
import com.nextcloud.talk.ui.StatusDrawable;
import com.nextcloud.talk.ui.theme.ViewThemeUtils;
import com.nextcloud.talk.users.UserManager;
@ -178,16 +180,18 @@ public class ChooseAccountDialogFragment extends DialogFragment {
// Creating listeners for quick-actions
binding.currentAccount.getRoot().setOnClickListener(v -> dismiss());
if (getActivity() instanceof MainActivity) {
binding.addAccount.setOnClickListener(v -> {
dismiss();
((MainActivity) getActivity()).addAccount();
// TODO
// ((MainActivity) getActivity()).addAccount();
});
binding.manageSettings.setOnClickListener(v -> {
Intent intent = new Intent(getContext(), SettingsActivity.class);
startActivity(intent);
dismiss();
((MainActivity) getActivity()).openSettings();
});
}
binding.setStatus.setOnClickListener(v -> {
dismiss();
@ -294,10 +298,14 @@ public class ChooseAccountDialogFragment extends DialogFragment {
if (userManager.setUserAsActive(user).blockingGet()) {
cookieManager.getCookieStore().removeAll();
if (getActivity() != null) {
getActivity().runOnUiThread(
() -> ((MainActivity) getActivity()).resetConversationsList());
}
Intent intent = new Intent(getContext(), ConversationsListActivity.class);
// TODO: might be better with FLAG_ACTIVITY_SINGLE_TOP instead than FLAG_ACTIVITY_CLEAR_TOP to
// have a smoother transition. However the handling in onNewIntent() in
// ConversationListActivity must be improved for this.
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
dismiss();
}
}

View File

@ -38,7 +38,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
import com.nextcloud.talk.R
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.controllers.ConversationsListController
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_ADD_FAVORITE
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_MARK_AS_READ
@ -47,6 +46,7 @@ import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_
import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_RENAME_ROOM
import com.nextcloud.talk.controllers.bottomsheet.EntryMenuController
import com.nextcloud.talk.controllers.bottomsheet.OperationsMenuController
import com.nextcloud.talk.conversationlist.ConversationsListActivity
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.DialogConversationOperationsBinding
import com.nextcloud.talk.jobs.LeaveConversationWorker
@ -64,7 +64,7 @@ import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class ConversationsListBottomDialog(
val activity: Activity,
val controller: ConversationsListController,
val controller: ConversationsListActivity,
val currentUser: User,
val conversation: Conversation
) : BottomSheetDialog(activity) {

View File

@ -40,87 +40,7 @@
android:windowContentOverlay="@null"
app:elevation="0dp">
<com.google.android.material.card.MaterialCardView
android:id="@+id/search_toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="16dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="1dp"
android:visibility="gone"
app:cardCornerRadius="25dp"
app:cardElevation="2dp"
app:strokeWidth="0dp"
tools:visibility="visible">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.button.MaterialButton
android:id="@+id/menu_button"
style="@style/Widget.AppTheme.Button.IconButton"
android:layout_width="3dp"
android:layout_height="1dp"
android:layout_marginStart="5dp"
android:contentDescription="@string/nc_action_open_main_menu"
android:visibility="gone"
app:cornerRadius="@dimen/button_corner_radius"
app:icon="@drawable/ic_menu"
app:iconTint="@color/fontAppbar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/search_text"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginStart="20dp"
android:layout_marginEnd="18dp"
android:ellipsize="end"
android:gravity="start|center_vertical"
android:lines="1"
android:textAlignment="viewStart"
android:textColor="@color/fontSecondaryAppbar"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/menu_button"
app:layout_constraintEnd_toStartOf="@id/rightContainer"
app:layout_constraintTop_toTopOf="parent"
tools:text="Search in Nextcloud" />
<FrameLayout
android:id="@+id/rightContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:minWidth="48dp"
android:layout_centerVertical="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.button.MaterialButton
android:id="@+id/switch_account_button"
style="@style/Widget.AppTheme.Button.IconButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:contentDescription="@string/nc_settings"
android:scaleType="fitCenter"
android:transitionName="userAvatar.transitionTag"
app:cornerRadius="@dimen/button_corner_radius"
app:iconSize="@dimen/avatar_size_app_bar"
app:iconTint="@null"
tools:icon="@drawable/ic_user" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"

View File

@ -25,11 +25,118 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/conversation_list_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/bg_default"
android:elevation="0dp"
android:clipChildren="true"
android:clipToPadding="false"
android:windowContentOverlay="@null"
app:elevation="0dp">
<com.google.android.material.card.MaterialCardView
android:id="@+id/search_toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="16dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="1dp"
android:visibility="gone"
app:cardCornerRadius="25dp"
app:cardElevation="2dp"
app:strokeWidth="0dp"
tools:visibility="visible">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.button.MaterialButton
android:id="@+id/menu_button"
style="@style/Widget.AppTheme.Button.IconButton"
android:layout_width="3dp"
android:layout_height="1dp"
android:layout_marginStart="5dp"
android:contentDescription="@string/nc_action_open_main_menu"
android:visibility="gone"
app:cornerRadius="@dimen/button_corner_radius"
app:icon="@drawable/ic_menu"
app:iconTint="@color/fontAppbar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/search_text"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginStart="20dp"
android:layout_marginEnd="18dp"
android:ellipsize="end"
android:gravity="start|center_vertical"
android:lines="1"
android:textAlignment="viewStart"
android:textColor="@color/fontSecondaryAppbar"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/menu_button"
app:layout_constraintEnd_toStartOf="@id/rightContainer"
app:layout_constraintTop_toTopOf="parent"
tools:text="Search in Nextcloud" />
<FrameLayout
android:id="@+id/rightContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:minWidth="48dp"
android:layout_centerVertical="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.button.MaterialButton
android:id="@+id/switch_account_button"
style="@style/Widget.AppTheme.Button.IconButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:contentDescription="@string/nc_settings"
android:scaleType="fitCenter"
android:transitionName="userAvatar.transitionTag"
app:cornerRadius="@dimen/button_corner_radius"
app:iconSize="@dimen/avatar_size_app_bar"
app:iconTint="@null"
tools:icon="@drawable/ic_user" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/conversation_list_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/appbar"
android:theme="?attr/actionBarPopupTheme"
app:layout_scrollFlags="enterAlwaysCollapsed|noScroll"
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
android:id="@+id/loading_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:layout_marginTop="50dp">
<include layout="@layout/rv_item_conversation_with_last_message_shimmer" />