From e903dac22480525c97ba7ccc90cde41eeb811491 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 29 Dec 2022 15:40:59 +0100 Subject: [PATCH 01/21] Adding changelog entry --- changelog.d/7864.wip | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7864.wip diff --git a/changelog.d/7864.wip b/changelog.d/7864.wip new file mode 100644 index 0000000000..4dc55708be --- /dev/null +++ b/changelog.d/7864.wip @@ -0,0 +1 @@ +[Poll] Render active polls list of a room From cba960fbd782c91ab7de7e84c3635d3374ce3de2 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 29 Dec 2022 16:05:52 +0100 Subject: [PATCH 02/21] Adding new entry "Poll history" into room profile screen --- library/ui-strings/src/main/res/values/strings.xml | 1 + .../app/features/roomprofile/RoomProfileController.kt | 7 +++++++ .../vector/app/features/roomprofile/RoomProfileFragment.kt | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 73cb60bb68..d7e56fcbb0 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2335,6 +2335,7 @@ "One person" "%1$d people" + Poll history Uploads Leave Room Leave diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt index eb43a345f2..87f5657fc8 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt @@ -56,6 +56,7 @@ class RoomProfileController @Inject constructor( fun onMemberListClicked() fun onBannedMemberListClicked() fun onNotificationsClicked() + fun onPollHistoryClicked() fun onUploadsClicked() fun createShortcut() fun onSettingsClicked() @@ -263,6 +264,12 @@ class RoomProfileController @Inject constructor( action = { callback?.onBannedMemberListClicked() } ) } + buildProfileAction( + id = "poll_history", + title = stringProvider.getString(R.string.room_profile_section_more_polls), + icon = R.drawable.ic_attachment_poll, + action = { callback?.onPollHistoryClicked() } + ) buildProfileAction( id = "uploads", title = stringProvider.getString(R.string.room_profile_section_more_uploads), diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index f4394111ab..a06fdf9152 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -269,6 +269,10 @@ class RoomProfileFragment : roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomNotificationSettings) } + override fun onPollHistoryClicked() { + // TODO navigate to new screen + } + override fun onUploadsClicked() { roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomUploads) } From 7436c2e1f5a60ed8507c9df53b49bec014182e07 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 29 Dec 2022 16:41:42 +0100 Subject: [PATCH 03/21] Navigate to new empty screen --- .../app/core/di/MavericksViewModelModule.kt | 6 ++ .../roomprofile/RoomProfileActivity.kt | 6 ++ .../roomprofile/RoomProfileFragment.kt | 2 +- .../roomprofile/RoomProfileSharedAction.kt | 1 + .../roomprofile/polls/RoomPollsAction.kt | 21 +++++++ .../roomprofile/polls/RoomPollsFragment.kt | 61 +++++++++++++++++++ .../roomprofile/polls/RoomPollsViewEvent.kt | 21 +++++++ .../roomprofile/polls/RoomPollsViewModel.kt | 41 +++++++++++++ .../roomprofile/polls/RoomPollsViewState.kt | 27 ++++++++ .../main/res/layout/fragment_room_polls.xml | 30 +++++++++ 10 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt create mode 100644 vector/src/main/res/layout/fragment_room_polls.xml diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index d22ab51e7a..911bbfa4a3 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -84,6 +84,7 @@ import im.vector.app.features.roomprofile.banned.RoomBannedMemberListViewModel import im.vector.app.features.roomprofile.members.RoomMemberListViewModel import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsViewModel import im.vector.app.features.roomprofile.permissions.RoomPermissionsViewModel +import im.vector.app.features.roomprofile.polls.RoomPollsViewModel import im.vector.app.features.roomprofile.settings.RoomSettingsViewModel import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedViewModel import im.vector.app.features.roomprofile.uploads.RoomUploadsViewModel @@ -697,4 +698,9 @@ interface MavericksViewModelModule { @IntoMap @MavericksViewModelKey(SetLinkViewModel::class) fun setLinkViewModelFactory(factory: SetLinkViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + + @Binds + @IntoMap + @MavericksViewModelKey(RoomPollsViewModel::class) + fun roomPollsViewModelFactory(factory: RoomPollsViewModel.Factory): MavericksAssistedViewModelFactory<*, *> } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt index 526d676dee..3c37c92650 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt @@ -36,6 +36,7 @@ import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment import im.vector.app.features.roomprofile.members.RoomMemberListFragment import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsFragment import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment +import im.vector.app.features.roomprofile.polls.RoomPollsFragment import im.vector.app.features.roomprofile.settings.RoomSettingsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment import im.vector.lib.core.utils.compat.getParcelableCompat @@ -98,6 +99,7 @@ class RoomProfileActivity : RoomProfileSharedAction.OpenRoomSettings -> openRoomSettings() RoomProfileSharedAction.OpenRoomAliasesSettings -> openRoomAlias() RoomProfileSharedAction.OpenRoomPermissionsSettings -> openRoomPermissions() + RoomProfileSharedAction.OpenRoomPolls -> openRoomPolls() RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads() RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers() RoomProfileSharedAction.OpenRoomNotificationSettings -> openRoomNotificationSettings() @@ -126,6 +128,10 @@ class RoomProfileActivity : finish() } + private fun openRoomPolls() { + addFragmentToBackstack(views.simpleFragmentContainer, RoomPollsFragment::class.java, roomProfileArgs) + } + private fun openRoomUploads() { addFragmentToBackstack(views.simpleFragmentContainer, RoomUploadsFragment::class.java, roomProfileArgs) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index a06fdf9152..51885dbf39 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -270,7 +270,7 @@ class RoomProfileFragment : } override fun onPollHistoryClicked() { - // TODO navigate to new screen + roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomPolls) } override fun onUploadsClicked() { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt index 7d62bb86a1..b243ceb206 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt @@ -25,6 +25,7 @@ sealed class RoomProfileSharedAction : VectorSharedAction { object OpenRoomSettings : RoomProfileSharedAction() object OpenRoomAliasesSettings : RoomProfileSharedAction() object OpenRoomPermissionsSettings : RoomProfileSharedAction() + object OpenRoomPolls : RoomProfileSharedAction() object OpenRoomUploads : RoomProfileSharedAction() object OpenRoomMembers : RoomProfileSharedAction() object OpenBannedRoomMembers : RoomProfileSharedAction() diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt new file mode 100644 index 0000000000..895079ec90 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import im.vector.app.core.platform.VectorViewModelAction + +sealed class RoomPollsAction : VectorViewModelAction diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt new file mode 100644 index 0000000000..a33dfdf93d --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.airbnb.mvrx.args +import com.airbnb.mvrx.fragmentViewModel +import com.airbnb.mvrx.withState +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentRoomPollsBinding +import im.vector.app.features.roomprofile.RoomProfileArgs + +@AndroidEntryPoint +class RoomPollsFragment : VectorBaseFragment() { + + private val roomProfileArgs: RoomProfileArgs by args() + + private val viewModel: RoomPollsViewModel by fragmentViewModel() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsBinding { + return FragmentRoomPollsBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + setupToolbar() + setupTabs() + } + + private fun setupToolbar() { + setupToolbar(views.roomPollsToolbar) + .allowBack() + } + + private fun setupTabs() { + // TODO + } + + override fun invalidate() = withState(viewModel) { + // TODO + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt new file mode 100644 index 0000000000..3896abf84c --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import im.vector.app.core.platform.VectorViewEvents + +sealed class RoomPollsViewEvent : VectorViewEvents diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt new file mode 100644 index 0000000000..cfda5af0cf --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import com.airbnb.mvrx.MavericksViewModelFactory +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory +import im.vector.app.core.platform.VectorViewModel + +class RoomPollsViewModel @AssistedInject constructor( + @Assisted initialState: RoomPollsViewState, +) : VectorViewModel(initialState) { + + @AssistedFactory + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: RoomPollsViewState): RoomPollsViewModel + } + + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + + override fun handle(action: RoomPollsAction) { + // do nothing for now + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt new file mode 100644 index 0000000000..0233ddb693 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import com.airbnb.mvrx.MavericksState +import im.vector.app.features.roomprofile.RoomProfileArgs + +data class RoomPollsViewState( + val roomId: String, +) : MavericksState { + + constructor(roomProfileArgs: RoomProfileArgs) : this(roomId = roomProfileArgs.roomId) +} diff --git a/vector/src/main/res/layout/fragment_room_polls.xml b/vector/src/main/res/layout/fragment_room_polls.xml new file mode 100644 index 0000000000..b1b91e9a18 --- /dev/null +++ b/vector/src/main/res/layout/fragment_room_polls.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + From 10133bd20ffe12d059049d906079f3e74e57990f Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 29 Dec 2022 17:46:07 +0100 Subject: [PATCH 04/21] Setup tab layout when landing on the room polls screen --- .../src/main/res/values/strings.xml | 1 + .../roomprofile/polls/RoomPollsAction.kt | 2 +- .../roomprofile/polls/RoomPollsFragment.kt | 24 +++++++++---- .../polls/RoomPollsPagerAdapter.kt | 36 +++++++++++++++++++ .../roomprofile/polls/RoomPollsViewEvent.kt | 2 +- .../roomprofile/polls/RoomPollsViewModel.kt | 2 +- .../polls/active/RoomActivePollsFragment.kt | 35 ++++++++++++++++++ .../main/res/layout/fragment_room_polls.xml | 32 ++++++++++++++--- .../res/layout/fragment_room_polls_list.xml | 7 ++++ 9 files changed, 128 insertions(+), 13 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt create mode 100644 vector/src/main/res/layout/fragment_room_polls_list.xml diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index d7e56fcbb0..e0f2f7b288 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3191,6 +3191,7 @@ Voters see results as soon as they have voted Closed poll Results are only revealed when you end the poll + Active polls Share location diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt index 895079ec90..9d87f13f14 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright (c) 2022 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. diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt index a33dfdf93d..7617da71df 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright (c) 2022 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. @@ -22,8 +22,9 @@ import android.view.View import android.view.ViewGroup import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel -import com.airbnb.mvrx.withState +import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomPollsBinding import im.vector.app.features.roomprofile.RoomProfileArgs @@ -35,6 +36,8 @@ class RoomPollsFragment : VectorBaseFragment() { private val viewModel: RoomPollsViewModel by fragmentViewModel() + private var tabLayoutMediator: TabLayoutMediator? = null + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsBinding { return FragmentRoomPollsBinding.inflate(inflater, container, false) } @@ -46,16 +49,25 @@ class RoomPollsFragment : VectorBaseFragment() { setupTabs() } + override fun onDestroyView() { + views.roomPollsViewPager.adapter = null + tabLayoutMediator?.detach() + tabLayoutMediator = null + super.onDestroyView() + } + private fun setupToolbar() { setupToolbar(views.roomPollsToolbar) .allowBack() } private fun setupTabs() { - // TODO - } + views.roomPollsViewPager.adapter = RoomPollsPagerAdapter(this) - override fun invalidate() = withState(viewModel) { - // TODO + tabLayoutMediator = TabLayoutMediator(views.roomPollsTabs, views.roomPollsViewPager) { tab, position -> + when (position) { + 0 -> tab.text = getString(R.string.active_polls) + } + }.also { it.attach() } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt new file mode 100644 index 0000000000..5472782079 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import androidx.fragment.app.Fragment +import androidx.viewpager2.adapter.FragmentStateAdapter +import im.vector.app.features.roomprofile.polls.active.RoomActivePollsFragment + +class RoomPollsPagerAdapter( + private val fragment: Fragment +) : FragmentStateAdapter(fragment) { + + override fun getItemCount() = 1 + + override fun createFragment(position: Int): Fragment { + return instantiateFragment(RoomActivePollsFragment::class.java.name) + } + + private fun instantiateFragment(fragmentName: String): Fragment { + return fragment.childFragmentManager.fragmentFactory.instantiate(fragment.requireContext().classLoader, fragmentName) + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt index 3896abf84c..231123563a 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright (c) 2022 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. diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt index cfda5af0cf..42278ff976 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright (c) 2022 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. diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt new file mode 100644 index 0000000000..230da49b22 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls.active + +import android.view.LayoutInflater +import android.view.ViewGroup +import com.airbnb.mvrx.parentFragmentViewModel +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentRoomPollsListBinding +import im.vector.app.features.roomprofile.polls.RoomPollsViewModel + +@AndroidEntryPoint +class RoomActivePollsFragment : VectorBaseFragment() { + + private val viewModel: RoomPollsViewModel by parentFragmentViewModel(RoomPollsViewModel::class) + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsListBinding { + return FragmentRoomPollsListBinding.inflate(inflater, container, false) + } +} diff --git a/vector/src/main/res/layout/fragment_room_polls.xml b/vector/src/main/res/layout/fragment_room_polls.xml index b1b91e9a18..96a94cd9c5 100644 --- a/vector/src/main/res/layout/fragment_room_polls.xml +++ b/vector/src/main/res/layout/fragment_room_polls.xml @@ -1,7 +1,6 @@ @@ -21,10 +20,35 @@ + + + android:layout_width="0dp" + android:layout_height="0dp" + app:layout_behavior="@string/appbar_scrolling_view_behavior" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/roomPollsTabs" /> diff --git a/vector/src/main/res/layout/fragment_room_polls_list.xml b/vector/src/main/res/layout/fragment_room_polls_list.xml new file mode 100644 index 0000000000..1d672087a9 --- /dev/null +++ b/vector/src/main/res/layout/fragment_room_polls_list.xml @@ -0,0 +1,7 @@ + + + + + From 9f97579f9dc4c928fd8f95449fde3a10b8f77040 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 10:07:50 +0100 Subject: [PATCH 05/21] Epoxy model for active poll --- .../polls/active/ActivePollItem.kt | 51 +++++++++++++++++++ .../src/main/res/layout/item_poll_active.xml | 42 +++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt create mode 100644 vector/src/main/res/layout/item_poll_active.xml diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt new file mode 100644 index 0000000000..2a927653f1 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls.active + +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.app.R +import im.vector.app.core.epoxy.ClickListener +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick + +@EpoxyModelClass +abstract class ActivePollItem : VectorEpoxyModel(R.layout.item_poll_active) { + + @EpoxyAttribute + lateinit var formattedDate: String + + @EpoxyAttribute + lateinit var title: String + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var clickListener: ClickListener? = null + + override fun bind(holder: Holder) { + super.bind(holder) + holder.view.onClick(clickListener) + holder.date.text = formattedDate + holder.title.text = title + } + + class Holder : VectorEpoxyHolder() { + val date by bind(R.id.pollActiveDate) + val title by bind(R.id.pollActiveTitle) + } +} diff --git a/vector/src/main/res/layout/item_poll_active.xml b/vector/src/main/res/layout/item_poll_active.xml new file mode 100644 index 0000000000..8cf6c9e576 --- /dev/null +++ b/vector/src/main/res/layout/item_poll_active.xml @@ -0,0 +1,42 @@ + + + + + + + + + + From 7b63f891c33ffbb28d42491ac4ac48b89aef0a4e Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 10:42:42 +0100 Subject: [PATCH 06/21] Epoxy controller to render active poll list --- .../features/roomprofile/polls/PollSummary.kt | 25 ++++++++++ .../roomprofile/polls/RoomPollsViewState.kt | 1 + .../polls/active/RoomActivePollsController.kt | 49 +++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt new file mode 100644 index 0000000000..3eb45c6144 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +sealed interface PollSummary { + data class ActivePoll( + val id: String, + val creationTimestamp: Long, + val title: String, + ) : PollSummary +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt index 0233ddb693..74794c99b1 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt @@ -21,6 +21,7 @@ import im.vector.app.features.roomprofile.RoomProfileArgs data class RoomPollsViewState( val roomId: String, + val polls: List = emptyList(), ) : MavericksState { constructor(roomProfileArgs: RoomProfileArgs) : this(roomId = roomProfileArgs.roomId) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt new file mode 100644 index 0000000000..9f26569e58 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls.active + +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.core.date.DateFormatKind +import im.vector.app.core.date.VectorDateFormatter +import im.vector.app.features.roomprofile.polls.PollSummary +import javax.inject.Inject + +class RoomActivePollsController @Inject constructor( + val dateFormatter: VectorDateFormatter, +) : TypedEpoxyController>() { + + interface Listener { + fun onPollClicked(pollId: String) + } + + var listener: Listener? = null + + override fun buildModels(data: List?) { + if (data == null) return + + val host = this + data.forEach { poll -> + activePollItem { + formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.EDIT_HISTORY_HEADER)) + title(poll.title) + clickListener { + host.listener?.onPollClicked(poll.id) + } + } + } + } +} From f20513eb16602a7b05d02231ca784215f0a28551 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 10:56:44 +0100 Subject: [PATCH 07/21] Render the active polls list on fragment --- .../polls/active/RoomActivePollsFragment.kt | 45 ++++++++++++++++++- .../res/layout/fragment_room_polls_list.xml | 13 ++++++ .../src/main/res/layout/item_poll_active.xml | 1 + 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index 230da49b22..10518d4b18 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -16,20 +16,63 @@ package im.vector.app.features.roomprofile.polls.active +import android.os.Bundle import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import com.airbnb.mvrx.parentFragmentViewModel +import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.extensions.cleanup import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomPollsListBinding +import im.vector.app.features.roomprofile.polls.PollSummary import im.vector.app.features.roomprofile.polls.RoomPollsViewModel +import javax.inject.Inject @AndroidEntryPoint -class RoomActivePollsFragment : VectorBaseFragment() { +class RoomActivePollsFragment : + VectorBaseFragment(), + RoomActivePollsController.Listener { + + @Inject + lateinit var roomActivePollsController: RoomActivePollsController private val viewModel: RoomPollsViewModel by parentFragmentViewModel(RoomPollsViewModel::class) override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsListBinding { return FragmentRoomPollsListBinding.inflate(inflater, container, false) } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupList() + } + + private fun setupList() { + roomActivePollsController.listener = this + views.activePollsList.adapter = roomActivePollsController.adapter + } + + override fun onDestroyView() { + cleanUpList() + super.onDestroyView() + } + + private fun cleanUpList() { + views.activePollsList.cleanup() + roomActivePollsController.listener = null + } + + override fun invalidate() = withState(viewModel) { viewState -> + renderList(viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)) + } + + private fun renderList(polls: List) { + roomActivePollsController.setData(polls) + } + + override fun onPollClicked(pollId: String) { + // TODO navigate to details + } } diff --git a/vector/src/main/res/layout/fragment_room_polls_list.xml b/vector/src/main/res/layout/fragment_room_polls_list.xml index 1d672087a9..39add6a298 100644 --- a/vector/src/main/res/layout/fragment_room_polls_list.xml +++ b/vector/src/main/res/layout/fragment_room_polls_list.xml @@ -1,7 +1,20 @@ + + diff --git a/vector/src/main/res/layout/item_poll_active.xml b/vector/src/main/res/layout/item_poll_active.xml index 8cf6c9e576..2db6450f94 100644 --- a/vector/src/main/res/layout/item_poll_active.xml +++ b/vector/src/main/res/layout/item_poll_active.xml @@ -10,6 +10,7 @@ android:id="@+id/pollActiveDate" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginTop="32dp" android:textAppearance="@style/TextAppearance.Vector.Caption" android:textColor="?vctr_content_tertiary" app:layout_constraintStart_toStartOf="parent" From 77d3b7da04b0e8e2cd9ff6ab44392565675eef11 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 11:40:41 +0100 Subject: [PATCH 08/21] Fix missing id in Epoxy model --- .../roomprofile/polls/active/RoomActivePollsController.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt index 9f26569e58..fd32ae51d0 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt @@ -38,6 +38,7 @@ class RoomActivePollsController @Inject constructor( val host = this data.forEach { poll -> activePollItem { + id(poll.id) formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.EDIT_HISTORY_HEADER)) title(poll.title) clickListener { From 8de86e74807339f5a02abcea6fd5c1452ffc68c9 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 11:59:48 +0100 Subject: [PATCH 09/21] Render mocked data get from use case --- .../roomprofile/polls/GetPollsUseCase.kt | 65 +++++++++++++++++++ .../roomprofile/polls/RoomPollsAction.kt | 4 +- .../roomprofile/polls/RoomPollsFilter.kt | 22 +++++++ .../roomprofile/polls/RoomPollsViewModel.kt | 23 ++++++- .../polls/active/RoomActivePollsFragment.kt | 10 ++- .../res/layout/fragment_room_polls_list.xml | 3 +- 6 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt new file mode 100644 index 0000000000..fa8c6d0aa6 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map +import javax.inject.Inject + +class GetPollsUseCase @Inject constructor() { + + fun execute(filter: RoomPollsFilter): Flow> { + // TODO unmock and add unit tests + return when (filter) { + RoomPollsFilter.ACTIVE -> getActivePolls() + RoomPollsFilter.ENDED -> emptyFlow() + }.map { it.sortedByDescending { poll -> poll.creationTimestamp } } + } + + private fun getActivePolls(): Flow> { + return flowOf( + listOf( + PollSummary.ActivePoll( + id = "id1", + // 2022/06/28 UTC+1 + creationTimestamp = 1656367200000, + title = "Which charity would you like to support?" + ), + PollSummary.ActivePoll( + id = "id2", + // 2022/06/26 UTC+1 + creationTimestamp = 1656194400000, + title = "Which sport should the pupils do this year?" + ), + PollSummary.ActivePoll( + id = "id3", + // 2022/06/24 UTC+1 + creationTimestamp = 1656021600000, + title = "What type of food should we have at the party?" + ), + PollSummary.ActivePoll( + id = "id4", + // 2022/06/22 UTC+1 + creationTimestamp = 1655848800000, + title = "What film should we show at the end of the year party?" + ), + ) + ) + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt index 9d87f13f14..27753b6d16 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt @@ -18,4 +18,6 @@ package im.vector.app.features.roomprofile.polls import im.vector.app.core.platform.VectorViewModelAction -sealed class RoomPollsAction : VectorViewModelAction +sealed interface RoomPollsAction : VectorViewModelAction { + data class SetFilter(val filter: RoomPollsFilter) : RoomPollsAction +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt new file mode 100644 index 0000000000..68ebb13f7d --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +enum class RoomPollsFilter { + ACTIVE, + ENDED, +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt index 42278ff976..27ba6679d8 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -23,9 +23,13 @@ import dagger.assisted.AssistedInject import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach class RoomPollsViewModel @AssistedInject constructor( @Assisted initialState: RoomPollsViewState, + private val getPollsUseCase: GetPollsUseCase, ) : VectorViewModel(initialState) { @AssistedFactory @@ -35,7 +39,24 @@ class RoomPollsViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + private var pollsCollectionJob: Job? = null + + // TODO add unit tests override fun handle(action: RoomPollsAction) { - // do nothing for now + when (action) { + is RoomPollsAction.SetFilter -> handleSetFilter(action.filter) + } + } + + override fun onCleared() { + pollsCollectionJob = null + super.onCleared() + } + + private fun handleSetFilter(filter: RoomPollsFilter) { + pollsCollectionJob?.cancel() + pollsCollectionJob = getPollsUseCase.execute(filter) + .onEach { setState { copy(polls = it) } } + .launchIn(viewModelScope) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index 10518d4b18..ed851a045d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -24,9 +24,12 @@ import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.extensions.cleanup +import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomPollsListBinding import im.vector.app.features.roomprofile.polls.PollSummary +import im.vector.app.features.roomprofile.polls.RoomPollsAction +import im.vector.app.features.roomprofile.polls.RoomPollsFilter import im.vector.app.features.roomprofile.polls.RoomPollsViewModel import javax.inject.Inject @@ -51,7 +54,7 @@ class RoomActivePollsFragment : private fun setupList() { roomActivePollsController.listener = this - views.activePollsList.adapter = roomActivePollsController.adapter + views.activePollsList.configureWith(roomActivePollsController) } override fun onDestroyView() { @@ -64,6 +67,11 @@ class RoomActivePollsFragment : roomActivePollsController.listener = null } + override fun onResume() { + super.onResume() + viewModel.handle(RoomPollsAction.SetFilter(RoomPollsFilter.ACTIVE)) + } + override fun invalidate() = withState(viewModel) { viewState -> renderList(viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)) } diff --git a/vector/src/main/res/layout/fragment_room_polls_list.xml b/vector/src/main/res/layout/fragment_room_polls_list.xml index 39add6a298..1aa6625ae5 100644 --- a/vector/src/main/res/layout/fragment_room_polls_list.xml +++ b/vector/src/main/res/layout/fragment_room_polls_list.xml @@ -8,8 +8,9 @@ Date: Fri, 30 Dec 2022 12:08:55 +0100 Subject: [PATCH 10/21] Allow access of poll history only in debug variant --- .../roomprofile/RoomProfileController.kt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt index 87f5657fc8..30bd6c7ed3 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt @@ -18,6 +18,7 @@ package im.vector.app.features.roomprofile import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.epoxy.expandableTextItem import im.vector.app.core.epoxy.profiles.buildProfileAction @@ -264,12 +265,15 @@ class RoomProfileController @Inject constructor( action = { callback?.onBannedMemberListClicked() } ) } - buildProfileAction( - id = "poll_history", - title = stringProvider.getString(R.string.room_profile_section_more_polls), - icon = R.drawable.ic_attachment_poll, - action = { callback?.onPollHistoryClicked() } - ) + if (BuildConfig.DEBUG) { + // WIP, will be in release when related screens will be finished + buildProfileAction( + id = "poll_history", + title = stringProvider.getString(R.string.room_profile_section_more_polls), + icon = R.drawable.ic_attachment_poll, + action = { callback?.onPollHistoryClicked() } + ) + } buildProfileAction( id = "uploads", title = stringProvider.getString(R.string.room_profile_section_more_uploads), From 71b7edc6f2c095f476fda596cdc6cbaf2b3ca159 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 12:12:57 +0100 Subject: [PATCH 11/21] Adding debug log --- .../roomprofile/polls/active/RoomActivePollsFragment.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index ed851a045d..b4e812a49e 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -31,6 +31,7 @@ import im.vector.app.features.roomprofile.polls.PollSummary import im.vector.app.features.roomprofile.polls.RoomPollsAction import im.vector.app.features.roomprofile.polls.RoomPollsFilter import im.vector.app.features.roomprofile.polls.RoomPollsViewModel +import timber.log.Timber import javax.inject.Inject @AndroidEntryPoint @@ -82,5 +83,6 @@ class RoomActivePollsFragment : override fun onPollClicked(pollId: String) { // TODO navigate to details + Timber.d("poll with id $pollId clicked") } } From bc985aa1ef310e5fe45cbaefc4b4cab71fa71dc8 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 14:19:50 +0100 Subject: [PATCH 12/21] Adding unit tests for ViewModel --- .../roomprofile/polls/RoomPollsViewModel.kt | 5 +- .../polls/RoomPollsViewModelTest.kt | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt index 27ba6679d8..7def7a508d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -16,6 +16,7 @@ package im.vector.app.features.roomprofile.polls +import androidx.annotation.VisibleForTesting import com.airbnb.mvrx.MavericksViewModelFactory import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -39,9 +40,9 @@ class RoomPollsViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() - private var pollsCollectionJob: Job? = null + @VisibleForTesting + var pollsCollectionJob: Job? = null - // TODO add unit tests override fun handle(action: RoomPollsAction) { when (action) { is RoomPollsAction.SetFilter -> handleSetFilter(action.filter) diff --git a/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt b/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt new file mode 100644 index 0000000000..54b2a60d55 --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import com.airbnb.mvrx.test.MavericksTestRule +import im.vector.app.test.test +import im.vector.app.test.testDispatcher +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.flow.flowOf +import org.amshove.kluent.shouldNotBeNull +import org.junit.Rule +import org.junit.Test + +private const val ROOM_ID = "room-id" + +class RoomPollsViewModelTest { + + @get:Rule + val mavericksTestRule = MavericksTestRule(testDispatcher = testDispatcher) + + private val fakeGetPollsUseCase = mockk() + private val initialState = RoomPollsViewState(ROOM_ID) + + private fun createViewModel(): RoomPollsViewModel { + return RoomPollsViewModel( + initialState = initialState, + getPollsUseCase = fakeGetPollsUseCase, + ) + } + + @Test + fun `given SetFilter action when handle then useCase is called with given filter and viewState is updated`() { + // Given + val filter = RoomPollsFilter.ACTIVE + val action = RoomPollsAction.SetFilter(filter = filter) + val polls = listOf(givenAPollSummary()) + every { fakeGetPollsUseCase.execute(any()) } returns flowOf(polls) + val viewModel = createViewModel() + val expectedViewState = initialState.copy(polls = polls) + + // When + val viewModelTest = viewModel.test() + viewModel.pollsCollectionJob = null + viewModel.handle(action) + + // Then + viewModelTest + .assertLatestState(expectedViewState) + .finish() + viewModel.pollsCollectionJob.shouldNotBeNull() + verify { + viewModel.pollsCollectionJob?.cancel() + fakeGetPollsUseCase.execute(filter) + } + } + + private fun givenAPollSummary(): PollSummary { + return mockk() + } +} From e0b77936c1e4325387a1e06e4d4fef34bd7acfdd Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 14:27:11 +0100 Subject: [PATCH 13/21] Changing the date format --- .../roomprofile/polls/active/RoomActivePollsController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt index fd32ae51d0..2fab886282 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt @@ -39,7 +39,7 @@ class RoomActivePollsController @Inject constructor( data.forEach { poll -> activePollItem { id(poll.id) - formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.EDIT_HISTORY_HEADER)) + formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)) title(poll.title) clickListener { host.listener?.onPollClicked(poll.id) From bd9c53a96c96aa870d3edcb8db44a52f6afb2d42 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 14:57:37 +0100 Subject: [PATCH 14/21] Show message when list is empty --- .../src/main/res/values/strings.xml | 3 ++- .../roomprofile/polls/RoomPollsFragment.kt | 2 +- .../polls/active/RoomActivePollsFragment.kt | 8 +++++-- .../res/layout/fragment_room_polls_list.xml | 23 ++++++++++++++++++- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index e0f2f7b288..43507e60ce 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3191,7 +3191,8 @@ Voters see results as soon as they have voted Closed poll Results are only revealed when you end the poll - Active polls + Active polls + There are no active polls in this room Share location diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt index 7617da71df..5c150f4391 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt @@ -66,7 +66,7 @@ class RoomPollsFragment : VectorBaseFragment() { tabLayoutMediator = TabLayoutMediator(views.roomPollsTabs, views.roomPollsViewPager) { tab, position -> when (position) { - 0 -> tab.text = getString(R.string.active_polls) + 0 -> tab.text = getString(R.string.room_polls_active) } }.also { it.attach() } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index b4e812a49e..4cc318edf9 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -20,9 +20,11 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.isVisible import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment @@ -55,7 +57,8 @@ class RoomActivePollsFragment : private fun setupList() { roomActivePollsController.listener = this - views.activePollsList.configureWith(roomActivePollsController) + views.roomPollsList.configureWith(roomActivePollsController) + views.roomPollsEmptyTitle.text = getString(R.string.room_polls_active_no_item) } override fun onDestroyView() { @@ -64,7 +67,7 @@ class RoomActivePollsFragment : } private fun cleanUpList() { - views.activePollsList.cleanup() + views.roomPollsList.cleanup() roomActivePollsController.listener = null } @@ -79,6 +82,7 @@ class RoomActivePollsFragment : private fun renderList(polls: List) { roomActivePollsController.setData(polls) + views.roomPollsEmptyTitle.isVisible = polls.isEmpty() } override fun onPollClicked(pollId: String) { diff --git a/vector/src/main/res/layout/fragment_room_polls_list.xml b/vector/src/main/res/layout/fragment_room_polls_list.xml index 1aa6625ae5..6949bb0c67 100644 --- a/vector/src/main/res/layout/fragment_room_polls_list.xml +++ b/vector/src/main/res/layout/fragment_room_polls_list.xml @@ -6,7 +6,7 @@ android:layout_height="match_parent"> + + + From 6c0c5e506408d242ce1792ddd833c41836e573c3 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 15:12:12 +0100 Subject: [PATCH 15/21] Rename poll item layout to be more generic --- .../app/features/roomprofile/polls/active/ActivePollItem.kt | 2 +- vector/src/main/res/layout/fragment_room_polls_list.xml | 2 +- .../src/main/res/layout/{item_poll_active.xml => item_poll.xml} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename vector/src/main/res/layout/{item_poll_active.xml => item_poll.xml} (100%) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt index 2a927653f1..35b1ecd6e1 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt @@ -26,7 +26,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.onClick @EpoxyModelClass -abstract class ActivePollItem : VectorEpoxyModel(R.layout.item_poll_active) { +abstract class ActivePollItem : VectorEpoxyModel(R.layout.item_poll) { @EpoxyAttribute lateinit var formattedDate: String diff --git a/vector/src/main/res/layout/fragment_room_polls_list.xml b/vector/src/main/res/layout/fragment_room_polls_list.xml index 6949bb0c67..8eb27e5e00 100644 --- a/vector/src/main/res/layout/fragment_room_polls_list.xml +++ b/vector/src/main/res/layout/fragment_room_polls_list.xml @@ -15,7 +15,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:itemCount="5" - tools:listitem="@layout/item_poll_active" /> + tools:listitem="@layout/item_poll" /> Date: Fri, 30 Dec 2022 15:48:14 +0100 Subject: [PATCH 16/21] Replace usage of colorAccent --- vector/src/main/res/layout/fragment_room_polls.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vector/src/main/res/layout/fragment_room_polls.xml b/vector/src/main/res/layout/fragment_room_polls.xml index 96a94cd9c5..dcaf483251 100644 --- a/vector/src/main/res/layout/fragment_room_polls.xml +++ b/vector/src/main/res/layout/fragment_room_polls.xml @@ -24,22 +24,22 @@ android:id="@+id/roomPollsTabs" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginTop="20dp" android:layout_marginHorizontal="10dp" + android:layout_marginTop="20dp" android:background="?android:colorBackground" app:layout_constraintBottom_toTopOf="@id/roomPollsViewPager" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/appBarLayout" + app:tabGravity="start" app:tabIndicatorFullWidth="false" app:tabIndicatorHeight="1dp" - app:tabPaddingBottom="-15dp" - app:tabTextColor="?vctr_content_primary" - app:tabSelectedTextColor="?colorAccent" - app:tabTextAppearance="@style/TextAppearance.Vector.Body" - app:tabGravity="start" app:tabMaxWidth="0dp" - app:tabMode="scrollable" /> + app:tabMode="scrollable" + app:tabPaddingBottom="-15dp" + app:tabSelectedTextColor="?colorSecondary" + app:tabTextAppearance="@style/TextAppearance.Vector.Body" + app:tabTextColor="?vctr_content_primary" /> Date: Fri, 30 Dec 2022 16:45:28 +0100 Subject: [PATCH 17/21] Ignore missing ContentDescription --- .../roomprofile/polls/active/RoomActivePollsController.kt | 4 +++- vector/src/main/res/layout/item_poll.xml | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt index 2fab886282..dc14ec366d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt @@ -33,7 +33,9 @@ class RoomActivePollsController @Inject constructor( var listener: Listener? = null override fun buildModels(data: List?) { - if (data == null) return + if (data.isNullOrEmpty()) { + return + } val host = this data.forEach { poll -> diff --git a/vector/src/main/res/layout/item_poll.xml b/vector/src/main/res/layout/item_poll.xml index 2db6450f94..05e9b3a62a 100644 --- a/vector/src/main/res/layout/item_poll.xml +++ b/vector/src/main/res/layout/item_poll.xml @@ -25,7 +25,8 @@ android:src="@drawable/ic_attachment_poll" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/pollActiveDate" - app:tint="?vctr_content_secondary" /> + app:tint="?vctr_content_secondary" + tools:ignore="ContentDescription" /> Date: Thu, 5 Jan 2023 15:09:41 +0100 Subject: [PATCH 18/21] Renaming of filter enum --- .../app/features/roomprofile/polls/GetPollsUseCase.kt | 6 +++--- .../app/features/roomprofile/polls/RoomPollsAction.kt | 2 +- .../polls/{RoomPollsFilter.kt => RoomPollsFilterType.kt} | 2 +- .../app/features/roomprofile/polls/RoomPollsViewModel.kt | 2 +- .../roomprofile/polls/active/RoomActivePollsFragment.kt | 4 ++-- .../features/roomprofile/polls/RoomPollsViewModelTest.kt | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename vector/src/main/java/im/vector/app/features/roomprofile/polls/{RoomPollsFilter.kt => RoomPollsFilterType.kt} (95%) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt index fa8c6d0aa6..d35d192e04 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt @@ -24,11 +24,11 @@ import javax.inject.Inject class GetPollsUseCase @Inject constructor() { - fun execute(filter: RoomPollsFilter): Flow> { + fun execute(filter: RoomPollsFilterType): Flow> { // TODO unmock and add unit tests return when (filter) { - RoomPollsFilter.ACTIVE -> getActivePolls() - RoomPollsFilter.ENDED -> emptyFlow() + RoomPollsFilterType.ACTIVE -> getActivePolls() + RoomPollsFilterType.ENDED -> emptyFlow() }.map { it.sortedByDescending { poll -> poll.creationTimestamp } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt index 27753b6d16..5f074bdd6f 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt @@ -19,5 +19,5 @@ package im.vector.app.features.roomprofile.polls import im.vector.app.core.platform.VectorViewModelAction sealed interface RoomPollsAction : VectorViewModelAction { - data class SetFilter(val filter: RoomPollsFilter) : RoomPollsAction + data class SetFilter(val filter: RoomPollsFilterType) : RoomPollsAction } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilterType.kt similarity index 95% rename from vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt rename to vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilterType.kt index 68ebb13f7d..39f1163536 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilterType.kt @@ -16,7 +16,7 @@ package im.vector.app.features.roomprofile.polls -enum class RoomPollsFilter { +enum class RoomPollsFilterType { ACTIVE, ENDED, } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt index 7def7a508d..7bc06894fa 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -54,7 +54,7 @@ class RoomPollsViewModel @AssistedInject constructor( super.onCleared() } - private fun handleSetFilter(filter: RoomPollsFilter) { + private fun handleSetFilter(filter: RoomPollsFilterType) { pollsCollectionJob?.cancel() pollsCollectionJob = getPollsUseCase.execute(filter) .onEach { setState { copy(polls = it) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index 4cc318edf9..61c7e961bd 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -31,7 +31,7 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomPollsListBinding import im.vector.app.features.roomprofile.polls.PollSummary import im.vector.app.features.roomprofile.polls.RoomPollsAction -import im.vector.app.features.roomprofile.polls.RoomPollsFilter +import im.vector.app.features.roomprofile.polls.RoomPollsFilterType import im.vector.app.features.roomprofile.polls.RoomPollsViewModel import timber.log.Timber import javax.inject.Inject @@ -73,7 +73,7 @@ class RoomActivePollsFragment : override fun onResume() { super.onResume() - viewModel.handle(RoomPollsAction.SetFilter(RoomPollsFilter.ACTIVE)) + viewModel.handle(RoomPollsAction.SetFilter(RoomPollsFilterType.ACTIVE)) } override fun invalidate() = withState(viewModel) { viewState -> diff --git a/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt b/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt index 54b2a60d55..0dce2dd6e0 100644 --- a/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt @@ -47,7 +47,7 @@ class RoomPollsViewModelTest { @Test fun `given SetFilter action when handle then useCase is called with given filter and viewState is updated`() { // Given - val filter = RoomPollsFilter.ACTIVE + val filter = RoomPollsFilterType.ACTIVE val action = RoomPollsAction.SetFilter(filter = filter) val polls = listOf(givenAPollSummary()) every { fakeGetPollsUseCase.execute(any()) } returns flowOf(polls) From ff9e78be42c500fd3a0985cadb9db67be8c54df3 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:20:20 +0100 Subject: [PATCH 19/21] Use classical for loop instead of forEach --- .../roomprofile/polls/active/RoomActivePollsController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt index dc14ec366d..7a7c818693 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt @@ -38,7 +38,7 @@ class RoomActivePollsController @Inject constructor( } val host = this - data.forEach { poll -> + for (poll in data) { activePollItem { id(poll.id) formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)) From 2dab6ed052912e6296b643d15b30c69ce0df7516 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:27:11 +0100 Subject: [PATCH 20/21] Fix horizontal margin of tabs --- vector/src/main/res/layout/fragment_room_polls.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/layout/fragment_room_polls.xml b/vector/src/main/res/layout/fragment_room_polls.xml index dcaf483251..396d6fd8c5 100644 --- a/vector/src/main/res/layout/fragment_room_polls.xml +++ b/vector/src/main/res/layout/fragment_room_polls.xml @@ -24,7 +24,7 @@ android:id="@+id/roomPollsTabs" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginHorizontal="10dp" + android:layout_marginHorizontal="4dp" android:layout_marginTop="20dp" android:background="?android:colorBackground" app:layout_constraintBottom_toTopOf="@id/roomPollsViewPager" From 7fc9705f3a92d392b0ce8855ecd79e6abb32cc40 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 5 Jan 2023 16:37:06 +0100 Subject: [PATCH 21/21] Adding importantForAccessibility attribute to icon --- vector/src/main/res/layout/item_poll.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/layout/item_poll.xml b/vector/src/main/res/layout/item_poll.xml index 05e9b3a62a..956ecf9b3c 100644 --- a/vector/src/main/res/layout/item_poll.xml +++ b/vector/src/main/res/layout/item_poll.xml @@ -22,6 +22,7 @@ android:layout_width="16dp" android:layout_height="16dp" android:layout_marginTop="12dp" + android:importantForAccessibility="no" android:src="@drawable/ic_attachment_poll" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/pollActiveDate"