element-ios/Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/Location/LocationPlainCell.swift

146 lines
5.9 KiB
Swift

//
// Copyright 2021-2024 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only
// Please see LICENSE in the repository root for full details.
//
import Foundation
import MatrixSDK
class LocationPlainCell: SizableBaseRoomCell, RoomCellReactionsDisplayable, RoomCellReadMarkerDisplayable {
private var locationView: RoomTimelineLocationView!
private var event: MXEvent?
override func render(_ cellData: MXKCellData!) {
super.render(cellData)
guard let bubbleData = cellData as? RoomBubbleCellData,
let event = bubbleData.events.last
else {
return
}
locationView.update(theme: ThemeService.shared().theme)
locationView.delegate = self
self.event = event
if bubbleData.cellDataTag == .location {
renderStaticLocation(event)
} else if bubbleData.cellDataTag == .liveLocation,
let beaconInfoSummary = bubbleData.beaconInfoSummary {
renderLiveLocation(beaconInfoSummary)
}
}
private func renderStaticLocation(_ event: MXEvent) {
guard let locationContent = event.location else {
return
}
locationView.locationDescription = locationContent.locationDescription
let location = CLLocationCoordinate2D(latitude: locationContent.latitude, longitude: locationContent.longitude)
let mapStyleURL = bubbleData.mxSession.vc_homeserverConfiguration().tileServer.mapStyleURL
let avatarViewData: AvatarViewData?
if locationContent.assetType == .user {
avatarViewData = AvatarViewData(matrixItemId: bubbleData.senderId,
displayName: bubbleData.senderDisplayName,
avatarUrl: bubbleData.senderAvatarUrl,
mediaManager: bubbleData.mxSession.mediaManager,
fallbackImage: .matrixItem(bubbleData.senderId, bubbleData.senderDisplayName))
} else {
avatarViewData = nil
}
locationView.displayStaticLocation(with: RoomTimelineLocationViewData(location: location, userAvatarData: avatarViewData, mapStyleURL: mapStyleURL))
}
private func renderLiveLocation(_ beaconInfoSummary: MXBeaconInfoSummaryProtocol) {
let liveLocationState: TimelineLiveLocationViewState = locationSharingViewState(from: beaconInfoSummary)
let avatarViewData = AvatarViewData(matrixItemId: bubbleData.senderId,
displayName: bubbleData.senderDisplayName,
avatarUrl: bubbleData.senderAvatarUrl,
mediaManager: bubbleData.mxSession.mediaManager,
fallbackImage: .matrixItem(bubbleData.senderId, bubbleData.senderDisplayName))
let mapStyleURL = bubbleData.mxSession.vc_homeserverConfiguration().tileServer.mapStyleURL
locationView.displayLiveLocation(with: RoomTimelineLocationViewData(location: nil, userAvatarData: avatarViewData, mapStyleURL: mapStyleURL),
liveLocationViewState: liveLocationState)
}
private func locationSharingViewState(from beaconInfoSummary: MXBeaconInfoSummaryProtocol) -> TimelineLiveLocationViewState {
let viewState: TimelineLiveLocationViewState
let liveLocationStatus: LiveLocationSharingStatus
if beaconInfoSummary.hasStopped || beaconInfoSummary.hasExpired {
liveLocationStatus = .stopped
} else if let lastBeacon = beaconInfoSummary.lastBeacon {
let expiryTimeinterval = TimeInterval(beaconInfoSummary.expiryTimestamp/1000) // Timestamp is in millisecond in the SDK
let coordinate = CLLocationCoordinate2D(latitude: lastBeacon.location.latitude, longitude: lastBeacon.location.longitude)
liveLocationStatus = .started(coordinate, expiryTimeinterval)
} else {
liveLocationStatus = .starting
}
if beaconInfoSummary.userId == bubbleData.mxSession.myUserId {
viewState = .outgoing(liveLocationStatus)
} else {
viewState = .incoming(liveLocationStatus)
}
return viewState
}
override func setupViews() {
super.setupViews()
roomCellContentView?.backgroundColor = .clear
roomCellContentView?.showSenderInfo = true
roomCellContentView?.showPaginationTitle = false
guard let contentView = roomCellContentView?.innerContentView else {
return
}
locationView = RoomTimelineLocationView.loadFromNib()
contentView.vc_addSubViewMatchingParent(locationView)
}
override func prepareForReuse() {
super.prepareForReuse()
self.event = nil
}
override func onLongPressGesture(_ longPressGestureRecognizer: UILongPressGestureRecognizer!) {
var userInfo: [String: Any]?
if let event = self.event {
userInfo = [kMXKRoomBubbleCellEventKey: event]
}
delegate.cell(self, didRecognizeAction: kMXKRoomBubbleCellLongPressOnEvent, userInfo: userInfo)
}
}
extension LocationPlainCell: RoomTimelineLocationViewDelegate {
func roomTimelineLocationViewDidTapStopButton(_ roomTimelineLocationView: RoomTimelineLocationView) {
delegate.cell(self, didRecognizeAction: kMXKRoomBubbleCellStopShareButtonPressed, userInfo: nil)
}
func roomTimelineLocationViewDidTapRetryButton(_ roomTimelineLocationView: RoomTimelineLocationView) {
delegate.cell(self, didRecognizeAction: kMXKRoomBubbleCellRetryShareButtonPressed, userInfo: nil)
}
}