mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Handle media previews and invite avatars through the account data (#4142)
* added account data media display policy handling to NSE * pr suggestions * update compound * code improvement
This commit is contained in:
@@ -39,6 +39,9 @@ class ClientProxy: ClientProxyProtocol {
|
||||
// periphery:ignore - required for instance retention in the rust codebase
|
||||
private var sendQueueListenerTaskHandle: TaskHandle?
|
||||
|
||||
// periphery:ignore - required for instance retention in the rust codebase
|
||||
private var mediaPreviewConfigListenerTaskHandle: TaskHandle?
|
||||
|
||||
private var delegateHandle: TaskHandle?
|
||||
|
||||
// These following summary providers both operate on the same allRooms() list but
|
||||
@@ -132,6 +135,16 @@ class ClientProxy: ClientProxyProtocol {
|
||||
verificationStateSubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
private let timelineMediaVisibilitySubject = CurrentValueSubject<TimelineMediaVisibility, Never>(.always)
|
||||
var timelineMediaVisibilityPublisher: CurrentValuePublisher<TimelineMediaVisibility, Never> {
|
||||
timelineMediaVisibilitySubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
private let hideInviteAvatarsSubject = CurrentValueSubject<Bool, Never>(false)
|
||||
var hideInviteAvatarsPublisher: CurrentValuePublisher<Bool, Never> {
|
||||
hideInviteAvatarsSubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
var roomsToAwait: Set<String> = []
|
||||
|
||||
private let sendQueueStatusSubject = CurrentValueSubject<Bool, Never>(false)
|
||||
@@ -230,6 +243,10 @@ class ClientProxy: ClientProxyProtocol {
|
||||
MXLog.error("Failed setting media retention policy with error: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
Task {
|
||||
mediaPreviewConfigListenerTaskHandle = await createMediaPreviewConfigObserver()
|
||||
}
|
||||
}
|
||||
|
||||
var userID: String {
|
||||
@@ -724,6 +741,16 @@ class ClientProxy: ClientProxyProtocol {
|
||||
return .failure(.sdkError(error))
|
||||
}
|
||||
}
|
||||
|
||||
func fetchMediaPreviewConfiguration() async -> Result<MediaPreviewConfig?, ClientProxyError> {
|
||||
do {
|
||||
let config = try await client.fetchMediaPreviewConfig()
|
||||
return .success(config)
|
||||
} catch {
|
||||
MXLog.error("Failed fetching media preview config with error: \(error)")
|
||||
return .failure(.sdkError(error))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Ignored users
|
||||
|
||||
@@ -798,6 +825,28 @@ class ClientProxy: ClientProxyProtocol {
|
||||
return users.elements
|
||||
}
|
||||
|
||||
// MARK: Moderation & Safety
|
||||
|
||||
func setTimelineMediaVisibility(_ value: TimelineMediaVisibility) async -> Result<Void, ClientProxyError> {
|
||||
do {
|
||||
try await client.setMediaPreviewDisplayPolicy(policy: value.rustValue)
|
||||
return .success(())
|
||||
} catch {
|
||||
MXLog.error("Failed to set timeline media visibility: \(error)")
|
||||
return .failure(.sdkError(error))
|
||||
}
|
||||
}
|
||||
|
||||
func setHideInviteAvatars(_ value: Bool) async -> Result<Void, ClientProxyError> {
|
||||
do {
|
||||
try await client.setInviteAvatarsDisplayPolicy(policy: value ? .off : .on)
|
||||
return .success(())
|
||||
} catch {
|
||||
MXLog.error("Failed to set hide invite avatars: \(error)")
|
||||
return .failure(.sdkError(error))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func cacheAccountURL() async {
|
||||
@@ -867,6 +916,26 @@ class ClientProxy: ClientProxyProtocol {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private func createMediaPreviewConfigObserver() async -> TaskHandle? {
|
||||
do {
|
||||
return try await client.subscribeToMediaPreviewConfig(listener: SDKListener { [weak self] config in
|
||||
guard let self else { return }
|
||||
|
||||
if let config {
|
||||
timelineMediaVisibilitySubject.send(config.mediaPreviewVisibility)
|
||||
hideInviteAvatarsSubject.send(config.hideInviteAvatars)
|
||||
} else {
|
||||
// return default values
|
||||
timelineMediaVisibilitySubject.send(.always)
|
||||
hideInviteAvatarsSubject.send(false)
|
||||
}
|
||||
})
|
||||
} catch {
|
||||
MXLog.error("Failed creating media preview config observer: \(error)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
private func createRoomListServiceObserver(_ roomListService: RoomListService) -> TaskHandle {
|
||||
roomListService.state(listener: SDKListener { [weak self] state in
|
||||
@@ -1133,3 +1202,38 @@ private struct ClientProxyServices {
|
||||
self.roomListService = roomListService
|
||||
}
|
||||
}
|
||||
|
||||
private extension MediaPreviewConfig {
|
||||
var mediaPreviewVisibility: TimelineMediaVisibility {
|
||||
switch mediaPreviews {
|
||||
case .on:
|
||||
.always
|
||||
case .private:
|
||||
.privateOnly
|
||||
case .off:
|
||||
.never
|
||||
}
|
||||
}
|
||||
|
||||
var hideInviteAvatars: Bool {
|
||||
switch inviteAvatars {
|
||||
case .off:
|
||||
true
|
||||
case .on:
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension TimelineMediaVisibility {
|
||||
var rustValue: MediaPreviews {
|
||||
switch self {
|
||||
case .always:
|
||||
.on
|
||||
case .never:
|
||||
.off
|
||||
case .privateOnly:
|
||||
.private
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,13 @@ enum SessionVerificationState {
|
||||
case unverified
|
||||
}
|
||||
|
||||
// The `Decodable` conformance is just for the purpose of migration
|
||||
enum TimelineMediaVisibility: Decodable {
|
||||
case always
|
||||
case privateOnly
|
||||
case never
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
||||
var actionsPublisher: AnyPublisher<ClientProxyAction, Never> { get }
|
||||
@@ -93,6 +100,10 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
||||
/// We delay fetching this until after the first sync. Nil until then
|
||||
var ignoredUsersPublisher: CurrentValuePublisher<[String]?, Never> { get }
|
||||
|
||||
var timelineMediaVisibilityPublisher: CurrentValuePublisher<TimelineMediaVisibility, Never> { get }
|
||||
|
||||
var hideInviteAvatarsPublisher: CurrentValuePublisher<Bool, Never> { get }
|
||||
|
||||
var pusherNotificationClientIdentifier: String? { get }
|
||||
|
||||
var roomSummaryProvider: RoomSummaryProviderProtocol { get }
|
||||
@@ -185,6 +196,8 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
||||
func isAliasAvailable(_ alias: String) async -> Result<Bool, ClientProxyError>
|
||||
|
||||
@discardableResult func clearCaches() async -> Result<Void, ClientProxyError>
|
||||
|
||||
func fetchMediaPreviewConfiguration() async -> Result<MediaPreviewConfig?, ClientProxyError>
|
||||
|
||||
// MARK: - Ignored users
|
||||
|
||||
@@ -210,4 +223,9 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
||||
func resetIdentity() async -> Result<IdentityResetHandle?, ClientProxyError>
|
||||
|
||||
func userIdentity(for userID: String) async -> Result<UserIdentityProxyProtocol?, ClientProxyError>
|
||||
|
||||
// MARK: - Moderation & Safety
|
||||
|
||||
func setTimelineMediaVisibility(_ value: TimelineMediaVisibility) async -> Result<Void, ClientProxyError>
|
||||
func setHideInviteAvatars(_ value: Bool) async -> Result<Void, ClientProxyError>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user