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