mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-17 02:15:17 +08:00
Implement bottom sheet controller.
This commit is contained in:
parent
44b2a7fb72
commit
924d7e10a1
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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.location.live.map
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.airbnb.epoxy.EpoxyController
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.date.DateFormatKind
|
||||||
|
import im.vector.app.core.date.VectorDateFormatter
|
||||||
|
import im.vector.app.core.resources.DateProvider
|
||||||
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import im.vector.app.core.resources.toTimestamp
|
||||||
|
import im.vector.app.core.time.Clock
|
||||||
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
|
import im.vector.app.features.location.live.map.bottomsheet.liveLocationUserItem
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class LiveLocationBottomSheetController @Inject constructor(
|
||||||
|
private val avatarRenderer: AvatarRenderer,
|
||||||
|
private val vectorDateFormatter: VectorDateFormatter,
|
||||||
|
private val stringProvider: StringProvider,
|
||||||
|
private val clock: Clock,
|
||||||
|
private val context: Context,
|
||||||
|
) : EpoxyController() {
|
||||||
|
|
||||||
|
interface Callback {
|
||||||
|
fun onUserSelected(userId: String)
|
||||||
|
fun onStopLocationClicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var userLocations: List<UserLiveLocationViewState>? = null
|
||||||
|
var callback: Callback? = null
|
||||||
|
|
||||||
|
fun setData(userLocations: List<UserLiveLocationViewState>) {
|
||||||
|
this.userLocations = userLocations
|
||||||
|
requestModelBuild()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun buildModels() {
|
||||||
|
val currentUserLocations = userLocations ?: return
|
||||||
|
val host = this
|
||||||
|
|
||||||
|
currentUserLocations.forEach { liveLocationViewState ->
|
||||||
|
val remainingTime = getFormattedLocalTimeEndOfLive(liveLocationViewState.endOfLiveTimestampMillis)
|
||||||
|
liveLocationUserItem {
|
||||||
|
id(liveLocationViewState.matrixItem.id)
|
||||||
|
matrixItem(liveLocationViewState.matrixItem)
|
||||||
|
stringProvider(host.stringProvider)
|
||||||
|
clock(host.clock)
|
||||||
|
avatarRenderer(host.avatarRenderer)
|
||||||
|
remainingTime(remainingTime)
|
||||||
|
locationUpdateTimeMillis(liveLocationViewState.locationTimestampMillis)
|
||||||
|
showStopSharingButton(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFormattedLocalTimeEndOfLive(endOfLiveDateTimestampMillis: Long?): String {
|
||||||
|
val endOfLiveDateTime = DateProvider.toLocalDateTime(endOfLiveDateTimestampMillis)
|
||||||
|
val formattedDateTime = endOfLiveDateTime.toTimestamp().let { vectorDateFormatter.format(it, DateFormatKind.MESSAGE_SIMPLE) }
|
||||||
|
return stringProvider.getString(R.string.location_share_live_until, formattedDateTime)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* 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.location.live.map.bottomsheet
|
||||||
|
|
||||||
|
import android.widget.Button
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
|
import com.airbnb.epoxy.EpoxyModelClass
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||||
|
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||||
|
import im.vector.app.core.epoxy.onClick
|
||||||
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import im.vector.app.core.time.Clock
|
||||||
|
import im.vector.app.core.utils.TextUtils
|
||||||
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
|
import im.vector.lib.core.utils.timer.CountUpTimer
|
||||||
|
import org.matrix.android.sdk.api.util.MatrixItem
|
||||||
|
import org.threeten.bp.Duration
|
||||||
|
|
||||||
|
@EpoxyModelClass(layout = R.layout.item_live_location_users_bottom_sheet)
|
||||||
|
abstract class LiveLocationUserItem : VectorEpoxyModel<LiveLocationUserItem.Holder>() {
|
||||||
|
|
||||||
|
interface Callback {
|
||||||
|
fun onStopSharingClicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var callback: Callback? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
lateinit var matrixItem: MatrixItem
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
lateinit var avatarRenderer: AvatarRenderer
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
lateinit var stringProvider: StringProvider
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
lateinit var clock: Clock
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var remainingTime: String? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var locationUpdateTimeMillis: Long? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var showStopSharingButton: Boolean = false
|
||||||
|
|
||||||
|
private var timer: CountUpTimer? = null
|
||||||
|
|
||||||
|
override fun bind(holder: Holder) {
|
||||||
|
super.bind(holder)
|
||||||
|
avatarRenderer.render(matrixItem, holder.itemUserAvatarImageView)
|
||||||
|
holder.itemUserDisplayNameTextView.text = matrixItem.displayName
|
||||||
|
holder.itemRemainingTimeTextView.text = remainingTime
|
||||||
|
|
||||||
|
holder.itemStopSharingButton.isVisible = showStopSharingButton
|
||||||
|
if (showStopSharingButton) {
|
||||||
|
holder.itemStopSharingButton.onClick {
|
||||||
|
callback?.onStopSharingClicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timer = CountUpTimer(1000).apply {
|
||||||
|
tickListener = object : CountUpTimer.TickListener {
|
||||||
|
override fun onTick(milliseconds: Long) {
|
||||||
|
holder.itemLastUpdatedAtTextView.text = getFormattedLastUpdatedAt(locationUpdateTimeMillis)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFormattedLastUpdatedAt(locationUpdateTimeMillis: Long?): String {
|
||||||
|
if (locationUpdateTimeMillis == null) return ""
|
||||||
|
val elapsedTime = clock.epochMillis() - locationUpdateTimeMillis
|
||||||
|
val duration = Duration.ofMillis(elapsedTime.coerceAtLeast(0L))
|
||||||
|
return stringProvider.getString(R.string.live_location_bottom_sheet_last_updated_at, TextUtils.formatDurationWithUnits(stringProvider, duration))
|
||||||
|
}
|
||||||
|
|
||||||
|
class Holder : VectorEpoxyHolder() {
|
||||||
|
val itemUserAvatarImageView by bind<ImageView>(R.id.itemUserAvatarImageView)
|
||||||
|
val itemUserDisplayNameTextView by bind<TextView>(R.id.itemUserDisplayNameTextView)
|
||||||
|
val itemRemainingTimeTextView by bind<TextView>(R.id.itemRemainingTimeTextView)
|
||||||
|
val itemLastUpdatedAtTextView by bind<TextView>(R.id.itemLastUpdatedAtTextView)
|
||||||
|
val itemStopSharingButton by bind<Button>(R.id.itemStopSharingButton)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user