mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-17 15:09:31 +02:00
vector-im/element-ios/issues/5298 - Various tweaks following code review.
This commit is contained in:
committed by
Stefan Ceriu
parent
0bac754ad9
commit
7161b99d1c
@@ -23,13 +23,6 @@ import Keys
|
||||
final class BuildSettings: NSObject {
|
||||
|
||||
// MARK: - Bundle Settings
|
||||
static var bundleDisplayName: String {
|
||||
guard let bundleDisplayName = Bundle.app.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String else {
|
||||
fatalError("CFBundleDisplayName should be defined")
|
||||
}
|
||||
return bundleDisplayName
|
||||
}
|
||||
|
||||
static var applicationGroupIdentifier: String {
|
||||
guard let applicationGroupIdentifier = Bundle.app.object(forInfoDictionaryKey: "applicationGroupIdentifier") as? String else {
|
||||
fatalError("applicationGroupIdentifier should be defined")
|
||||
|
||||
@@ -950,7 +950,7 @@ Tap the + to start adding people.";
|
||||
|
||||
// Analytics
|
||||
"analytics_prompt_title" = "Help improve %@";
|
||||
"analytics_prompt_message_new_user" = "Help us identify issues and improve Element by sharing anonymous usage data. To understand how people use multiple devices, we’ll generate a random identifier, shared by your devices.";
|
||||
"analytics_prompt_message_new_user" = "Help us identify issues and improve %@ by sharing anonymous usage data. To understand how people use multiple devices, we’ll generate a random identifier, shared by your devices.";
|
||||
"analytics_prompt_message_upgrade" = "You previously consented to share anonymous usage data with us. Now, to help understand how people use multiple devices, we’ll generate a random identifier, shared by your devices.";
|
||||
/* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */
|
||||
"analytics_prompt_terms_new_user" = "You can read all our terms %@.";
|
||||
@@ -1752,7 +1752,7 @@ Tap the + to start adding people.";
|
||||
"spaces_coming_soon_title" = "Coming soon";
|
||||
"spaces_add_rooms_coming_soon_title" = "Adding rooms coming soon";
|
||||
"spaces_invites_coming_soon_title" = "Invites coming soon";
|
||||
"spaces_coming_soon_detail" = "This feature hasn’t been implemented here, but it’s on the way. For now, you can do that with Element on your computer.";
|
||||
"spaces_coming_soon_detail" = "This feature hasn’t been implemented here, but it’s on the way. For now, you can do that with %@ on your computer.";
|
||||
"space_participants_action_remove" = "Remove from this space";
|
||||
"space_participants_action_ban" = "Ban from this space";
|
||||
"space_home_show_all_rooms" = "Show all rooms";
|
||||
@@ -1856,11 +1856,11 @@ Tap the + to start adding people.";
|
||||
|
||||
"location_sharing_share_action" = "Share";
|
||||
|
||||
"location_sharing_loading_map_error_title" = "Element could not load the map. Please try again later.";
|
||||
"location_sharing_loading_map_error_title" = "%@ could not load the map. Please try again later.";
|
||||
|
||||
"location_sharing_locating_user_error_title" = "Element could not access your location. Please try again later.";
|
||||
"location_sharing_locating_user_error_title" = "%@ could not access your location. Please try again later.";
|
||||
|
||||
"location_sharing_invalid_authorization_error_title" = "Element does not have permission to access your location. You can enable access in Settings > Location";
|
||||
"location_sharing_invalid_authorization_error_title" = "%@ does not have permission to access your location. You can enable access in Settings > Location";
|
||||
|
||||
"location_sharing_invalid_authorization_not_now" = "Not now";
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ public class VectorL10n: NSObject {
|
||||
public static func activeCallDetails(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "active_call_details", p1)
|
||||
}
|
||||
/// Help us identify issues and improve Element by sharing anonymous usage data. To understand how people use multiple devices, we’ll generate a random identifier, shared by your devices.
|
||||
public static var analyticsPromptMessageNewUser: String {
|
||||
return VectorL10n.tr("Vector", "analytics_prompt_message_new_user")
|
||||
/// Help us identify issues and improve %@ by sharing anonymous usage data. To understand how people use multiple devices, we’ll generate a random identifier, shared by your devices.
|
||||
public static func analyticsPromptMessageNewUser(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "analytics_prompt_message_new_user", p1)
|
||||
}
|
||||
/// You previously consented to share anonymous usage data with us. Now, to help understand how people use multiple devices, we’ll generate a random identifier, shared by your devices.
|
||||
public static var analyticsPromptMessageUpgrade: String {
|
||||
@@ -2195,9 +2195,9 @@ public class VectorL10n: NSObject {
|
||||
public static var locationSharingCloseAction: String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_close_action")
|
||||
}
|
||||
/// Element does not have permission to access your location. You can enable access in Settings > Location
|
||||
public static var locationSharingInvalidAuthorizationErrorTitle: String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_invalid_authorization_error_title")
|
||||
/// %@ does not have permission to access your location. You can enable access in Settings > Location
|
||||
public static func locationSharingInvalidAuthorizationErrorTitle(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_invalid_authorization_error_title", p1)
|
||||
}
|
||||
/// Not now
|
||||
public static var locationSharingInvalidAuthorizationNotNow: String {
|
||||
@@ -2207,13 +2207,13 @@ public class VectorL10n: NSObject {
|
||||
public static var locationSharingInvalidAuthorizationSettings: String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_invalid_authorization_settings")
|
||||
}
|
||||
/// Element could not load the map. Please try again later.
|
||||
public static var locationSharingLoadingMapErrorTitle: String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_loading_map_error_title")
|
||||
/// %@ could not load the map. Please try again later.
|
||||
public static func locationSharingLoadingMapErrorTitle(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_loading_map_error_title", p1)
|
||||
}
|
||||
/// Element could not access your location. Please try again later.
|
||||
public static var locationSharingLocatingUserErrorTitle: String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_locating_user_error_title")
|
||||
/// %@ could not access your location. Please try again later.
|
||||
public static func locationSharingLocatingUserErrorTitle(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "location_sharing_locating_user_error_title", p1)
|
||||
}
|
||||
/// Open in Apple Maps
|
||||
public static var locationSharingOpenAppleMaps: String {
|
||||
@@ -5155,9 +5155,9 @@ public class VectorL10n: NSObject {
|
||||
public static var spacesAddRoomsComingSoonTitle: String {
|
||||
return VectorL10n.tr("Vector", "spaces_add_rooms_coming_soon_title")
|
||||
}
|
||||
/// This feature hasn’t been implemented here, but it’s on the way. For now, you can do that with Element on your computer.
|
||||
public static var spacesComingSoonDetail: String {
|
||||
return VectorL10n.tr("Vector", "spaces_coming_soon_detail")
|
||||
/// This feature hasn’t been implemented here, but it’s on the way. For now, you can do that with %@ on your computer.
|
||||
public static func spacesComingSoonDetail(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "spaces_coming_soon_detail", p1)
|
||||
}
|
||||
/// Coming soon
|
||||
public static var spacesComingSoonTitle: String {
|
||||
|
||||
@@ -19,17 +19,14 @@ import Foundation
|
||||
/// Used to handle the application information
|
||||
@objcMembers
|
||||
final class AppInfo: NSObject {
|
||||
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
/// Current application information
|
||||
static var current: AppInfo {
|
||||
let appDisplayName = BuildSettings.bundleDisplayName
|
||||
let buildInfo: BuildInfo = BuildInfo()
|
||||
|
||||
return AppInfo(displayName: appDisplayName,
|
||||
return AppInfo(displayName: self.bundleDisplayName,
|
||||
appVersion: AppVersion.current,
|
||||
buildInfo: buildInfo)
|
||||
buildInfo: BuildInfo())
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
@@ -52,4 +49,11 @@ final class AppInfo: NSObject {
|
||||
self.appVersion = appVersion
|
||||
self.buildInfo = buildInfo
|
||||
}
|
||||
|
||||
private static var bundleDisplayName: String {
|
||||
guard let bundleDisplayName = Bundle.app.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String else {
|
||||
fatalError("CFBundleDisplayName should be defined")
|
||||
}
|
||||
return bundleDisplayName
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ class FindYourContactsFooterView: UIView, NibLoadable, Themable {
|
||||
button.layer.cornerRadius = 8
|
||||
|
||||
titleLabel.text = VectorL10n.findYourContactsTitle
|
||||
messageLabel.text = VectorL10n.findYourContactsMessage(BuildSettings.bundleDisplayName)
|
||||
messageLabel.text = VectorL10n.findYourContactsMessage(AppInfo.current.displayName)
|
||||
button.setTitle(VectorL10n.findYourContactsButtonTitle, for: .normal)
|
||||
footerLabel.text = VectorL10n.findYourContactsFooter
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ final class InviteFriendsPresenter: NSObject {
|
||||
|
||||
private func buildShareText(with userId: String) -> String {
|
||||
let userMatrixToLink: String = MXTools.permalinkToUser(withUserId: userId)
|
||||
return VectorL10n.inviteFriendsShareText(BuildSettings.bundleDisplayName, userMatrixToLink)
|
||||
return VectorL10n.inviteFriendsShareText(AppInfo.current.displayName, userMatrixToLink)
|
||||
}
|
||||
|
||||
private func present(_ viewController: UIViewController, animated: Bool) {
|
||||
|
||||
@@ -19,8 +19,10 @@ import Reusable
|
||||
import Mapbox
|
||||
import Keys
|
||||
|
||||
class RoomTimelineLocationView: UIView, NibLoadable, MGLMapViewDelegate {
|
||||
class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegate {
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
private struct Constants {
|
||||
static let mapHeight: CGFloat = 300.0
|
||||
static let mapTilerKey = RiotKeys().mapTilerAPIKey
|
||||
@@ -29,8 +31,8 @@ class RoomTimelineLocationView: UIView, NibLoadable, MGLMapViewDelegate {
|
||||
static let cellCornerRadius: CGFloat = 8.0
|
||||
}
|
||||
|
||||
// MARK: Properties
|
||||
// MARK: - Private
|
||||
// MARK: - Properties
|
||||
// MARK: Private
|
||||
|
||||
@IBOutlet private var descriptionContainerView: UIView!
|
||||
@IBOutlet private var descriptionLabel: UILabel!
|
||||
@@ -38,7 +40,7 @@ class RoomTimelineLocationView: UIView, NibLoadable, MGLMapViewDelegate {
|
||||
private var mapView: MGLMapView!
|
||||
private var annotationView: LocationUserMarkerView?
|
||||
|
||||
// MARK: - Public
|
||||
// MARK: Public
|
||||
|
||||
var locationDescription: String? {
|
||||
get {
|
||||
@@ -67,9 +69,6 @@ class RoomTimelineLocationView: UIView, NibLoadable, MGLMapViewDelegate {
|
||||
clipsToBounds = true
|
||||
layer.borderWidth = Constants.cellBorderRadius
|
||||
layer.cornerRadius = Constants.cellCornerRadius
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(updateTheme), name: .themeServiceDidChangeTheme, object: nil)
|
||||
updateTheme()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
@@ -99,17 +98,17 @@ class RoomTimelineLocationView: UIView, NibLoadable, MGLMapViewDelegate {
|
||||
mapView.addAnnotation(pointAnnotation)
|
||||
}
|
||||
|
||||
// MARK: - Themable
|
||||
|
||||
func update(theme: Theme) {
|
||||
descriptionLabel.textColor = theme.colors.primaryContent
|
||||
descriptionLabel.font = theme.fonts.footnote
|
||||
layer.borderColor = theme.colors.quinaryContent.cgColor
|
||||
}
|
||||
|
||||
// MARK: - MGLMapViewDelegate
|
||||
|
||||
func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
|
||||
return annotationView
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
@objc private func updateTheme() {
|
||||
descriptionLabel.textColor = ThemeService.shared().theme.colors.primaryContent
|
||||
descriptionLabel.font = ThemeService.shared().theme.fonts.footnote
|
||||
layer.borderColor = ThemeService.shared().theme.colors.quinaryContent.cgColor
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,6 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol {
|
||||
private let activityIndicatorPresenter: ActivityIndicatorPresenterType
|
||||
private var selectedEventId: String?
|
||||
|
||||
private var pollEditFormCoordinator: PollEditFormCoordinator?
|
||||
private var locationSharingCoordinator: LocationSharingCoordinator?
|
||||
|
||||
private var roomDataSourceManager: MXKRoomDataSourceManager {
|
||||
return MXKRoomDataSourceManager.sharedManager(forMatrixSession: self.parameters.session)
|
||||
}
|
||||
@@ -199,6 +196,56 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol {
|
||||
|
||||
completion?()
|
||||
}
|
||||
|
||||
private func startLocationCoordinatorWithEvent(_ event: MXEvent? = nil, bubbleData: MXKRoomBubbleCellDataStoring? = nil) {
|
||||
guard #available(iOS 14.0, *) else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let navigationRouter = self.navigationRouter,
|
||||
let mediaManager = mxSession?.mediaManager,
|
||||
let user = mxSession?.myUser else {
|
||||
MXLog.error("[RoomCoordinator] Invalid location sharing coordinator parameters. Returning.")
|
||||
return
|
||||
}
|
||||
|
||||
var avatarData: AvatarInputProtocol
|
||||
if event != nil, let bubbleData = bubbleData {
|
||||
avatarData = AvatarInput(mxContentUri: bubbleData.senderAvatarUrl,
|
||||
matrixItemId: bubbleData.senderId,
|
||||
displayName: bubbleData.senderDisplayName)
|
||||
} else {
|
||||
avatarData = AvatarInput(mxContentUri: user.avatarUrl,
|
||||
matrixItemId: user.userId,
|
||||
displayName: user.displayname)
|
||||
}
|
||||
|
||||
var location: CLLocationCoordinate2D?
|
||||
if let locationContent = event?.location {
|
||||
location = CLLocationCoordinate2D(latitude: locationContent.latitude, longitude: locationContent.longitude)
|
||||
}
|
||||
|
||||
let parameters = LocationSharingCoordinatorParameters(roomDataSource: roomViewController.roomDataSource,
|
||||
mediaManager: mediaManager,
|
||||
avatarData: avatarData,
|
||||
location: location)
|
||||
|
||||
let coordinator = LocationSharingCoordinator(parameters: parameters)
|
||||
|
||||
coordinator.completion = { [weak self, weak coordinator] in
|
||||
guard let self = self, let coordinator = coordinator else {
|
||||
return
|
||||
}
|
||||
|
||||
self.navigationRouter?.dismissModule(animated: true, completion: nil)
|
||||
self.remove(childCoordinator: coordinator)
|
||||
}
|
||||
|
||||
add(childCoordinator: coordinator)
|
||||
|
||||
navigationRouter.present(coordinator, animated: true)
|
||||
coordinator.start()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - RoomIdentifiable
|
||||
@@ -262,10 +309,22 @@ extension RoomCoordinator: RoomViewControllerDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
let parameters = PollEditFormCoordinatorParameters(navigationRouter: self.navigationRouter, room: roomViewController.roomDataSource.room)
|
||||
pollEditFormCoordinator = PollEditFormCoordinator(parameters: parameters)
|
||||
let parameters = PollEditFormCoordinatorParameters(room: roomViewController.roomDataSource.room)
|
||||
let coordinator = PollEditFormCoordinator(parameters: parameters)
|
||||
|
||||
pollEditFormCoordinator?.start()
|
||||
coordinator.completion = { [weak self, weak coordinator] in
|
||||
guard let self = self, let coordinator = coordinator else {
|
||||
return
|
||||
}
|
||||
|
||||
self.navigationRouter?.dismissModule(animated: true, completion: nil)
|
||||
self.remove(childCoordinator: coordinator)
|
||||
}
|
||||
|
||||
add(childCoordinator: coordinator)
|
||||
|
||||
navigationRouter?.present(coordinator, animated: true)
|
||||
coordinator.start()
|
||||
}
|
||||
|
||||
func roomViewControllerDidRequestLocationSharingFormPresentation(_ roomViewController: RoomViewController) {
|
||||
@@ -291,45 +350,4 @@ extension RoomCoordinator: RoomViewControllerDelegate {
|
||||
|
||||
PollTimelineProvider.shared.pollTimelineCoordinatorForEventIdentifier(eventIdentifier)?.endPoll()
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func startLocationCoordinatorWithEvent(_ event: MXEvent? = nil, bubbleData: MXKRoomBubbleCellDataStoring? = nil) {
|
||||
guard #available(iOS 14.0, *) else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let navigationRouter = self.navigationRouter,
|
||||
let mediaManager = mxSession?.mediaManager,
|
||||
let user = mxSession?.myUser else {
|
||||
MXLog.error("[RoomCoordinator] Invalid location sharing coordinator parameters. Returning.")
|
||||
return
|
||||
}
|
||||
|
||||
var avatarData: AvatarInputProtocol
|
||||
if event != nil, let bubbleData = bubbleData {
|
||||
avatarData = AvatarInput(mxContentUri: bubbleData.senderAvatarUrl,
|
||||
matrixItemId: bubbleData.senderId,
|
||||
displayName: bubbleData.senderDisplayName)
|
||||
} else {
|
||||
avatarData = AvatarInput(mxContentUri: user.avatarUrl,
|
||||
matrixItemId: user.userId,
|
||||
displayName: user.displayname)
|
||||
}
|
||||
|
||||
var location: CLLocationCoordinate2D?
|
||||
if let locationContent = event?.location {
|
||||
location = CLLocationCoordinate2D(latitude: locationContent.latitude, longitude: locationContent.longitude)
|
||||
}
|
||||
|
||||
let parameters = LocationSharingCoordinatorParameters(navigationRouter: navigationRouter,
|
||||
roomDataSource: roomViewController.roomDataSource,
|
||||
mediaManager: mediaManager,
|
||||
avatarData: avatarData,
|
||||
location: location)
|
||||
|
||||
locationSharingCoordinator = LocationSharingCoordinator(parameters: parameters)
|
||||
|
||||
locationSharingCoordinator?.start()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ class LocationBubbleCell: SizableBaseBubbleCell, BubbleCellReactionsDisplayable
|
||||
return
|
||||
}
|
||||
|
||||
locationView.update(theme: ThemeService.shared().theme)
|
||||
locationView.locationDescription = locationContent.locationDescription
|
||||
|
||||
let location = CLLocationCoordinate2D(latitude: locationContent.latitude, longitude: locationContent.longitude)
|
||||
|
||||
@@ -154,7 +154,7 @@ final class SpaceMemberListViewController: RoomParticipantsViewController {
|
||||
// MARK: - Actions
|
||||
|
||||
@objc private func onAddParticipantButtonPressed() {
|
||||
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesInvitesComingSoonTitle, message: VectorL10n.spacesComingSoonDetail, animated: true, handler: nil)
|
||||
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesInvitesComingSoonTitle, message: VectorL10n.spacesComingSoonDetail(AppInfo.current.displayName), animated: true, handler: nil)
|
||||
}
|
||||
|
||||
private func cancelButtonAction() {
|
||||
@@ -184,11 +184,11 @@ final class SpaceMemberListViewController: RoomParticipantsViewController {
|
||||
|
||||
override func roomMemberDetailsViewController(_ roomMemberDetailsViewController: MXKRoomMemberDetailsViewController!, startChatWithMemberId matrixId: String!, completion: (() -> Void)!) {
|
||||
completion()
|
||||
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesComingSoonTitle, message: VectorL10n.spacesComingSoonDetail, animated: true, handler: nil)
|
||||
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesComingSoonTitle, message: VectorL10n.spacesComingSoonDetail(AppInfo.current.displayName), animated: true, handler: nil)
|
||||
}
|
||||
|
||||
override func roomMemberDetailsViewController(_ roomMemberDetailsViewController: MXKRoomMemberDetailsViewController!, placeVoipCallWithMemberId matrixId: String!, andVideo isVideoCall: Bool) {
|
||||
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesComingSoonTitle, message: VectorL10n.spacesComingSoonDetail, animated: true, handler: nil)
|
||||
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesComingSoonTitle, message: VectorL10n.spacesComingSoonDetail(AppInfo.current.displayName), animated: true, handler: nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@ final class SpaceExploreRoomViewController: UIViewController {
|
||||
}
|
||||
|
||||
@objc private func addRoomAction(semder: UIView) {
|
||||
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesAddRoomsComingSoonTitle, message: VectorL10n.spacesComingSoonDetail, animated: true, handler: nil)
|
||||
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesAddRoomsComingSoonTitle, message: VectorL10n.spacesComingSoonDetail(AppInfo.current.displayName), animated: true, handler: nil)
|
||||
}
|
||||
|
||||
// MARK: - UISearchBarDelegate
|
||||
|
||||
@@ -50,7 +50,7 @@ final class InviteFriendsHeaderView: UIView, NibLoadable, Themable {
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
button.setTitle(VectorL10n.inviteFriendsAction(BuildSettings.bundleDisplayName), for: .normal)
|
||||
button.setTitle(VectorL10n.inviteFriendsAction(AppInfo.current.displayName), for: .normal)
|
||||
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
|
||||
button.layer.cornerRadius = 8
|
||||
button.layer.borderWidth = 2
|
||||
|
||||
@@ -489,15 +489,20 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
private func presentAnalyticsPrompt(with session: MXSession) {
|
||||
let parameters = AnalyticsPromptCoordinatorParameters(session: session, navigationRouter: navigationRouter)
|
||||
let parameters = AnalyticsPromptCoordinatorParameters(session: session)
|
||||
let coordinator = AnalyticsPromptCoordinator(parameters: parameters)
|
||||
|
||||
coordinator.completion = { [weak self, weak coordinator] in
|
||||
guard let self = self, let coordinator = coordinator else { return }
|
||||
|
||||
self.navigationRouter.dismissModule(animated: true, completion: nil)
|
||||
self.remove(childCoordinator: coordinator)
|
||||
}
|
||||
|
||||
coordinator.start()
|
||||
add(childCoordinator: coordinator)
|
||||
|
||||
navigationRouter.present(coordinator, animated: true)
|
||||
coordinator.start()
|
||||
}
|
||||
|
||||
// MARK: UserSessions management
|
||||
|
||||
@@ -27,4 +27,6 @@ INFOPLIST_FILE = RiotSwiftUI/Info.plist
|
||||
|
||||
SKIP_INSTALL = YES
|
||||
|
||||
SWIFT_OBJC_BRIDGING_HEADER = $(SRCROOT)/$(PRODUCT_NAME)/RiotSwiftUI-Bridging-Header.h
|
||||
|
||||
SWIFT_OBJC_INTERFACE_HEADER_NAME = GeneratedInterface-Swift.h
|
||||
|
||||
@@ -66,7 +66,7 @@ extension AnalyticsPromptType {
|
||||
var message: String {
|
||||
switch self {
|
||||
case .newUser:
|
||||
return VectorL10n.analyticsPromptMessageNewUser
|
||||
return VectorL10n.analyticsPromptMessageNewUser(AppInfo.current.displayName)
|
||||
case .upgrade:
|
||||
return VectorL10n.analyticsPromptMessageUpgrade
|
||||
}
|
||||
|
||||
@@ -21,11 +21,9 @@ import SwiftUI
|
||||
struct AnalyticsPromptCoordinatorParameters {
|
||||
/// The session to use if analytics are enabled.
|
||||
let session: MXSession
|
||||
/// The navigation router used to display the prompt.
|
||||
let navigationRouter: NavigationRouterType
|
||||
}
|
||||
|
||||
final class AnalyticsPromptCoordinator: Coordinator {
|
||||
final class AnalyticsPromptCoordinator: Coordinator, Presentable {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
@@ -78,8 +76,6 @@ final class AnalyticsPromptCoordinator: Coordinator {
|
||||
|
||||
MXLog.debug("[AnalyticsPromptCoordinator] did start.")
|
||||
|
||||
parameters.navigationRouter.present(toPresentable(), animated: true)
|
||||
|
||||
analyticsPromptViewModel.completion = { [weak self] result in
|
||||
MXLog.debug("[AnalyticsPromptCoordinator] AnalyticsPromptViewModel did complete with result: \(result).")
|
||||
|
||||
@@ -88,11 +84,9 @@ final class AnalyticsPromptCoordinator: Coordinator {
|
||||
switch result {
|
||||
case .enable:
|
||||
Analytics.shared.optIn(with: self.parameters.session)
|
||||
self.parameters.navigationRouter.dismissModule(animated: true, completion: nil)
|
||||
self.completion?()
|
||||
case .disable:
|
||||
Analytics.shared.optOut()
|
||||
self.parameters.navigationRouter.dismissModule(animated: true, completion: nil)
|
||||
self.completion?()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,14 +20,13 @@ import SwiftUI
|
||||
import Keys
|
||||
|
||||
struct LocationSharingCoordinatorParameters {
|
||||
let navigationRouter: NavigationRouterType
|
||||
let roomDataSource: MXKRoomDataSource
|
||||
let mediaManager: MXMediaManager
|
||||
let avatarData: AvatarInputProtocol
|
||||
let location: CLLocationCoordinate2D?
|
||||
}
|
||||
|
||||
final class LocationSharingCoordinator: Coordinator {
|
||||
final class LocationSharingCoordinator: Coordinator, Presentable {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
@@ -44,9 +43,10 @@ final class LocationSharingCoordinator: Coordinator {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
// Must be used only internally
|
||||
var childCoordinators: [Coordinator] = []
|
||||
|
||||
var completion: (() -> Void)?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
@@ -70,14 +70,12 @@ final class LocationSharingCoordinator: Coordinator {
|
||||
return
|
||||
}
|
||||
|
||||
parameters.navigationRouter.present(locationSharingHostingController, animated: true)
|
||||
|
||||
locationSharingViewModel.completion = { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch result {
|
||||
case .cancel:
|
||||
self.parameters.navigationRouter.dismissModule(animated: true, completion: nil)
|
||||
self.completion?()
|
||||
case .share(let latitude, let longitude):
|
||||
if let location = self.parameters.location {
|
||||
self.showActivityControllerForLocation(location)
|
||||
@@ -91,8 +89,8 @@ final class LocationSharingCoordinator: Coordinator {
|
||||
description: nil) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.parameters.navigationRouter.dismissModule(animated: true, completion: nil)
|
||||
self.locationSharingViewModel.dispatch(action: .stopLoading(nil))
|
||||
self.completion?()
|
||||
} failure: { [weak self] error in
|
||||
guard let self = self else { return }
|
||||
|
||||
@@ -104,85 +102,19 @@ final class LocationSharingCoordinator: Coordinator {
|
||||
}
|
||||
}
|
||||
|
||||
func showActivityControllerForLocation(_ location: CLLocationCoordinate2D) {
|
||||
let vc = UIActivityViewController(activityItems: activityItems(location: location),
|
||||
// MARK: - Presentable
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
return locationSharingHostingController
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func showActivityControllerForLocation(_ location: CLLocationCoordinate2D) {
|
||||
let vc = UIActivityViewController(activityItems: [ShareToMapsAppActivity.urlForMapsAppType(.apple, location: location)],
|
||||
applicationActivities: [ShareToMapsAppActivity(type: .apple, location: location),
|
||||
ShareToMapsAppActivity(type: .google, location: location)])
|
||||
|
||||
locationSharingHostingController.present(vc, animated: true)
|
||||
}
|
||||
|
||||
func activityItems(location: CLLocationCoordinate2D) -> [Any] {
|
||||
var items = [Any]()
|
||||
|
||||
// Make the share sheet show a pretty location thumbnail
|
||||
if let url = NSURL(string: "https://maps.apple.com?ll=\(location.latitude),\(location.longitude)") {
|
||||
items.append(url)
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
}
|
||||
|
||||
extension UIActivity.ActivityType {
|
||||
static let shareToMapsApp = UIActivity.ActivityType("Element.ShareToMapsApp")
|
||||
}
|
||||
|
||||
class ShareToMapsAppActivity: UIActivity {
|
||||
|
||||
enum MapsAppType {
|
||||
case apple
|
||||
case google
|
||||
}
|
||||
|
||||
let type: MapsAppType
|
||||
let location: CLLocationCoordinate2D
|
||||
|
||||
private override init() {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
init(type: MapsAppType, location: CLLocationCoordinate2D) {
|
||||
self.type = type
|
||||
self.location = location
|
||||
}
|
||||
|
||||
override var activityTitle: String? {
|
||||
switch type {
|
||||
case .apple:
|
||||
return VectorL10n.locationSharingOpenAppleMaps
|
||||
case .google:
|
||||
return VectorL10n.locationSharingOpenGoogleMaps
|
||||
}
|
||||
}
|
||||
|
||||
var activityCategory: UIActivity.Category {
|
||||
return .action
|
||||
}
|
||||
|
||||
override var activityType: UIActivity.ActivityType {
|
||||
return .shareToMapsApp
|
||||
}
|
||||
|
||||
override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func prepare(withActivityItems activityItems: [Any]) {
|
||||
var url: URL?
|
||||
switch type {
|
||||
case .apple:
|
||||
url = URL(string: "https://maps.apple.com?ll=\(location.latitude),\(location.longitude)&q=Pin")
|
||||
case .google:
|
||||
url = URL(string: "https://www.google.com/maps/search/?api=1&query=\(location.latitude),\(location.longitude)")
|
||||
}
|
||||
|
||||
guard let url = url else {
|
||||
activityDidFinish(false)
|
||||
return
|
||||
}
|
||||
|
||||
UIApplication.shared.open(url, options: [:]) { [weak self] result in
|
||||
self?.activityDidFinish(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// Copyright 2021 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.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension UIActivity.ActivityType {
|
||||
static let shareToMapsApp = UIActivity.ActivityType("Element.ShareToMapsApp")
|
||||
}
|
||||
|
||||
class ShareToMapsAppActivity: UIActivity {
|
||||
enum MapsAppType {
|
||||
case apple
|
||||
case google
|
||||
}
|
||||
|
||||
let type: MapsAppType
|
||||
let location: CLLocationCoordinate2D
|
||||
|
||||
private override init() {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
init(type: MapsAppType, location: CLLocationCoordinate2D) {
|
||||
self.type = type
|
||||
self.location = location
|
||||
}
|
||||
|
||||
static func urlForMapsAppType(_ type: MapsAppType, location: CLLocationCoordinate2D) -> URL {
|
||||
switch type {
|
||||
case .apple:
|
||||
return URL(string: "https://maps.apple.com?ll=\(location.latitude),\(location.longitude)&q=Pin")!
|
||||
case .google:
|
||||
return URL(string: "https://www.google.com/maps/search/?api=1&query=\(location.latitude),\(location.longitude)")!
|
||||
}
|
||||
}
|
||||
|
||||
override var activityTitle: String? {
|
||||
switch type {
|
||||
case .apple:
|
||||
return VectorL10n.locationSharingOpenAppleMaps
|
||||
case .google:
|
||||
return VectorL10n.locationSharingOpenGoogleMaps
|
||||
}
|
||||
}
|
||||
|
||||
var activityCategory: UIActivity.Category {
|
||||
return .action
|
||||
}
|
||||
|
||||
override var activityType: UIActivity.ActivityType {
|
||||
return .shareToMapsApp
|
||||
}
|
||||
|
||||
override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func prepare(withActivityItems activityItems: [Any]) {
|
||||
let url = Self.urlForMapsAppType(type, location: location)
|
||||
|
||||
UIApplication.shared.open(url, options: [:]) { [weak self] result in
|
||||
self?.activityDidFinish(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,17 +73,17 @@ class LocationSharingViewModel: LocationSharingViewModelType {
|
||||
switch error {
|
||||
case .failedLoadingMap:
|
||||
state.bindings.alertInfo = ErrorAlertInfo(id: .mapLoadingError,
|
||||
title: VectorL10n.locationSharingLoadingMapErrorTitle,
|
||||
title: VectorL10n.locationSharingLoadingMapErrorTitle(AppInfo.current.displayName) ,
|
||||
primaryButton: (VectorL10n.ok, { completion?(.cancel) }),
|
||||
secondaryButton: nil)
|
||||
case .failedLocatingUser:
|
||||
state.bindings.alertInfo = ErrorAlertInfo(id: .userLocatingError,
|
||||
title: VectorL10n.locationSharingLocatingUserErrorTitle,
|
||||
title: VectorL10n.locationSharingLocatingUserErrorTitle(AppInfo.current.displayName),
|
||||
primaryButton: (VectorL10n.ok, { completion?(.cancel) }),
|
||||
secondaryButton: nil)
|
||||
case .invalidLocationAuthorization:
|
||||
state.bindings.alertInfo = ErrorAlertInfo(id: .authorizationError,
|
||||
title: VectorL10n.locationSharingInvalidAuthorizationErrorTitle,
|
||||
title: VectorL10n.locationSharingInvalidAuthorizationErrorTitle(AppInfo.current.displayName),
|
||||
primaryButton: (VectorL10n.locationSharingInvalidAuthorizationNotNow, { completion?(.cancel) }),
|
||||
secondaryButton: (VectorL10n.locationSharingInvalidAuthorizationSettings, {
|
||||
if let applicationSettingsURL = URL(string:UIApplication.openSettingsURLString) {
|
||||
@@ -101,7 +101,7 @@ class LocationSharingViewModel: LocationSharingViewModelType {
|
||||
|
||||
if error != nil {
|
||||
state.bindings.alertInfo = ErrorAlertInfo(id: .locationSharingError,
|
||||
title: VectorL10n.locationSharingInvalidAuthorizationErrorTitle,
|
||||
title: VectorL10n.locationSharingInvalidAuthorizationErrorTitle(AppInfo.current.displayName),
|
||||
primaryButton: (VectorL10n.ok, nil),
|
||||
secondaryButton: nil)
|
||||
}
|
||||
|
||||
@@ -21,11 +21,10 @@ import UIKit
|
||||
import SwiftUI
|
||||
|
||||
struct PollEditFormCoordinatorParameters {
|
||||
let navigationRouter: NavigationRouterType?
|
||||
let room: MXRoom
|
||||
}
|
||||
|
||||
final class PollEditFormCoordinator: Coordinator {
|
||||
final class PollEditFormCoordinator: Coordinator, Presentable {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
@@ -42,9 +41,10 @@ final class PollEditFormCoordinator: Coordinator {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
// Must be used only internally
|
||||
var childCoordinators: [Coordinator] = []
|
||||
|
||||
var completion: (() -> Void)?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
@@ -65,13 +65,11 @@ final class PollEditFormCoordinator: Coordinator {
|
||||
return
|
||||
}
|
||||
|
||||
parameters.navigationRouter?.present(pollEditFormHostingController, animated: true)
|
||||
|
||||
pollEditFormViewModel.completion = { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
switch result {
|
||||
case .cancel:
|
||||
self.parameters.navigationRouter?.dismissModule(animated: true, completion: nil)
|
||||
self.completion?()
|
||||
case .create(let question, let answerOptions):
|
||||
var options = [MXEventContentPollStartAnswerOption]()
|
||||
for answerOption in answerOptions {
|
||||
@@ -88,8 +86,8 @@ final class PollEditFormCoordinator: Coordinator {
|
||||
self.parameters.room.sendPollStart(withContent: pollStartContent, localEcho: nil) { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.parameters.navigationRouter?.dismissModule(animated: true, completion: nil)
|
||||
self.pollEditFormViewModel.dispatch(action: .stopLoading(nil))
|
||||
self.completion?()
|
||||
} failure: { [weak self] error in
|
||||
guard let self = self else { return }
|
||||
|
||||
@@ -99,4 +97,10 @@ final class PollEditFormCoordinator: Coordinator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
return pollEditFormHostingController
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ struct PollTimelineCoordinatorParameters {
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
final class PollTimelineCoordinator: Coordinator, PollAggregatorDelegate {
|
||||
final class PollTimelineCoordinator: Coordinator, Presentable, PollAggregatorDelegate {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ protocol UserSuggestionCoordinatorDelegate: AnyObject {
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
final class UserSuggestionCoordinator: Coordinator {
|
||||
final class UserSuggestionCoordinator: Coordinator, Presentable {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ struct TemplateUserProfileCoordinatorParameters {
|
||||
let session: MXSession
|
||||
}
|
||||
|
||||
final class TemplateUserProfileCoordinator: Coordinator {
|
||||
final class TemplateUserProfileCoordinator: Coordinator, Presentable {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import UIKit
|
||||
|
||||
@objcMembers
|
||||
final class TemplateRoomsCoordinator: Coordinator {
|
||||
final class TemplateRoomsCoordinator: Coordinator, Presentable {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
|
||||
5
RiotSwiftUI/RiotSwiftUI-Bridging-Header.h
Normal file
5
RiotSwiftUI/RiotSwiftUI-Bridging-Header.h
Normal file
@@ -0,0 +1,5 @@
|
||||
//
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
||||
#import "BuildInfo.h"
|
||||
@@ -39,6 +39,8 @@ targets:
|
||||
- "**/MatrixSDK/**"
|
||||
- "**/Coordinator/**"
|
||||
- "**/Test/**"
|
||||
- path: ../Riot/Managers/AppInfo/
|
||||
- path: ../Riot/Categories/Bundle.swift
|
||||
- path: ../Riot/Generated/Strings.swift
|
||||
- path: ../Riot/Generated/Images.swift
|
||||
- path: ../Riot/Managers/Theme/ThemeIdentifier.swift
|
||||
|
||||
Reference in New Issue
Block a user