Skip to content

Commit

Permalink
Merge pull request #7867 from vector-im/feature/mna/active-polls-ui
Browse files Browse the repository at this point in the history
[Poll] Render active polls list of a room (PSG-908)
  • Loading branch information
mnaturel authored Jan 6, 2023
2 parents b8da53b + 7fc9705 commit 41bcdd7
Show file tree
Hide file tree
Showing 23 changed files with 800 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog.d/7864.wip
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[Poll] Render active polls list of a room
3 changes: 3 additions & 0 deletions library/ui-strings/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2335,6 +2335,7 @@
<item quantity="one">"One person"</item>
<item quantity="other">"%1$d people"</item>
</plurals>
<string name="room_profile_section_more_polls">Poll history</string>
<string name="room_profile_section_more_uploads">Uploads</string>
<string name="room_profile_section_more_leave">Leave Room</string>
<string name="direct_room_profile_section_more_leave">Leave</string>
Expand Down Expand Up @@ -3190,6 +3191,8 @@
<string name="open_poll_option_description">Voters see results as soon as they have voted</string>
<string name="closed_poll_option_title">Closed poll</string>
<string name="closed_poll_option_description">Results are only revealed when you end the poll</string>
<string name="room_polls_active">Active polls</string>
<string name="room_polls_active_no_item">There are no active polls in this room</string>

<!-- Location -->
<string name="location_activity_title_static_sharing">Share location</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<*, *>
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -56,6 +57,7 @@ class RoomProfileController @Inject constructor(
fun onMemberListClicked()
fun onBannedMemberListClicked()
fun onNotificationsClicked()
fun onPollHistoryClicked()
fun onUploadsClicked()
fun createShortcut()
fun onSettingsClicked()
Expand Down Expand Up @@ -263,6 +265,15 @@ class RoomProfileController @Inject constructor(
action = { callback?.onBannedMemberListClicked() }
)
}
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),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,10 @@ class RoomProfileFragment :
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomNotificationSettings)
}

override fun onPollHistoryClicked() {
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomPolls)
}

override fun onUploadsClicked() {
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomUploads)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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: RoomPollsFilterType): Flow<List<PollSummary>> {
// TODO unmock and add unit tests
return when (filter) {
RoomPollsFilterType.ACTIVE -> getActivePolls()
RoomPollsFilterType.ENDED -> emptyFlow()
}.map { it.sortedByDescending { poll -> poll.creationTimestamp } }
}

private fun getActivePolls(): Flow<List<PollSummary.ActivePoll>> {
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?"
),
)
)
}
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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 im.vector.app.core.platform.VectorViewModelAction

sealed interface RoomPollsAction : VectorViewModelAction {
data class SetFilter(val filter: RoomPollsFilterType) : RoomPollsAction
}
Original file line number Diff line number Diff line change
@@ -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 RoomPollsFilterType {
ACTIVE,
ENDED,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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 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.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

@AndroidEntryPoint
class RoomPollsFragment : VectorBaseFragment<FragmentRoomPollsBinding>() {

private val roomProfileArgs: RoomProfileArgs by args()

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)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

setupToolbar()
setupTabs()
}

override fun onDestroyView() {
views.roomPollsViewPager.adapter = null
tabLayoutMediator?.detach()
tabLayoutMediator = null
super.onDestroyView()
}

private fun setupToolbar() {
setupToolbar(views.roomPollsToolbar)
.allowBack()
}

private fun setupTabs() {
views.roomPollsViewPager.adapter = RoomPollsPagerAdapter(this)

tabLayoutMediator = TabLayoutMediator(views.roomPollsTabs, views.roomPollsViewPager) { tab, position ->
when (position) {
0 -> tab.text = getString(R.string.room_polls_active)
}
}.also { it.attach() }
}
}
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* 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 im.vector.app.core.platform.VectorViewEvents

sealed class RoomPollsViewEvent : VectorViewEvents
Loading

0 comments on commit 41bcdd7

Please sign in to comment.