diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml
index 591b1885a7..5d8d3dc752 100644
--- a/vector/src/main/AndroidManifest.xml
+++ b/vector/src/main/AndroidManifest.xml
@@ -44,6 +44,7 @@
android:label="@string/title_activity_emoji_reaction_picker" />
+
{
// TODO better UI
if (it) {
@@ -115,30 +110,27 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
override fun configure(toolbar: Toolbar) {
setSupportActionBar(toolbar)
supportActionBar?.setHomeButtonEnabled(true)
- supportActionBar?.setDisplayHomeAsUpEnabled(true)
- val drawerToggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, 0, 0)
- drawerLayout.addDrawerListener(drawerToggle)
- drawerToggle.syncState()
+ supportActionBar?.setDisplayUseLogoEnabled(true)
}
override fun getMenuRes() = R.menu.home
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
- android.R.id.home -> {
+ android.R.id.home -> {
drawerLayout.openDrawer(GravityCompat.START)
return true
}
- R.id.sliding_menu_settings -> {
+ R.id.sliding_menu_settings -> {
startActivity(VectorSettingsActivity.getIntent(this, "TODO"))
return true
}
- R.id.sliding_menu_sign_out -> {
+ R.id.sliding_menu_sign_out -> {
SignOutUiWorker(this).perform(Matrix.getInstance().currentSession!!)
return true
}
// TODO Temporary code here to create a room
- R.id.tmp_menu_create_room -> {
+ R.id.tmp_menu_create_room -> {
// Start Activity for now
startActivity(Intent(this, RoomDirectoryActivity::class.java))
return true
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/HomeDrawerFragment.kt
index 4458d456f2..9566e881da 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/HomeDrawerFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/HomeDrawerFragment.kt
@@ -17,11 +17,12 @@
package im.vector.riotredesign.features.home
import android.os.Bundle
+import im.vector.matrix.android.api.Matrix
import im.vector.riotredesign.R
import im.vector.riotredesign.core.extensions.replaceChildFragment
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.home.group.GroupListFragment
-import im.vector.riotredesign.features.home.room.list.RoomListFragment
+import kotlinx.android.synthetic.main.fragment_home_drawer.*
class HomeDrawerFragment : VectorBaseFragment() {
@@ -38,9 +39,14 @@ class HomeDrawerFragment : VectorBaseFragment() {
super.onActivityCreated(savedInstanceState)
if (savedInstanceState == null) {
val groupListFragment = GroupListFragment.newInstance()
- replaceChildFragment(groupListFragment, R.id.groupListFragmentContainer)
- val roomListFragment = RoomListFragment.newInstance()
- replaceChildFragment(roomListFragment, R.id.roomListFragmentContainer)
+ replaceChildFragment(groupListFragment, R.id.homeDrawerGroupListContainer)
+ }
+ val session = Matrix.getInstance().currentSession ?: return
+ val user = session.getUser(session.sessionParams.credentials.userId)
+ if (user != null) {
+ AvatarRenderer.render(user.avatarUrl, user.userId, user.displayName, homeDrawerHeaderAvatarView)
+ homeDrawerUsernameView.text = user.displayName
+ homeDrawerUserIdView.text = user.userId
}
}
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/HomeNavigator.kt b/vector/src/main/java/im/vector/riotredesign/features/home/HomeNavigator.kt
index ad3cd4cfcf..d435cd607e 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/HomeNavigator.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/HomeNavigator.kt
@@ -18,11 +18,13 @@ package im.vector.riotredesign.features.home
import androidx.core.view.GravityCompat
import androidx.fragment.app.FragmentManager
+import im.vector.matrix.android.api.session.group.model.GroupSummary
import im.vector.riotredesign.R
-import im.vector.riotredesign.core.extensions.addFragmentToBackstack
import im.vector.riotredesign.core.extensions.replaceFragment
+import im.vector.riotredesign.features.home.group.SelectedGroupFragment
+import im.vector.riotredesign.features.home.group.SelectedGroupParams
+import im.vector.riotredesign.features.home.room.detail.RoomDetailActivity
import im.vector.riotredesign.features.home.room.detail.RoomDetailArgs
-import im.vector.riotredesign.features.home.room.detail.RoomDetailFragment
import kotlinx.android.synthetic.main.activity_home.*
import timber.log.Timber
@@ -32,22 +34,25 @@ class HomeNavigator {
private var rootRoomId: String? = null
+ fun openSelectedGroup(groupSummary: GroupSummary) {
+ Timber.v("Open selected group ${groupSummary.groupId}")
+ activity?.let {
+ val args = SelectedGroupParams(groupSummary.groupId, groupSummary.displayName, groupSummary.avatarUrl)
+ val selectedGroupFragment = SelectedGroupFragment.newInstance(args)
+ it.drawerLayout?.closeDrawer(GravityCompat.START)
+ it.replaceFragment(selectedGroupFragment, R.id.homeDetailFragmentContainer)
+ }
+ }
+
fun openRoomDetail(roomId: String,
- eventId: String?,
- addToBackstack: Boolean = false) {
- Timber.v("Open room detail $roomId - $eventId - $addToBackstack")
+ eventId: String?) {
+ Timber.v("Open room detail $roomId - $eventId")
activity?.let {
//TODO enable eventId permalink. It doesn't work enough at the moment.
- val args = RoomDetailArgs(roomId)
- val roomDetailFragment = RoomDetailFragment.newInstance(args)
it.drawerLayout?.closeDrawer(GravityCompat.START)
- if (addToBackstack) {
- it.addFragmentToBackstack(roomDetailFragment, R.id.homeDetailFragmentContainer, roomId)
- } else {
- rootRoomId = roomId
- clearBackStack(it.supportFragmentManager)
- it.replaceFragment(roomDetailFragment, R.id.homeDetailFragmentContainer)
- }
+ val args = RoomDetailArgs(roomId)
+ val roomDetailIntent = RoomDetailActivity.newIntent(it, args)
+ it.startActivity(roomDetailIntent)
}
}
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/HomePermalinkHandler.kt b/vector/src/main/java/im/vector/riotredesign/features/home/HomePermalinkHandler.kt
index 143ddb57de..f2a42a3310 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/HomePermalinkHandler.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/HomePermalinkHandler.kt
@@ -34,10 +34,10 @@ class HomePermalinkHandler(private val navigator: HomeNavigator) {
val permalinkData = PermalinkParser.parse(deepLink)
when (permalinkData) {
is PermalinkData.EventLink -> {
- navigator.openRoomDetail(permalinkData.roomIdOrAlias, permalinkData.eventId, true)
+ navigator.openRoomDetail(permalinkData.roomIdOrAlias, permalinkData.eventId)
}
is PermalinkData.RoomLink -> {
- navigator.openRoomDetail(permalinkData.roomIdOrAlias, null, true)
+ navigator.openRoomDetail(permalinkData.roomIdOrAlias, null)
}
is PermalinkData.GroupLink -> {
navigator.openGroupDetail(permalinkData.groupId)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/LoadingFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/LoadingFragment.kt
new file mode 100644
index 0000000000..de5eca7193
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/LoadingFragment.kt
@@ -0,0 +1,49 @@
+/*
+ *
+ * * Copyright 2019 New Vector Ltd
+ * *
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ *
+ */
+
+package im.vector.riotredesign.features.home
+
+import android.graphics.drawable.AnimationDrawable
+import android.os.Bundle
+import android.view.View
+import im.vector.riotredesign.R
+import im.vector.riotredesign.core.platform.VectorBaseFragment
+import kotlinx.android.synthetic.main.fragment_loading.*
+
+class LoadingFragment : VectorBaseFragment() {
+
+ companion object {
+
+ fun newInstance(): LoadingFragment {
+ return LoadingFragment()
+ }
+ }
+
+ override fun getLayoutResId() = R.layout.fragment_loading
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ val background = animatedLogoImageView.background
+ if (background is AnimationDrawable) {
+ background.start()
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupListFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupListFragment.kt
index 5ed550a2fd..884b7a6146 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupListFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupListFragment.kt
@@ -22,9 +22,11 @@ import com.airbnb.mvrx.Success
import com.airbnb.mvrx.fragmentViewModel
import im.vector.matrix.android.api.session.group.model.GroupSummary
import im.vector.riotredesign.R
+import im.vector.riotredesign.core.extensions.observeEvent
import im.vector.riotredesign.core.platform.StateView
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.home.HomeModule
+import im.vector.riotredesign.features.home.HomeNavigator
import kotlinx.android.synthetic.main.fragment_group_list.*
import org.koin.android.ext.android.inject
import org.koin.android.scope.ext.android.bindScope
@@ -39,6 +41,7 @@ class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback
}
private val viewModel: GroupListViewModel by fragmentViewModel()
+ private val homeNavigator by inject()
private val groupController by inject()
override fun getLayoutResId() = R.layout.fragment_group_list
@@ -50,6 +53,9 @@ class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback
stateView.contentView = epoxyRecyclerView
epoxyRecyclerView.setController(groupController)
viewModel.subscribe { renderState(it) }
+ viewModel.openGroupLiveData.observeEvent(this) {
+ homeNavigator.openSelectedGroup(it)
+ }
}
private fun renderState(state: GroupListViewState) {
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupListViewModel.kt b/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupListViewModel.kt
index 1cd2380282..bbe042dfea 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupListViewModel.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupListViewModel.kt
@@ -16,17 +16,25 @@
package im.vector.riotredesign.features.home.group
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
import arrow.core.Option
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext
import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.group.model.GroupSummary
import im.vector.matrix.rx.rx
import im.vector.riotredesign.core.platform.VectorViewModel
+import im.vector.riotredesign.core.resources.StringProvider
+import im.vector.riotredesign.core.utils.LiveEvent
import org.koin.android.ext.android.get
+const val ALL_COMMUNITIES_GROUP_ID = "ALL_COMMUNITIES_GROUP_ID"
+
class GroupListViewModel(initialState: GroupListViewState,
private val selectedGroupHolder: SelectedGroupStore,
- private val session: Session
+ private val session: Session,
+ private val stringProvider: StringProvider
) : VectorViewModel(initialState) {
companion object : MvRxViewModelFactory {
@@ -35,10 +43,15 @@ class GroupListViewModel(initialState: GroupListViewState,
override fun create(viewModelContext: ViewModelContext, state: GroupListViewState): GroupListViewModel? {
val currentSession = viewModelContext.activity.get()
val selectedGroupHolder = viewModelContext.activity.get()
- return GroupListViewModel(state, selectedGroupHolder, currentSession)
+ val stringProvider = viewModelContext.activity.get()
+ return GroupListViewModel(state, selectedGroupHolder, currentSession, stringProvider)
}
}
+ private val _openGroupLiveData = MutableLiveData>()
+ val openGroupLiveData: LiveData>
+ get() = _openGroupLiveData
+
init {
observeGroupSummaries()
observeState()
@@ -46,8 +59,8 @@ class GroupListViewModel(initialState: GroupListViewState,
private fun observeState() {
subscribe {
- val selectedGroup = Option.fromNullable(it.selectedGroup)
- selectedGroupHolder.post(selectedGroup)
+ val optionGroup = Option.fromNullable(it.selectedGroup)
+ selectedGroupHolder.post(optionGroup)
}
}
@@ -62,15 +75,21 @@ class GroupListViewModel(initialState: GroupListViewState,
private fun handleSelectGroup(action: GroupListActions.SelectGroup) = withState { state ->
if (state.selectedGroup?.groupId != action.groupSummary.groupId) {
setState { copy(selectedGroup = action.groupSummary) }
- } else {
- setState { copy(selectedGroup = null) }
+ _openGroupLiveData.postValue(LiveEvent(action.groupSummary))
}
}
-
private fun observeGroupSummaries() {
session
.rx().liveGroupSummaries()
+ .map {
+ val myUser = session.getUser(session.sessionParams.credentials.userId)
+ val allCommunityGroup = GroupSummary(
+ groupId = ALL_COMMUNITIES_GROUP_ID,
+ displayName = "All Communities",
+ avatarUrl = myUser?.avatarUrl ?: "")
+ listOf(allCommunityGroup) + it
+ }
.execute { async ->
copy(asyncGroups = async)
}
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryItem.kt
index eef0e8659a..2bb1f81e6e 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryItem.kt
@@ -16,13 +16,14 @@
package im.vector.riotredesign.features.home.group
+import android.view.ViewGroup
import android.widget.ImageView
+import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.riotredesign.R
import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
-import im.vector.riotredesign.core.platform.CheckableFrameLayout
import im.vector.riotredesign.features.home.AvatarRenderer
@EpoxyModelClass(layout = R.layout.item_group)
@@ -36,14 +37,15 @@ abstract class GroupSummaryItem : VectorEpoxyModel() {
override fun bind(holder: Holder) {
super.bind(holder)
- holder.rootView.isSelected = selected
holder.rootView.setOnClickListener { listener?.invoke() }
+ holder.groupNameView.text = groupName
AvatarRenderer.render(avatarUrl, groupId, groupName.toString(), holder.avatarImageView)
}
class Holder : VectorEpoxyHolder() {
val avatarImageView by bind(R.id.groupAvatarImageView)
- val rootView by bind(R.id.itemGroupLayout)
+ val groupNameView by bind(R.id.groupNameView)
+ val rootView by bind(R.id.itemGroupLayout)
}
}
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/group/SelectedGroupFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/group/SelectedGroupFragment.kt
new file mode 100644
index 0000000000..add2ef6f2b
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/group/SelectedGroupFragment.kt
@@ -0,0 +1,111 @@
+/*
+ *
+ * * Copyright 2019 New Vector Ltd
+ * *
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ *
+ */
+
+package im.vector.riotredesign.features.home.group
+
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.os.Parcelable
+import com.airbnb.mvrx.args
+import com.bumptech.glide.request.target.SimpleTarget
+import com.bumptech.glide.request.transition.Transition
+import im.vector.riotredesign.R
+import im.vector.riotredesign.core.extensions.replaceChildFragment
+import im.vector.riotredesign.core.glide.GlideApp
+import im.vector.riotredesign.core.platform.ToolbarConfigurable
+import im.vector.riotredesign.core.platform.VectorBaseFragment
+import im.vector.riotredesign.features.home.AvatarRenderer
+import im.vector.riotredesign.features.home.room.list.RoomListFragment
+import im.vector.riotredesign.features.home.room.list.RoomListParams
+import kotlinx.android.parcel.Parcelize
+import kotlinx.android.synthetic.main.fragment_selected_group.*
+
+@Parcelize
+data class SelectedGroupParams(
+ val groupId: String,
+ val groupName: String,
+ val groupAvatar: String
+) : Parcelable
+
+class SelectedGroupFragment : VectorBaseFragment() {
+
+ private val selectedGroupParams: SelectedGroupParams by args()
+
+ override fun getLayoutResId(): Int {
+ return R.layout.fragment_selected_group
+ }
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ if (savedInstanceState == null) {
+ updateSelectedFragment(RoomListFragment.DisplayMode.HOME)
+ toolbar.setTitle(RoomListFragment.DisplayMode.HOME.titleRes)
+ }
+ setupBottomNavigationView()
+ setupToolbar()
+ }
+
+ private fun setupToolbar() {
+ val parentActivity = vectorBaseActivity
+ if (parentActivity is ToolbarConfigurable) {
+ parentActivity.configure(toolbar)
+ }
+ val toolbarLogoTarget = object : SimpleTarget() {
+ override fun onResourceReady(resource: Drawable, transition: Transition?) {
+ toolbar.logo = resource
+ }
+ }
+ AvatarRenderer.render(
+ requireContext(),
+ GlideApp.with(this),
+ selectedGroupParams.groupAvatar,
+ selectedGroupParams.groupId,
+ selectedGroupParams.groupName,
+ toolbarLogoTarget
+ )
+ }
+
+ private fun setupBottomNavigationView() {
+ bottomNavigationView.setOnNavigationItemSelectedListener {
+ val displayMode = when {
+ it.itemId == R.id.bottom_action_people -> RoomListFragment.DisplayMode.PEOPLE
+ it.itemId == R.id.bottom_action_rooms -> RoomListFragment.DisplayMode.ROOMS
+ else -> RoomListFragment.DisplayMode.HOME
+ }
+ updateSelectedFragment(displayMode)
+ toolbar.setTitle(displayMode.titleRes)
+ true
+ }
+ }
+
+ private fun updateSelectedFragment(displayMode: RoomListFragment.DisplayMode) {
+ val roomListParams = RoomListParams(displayMode)
+ val roomListFragment = RoomListFragment.newInstance(roomListParams)
+ replaceChildFragment(roomListFragment, R.id.roomListContainer)
+ }
+
+ companion object {
+
+ fun newInstance(args: SelectedGroupParams): SelectedGroupFragment {
+ return SelectedGroupFragment().apply {
+ setArguments(args)
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/LoadingRoomDetailFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/LoadingRoomDetailFragment.kt
deleted file mode 100644
index eefb65662a..0000000000
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/LoadingRoomDetailFragment.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2019 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.riotredesign.features.home.room.detail
-
-import android.graphics.drawable.AnimationDrawable
-import android.os.Bundle
-import android.view.View
-import im.vector.riotredesign.R
-import im.vector.riotredesign.core.platform.VectorBaseFragment
-import kotlinx.android.synthetic.main.fragment_loading_room_detail.*
-
-class LoadingRoomDetailFragment : VectorBaseFragment() {
-
- companion object {
-
- fun newInstance(): LoadingRoomDetailFragment {
- return LoadingRoomDetailFragment()
- }
- }
-
- override fun getLayoutResId() = R.layout.fragment_loading_room_detail
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- val background = animatedLogoImageView.background
- if (background is AnimationDrawable) {
- background.start()
- }
- }
-
-
-}
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailActivity.kt
new file mode 100644
index 0000000000..fd79e8c123
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailActivity.kt
@@ -0,0 +1,57 @@
+/*
+ *
+ * * Copyright 2019 New Vector Ltd
+ * *
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ *
+ */
+
+package im.vector.riotredesign.features.home.room.detail
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import im.vector.riotredesign.R
+import im.vector.riotredesign.core.extensions.replaceFragment
+import im.vector.riotredesign.core.platform.VectorBaseActivity
+
+class RoomDetailActivity : VectorBaseActivity() {
+
+ override fun getLayoutRes(): Int {
+ return R.layout.activity_room_detail
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ if (savedInstanceState == null) {
+ val roomDetailArgs: RoomDetailArgs = intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS)
+ ?: return
+ val roomDetailFragment = RoomDetailFragment.newInstance(roomDetailArgs)
+ replaceFragment(roomDetailFragment, R.id.roomDetailContainer)
+ }
+ }
+
+ companion object {
+
+ private const val EXTRA_ROOM_DETAIL_ARGS = "EXTRA_ROOM_DETAIL_ARGS"
+
+ fun newIntent(context: Context, roomDetailArgs: RoomDetailArgs): Intent {
+ return Intent(context, RoomDetailActivity::class.java).apply {
+ putExtra(EXTRA_ROOM_DETAIL_ARGS, roomDetailArgs)
+ }
+ }
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt
index 0278607a8f..dbc7408a63 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt
@@ -64,7 +64,6 @@ import im.vector.riotredesign.core.epoxy.LayoutManagerStateRestorer
import im.vector.riotredesign.core.extensions.hideKeyboard
import im.vector.riotredesign.core.extensions.observeEvent
import im.vector.riotredesign.core.glide.GlideApp
-import im.vector.riotredesign.core.platform.ToolbarConfigurable
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.core.utils.*
import im.vector.riotredesign.features.autocomplete.command.AutocompleteCommandPresenter
@@ -170,7 +169,6 @@ class RoomDetailFragment :
actionViewModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java)
bindScope(getOrCreateScope(HomeModule.ROOM_DETAIL_SCOPE))
setupRecyclerView()
- setupToolbar()
setupComposer()
setupAttachmentButton()
setupInviteView()
@@ -194,7 +192,7 @@ class RoomDetailFragment :
if (resultCode == RESULT_OK && data != null) {
when (requestCode) {
REQUEST_FILES_REQUEST_CODE, TAKE_IMAGE_REQUEST_CODE -> handleMediaIntent(data)
- REACTION_SELECT_REQUEST_CODE -> {
+ REACTION_SELECT_REQUEST_CODE -> {
val eventId = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_EVENT_ID)
?: return
val reaction = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_REACTION_RESULT)
@@ -213,13 +211,6 @@ class RoomDetailFragment :
// PRIVATE METHODS *****************************************************************************
- private fun setupToolbar() {
- val parentActivity = vectorBaseActivity
- if (parentActivity is ToolbarConfigurable) {
- parentActivity.configure(toolbar)
- }
- }
-
private fun setupRecyclerView() {
val epoxyVisibilityTracker = EpoxyVisibilityTracker()
epoxyVisibilityTracker.attach(recyclerView)
@@ -362,24 +353,24 @@ class RoomDetailFragment :
private fun onSendChoiceClicked(dialogListItem: DialogListItem) {
Timber.v("On send choice clicked: $dialogListItem")
when (dialogListItem) {
- is DialogListItem.SendFile -> {
+ is DialogListItem.SendFile -> {
// launchFileIntent
}
- is DialogListItem.SendVoice -> {
+ is DialogListItem.SendVoice -> {
//launchAudioRecorderIntent()
}
- is DialogListItem.SendSticker -> {
+ is DialogListItem.SendSticker -> {
//startStickerPickerActivity()
}
is DialogListItem.TakePhotoVideo ->
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_CAMERA)) {
// launchCamera()
}
- is DialogListItem.TakePhoto ->
+ is DialogListItem.TakePhoto ->
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_CAMERA)) {
openCamera(requireActivity(), CAMERA_VALUE_TITLE, TAKE_IMAGE_REQUEST_CODE)
}
- is DialogListItem.TakeVideo ->
+ is DialogListItem.TakeVideo ->
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_VIDEO_CAMERA)) {
// launchNativeVideoRecorder()
}
@@ -426,20 +417,20 @@ class RoomDetailFragment :
private fun renderSendMessageResult(sendMessageResult: SendMessageResult) {
when (sendMessageResult) {
is SendMessageResult.MessageSent,
- is SendMessageResult.SlashCommandHandled -> {
+ is SendMessageResult.SlashCommandHandled -> {
// Clear composer
composerEditText.text = null
}
- is SendMessageResult.SlashCommandError -> {
+ is SendMessageResult.SlashCommandError -> {
displayCommandError(getString(R.string.command_problem_with_parameters, sendMessageResult.command.command))
}
- is SendMessageResult.SlashCommandUnknown -> {
+ is SendMessageResult.SlashCommandUnknown -> {
displayCommandError(getString(R.string.unrecognized_command, sendMessageResult.command))
}
- is SendMessageResult.SlashCommandResultOk -> {
+ is SendMessageResult.SlashCommandResultOk -> {
// Ignore
}
- is SendMessageResult.SlashCommandResultError -> {
+ is SendMessageResult.SlashCommandResultError -> {
displayCommandError(sendMessageResult.throwable.localizedMessage)
}
is SendMessageResult.SlashCommandNotImplemented -> {
@@ -537,22 +528,22 @@ class RoomDetailFragment :
it?.getContentIfNotHandled()?.let { actionData ->
when (actionData.actionId) {
- MessageMenuViewModel.ACTION_ADD_REACTION -> {
+ MessageMenuViewModel.ACTION_ADD_REACTION -> {
val eventId = actionData.data?.toString() ?: return
startActivityForResult(EmojiReactionPickerActivity.intent(requireContext(), eventId), REACTION_SELECT_REQUEST_CODE)
}
- MessageMenuViewModel.ACTION_COPY -> {
+ MessageMenuViewModel.ACTION_COPY -> {
//I need info about the current selected message :/
copyToClipboard(requireContext(), actionData.data?.toString() ?: "", false)
val snack = Snackbar.make(view!!, requireContext().getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT)
snack.view.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.notification_accent_color))
snack.show()
}
- MessageMenuViewModel.ACTION_DELETE -> {
+ MessageMenuViewModel.ACTION_DELETE -> {
val eventId = actionData.data?.toString() ?: return
roomDetailViewModel.process(RoomDetailActions.RedactAction(eventId, context?.getString(R.string.event_redacted_by_user_reason)))
}
- MessageMenuViewModel.ACTION_SHARE -> {
+ MessageMenuViewModel.ACTION_SHARE -> {
//TODO current data communication is too limited
//Need to now the media type
actionData.data?.toString()?.let {
@@ -595,13 +586,13 @@ class RoomDetailFragment :
.setPositiveButton(R.string.ok) { dialog, id -> dialog.cancel() }
.show()
}
- MessageMenuViewModel.ACTION_QUICK_REACT -> {
+ MessageMenuViewModel.ACTION_QUICK_REACT -> {
//eventId,ClickedOn,Opposite
(actionData.data as? Triple)?.let { (eventId, clickedOn, opposite) ->
roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(eventId, clickedOn, opposite))
}
}
- else -> {
+ else -> {
Toast.makeText(context, "Action ${actionData.actionId} not implemented", Toast.LENGTH_LONG).show()
}
}
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListFragment.kt
index 5a43a21e05..794c011d41 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListFragment.kt
@@ -17,8 +17,8 @@
package im.vector.riotredesign.features.home.room.list
import android.os.Bundle
-import android.text.Editable
-import android.text.TextWatcher
+import android.os.Parcelable
+import androidx.annotation.StringRes
import androidx.recyclerview.widget.LinearLayoutManager
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Incomplete
@@ -29,21 +29,35 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.riotredesign.R
import im.vector.riotredesign.core.epoxy.LayoutManagerStateRestorer
import im.vector.riotredesign.core.extensions.observeEvent
-import im.vector.riotredesign.core.extensions.setupAsSearch
import im.vector.riotredesign.core.platform.StateView
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.home.HomeModule
import im.vector.riotredesign.features.home.HomeNavigator
+import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.fragment_room_list.*
import org.koin.android.ext.android.inject
import org.koin.android.scope.ext.android.bindScope
import org.koin.android.scope.ext.android.getOrCreateScope
+@Parcelize
+data class RoomListParams(
+ val displayMode: RoomListFragment.DisplayMode
+) : Parcelable
+
+
class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback {
+ enum class DisplayMode(@StringRes val titleRes: Int) {
+ HOME(R.string.bottom_action_home),
+ PEOPLE(R.string.bottom_action_people),
+ ROOMS(R.string.bottom_action_rooms)
+ }
+
companion object {
- fun newInstance(): RoomListFragment {
- return RoomListFragment()
+ fun newInstance(roomListParams: RoomListParams): RoomListFragment {
+ return RoomListFragment().apply {
+ setArguments(roomListParams)
+ }
}
}
@@ -57,7 +71,6 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback {
super.onActivityCreated(savedInstanceState)
bindScope(getOrCreateScope(HomeModule.ROOM_LIST_SCOPE))
setupRecyclerView()
- setupFilterView()
roomListViewModel.subscribe { renderState(it) }
roomListViewModel.openRoomLiveData.observeEvent(this) {
homeNavigator.openRoomDetail(it, null)
@@ -74,19 +87,6 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback {
epoxyRecyclerView.setController(roomController)
}
- private fun setupFilterView() {
- filterRoomView.setupAsSearch()
- filterRoomView.addTextChangedListener(object : TextWatcher {
- override fun afterTextChanged(s: Editable?) = Unit
-
- override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
-
- override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
- roomListViewModel.accept(RoomListActions.FilterRooms(s))
- }
- })
- }
-
private fun renderState(state: RoomListViewState) {
when (state.asyncRooms) {
is Incomplete -> renderLoading()
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewModel.kt
index b9476ce528..fd9c19d315 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewModel.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewModel.kt
@@ -30,6 +30,7 @@ import im.vector.matrix.android.api.session.room.model.tag.RoomTag
import im.vector.matrix.rx.rx
import im.vector.riotredesign.core.platform.VectorViewModel
import im.vector.riotredesign.core.utils.LiveEvent
+import im.vector.riotredesign.features.home.group.ALL_COMMUNITIES_GROUP_ID
import im.vector.riotredesign.features.home.group.SelectedGroupStore
import im.vector.riotredesign.features.home.room.VisibleRoomStore
import io.reactivex.Observable
@@ -118,7 +119,7 @@ class RoomListViewModel(initialState: RoomListViewState,
val filteredDirectRooms = filteredRooms
.filter { it.isDirect }
.filter {
- if (selectedGroup == null) {
+ if (selectedGroup == null || selectedGroup.groupId == ALL_COMMUNITIES_GROUP_ID) {
true
} else {
it.otherMemberIds
@@ -130,7 +131,8 @@ class RoomListViewModel(initialState: RoomListViewState,
val filteredGroupRooms = filteredRooms
.filter { !it.isDirect }
.filter {
- selectedGroup?.roomIds?.contains(it.roomId) ?: true
+ selectedGroup?.groupId == ALL_COMMUNITIES_GROUP_ID
+ || selectedGroup?.roomIds?.contains(it.roomId) ?: true
}
buildRoomSummaries(filteredDirectRooms + filteredGroupRooms)
}
diff --git a/vector/src/main/res/layout/activity_room_detail.xml b/vector/src/main/res/layout/activity_room_detail.xml
new file mode 100644
index 0000000000..1dae010e2f
--- /dev/null
+++ b/vector/src/main/res/layout/activity_room_detail.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/layout/fragment_group_list.xml b/vector/src/main/res/layout/fragment_group_list.xml
index a075d51134..810fe3e47b 100644
--- a/vector/src/main/res/layout/fragment_group_list.xml
+++ b/vector/src/main/res/layout/fragment_group_list.xml
@@ -4,8 +4,7 @@
+ android:layout_height="match_parent">
-
+
+
+
+
+
+
+
+
+
+
+
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/homeDrawerHeader" />
\ No newline at end of file
diff --git a/vector/src/main/res/layout/fragment_loading_room_detail.xml b/vector/src/main/res/layout/fragment_loading.xml
similarity index 100%
rename from vector/src/main/res/layout/fragment_loading_room_detail.xml
rename to vector/src/main/res/layout/fragment_loading.xml
diff --git a/vector/src/main/res/layout/fragment_room_list.xml b/vector/src/main/res/layout/fragment_room_list.xml
index 6355db7727..19cfdd59c0 100644
--- a/vector/src/main/res/layout/fragment_room_list.xml
+++ b/vector/src/main/res/layout/fragment_room_list.xml
@@ -1,53 +1,15 @@
-
-
+
-
-
-
-
-
-
-
\ No newline at end of file
+
diff --git a/vector/src/main/res/layout/fragment_selected_group.xml b/vector/src/main/res/layout/fragment_selected_group.xml
new file mode 100644
index 0000000000..e2cd454db3
--- /dev/null
+++ b/vector/src/main/res/layout/fragment_selected_group.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/layout/item_group.xml b/vector/src/main/res/layout/item_group.xml
index 7dec77bebb..cfc230c92b 100644
--- a/vector/src/main/res/layout/item_group.xml
+++ b/vector/src/main/res/layout/item_group.xml
@@ -1,22 +1,48 @@
-
+ android:padding="16dp">
-
\ No newline at end of file
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/menu/selected_group_navigation.xml b/vector/src/main/res/menu/selected_group_navigation.xml
new file mode 100644
index 0000000000..e049195073
--- /dev/null
+++ b/vector/src/main/res/menu/selected_group_navigation.xml
@@ -0,0 +1,25 @@
+
+