mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Make Element Call widget URL configurable (#2971)
This commit is contained in:
parent
78b0c7068d
commit
b2c9878df6
@ -264,6 +264,7 @@
|
|||||||
3F2148F11164C7C5609984EB /* GZIP in Frameworks */ = {isa = PBXBuildFile; productRef = 2B788C81F6369D164ADEB917 /* GZIP */; };
|
3F2148F11164C7C5609984EB /* GZIP in Frameworks */ = {isa = PBXBuildFile; productRef = 2B788C81F6369D164ADEB917 /* GZIP */; };
|
||||||
3F327A62D233933F54F0F33A /* SwiftOGG in Frameworks */ = {isa = PBXBuildFile; productRef = 3FE40E79C36E7903121E6E3B /* SwiftOGG */; };
|
3F327A62D233933F54F0F33A /* SwiftOGG in Frameworks */ = {isa = PBXBuildFile; productRef = 3FE40E79C36E7903121E6E3B /* SwiftOGG */; };
|
||||||
3F70E237CE4C3FAB02FC227F /* NotificationConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C830A64609CBD152F06E0457 /* NotificationConstants.swift */; };
|
3F70E237CE4C3FAB02FC227F /* NotificationConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C830A64609CBD152F06E0457 /* NotificationConstants.swift */; };
|
||||||
|
3F997171C3C79A45E92BF9EF /* ElementWellKnown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79FAC366FF299BCC555D756E /* ElementWellKnown.swift */; };
|
||||||
401BB28CD6B7DD6B4E7863E7 /* ServerConfirmationScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9342F5D6729627B6393AF853 /* ServerConfirmationScreenModels.swift */; };
|
401BB28CD6B7DD6B4E7863E7 /* ServerConfirmationScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9342F5D6729627B6393AF853 /* ServerConfirmationScreenModels.swift */; };
|
||||||
407DCE030E0F9B7C9861D38A /* LRUCache in Frameworks */ = {isa = PBXBuildFile; productRef = 1081D3630AAD3ACEDDEC3A98 /* LRUCache */; };
|
407DCE030E0F9B7C9861D38A /* LRUCache in Frameworks */ = {isa = PBXBuildFile; productRef = 1081D3630AAD3ACEDDEC3A98 /* LRUCache */; };
|
||||||
40B79D20A873620F7F128A2C /* UserPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35FA991289149D31F4286747 /* UserPreference.swift */; };
|
40B79D20A873620F7F128A2C /* UserPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35FA991289149D31F4286747 /* UserPreference.swift */; };
|
||||||
@ -1621,6 +1622,7 @@
|
|||||||
78913D6E120D46138E97C107 /* NavigationSplitCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationSplitCoordinatorTests.swift; sourceTree = "<group>"; };
|
78913D6E120D46138E97C107 /* NavigationSplitCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationSplitCoordinatorTests.swift; sourceTree = "<group>"; };
|
||||||
7893780A1FD6E3F38B3E9049 /* UserIndicatorControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorControllerMock.swift; sourceTree = "<group>"; };
|
7893780A1FD6E3F38B3E9049 /* UserIndicatorControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorControllerMock.swift; sourceTree = "<group>"; };
|
||||||
796CBD0C56FA0D3AEDAB255B /* SessionVerificationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenCoordinator.swift; sourceTree = "<group>"; };
|
796CBD0C56FA0D3AEDAB255B /* SessionVerificationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
|
79FAC366FF299BCC555D756E /* ElementWellKnown.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementWellKnown.swift; sourceTree = "<group>"; };
|
||||||
7A03E073077D92AA19C43DCF /* IdentityConfirmationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenCoordinator.swift; sourceTree = "<group>"; };
|
7A03E073077D92AA19C43DCF /* IdentityConfirmationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
7A5D2323D7B6BF4913EB7EED /* landscape_test_image.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = landscape_test_image.jpg; sourceTree = "<group>"; };
|
7A5D2323D7B6BF4913EB7EED /* landscape_test_image.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = landscape_test_image.jpg; sourceTree = "<group>"; };
|
||||||
7AAD8C633AA57948B34EDCF7 /* RoomChangeRolesScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomChangeRolesScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
7AAD8C633AA57948B34EDCF7 /* RoomChangeRolesScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomChangeRolesScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
@ -3862,6 +3864,7 @@
|
|||||||
D09A267106B9585D3D0CFC0D /* ClientError.swift */,
|
D09A267106B9585D3D0CFC0D /* ClientError.swift */,
|
||||||
18F2958E6D247AE2516BEEE8 /* ClientProxy.swift */,
|
18F2958E6D247AE2516BEEE8 /* ClientProxy.swift */,
|
||||||
6033779EB37259F27F938937 /* ClientProxyProtocol.swift */,
|
6033779EB37259F27F938937 /* ClientProxyProtocol.swift */,
|
||||||
|
79FAC366FF299BCC555D756E /* ElementWellKnown.swift */,
|
||||||
);
|
);
|
||||||
path = Client;
|
path = Client;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -6060,6 +6063,7 @@
|
|||||||
48416BBEB8DDF3E4DED0EDB6 /* ElementCallServiceProtocol.swift in Sources */,
|
48416BBEB8DDF3E4DED0EDB6 /* ElementCallServiceProtocol.swift in Sources */,
|
||||||
07CC13C5729C24255348CBBD /* ElementCallWidgetDriver.swift in Sources */,
|
07CC13C5729C24255348CBBD /* ElementCallWidgetDriver.swift in Sources */,
|
||||||
370AF5BFCD4384DD455479B6 /* ElementCallWidgetDriverProtocol.swift in Sources */,
|
370AF5BFCD4384DD455479B6 /* ElementCallWidgetDriverProtocol.swift in Sources */,
|
||||||
|
3F997171C3C79A45E92BF9EF /* ElementWellKnown.swift in Sources */,
|
||||||
7C1A7B594B2F8143F0DD0005 /* ElementXAttributeScope.swift in Sources */,
|
7C1A7B594B2F8143F0DD0005 /* ElementXAttributeScope.swift in Sources */,
|
||||||
7361B011A79BF723D8C9782B /* EmojiCategory.swift in Sources */,
|
7361B011A79BF723D8C9782B /* EmojiCategory.swift in Sources */,
|
||||||
E45C9FA22BC13B477FD3B4AC /* EmojiDetection.swift in Sources */,
|
E45C9FA22BC13B477FD3B4AC /* EmojiDetection.swift in Sources */,
|
||||||
|
@ -39,7 +39,7 @@ final class AppSettings {
|
|||||||
case sharePresence
|
case sharePresence
|
||||||
case hideUnreadMessagesBadge
|
case hideUnreadMessagesBadge
|
||||||
|
|
||||||
case elementCallBaseURL
|
case elementCallBaseURLOverride
|
||||||
case elementCallEncryptionEnabled
|
case elementCallEncryptionEnabled
|
||||||
|
|
||||||
// Feature flags
|
// Feature flags
|
||||||
@ -249,8 +249,10 @@ final class AppSettings {
|
|||||||
|
|
||||||
// MARK: - Element Call
|
// MARK: - Element Call
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.elementCallBaseURL, defaultValue: "https://call.element.io", storageType: .userDefaults(store))
|
let elementCallBaseURL: URL = "https://call.element.io"
|
||||||
var elementCallBaseURL: URL
|
|
||||||
|
@UserPreference(key: UserDefaultsKeys.elementCallBaseURLOverride, defaultValue: nil, storageType: .userDefaults(store))
|
||||||
|
var elementCallBaseURLOverride: URL?
|
||||||
|
|
||||||
// MARK: - Users
|
// MARK: - Users
|
||||||
|
|
||||||
|
@ -555,9 +555,11 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
private func presentCallScreen(roomProxy: RoomProxyProtocol) {
|
private func presentCallScreen(roomProxy: RoomProxyProtocol) {
|
||||||
let callScreenCoordinator = CallScreenCoordinator(parameters: .init(elementCallService: elementCallService,
|
let callScreenCoordinator = CallScreenCoordinator(parameters: .init(elementCallService: elementCallService,
|
||||||
|
clientProxy: userSession.clientProxy,
|
||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
callBaseURL: appSettings.elementCallBaseURL,
|
clientID: InfoPlistReader.main.bundleIdentifier,
|
||||||
clientID: InfoPlistReader.main.bundleIdentifier))
|
elementCallBaseURL: appSettings.elementCallBaseURL,
|
||||||
|
elementCallBaseURLOverride: appSettings.elementCallBaseURLOverride))
|
||||||
|
|
||||||
callScreenCoordinator.actions
|
callScreenCoordinator.actions
|
||||||
.sink { [weak self] action in
|
.sink { [weak self] action in
|
||||||
|
@ -1920,6 +1920,7 @@ class ClientProxyMock: ClientProxyProtocol {
|
|||||||
set(value) { underlyingHomeserver = value }
|
set(value) { underlyingHomeserver = value }
|
||||||
}
|
}
|
||||||
var underlyingHomeserver: String!
|
var underlyingHomeserver: String!
|
||||||
|
var userIDServerName: String?
|
||||||
var userDisplayNamePublisher: CurrentValuePublisher<String?, Never> {
|
var userDisplayNamePublisher: CurrentValuePublisher<String?, Never> {
|
||||||
get { return underlyingUserDisplayNamePublisher }
|
get { return underlyingUserDisplayNamePublisher }
|
||||||
set(value) { underlyingUserDisplayNamePublisher = value }
|
set(value) { underlyingUserDisplayNamePublisher = value }
|
||||||
@ -3564,6 +3565,70 @@ class ClientProxyMock: ClientProxyProtocol {
|
|||||||
return resolveRoomAliasReturnValue
|
return resolveRoomAliasReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//MARK: - getElementWellKnown
|
||||||
|
|
||||||
|
var getElementWellKnownUnderlyingCallsCount = 0
|
||||||
|
var getElementWellKnownCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return getElementWellKnownUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = getElementWellKnownUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
getElementWellKnownUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
getElementWellKnownUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var getElementWellKnownCalled: Bool {
|
||||||
|
return getElementWellKnownCallsCount > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var getElementWellKnownUnderlyingReturnValue: Result<ElementWellKnown?, ClientProxyError>!
|
||||||
|
var getElementWellKnownReturnValue: Result<ElementWellKnown?, ClientProxyError>! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return getElementWellKnownUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: Result<ElementWellKnown?, ClientProxyError>? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = getElementWellKnownUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
getElementWellKnownUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
getElementWellKnownUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var getElementWellKnownClosure: (() async -> Result<ElementWellKnown?, ClientProxyError>)?
|
||||||
|
|
||||||
|
func getElementWellKnown() async -> Result<ElementWellKnown?, ClientProxyError> {
|
||||||
|
getElementWellKnownCallsCount += 1
|
||||||
|
if let getElementWellKnownClosure = getElementWellKnownClosure {
|
||||||
|
return await getElementWellKnownClosure()
|
||||||
|
} else {
|
||||||
|
return getElementWellKnownReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
//MARK: - ignoreUser
|
//MARK: - ignoreUser
|
||||||
|
|
||||||
var ignoreUserUnderlyingCallsCount = 0
|
var ignoreUserUnderlyingCallsCount = 0
|
||||||
|
@ -1439,6 +1439,81 @@ open class ClientSDKMock: MatrixRustSDK.Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//MARK: - getUrl
|
||||||
|
|
||||||
|
open var getUrlUrlThrowableError: Error?
|
||||||
|
var getUrlUrlUnderlyingCallsCount = 0
|
||||||
|
open var getUrlUrlCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return getUrlUrlUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = getUrlUrlUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
getUrlUrlUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
getUrlUrlUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var getUrlUrlCalled: Bool {
|
||||||
|
return getUrlUrlCallsCount > 0
|
||||||
|
}
|
||||||
|
open var getUrlUrlReceivedUrl: String?
|
||||||
|
open var getUrlUrlReceivedInvocations: [String] = []
|
||||||
|
|
||||||
|
var getUrlUrlUnderlyingReturnValue: String!
|
||||||
|
open var getUrlUrlReturnValue: String! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return getUrlUrlUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: String? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = getUrlUrlUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
getUrlUrlUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
getUrlUrlUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var getUrlUrlClosure: ((String) async throws -> String)?
|
||||||
|
|
||||||
|
open override func getUrl(url: String) async throws -> String {
|
||||||
|
if let error = getUrlUrlThrowableError {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
getUrlUrlCallsCount += 1
|
||||||
|
getUrlUrlReceivedUrl = url
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.getUrlUrlReceivedInvocations.append(url)
|
||||||
|
}
|
||||||
|
if let getUrlUrlClosure = getUrlUrlClosure {
|
||||||
|
return try await getUrlUrlClosure(url)
|
||||||
|
} else {
|
||||||
|
return getUrlUrlReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//MARK: - homeserver
|
//MARK: - homeserver
|
||||||
|
|
||||||
var homeserverUnderlyingCallsCount = 0
|
var homeserverUnderlyingCallsCount = 0
|
||||||
@ -3277,6 +3352,75 @@ open class ClientSDKMock: MatrixRustSDK.Client {
|
|||||||
return userIdReturnValue
|
return userIdReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//MARK: - userIdServerName
|
||||||
|
|
||||||
|
open var userIdServerNameThrowableError: Error?
|
||||||
|
var userIdServerNameUnderlyingCallsCount = 0
|
||||||
|
open var userIdServerNameCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return userIdServerNameUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = userIdServerNameUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
userIdServerNameUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
userIdServerNameUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var userIdServerNameCalled: Bool {
|
||||||
|
return userIdServerNameCallsCount > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var userIdServerNameUnderlyingReturnValue: String!
|
||||||
|
open var userIdServerNameReturnValue: String! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return userIdServerNameUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: String? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = userIdServerNameUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
userIdServerNameUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
userIdServerNameUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var userIdServerNameClosure: (() throws -> String)?
|
||||||
|
|
||||||
|
open override func userIdServerName() throws -> String {
|
||||||
|
if let error = userIdServerNameThrowableError {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
userIdServerNameCallsCount += 1
|
||||||
|
if let userIdServerNameClosure = userIdServerNameClosure {
|
||||||
|
return try userIdServerNameClosure()
|
||||||
|
} else {
|
||||||
|
return userIdServerNameReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
open class ClientBuilderSDKMock: MatrixRustSDK.ClientBuilder {
|
open class ClientBuilderSDKMock: MatrixRustSDK.ClientBuilder {
|
||||||
init() {
|
init() {
|
||||||
@ -9170,82 +9314,6 @@ open class NotificationSettingsSDKMock: MatrixRustSDK.NotificationSettings {
|
|||||||
try await unmuteRoomRoomIdIsEncryptedIsOneToOneClosure?(roomId, isEncrypted, isOneToOne)
|
try await unmuteRoomRoomIdIsEncryptedIsOneToOneClosure?(roomId, isEncrypted, isOneToOne)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open class OidcAuthorizationDataSDKMock: MatrixRustSDK.OidcAuthorizationData {
|
|
||||||
init() {
|
|
||||||
super.init(noPointer: .init())
|
|
||||||
}
|
|
||||||
|
|
||||||
public required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
|
|
||||||
fatalError("init(unsafeFromRawPointer:) has not been implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate var pointer: UnsafeMutableRawPointer!
|
|
||||||
|
|
||||||
//MARK: - loginUrl
|
|
||||||
|
|
||||||
var loginUrlUnderlyingCallsCount = 0
|
|
||||||
open var loginUrlCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return loginUrlUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = loginUrlUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
loginUrlUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
loginUrlUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
open var loginUrlCalled: Bool {
|
|
||||||
return loginUrlCallsCount > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
var loginUrlUnderlyingReturnValue: String!
|
|
||||||
open var loginUrlReturnValue: String! {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return loginUrlUnderlyingReturnValue
|
|
||||||
} else {
|
|
||||||
var returnValue: String? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = loginUrlUnderlyingReturnValue
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
loginUrlUnderlyingReturnValue = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
loginUrlUnderlyingReturnValue = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
open var loginUrlClosure: (() -> String)?
|
|
||||||
|
|
||||||
open override func loginUrl() -> String {
|
|
||||||
loginUrlCallsCount += 1
|
|
||||||
if let loginUrlClosure = loginUrlClosure {
|
|
||||||
return loginUrlClosure()
|
|
||||||
} else {
|
|
||||||
return loginUrlReturnValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
open class QrCodeDataSDKMock: MatrixRustSDK.QrCodeData {
|
open class QrCodeDataSDKMock: MatrixRustSDK.QrCodeData {
|
||||||
init() {
|
init() {
|
||||||
super.init(noPointer: .init())
|
super.init(noPointer: .init())
|
||||||
|
@ -19,9 +19,11 @@ import SwiftUI
|
|||||||
|
|
||||||
struct CallScreenCoordinatorParameters {
|
struct CallScreenCoordinatorParameters {
|
||||||
let elementCallService: ElementCallServiceProtocol
|
let elementCallService: ElementCallServiceProtocol
|
||||||
|
let clientProxy: ClientProxyProtocol
|
||||||
let roomProxy: RoomProxyProtocol
|
let roomProxy: RoomProxyProtocol
|
||||||
let callBaseURL: URL
|
|
||||||
let clientID: String
|
let clientID: String
|
||||||
|
let elementCallBaseURL: URL
|
||||||
|
let elementCallBaseURLOverride: URL?
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CallScreenCoordinatorAction {
|
enum CallScreenCoordinatorAction {
|
||||||
@ -39,9 +41,11 @@ final class CallScreenCoordinator: CoordinatorProtocol {
|
|||||||
|
|
||||||
init(parameters: CallScreenCoordinatorParameters) {
|
init(parameters: CallScreenCoordinatorParameters) {
|
||||||
viewModel = CallScreenViewModel(elementCallService: parameters.elementCallService,
|
viewModel = CallScreenViewModel(elementCallService: parameters.elementCallService,
|
||||||
|
clientProxy: parameters.clientProxy,
|
||||||
roomProxy: parameters.roomProxy,
|
roomProxy: parameters.roomProxy,
|
||||||
callBaseURL: parameters.callBaseURL,
|
clientID: parameters.clientID,
|
||||||
clientID: parameters.clientID)
|
elementCallBaseURL: parameters.elementCallBaseURL,
|
||||||
|
elementCallBaseURLOverride: parameters.elementCallBaseURLOverride)
|
||||||
}
|
}
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
|
@ -38,9 +38,11 @@ class CallScreenViewModel: CallScreenViewModelType, CallScreenViewModelProtocol
|
|||||||
/// - callBaseURL: Which Element Call instance should be used
|
/// - callBaseURL: Which Element Call instance should be used
|
||||||
/// - clientID: Something to identify the current client on the Element Call side
|
/// - clientID: Something to identify the current client on the Element Call side
|
||||||
init(elementCallService: ElementCallServiceProtocol,
|
init(elementCallService: ElementCallServiceProtocol,
|
||||||
|
clientProxy: ClientProxyProtocol,
|
||||||
roomProxy: RoomProxyProtocol,
|
roomProxy: RoomProxyProtocol,
|
||||||
callBaseURL: URL,
|
clientID: String,
|
||||||
clientID: String) {
|
elementCallBaseURL: URL,
|
||||||
|
elementCallBaseURLOverride: URL?) {
|
||||||
self.elementCallService = elementCallService
|
self.elementCallService = elementCallService
|
||||||
self.roomProxy = roomProxy
|
self.roomProxy = roomProxy
|
||||||
|
|
||||||
@ -90,7 +92,15 @@ class CallScreenViewModel: CallScreenViewModelType, CallScreenViewModelProtocol
|
|||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
switch await widgetDriver.start(baseURL: callBaseURL, clientID: clientID) {
|
let baseURL = if let elementCallBaseURLOverride {
|
||||||
|
elementCallBaseURLOverride
|
||||||
|
} else if case .success(let wellKnown) = await clientProxy.getElementWellKnown(), let wellKnownCall = wellKnown?.call {
|
||||||
|
wellKnownCall.widgetURL
|
||||||
|
} else {
|
||||||
|
elementCallBaseURL
|
||||||
|
}
|
||||||
|
|
||||||
|
switch await widgetDriver.start(baseURL: baseURL, clientID: clientID) {
|
||||||
case .success(let url):
|
case .success(let url):
|
||||||
state.url = url
|
state.url = url
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
|
@ -172,7 +172,11 @@ private struct WebView: UIViewRepresentable {
|
|||||||
|
|
||||||
struct CallScreen_Previews: PreviewProvider {
|
struct CallScreen_Previews: PreviewProvider {
|
||||||
static let viewModel = {
|
static let viewModel = {
|
||||||
|
let clientProxy = ClientProxyMock()
|
||||||
|
clientProxy.getElementWellKnownReturnValue = .success(nil)
|
||||||
|
|
||||||
let roomProxy = RoomProxyMock()
|
let roomProxy = RoomProxyMock()
|
||||||
|
roomProxy.sendCallNotificationIfNeeededReturnValue = .success(())
|
||||||
|
|
||||||
let widgetDriver = ElementCallWidgetDriverMock()
|
let widgetDriver = ElementCallWidgetDriverMock()
|
||||||
widgetDriver.underlyingMessagePublisher = .init()
|
widgetDriver.underlyingMessagePublisher = .init()
|
||||||
@ -182,9 +186,11 @@ struct CallScreen_Previews: PreviewProvider {
|
|||||||
roomProxy.elementCallWidgetDriverReturnValue = widgetDriver
|
roomProxy.elementCallWidgetDriverReturnValue = widgetDriver
|
||||||
|
|
||||||
return CallScreenViewModel(elementCallService: ElementCallServiceMock(.init()),
|
return CallScreenViewModel(elementCallService: ElementCallServiceMock(.init()),
|
||||||
|
clientProxy: clientProxy,
|
||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
callBaseURL: "https://call.element.io",
|
clientID: "io.element.elementx",
|
||||||
clientID: "io.element.elementx")
|
elementCallBaseURL: "https://call.element.io",
|
||||||
|
elementCallBaseURLOverride: nil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
@ -32,7 +32,8 @@ final class DeveloperOptionsScreenCoordinator: CoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings)
|
viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings,
|
||||||
|
elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL)
|
||||||
|
|
||||||
viewModel.actions
|
viewModel.actions
|
||||||
.sink { [weak self] action in
|
.sink { [weak self] action in
|
||||||
|
@ -21,6 +21,7 @@ enum DeveloperOptionsScreenViewModelAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct DeveloperOptionsScreenViewState: BindableState {
|
struct DeveloperOptionsScreenViewState: BindableState {
|
||||||
|
let elementCallBaseURL: URL
|
||||||
var bindings: DeveloperOptionsScreenViewStateBindings
|
var bindings: DeveloperOptionsScreenViewStateBindings
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ enum DeveloperOptionsScreenViewAction {
|
|||||||
protocol DeveloperOptionsProtocol: AnyObject {
|
protocol DeveloperOptionsProtocol: AnyObject {
|
||||||
var logLevel: TracingConfiguration.LogLevel { get set }
|
var logLevel: TracingConfiguration.LogLevel { get set }
|
||||||
var hideUnreadMessagesBadge: Bool { get set }
|
var hideUnreadMessagesBadge: Bool { get set }
|
||||||
var elementCallBaseURL: URL { get set }
|
var elementCallBaseURLOverride: URL? { get set }
|
||||||
var fuzzyRoomListSearchEnabled: Bool { get set }
|
var fuzzyRoomListSearchEnabled: Bool { get set }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,9 +26,9 @@ class DeveloperOptionsScreenViewModel: DeveloperOptionsScreenViewModelType, Deve
|
|||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(developerOptions: DeveloperOptionsProtocol) {
|
init(developerOptions: DeveloperOptionsProtocol, elementCallBaseURL: URL) {
|
||||||
let bindings = DeveloperOptionsScreenViewStateBindings(developerOptions: developerOptions)
|
let bindings = DeveloperOptionsScreenViewStateBindings(developerOptions: developerOptions)
|
||||||
let state = DeveloperOptionsScreenViewState(bindings: bindings)
|
let state = DeveloperOptionsScreenViewState(elementCallBaseURL: elementCallBaseURL, bindings: bindings)
|
||||||
|
|
||||||
super.init(initialViewState: state)
|
super.init(initialViewState: state)
|
||||||
}
|
}
|
||||||
|
@ -38,14 +38,11 @@ struct DeveloperOptionsScreen: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Section("Element Call") {
|
Section("Element Call") {
|
||||||
TextField(context.elementCallBaseURL.absoluteString, text: $elementCallBaseURLString)
|
TextField(context.viewState.elementCallBaseURL.absoluteString, text: $elementCallBaseURLString)
|
||||||
.submitLabel(.done)
|
.submitLabel(.done)
|
||||||
.onSubmit {
|
.onSubmit {
|
||||||
guard let url = URL(string: elementCallBaseURLString) else {
|
guard let url = URL(string: elementCallBaseURLString) else { return }
|
||||||
return
|
context.elementCallBaseURLOverride = url
|
||||||
}
|
|
||||||
|
|
||||||
context.elementCallBaseURL = url
|
|
||||||
}
|
}
|
||||||
.autocorrectionDisabled(true)
|
.autocorrectionDisabled(true)
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
@ -148,7 +145,8 @@ private struct LogLevelConfigurationView: View {
|
|||||||
// MARK: - Previews
|
// MARK: - Previews
|
||||||
|
|
||||||
struct DeveloperOptionsScreen_Previews: PreviewProvider {
|
struct DeveloperOptionsScreen_Previews: PreviewProvider {
|
||||||
static let viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings)
|
static let viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings,
|
||||||
|
elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL)
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
DeveloperOptionsScreen(context: viewModel.context)
|
DeveloperOptionsScreen(context: viewModel.context)
|
||||||
|
@ -21,6 +21,7 @@ import OrderedCollections
|
|||||||
|
|
||||||
import MatrixRustSDK
|
import MatrixRustSDK
|
||||||
|
|
||||||
|
// swiftlint:disable file_length
|
||||||
class ClientProxy: ClientProxyProtocol {
|
class ClientProxy: ClientProxyProtocol {
|
||||||
private let client: ClientProtocol
|
private let client: ClientProtocol
|
||||||
private let networkMonitor: NetworkMonitorProtocol
|
private let networkMonitor: NetworkMonitorProtocol
|
||||||
@ -188,19 +189,6 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateVerificationState(_ verificationState: VerificationState) {
|
|
||||||
let verificationState: SessionVerificationState = switch verificationState {
|
|
||||||
case .unknown:
|
|
||||||
.unknown
|
|
||||||
case .unverified:
|
|
||||||
.unverified
|
|
||||||
case .verified:
|
|
||||||
.verified
|
|
||||||
}
|
|
||||||
|
|
||||||
verificationStateSubject.send(verificationState)
|
|
||||||
}
|
|
||||||
|
|
||||||
var userID: String {
|
var userID: String {
|
||||||
do {
|
do {
|
||||||
return try client.userId()
|
return try client.userId()
|
||||||
@ -214,7 +202,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
do {
|
do {
|
||||||
return try client.deviceId()
|
return try client.deviceId()
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed retrieving device id with error: \(error)")
|
MXLog.error("Failed retrieving deviceID with error: \(error)")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,6 +211,15 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
client.homeserver()
|
client.homeserver()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var userIDServerName: String? {
|
||||||
|
do {
|
||||||
|
return try client.userIdServerName()
|
||||||
|
} catch {
|
||||||
|
MXLog.error("Failed retrieving userID server name with error: \(error)")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private(set) lazy var pusherNotificationClientIdentifier: String? = {
|
private(set) lazy var pusherNotificationClientIdentifier: String? = {
|
||||||
// NOTE: The result is stored as part of the restoration token. Any changes
|
// NOTE: The result is stored as part of the restoration token. Any changes
|
||||||
// here would require a migration to correctly match incoming notifications.
|
// here would require a migration to correctly match incoming notifications.
|
||||||
@ -617,6 +614,23 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getElementWellKnown() async -> Result<ElementWellKnown?, ClientProxyError> {
|
||||||
|
guard let userIDServerName,
|
||||||
|
var url = URL(string: userIDServerName) else {
|
||||||
|
return .failure(.invalidUserIDServerName)
|
||||||
|
}
|
||||||
|
|
||||||
|
url.append(path: "/.well-known/element/element.json")
|
||||||
|
|
||||||
|
do {
|
||||||
|
let response = try await client.getUrl(url: url.absoluteString)
|
||||||
|
let sdkWellKnown = try makeElementWellKnown(string: response)
|
||||||
|
return .success(ElementWellKnown(sdkWellKnown))
|
||||||
|
} catch {
|
||||||
|
return .failure(.sdkError(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Ignored users
|
// MARK: Ignored users
|
||||||
|
|
||||||
func ignoreUser(_ userID: String) async -> Result<Void, ClientProxyError> {
|
func ignoreUser(_ userID: String) async -> Result<Void, ClientProxyError> {
|
||||||
@ -692,6 +706,19 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func updateVerificationState(_ verificationState: VerificationState) {
|
||||||
|
let verificationState: SessionVerificationState = switch verificationState {
|
||||||
|
case .unknown:
|
||||||
|
.unknown
|
||||||
|
case .unverified:
|
||||||
|
.unverified
|
||||||
|
case .verified:
|
||||||
|
.verified
|
||||||
|
}
|
||||||
|
|
||||||
|
verificationStateSubject.send(verificationState)
|
||||||
|
}
|
||||||
|
|
||||||
private func loadUserAvatarURLFromCache() {
|
private func loadUserAvatarURLFromCache() {
|
||||||
loadCachedAvatarURLTask = Task {
|
loadCachedAvatarURLTask = Task {
|
||||||
let urlString = await Task.dispatch(on: clientQueue) {
|
let urlString = await Task.dispatch(on: clientQueue) {
|
||||||
|
@ -41,6 +41,7 @@ enum ClientProxyError: Error {
|
|||||||
case sdkError(Error)
|
case sdkError(Error)
|
||||||
|
|
||||||
case invalidMedia
|
case invalidMedia
|
||||||
|
case invalidUserIDServerName
|
||||||
case failedUploadingMedia(Error, MatrixErrorCode)
|
case failedUploadingMedia(Error, MatrixErrorCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +96,8 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
|||||||
|
|
||||||
var homeserver: String { get }
|
var homeserver: String { get }
|
||||||
|
|
||||||
|
var userIDServerName: String? { get }
|
||||||
|
|
||||||
var userDisplayNamePublisher: CurrentValuePublisher<String?, Never> { get }
|
var userDisplayNamePublisher: CurrentValuePublisher<String?, Never> { get }
|
||||||
|
|
||||||
var userAvatarURLPublisher: CurrentValuePublisher<URL?, Never> { get }
|
var userAvatarURLPublisher: CurrentValuePublisher<URL?, Never> { get }
|
||||||
@ -163,6 +166,8 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
|||||||
|
|
||||||
func resolveRoomAlias(_ alias: String) async -> Result<ResolvedRoomAlias, ClientProxyError>
|
func resolveRoomAlias(_ alias: String) async -> Result<ResolvedRoomAlias, ClientProxyError>
|
||||||
|
|
||||||
|
func getElementWellKnown() async -> Result<ElementWellKnown?, ClientProxyError>
|
||||||
|
|
||||||
// MARK: - Ignored users
|
// MARK: - Ignored users
|
||||||
|
|
||||||
func ignoreUser(_ userID: String) async -> Result<Void, ClientProxyError>
|
func ignoreUser(_ userID: String) async -> Result<Void, ClientProxyError>
|
||||||
|
35
ElementX/Sources/Services/Client/ElementWellKnown.swift
Normal file
35
ElementX/Sources/Services/Client/ElementWellKnown.swift
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2024 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
|
||||||
|
import MatrixRustSDK
|
||||||
|
|
||||||
|
struct ElementWellKnown {
|
||||||
|
struct Call {
|
||||||
|
let widgetURL: URL
|
||||||
|
|
||||||
|
init?(_ wellKnown: MatrixRustSDK.ElementCallWellKnown) {
|
||||||
|
guard let widgetURL = URL(string: wellKnown.widgetUrl) else { return nil }
|
||||||
|
self.widgetURL = widgetURL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let call: Call?
|
||||||
|
|
||||||
|
init?(_ wellKnown: MatrixRustSDK.ElementWellKnown) {
|
||||||
|
call = Call(wellKnown.call)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user