diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Contents.json b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Contents.json
new file mode 100644
index 000000000..ad6d3af55
--- /dev/null
+++ b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "Group 1.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group 1@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group 1@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Group 1.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Group 1.png
new file mode 100644
index 000000000..d1087e6b3
Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Group 1.png differ
diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Group 1@2x.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Group 1@2x.png
new file mode 100644
index 000000000..ffad58d65
Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Group 1@2x.png differ
diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Group 1@3x.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Group 1@3x.png
new file mode 100644
index 000000000..cad21b28e
Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_ended_image.imageset/Group 1@3x.png differ
diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Contents.json b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Contents.json
new file mode 100644
index 000000000..188a203cc
--- /dev/null
+++ b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Contents.json
@@ -0,0 +1,26 @@
+{
+ "images" : [
+ {
+ "filename" : "Subtract.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Subtract@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Subtract@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Subtract.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Subtract.png
new file mode 100644
index 000000000..16be3b51b
Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Subtract.png differ
diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Subtract@2x.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Subtract@2x.png
new file mode 100644
index 000000000..4e20a1517
Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Subtract@2x.png differ
diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Subtract@3x.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Subtract@3x.png
new file mode 100644
index 000000000..61ea2a528
Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_icon.imageset/Subtract@3x.png differ
diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Contents.json b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Contents.json
new file mode 100644
index 000000000..ad6d3af55
--- /dev/null
+++ b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "Group 1.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group 1@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group 1@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Group 1.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Group 1.png
new file mode 100644
index 000000000..19c9bd1c3
Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Group 1.png differ
diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Group 1@2x.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Group 1@2x.png
new file mode 100644
index 000000000..f8054f3d4
Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Group 1@2x.png differ
diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Group 1@3x.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Group 1@3x.png
new file mode 100644
index 000000000..482496d25
Binary files /dev/null and b/Riot/Assets/Images.xcassets/Room/Location/location_live_cell_loading_image.imageset/Group 1@3x.png differ
diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings
index 83f855569..9c0a6f89a 100644
--- a/Riot/Assets/en.lproj/Vector.strings
+++ b/Riot/Assets/en.lproj/Vector.strings
@@ -2145,6 +2145,8 @@ Tap the + to start adding people.";
"location_sharing_live_map_callout_title" = "Share location";
"location_sharing_live_timer_outgoing" = "%@ left";
"location_sharing_live_timer_incoming" = "Live until %@";
+"location_sharing_live_loading" = "Loading Live location...";
+"location_sharing_live_error" = "Live location error";
// MARK: - MatrixKit
diff --git a/Riot/Generated/Images.swift b/Riot/Generated/Images.swift
index d9c9dadb8..6e39159cc 100644
--- a/Riot/Generated/Images.swift
+++ b/Riot/Generated/Images.swift
@@ -174,6 +174,9 @@ internal class Asset: NSObject {
internal static let voiceCallHangupIcon = ImageAsset(name: "voice_call_hangup_icon")
internal static let liveLocationIcon = ImageAsset(name: "live_location_icon")
internal static let locationCenterMapIcon = ImageAsset(name: "location_center_map_icon")
+ internal static let locationLiveCellEndedImage = ImageAsset(name: "location_live_cell_ended_image")
+ internal static let locationLiveCellIcon = ImageAsset(name: "location_live_cell_icon")
+ internal static let locationLiveCellLoadingImage = ImageAsset(name: "location_live_cell_loading_image")
internal static let locationLiveIcon = ImageAsset(name: "location_live_icon")
internal static let locationMarkerIcon = ImageAsset(name: "location_marker_icon")
internal static let locationPinIcon = ImageAsset(name: "location_pin_icon")
diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift
index 13aecc0c7..2c5e2c007 100644
--- a/Riot/Generated/Strings.swift
+++ b/Riot/Generated/Strings.swift
@@ -2763,6 +2763,14 @@ public class VectorL10n: NSObject {
public static var locationSharingInvalidAuthorizationSettings: String {
return VectorL10n.tr("Vector", "location_sharing_invalid_authorization_settings")
}
+ /// Live location error
+ public static var locationSharingLiveError: String {
+ return VectorL10n.tr("Vector", "location_sharing_live_error")
+ }
+ /// Loading Live location...
+ public static var locationSharingLiveLoading: String {
+ return VectorL10n.tr("Vector", "location_sharing_live_loading")
+ }
/// Share location
public static var locationSharingLiveMapCalloutTitle: String {
return VectorL10n.tr("Vector", "location_sharing_live_map_callout_title")
diff --git a/Riot/Managers/Theme/Theme.swift b/Riot/Managers/Theme/Theme.swift
index 93d9cb2a9..039175371 100644
--- a/Riot/Managers/Theme/Theme.swift
+++ b/Riot/Managers/Theme/Theme.swift
@@ -104,6 +104,16 @@ import DesignKit
var roomCellOutgoingBubbleBackgroundColor: UIColor { get }
+ // Localisation Cells
+
+ var roomCellLocalisationTextColor: UIColor { get }
+
+ var roomCellLocalisationStartedColor: UIColor { get }
+
+ var roomCellLocalisationEndedColor: UIColor { get }
+
+ var roomCellLocalisationErrorColor: UIColor { get }
+
// MARK: - Customisation methods
diff --git a/Riot/Managers/Theme/Themes/DarkTheme.swift b/Riot/Managers/Theme/Themes/DarkTheme.swift
index d61ed3954..6d076e037 100644
--- a/Riot/Managers/Theme/Themes/DarkTheme.swift
+++ b/Riot/Managers/Theme/Themes/DarkTheme.swift
@@ -98,6 +98,14 @@ class DarkTheme: NSObject, Theme {
}
var roomCellOutgoingBubbleBackgroundColor: UIColor = UIColor(rgb: 0x133A34)
+
+ var roomCellLocalisationTextColor: UIColor = UIColor(rgb: 0x17191C)
+
+ var roomCellLocalisationStartedColor: UIColor = UIColor(rgb: 0x5C56F5)
+
+ var roomCellLocalisationEndedColor: UIColor = UIColor(rgb: 0xC1C6CD)
+
+ var roomCellLocalisationErrorColor: UIColor = UIColor(rgb: 0xFF5B55)
func applyStyle(onTabBar tabBar: UITabBar) {
tabBar.unselectedItemTintColor = self.tabBarUnselectedItemTintColor
diff --git a/Riot/Managers/Theme/Themes/DefaultTheme.swift b/Riot/Managers/Theme/Themes/DefaultTheme.swift
index e2afd9339..5eaee1185 100644
--- a/Riot/Managers/Theme/Themes/DefaultTheme.swift
+++ b/Riot/Managers/Theme/Themes/DefaultTheme.swift
@@ -105,6 +105,14 @@ class DefaultTheme: NSObject, Theme {
var roomCellOutgoingBubbleBackgroundColor: UIColor = UIColor(rgb: 0xE7F8F3)
+ var roomCellLocalisationTextColor: UIColor = UIColor(rgb: 0x17191C)
+
+ var roomCellLocalisationStartedColor: UIColor = UIColor(rgb: 0x5C56F5)
+
+ var roomCellLocalisationEndedColor: UIColor = UIColor(rgb: 0xC1C6CD)
+
+ var roomCellLocalisationErrorColor: UIColor = UIColor(rgb: 0xFF5B55)
+
func applyStyle(onTabBar tabBar: UITabBar) {
tabBar.unselectedItemTintColor = self.tabBarUnselectedItemTintColor
tabBar.tintColor = self.tintColor
diff --git a/Riot/Modules/Room/Location/RoomTimelineLocationView.swift b/Riot/Modules/Room/Location/RoomTimelineLocationView.swift
index 4eb372b2d..c500bf87d 100644
--- a/Riot/Modules/Room/Location/RoomTimelineLocationView.swift
+++ b/Riot/Modules/Room/Location/RoomTimelineLocationView.swift
@@ -19,26 +19,60 @@ import Reusable
import Mapbox
import SwiftUI
-struct LiveLocationParameter {
- let bannerImage: UIImage
- let bannerTitle: String
- let timer: String?
- let shouldShowStopButton: Bool
- let isLive: Bool
+protocol RoomTimelineLocationViewDelegate: AnyObject {
+ func didTapStopButton()
+ func didTapRetryButton()
}
-enum LiveLocationState {
- case incomingLive(String?)
- case outgoingLive(String?)
+struct RoomTimelineLocationViewData {
+ let location: CLLocationCoordinate2D
+ let userAvatarData: AvatarViewData?
+ let mapStyleURL: URL
+}
+
+struct LiveLocationBannerViewData {
+ let placeholderImage: UIImage?
+ let iconTint: UIColor
+ let title: String
+ let titleColor: UIColor
+ let timeLeftString: String?
+ let rightButtonTitle: String?
+ let rightButtonTag: RightButtonTag
- func values() -> LiveLocationParameter {
- switch self {
- case .incomingLive(let timerString):
- return LiveLocationParameter(bannerImage: Asset.Images.locationLiveIcon.image, bannerTitle: VectorL10n.liveLocationSharingBannerTitle, timer: timerString, shouldShowStopButton: false, isLive: true)
- case .outgoingLive(let timerString):
- return LiveLocationParameter(bannerImage: Asset.Images.locationLiveIcon.image, bannerTitle: VectorL10n.liveLocationSharingBannerTitle, timer: timerString, shouldShowStopButton: true, isLive: true)
- }
+ var showTimer: Bool {
+ return timeLeftString != nil
}
+
+ var showRightButton: Bool {
+ return rightButtonTitle != nil
+ }
+
+ var showPlaceholderImage: Bool {
+ return placeholderImage != nil
+ }
+}
+
+enum TimelineLiveLocationViewState {
+ case incoming(_ status: IncomingLiveLocationSharingStatus) // live location started by other users
+ case outgoing(_ status: OutgoingLiveLocationSharingStatus) // live location started from current user
+}
+
+
+enum OutgoingLiveLocationSharingStatus {
+ case starting
+ case started(_ timeleft: TimeInterval)
+ case failure
+ case stopped
+}
+
+enum IncomingLiveLocationSharingStatus {
+ case started(_ timeleft: TimeInterval)
+ case stopped
+}
+
+enum RightButtonTag: Int {
+ case stopSharing = 0
+ case retrySharing
}
class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegate {
@@ -61,11 +95,12 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat
@IBOutlet private var attributionLabel: UILabel!
// MARK: - Live Location
+ @IBOutlet private var placeholderImage: UIImageView!
@IBOutlet private var liveLocationContainerView: UIView!
@IBOutlet private var liveLocationImageView: UIImageView!
@IBOutlet private var liveLocationStatusLabel: UILabel!
@IBOutlet private var liveLocationTimerLabel: UILabel!
- @IBOutlet private var stopSharingButton: UIButton!
+ @IBOutlet private var rightButton: UIButton!
@@ -73,6 +108,22 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat
private var annotationView: LocationMarkerView?
private static var usernameColorGenerator = UserNameColorGenerator()
+ private lazy var incomingTimerFormatter: DateFormatter = {
+ let dateFormatter = DateFormatter()
+ dateFormatter.dateFormat = "HH:mm"
+ return dateFormatter
+ }()
+
+ private lazy var outgoingTimerFormatter: DateComponentsFormatter = {
+ let formatter = DateComponentsFormatter()
+ formatter.zeroFormattingBehavior = .dropAll
+ formatter.allowedUnits = [.hour, .minute, .second]
+ formatter.unitsStyle = .brief
+ return formatter
+ }()
+
+ weak var delegate: RoomTimelineLocationViewDelegate?
+
// MARK: Public
var locationDescription: String? {
@@ -84,7 +135,7 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat
descriptionContainerView.isHidden = (newValue?.count ?? 0 == 0)
}
}
-
+
override func awakeFromNib() {
super.awakeFromNib()
@@ -104,12 +155,12 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat
layer.cornerRadius = Constants.cellCornerRadius
}
- // MARK: - Public
+ // MARK: - Private
- public func displayLocation(_ location: CLLocationCoordinate2D,
- userAvatarData: AvatarViewData? = nil,
- mapStyleURL: URL,
- liveLocationState: LiveLocationState? = nil) {
+ private func displayLocation(_ location: CLLocationCoordinate2D,
+ userAvatarData: AvatarViewData? = nil,
+ mapStyleURL: URL,
+ bannerViewData: LiveLocationBannerViewData? = nil) {
mapView.styleURL = mapStyleURL
@@ -131,23 +182,116 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat
mapView.addAnnotation(pointAnnotation)
// Configure live location banner
- guard let liveLocationParameters = liveLocationState?.values() else {
+ guard let bannerViewData = bannerViewData else {
liveLocationContainerView.isHidden = true
return
}
liveLocationContainerView.isHidden = false
- liveLocationImageView.image = liveLocationParameters.bannerImage
- liveLocationStatusLabel.text = liveLocationParameters.bannerTitle
- if let timerString = liveLocationParameters.timer {
- liveLocationTimerLabel.isHidden = false
- liveLocationTimerLabel.text = timerString
- } else {
- liveLocationTimerLabel.isHidden = true
- }
- stopSharingButton.isHidden = !liveLocationParameters.shouldShowStopButton
+
+ liveLocationImageView.image = Asset.Images.locationLiveCellIcon.image
+ liveLocationImageView.tintColor = bannerViewData.iconTint
+
+ liveLocationStatusLabel.text = bannerViewData.title
+ liveLocationStatusLabel.textColor = bannerViewData.titleColor
+
+ liveLocationTimerLabel.text = bannerViewData.timeLeftString
+ liveLocationTimerLabel.isHidden = !bannerViewData.showTimer
+
+ rightButton.setTitle(bannerViewData.rightButtonTitle, for: .normal)
+ rightButton.isHidden = !bannerViewData.showRightButton
+ rightButton.tag = bannerViewData.rightButtonTag.rawValue
+
+ placeholderImage.image = bannerViewData.placeholderImage
+ placeholderImage.isHidden = !bannerViewData.showPlaceholderImage
+ mapView.isHidden = bannerViewData.showPlaceholderImage
}
+ private func liveLocationBannerViewData(from viewState: TimelineLiveLocationViewState) -> LiveLocationBannerViewData {
+ let theme = ThemeService.shared().theme
+
+ let iconTint: UIColor
+ let title: String
+ var titleColor: UIColor = theme.roomCellLocalisationTextColor
+ var placeholderImage: UIImage?
+ var timeLeftString: String?
+ var rightButtonTitle: String?
+ var rightButtonTag: RightButtonTag = .stopSharing
+
+ switch viewState {
+ case .incoming(let liveLocationSharingStatus):
+ switch liveLocationSharingStatus {
+ case .started(let timeLeft):
+ iconTint = theme.roomCellLocalisationStartedColor
+ title = VectorL10n.liveLocationSharingBannerTitle
+ timeLeftString = generateTimerString(for: timeLeft, isIncomingLocation: true)
+ case .stopped:
+ iconTint = theme.roomCellLocalisationEndedColor
+ title = VectorL10n.liveLocationSharingEnded
+ titleColor = theme.roomCellLocalisationEndedColor
+ placeholderImage = Asset.Images.locationLiveCellEndedImage.image
+ }
+ case .outgoing(let liveLocationSharingStatus):
+ switch liveLocationSharingStatus {
+ case .starting:
+ iconTint = theme.roomCellLocalisationEndedColor
+ title = VectorL10n.locationSharingLiveLoading
+ titleColor = theme.roomCellLocalisationEndedColor
+ placeholderImage = Asset.Images.locationLiveCellLoadingImage.image
+ case .started(let timeLeft):
+ iconTint = theme.roomCellLocalisationStartedColor
+ title = VectorL10n.liveLocationSharingBannerTitle
+ timeLeftString = generateTimerString(for: timeLeft, isIncomingLocation: false)
+ rightButtonTitle = VectorL10n.stop
+ case .failure:
+ iconTint = theme.roomCellLocalisationErrorColor
+ title = VectorL10n.locationSharingLiveError
+ titleColor = theme.roomCellLocalisationEndedColor
+ rightButtonTitle = VectorL10n.retry
+ rightButtonTag = .retrySharing
+ case .stopped:
+ iconTint = theme.roomCellLocalisationEndedColor
+ title = VectorL10n.liveLocationSharingEnded
+ titleColor = theme.roomCellLocalisationEndedColor
+ placeholderImage = Asset.Images.locationLiveCellEndedImage.image
+ }
+ }
+
+ return LiveLocationBannerViewData(placeholderImage: placeholderImage, iconTint: iconTint, title: title, titleColor: titleColor, timeLeftString: timeLeftString, rightButtonTitle: rightButtonTitle, rightButtonTag: rightButtonTag)
+ }
+
+ private func generateTimerString(for timestamp: Double,
+ isIncomingLocation: Bool) -> String? {
+ let timerString: String?
+ if isIncomingLocation {
+ timerString = VectorL10n.locationSharingLiveTimerIncoming(incomingTimerFormatter.string(from: Date(timeIntervalSince1970: timestamp)))
+ } else if let outgoingTimer = outgoingTimerFormatter.string(from: Date(timeIntervalSince1970: timestamp).timeIntervalSinceNow) {
+ timerString = VectorL10n.locationSharingLiveTimerOutgoing(outgoingTimer)
+ } else {
+ timerString = nil
+ }
+ return timerString
+ }
+
+ // MARK: - Public
+
+ public func displayStaticLocation(with viewData: RoomTimelineLocationViewData) {
+ displayLocation(viewData.location,
+ userAvatarData: viewData.userAvatarData,
+ mapStyleURL: viewData.mapStyleURL,
+ bannerViewData: nil)
+ }
+
+ public func displayLiveLocation(with viewData: RoomTimelineLocationViewData, liveLocationViewState: TimelineLiveLocationViewState) {
+ let bannerViewData = liveLocationBannerViewData(from: liveLocationViewState)
+ displayLocation(viewData.location,
+ userAvatarData: viewData.userAvatarData,
+ mapStyleURL: viewData.mapStyleURL,
+ bannerViewData: bannerViewData)
+
+ }
+
+
// MARK: - Themable
func update(theme: Theme) {
@@ -167,7 +311,11 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat
// MARK: - Action
- @IBAction private func stopSharingAction(_ sender: Any) {
- // TODO: - Stop sharing action
+ @IBAction private func didTapTightButton(_ sender: Any) {
+ if rightButton.tag == RightButtonTag.stopSharing.rawValue {
+ delegate?.didTapStopButton()
+ } else if rightButton.tag == RightButtonTag.retrySharing.rawValue {
+ delegate?.didTapRetryButton()
+ }
}
}
diff --git a/Riot/Modules/Room/Location/RoomTimelineLocationView.xib b/Riot/Modules/Room/Location/RoomTimelineLocationView.xib
index c6cdf2ed3..a149fcead 100644
--- a/Riot/Modules/Room/Location/RoomTimelineLocationView.xib
+++ b/Riot/Modules/Room/Location/RoomTimelineLocationView.xib
@@ -4,7 +4,6 @@
-
@@ -15,6 +14,9 @@
+
+
+
@@ -41,7 +43,7 @@
-
+
@@ -77,7 +79,7 @@
-
+
@@ -129,11 +131,14 @@
-
+
+
+
+
@@ -148,13 +153,14 @@
-
+
+
-
+
diff --git a/Riot/Modules/Room/MXKRoomViewController.m b/Riot/Modules/Room/MXKRoomViewController.m
index a8d79f084..ba1dd3e21 100644
--- a/Riot/Modules/Room/MXKRoomViewController.m
+++ b/Riot/Modules/Room/MXKRoomViewController.m
@@ -3045,6 +3045,22 @@
[self promptUserToResendEvent:selectedEvent.eventId];
}
}
+ else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellStopShareButtonPressed])
+ {
+ MXEvent *selectedEvent = userInfo[kMXKRoomBubbleCellEventKey];
+ if (selectedEvent)
+ {
+ // TODO: - Implement stop live location action
+ }
+ }
+ else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellRetryShareButtonPressed])
+ {
+ MXEvent *selectedEvent = userInfo[kMXKRoomBubbleCellEventKey];
+ if (selectedEvent)
+ {
+ // TODO: - Implement retry live location action
+ }
+ }
}
#pragma mark - Clipboard
diff --git a/Riot/Modules/Room/TimelineCells/Common/MXKRoomBubbleTableViewCell.h b/Riot/Modules/Room/TimelineCells/Common/MXKRoomBubbleTableViewCell.h
index 8e247835f..15e18f89b 100644
--- a/Riot/Modules/Room/TimelineCells/Common/MXKRoomBubbleTableViewCell.h
+++ b/Riot/Modules/Room/TimelineCells/Common/MXKRoomBubbleTableViewCell.h
@@ -83,6 +83,20 @@ extern NSString *const kMXKRoomBubbleCellTapOnContentView;
*/
extern NSString *const kMXKRoomBubbleCellUnsentButtonPressed;
+/**
+ Action identifier used when the user pressed stop share button displayed in live location cell.
+
+ The `userInfo` dictionary contains an `MXEvent` object under the `kMXKRoomBubbleCellEventKey` key, representing the live location event to stop.
+ */
+extern NSString *const kMXKRoomBubbleCellStopShareButtonPressed;
+
+/**
+ Action identifier used when the user pressed retry share button displayed in live location cell.
+
+ The `userInfo` dictionary contains an `MXEvent` object under the `kMXKRoomBubbleCellEventKey` key, representing the live location event to retry.
+ */
+extern NSString *const kMXKRoomBubbleCellRetryShareButtonPressed;
+
/**
Action identifier used when the user long pressed on a displayed event.
diff --git a/Riot/Modules/Room/TimelineCells/Common/MXKRoomBubbleTableViewCell.m b/Riot/Modules/Room/TimelineCells/Common/MXKRoomBubbleTableViewCell.m
index c4367d598..f5fcdc4ff 100644
--- a/Riot/Modules/Room/TimelineCells/Common/MXKRoomBubbleTableViewCell.m
+++ b/Riot/Modules/Room/TimelineCells/Common/MXKRoomBubbleTableViewCell.m
@@ -41,7 +41,10 @@ NSString *const kMXKRoomBubbleCellTapOnAttachmentView = @"kMXKRoomBubbleCellTapO
NSString *const kMXKRoomBubbleCellTapOnOverlayContainer = @"kMXKRoomBubbleCellTapOnOverlayContainer";
NSString *const kMXKRoomBubbleCellTapOnContentView = @"kMXKRoomBubbleCellTapOnContentView";
+
NSString *const kMXKRoomBubbleCellUnsentButtonPressed = @"kMXKRoomBubbleCellUnsentButtonPressed";
+NSString *const kMXKRoomBubbleCellStopShareButtonPressed = @"kMXKRoomBubbleCellStopShareButtonPressed";
+NSString *const kMXKRoomBubbleCellRetryShareButtonPressed = @"kMXKRoomBubbleCellRetryShareButtonPressed";
NSString *const kMXKRoomBubbleCellLongPressOnEvent = @"kMXKRoomBubbleCellLongPressOnEvent";
NSString *const kMXKRoomBubbleCellLongPressOnProgressView = @"kMXKRoomBubbleCellLongPressOnProgressView";
diff --git a/Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/Location/LocationPlainCell.swift b/Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/Location/LocationPlainCell.swift
index 4d47dd775..a8f752f59 100644
--- a/Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/Location/LocationPlainCell.swift
+++ b/Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/Location/LocationPlainCell.swift
@@ -20,6 +20,7 @@ import MatrixSDK
class LocationPlainCell: SizableBaseRoomCell, RoomCellReactionsDisplayable, RoomCellReadMarkerDisplayable {
private var locationView: RoomTimelineLocationView!
+ private var event: MXEvent?
override func render(_ cellData: MXKCellData!) {
super.render(cellData)
@@ -31,6 +32,7 @@ class LocationPlainCell: SizableBaseRoomCell, RoomCellReactionsDisplayable, Room
return
}
+ self.event = event
locationView.update(theme: ThemeService.shared().theme)
// Comment this line and uncomment next one to test UI of live location tile
@@ -49,17 +51,19 @@ class LocationPlainCell: SizableBaseRoomCell, RoomCellReactionsDisplayable, Room
let mapStyleURL = bubbleData.mxSession.vc_homeserverConfiguration().tileServer.mapStyleURL
+ let avatarViewData: AvatarViewData?
+
if locationContent.assetType == .user {
- let avatarViewData = AvatarViewData(matrixItemId: bubbleData.senderId,
+ avatarViewData = AvatarViewData(matrixItemId: bubbleData.senderId,
displayName: bubbleData.senderDisplayName,
avatarUrl: bubbleData.senderAvatarUrl,
mediaManager: bubbleData.mxSession.mediaManager,
fallbackImage: .matrixItem(bubbleData.senderId, bubbleData.senderDisplayName))
-
- locationView.displayLocation(location, userAvatarData: avatarViewData, mapStyleURL: mapStyleURL)
} else {
- locationView.displayLocation(location, mapStyleURL: mapStyleURL)
+ avatarViewData = nil
}
+
+ locationView.displayStaticLocation(with: RoomTimelineLocationViewData(location: location, userAvatarData: avatarViewData, mapStyleURL: mapStyleURL))
}
private func renderLiveLocation(_ event: MXEvent) {
@@ -84,36 +88,11 @@ class LocationPlainCell: SizableBaseRoomCell, RoomCellReactionsDisplayable, Room
mediaManager: bubbleData.mxSession.mediaManager,
fallbackImage: .matrixItem(bubbleData.senderId, bubbleData.senderDisplayName))
let futurDateTimeInterval = Date(timeIntervalSinceNow: 3734).timeIntervalSince1970
- locationView.displayLocation(location, userAvatarData: avatarViewData, mapStyleURL: mapStyleURL, liveLocationState: .outgoingLive(generateTimerString(for: futurDateTimeInterval, isIncomingLocation: false)))
+
+ locationView.displayLiveLocation(with: RoomTimelineLocationViewData(location: location, userAvatarData: avatarViewData, mapStyleURL: mapStyleURL),
+ liveLocationViewState: .outgoing(.failure))
}
- private func generateTimerString(for timestamp: Double,
- isIncomingLocation: Bool) -> String? {
- let timerString: String?
- if isIncomingLocation {
- timerString = VectorL10n.locationSharingLiveTimerIncoming(incomingTimerFormatter.string(from: Date(timeIntervalSince1970: timestamp)))
- } else if let outgoingTimer = outgoingTimerFormatter.string(from: Date(timeIntervalSince1970: timestamp).timeIntervalSinceNow) {
- timerString = VectorL10n.locationSharingLiveTimerOutgoing(outgoingTimer)
- } else {
- timerString = nil
- }
- return timerString
- }
-
- private lazy var incomingTimerFormatter: DateFormatter = {
- let dateFormatter = DateFormatter()
- dateFormatter.dateFormat = "HH:mm"
- return dateFormatter
- }()
-
- private lazy var outgoingTimerFormatter: DateComponentsFormatter = {
- let formatter = DateComponentsFormatter()
- formatter.zeroFormattingBehavior = .dropAll
- formatter.allowedUnits = [.hour, .minute, .second]
- formatter.unitsStyle = .brief
- return formatter
- }()
-
override func setupViews() {
super.setupViews()
@@ -131,3 +110,21 @@ class LocationPlainCell: SizableBaseRoomCell, RoomCellReactionsDisplayable, Room
contentView.vc_addSubViewMatchingParent(locationView)
}
}
+
+extension LocationPlainCell: RoomTimelineLocationViewDelegate {
+ func didTapStopButton() {
+ guard let event = self.event else {
+ return
+ }
+
+ delegate.cell(self, didRecognizeAction: kMXKRoomBubbleCellStopShareButtonPressed, userInfo: [kMXKRoomBubbleCellEventKey: event])
+ }
+
+ func didTapRetryButton() {
+ guard let event = self.event else {
+ return
+ }
+
+ delegate.cell(self, didRecognizeAction: kMXKRoomBubbleCellRetryShareButtonPressed, userInfo: [kMXKRoomBubbleCellEventKey: event])
+ }
+}