mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Open map from timeline (#1199)
* Add navigation to expaneded map * Add MapLibreMapView.Options * Add AppActivityView * Add ShareToMapsAppActivity * Add share sheet presentation * Add localisations * Cleanup * Fix UT build errors * Revert breaking change * Fix UIView setup * Add support for location’s description * Show popover on iPad * Restore assets * More cleanup
This commit is contained in:
@@ -43,9 +43,9 @@ struct GeoURI: Hashable {
|
||||
|
||||
var string: String {
|
||||
if let uncertainty {
|
||||
return "geo:\(latitude),\(longitude);u=\(uncertainty)"
|
||||
return "geo:\(string(for: latitude)),\(string(for: longitude));u=\(string(for: uncertainty))"
|
||||
} else {
|
||||
return "geo:\(latitude),\(longitude)"
|
||||
return "geo:\(string(for: latitude)),\(string(for: longitude))"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,10 @@ struct GeoURI: Hashable {
|
||||
let uncertainty = matchOutput.uncertainty.flatMap(Double.init)
|
||||
return .init(latitude: latitude, longitude: longitude, uncertainty: uncertainty)
|
||||
}
|
||||
|
||||
private func string(for number: Double) -> String {
|
||||
NumberFormatter.decimal.string(from: .init(floatLiteral: number)) ?? "\(number)"
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:disable:next large_tuple
|
||||
@@ -78,3 +82,13 @@ extension GeoURI {
|
||||
self.init(latitude: coordinate.latitude, longitude: coordinate.longitude)
|
||||
}
|
||||
}
|
||||
|
||||
private extension NumberFormatter {
|
||||
static let decimal: NumberFormatter = {
|
||||
let numberFormatter = NumberFormatter()
|
||||
numberFormatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
numberFormatter.numberStyle = .decimal
|
||||
numberFormatter.maximumFractionDigits = 30
|
||||
return numberFormatter
|
||||
}()
|
||||
}
|
||||
|
||||
+35
-24
@@ -115,32 +115,12 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
||||
return .none
|
||||
}
|
||||
|
||||
var source: MediaSourceProxy?
|
||||
var body: String
|
||||
switch timelineItem {
|
||||
case let item as ImageRoomTimelineItem:
|
||||
source = item.content.source
|
||||
body = item.content.body
|
||||
case let item as VideoRoomTimelineItem:
|
||||
source = item.content.source
|
||||
body = item.content.body
|
||||
case let item as FileRoomTimelineItem:
|
||||
source = item.content.source
|
||||
body = item.content.body
|
||||
case let item as AudioRoomTimelineItem:
|
||||
// For now we are just displaying audio messages with the File preview until we create a timeline player for them.
|
||||
source = item.content.source
|
||||
body = item.content.body
|
||||
case let item as LocationRoomTimelineItem:
|
||||
guard let geoURI = item.content.geoURI else { return .none }
|
||||
return .displayLocation(body: item.content.body, geoURI: geoURI)
|
||||
default:
|
||||
return .none
|
||||
}
|
||||
|
||||
guard let source else { return .none }
|
||||
switch await mediaProvider.loadFileFromSource(source, body: body) {
|
||||
case .success(let file):
|
||||
return .displayMediaFile(file: file, title: body)
|
||||
case .failure:
|
||||
return .none
|
||||
return await displayMediaActionIfPossible(timelineItem: timelineItem)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,6 +201,37 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
||||
// Recompute all attributed strings on content size changes -> DynamicType support
|
||||
updateTimelineItems()
|
||||
}
|
||||
|
||||
private func displayMediaActionIfPossible(timelineItem: RoomTimelineItemProtocol) async -> RoomTimelineControllerAction {
|
||||
var source: MediaSourceProxy?
|
||||
var body: String
|
||||
|
||||
switch timelineItem {
|
||||
case let item as ImageRoomTimelineItem:
|
||||
source = item.content.source
|
||||
body = item.content.body
|
||||
case let item as VideoRoomTimelineItem:
|
||||
source = item.content.source
|
||||
body = item.content.body
|
||||
case let item as FileRoomTimelineItem:
|
||||
source = item.content.source
|
||||
body = item.content.body
|
||||
case let item as AudioRoomTimelineItem:
|
||||
// For now we are just displaying audio messages with the File preview until we create a timeline player for them.
|
||||
source = item.content.source
|
||||
body = item.content.body
|
||||
default:
|
||||
return .none
|
||||
}
|
||||
|
||||
guard let source else { return .none }
|
||||
switch await mediaProvider.loadFileFromSource(source, body: body) {
|
||||
case .success(let file):
|
||||
return .displayMediaFile(file: file, title: body)
|
||||
case .failure:
|
||||
return .none
|
||||
}
|
||||
}
|
||||
|
||||
private func updateTimelineItems() {
|
||||
var newTimelineItems = [RoomTimelineItemProtocol]()
|
||||
|
||||
+1
@@ -26,6 +26,7 @@ enum RoomTimelineControllerCallback {
|
||||
|
||||
enum RoomTimelineControllerAction {
|
||||
case displayMediaFile(file: MediaFileHandleProxy, title: String?)
|
||||
case displayLocation(body: String, geoURI: GeoURI)
|
||||
case none
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user