mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
change: hiding timeline media has three options
This commit is contained in:
@@ -18,7 +18,7 @@ protocol CommonSettingsProtocol {
|
|||||||
var traceLogPacks: Set<TraceLogPack> { get }
|
var traceLogPacks: Set<TraceLogPack> { get }
|
||||||
var enableOnlySignedDeviceIsolationMode: Bool { get }
|
var enableOnlySignedDeviceIsolationMode: Bool { get }
|
||||||
var hideInviteAvatars: Bool { get }
|
var hideInviteAvatars: Bool { get }
|
||||||
var hideTimelineMedia: Bool { get }
|
var timelineMediaVisibility: TimelineMediaVisibility { get }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Store Element specific app settings.
|
/// Store Element specific app settings.
|
||||||
@@ -47,7 +47,7 @@ final class AppSettings {
|
|||||||
case sharePresence
|
case sharePresence
|
||||||
case hideUnreadMessagesBadge
|
case hideUnreadMessagesBadge
|
||||||
case hideInviteAvatars
|
case hideInviteAvatars
|
||||||
case hideTimelineMedia
|
case timelineMediaVisibility
|
||||||
|
|
||||||
case elementCallBaseURLOverride
|
case elementCallBaseURLOverride
|
||||||
|
|
||||||
@@ -353,8 +353,14 @@ final class AppSettings {
|
|||||||
@UserPreference(key: UserDefaultsKeys.hideInviteAvatars, defaultValue: false, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.hideInviteAvatars, defaultValue: false, storageType: .userDefaults(store))
|
||||||
var hideInviteAvatars
|
var hideInviteAvatars
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.hideTimelineMedia, defaultValue: false, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.timelineMediaVisibility, defaultValue: TimelineMediaVisibility.always, storageType: .userDefaults(store))
|
||||||
var hideTimelineMedia
|
var timelineMediaVisibility
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AppSettings: CommonSettingsProtocol { }
|
extension AppSettings: CommonSettingsProtocol { }
|
||||||
|
|
||||||
|
enum TimelineMediaVisibility: Codable {
|
||||||
|
case always
|
||||||
|
case privateOnly
|
||||||
|
case never
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ protocol AdvancedSettingsProtocol: AnyObject {
|
|||||||
var viewSourceEnabled: Bool { get set }
|
var viewSourceEnabled: Bool { get set }
|
||||||
var appAppearance: AppAppearance { get set }
|
var appAppearance: AppAppearance { get set }
|
||||||
var sharePresence: Bool { get set }
|
var sharePresence: Bool { get set }
|
||||||
var hideTimelineMedia: Bool { get set }
|
var timelineMediaVisibility: TimelineMediaVisibility { get set }
|
||||||
var hideInviteAvatars: Bool { get set }
|
var hideInviteAvatars: Bool { get set }
|
||||||
var optimizeMediaUploads: Bool { get set }
|
var optimizeMediaUploads: Bool { get set }
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-2
@@ -35,6 +35,7 @@ struct AdvancedSettingsScreen: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
moderationAndSafetySection
|
moderationAndSafetySection
|
||||||
|
timelineMediaSection
|
||||||
}
|
}
|
||||||
.compoundList()
|
.compoundList()
|
||||||
.navigationTitle(L10n.commonAdvancedSettings)
|
.navigationTitle(L10n.commonAdvancedSettings)
|
||||||
@@ -43,8 +44,6 @@ struct AdvancedSettingsScreen: View {
|
|||||||
|
|
||||||
private var moderationAndSafetySection: some View {
|
private var moderationAndSafetySection: some View {
|
||||||
Section {
|
Section {
|
||||||
ListRow(label: .plain(title: L10n.screenAdvancedSettingsHideTimelineMediaToggleTitle),
|
|
||||||
kind: .toggle($context.hideTimelineMedia))
|
|
||||||
ListRow(label: .plain(title: L10n.screenAdvancedSettingsHideInviteAvatarsToggleTitle),
|
ListRow(label: .plain(title: L10n.screenAdvancedSettingsHideInviteAvatarsToggleTitle),
|
||||||
kind: .toggle($context.hideInviteAvatars))
|
kind: .toggle($context.hideInviteAvatars))
|
||||||
} header: {
|
} header: {
|
||||||
@@ -52,6 +51,23 @@ struct AdvancedSettingsScreen: View {
|
|||||||
.compoundListSectionHeader()
|
.compoundListSectionHeader()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var timelineMediaSection: some View {
|
||||||
|
Section {
|
||||||
|
ListRow(label: .plain(title: L10n.screenAdvancedSettingsShowMediaTimelineAlwaysShow),
|
||||||
|
kind: .selection(isSelected: context.timelineMediaVisibility == .always) { context.timelineMediaVisibility = .always })
|
||||||
|
ListRow(label: .plain(title: L10n.screenAdvancedSettingsShowMediaTimelinePrivateRooms),
|
||||||
|
kind: .selection(isSelected: context.timelineMediaVisibility == .privateOnly) { context.timelineMediaVisibility = .privateOnly })
|
||||||
|
ListRow(label: .plain(title: L10n.screenAdvancedSettingsShowMediaTimelineAlwaysHide),
|
||||||
|
kind: .selection(isSelected: context.timelineMediaVisibility == .never) { context.timelineMediaVisibility = .never })
|
||||||
|
} header: {
|
||||||
|
Text(L10n.screenAdvancedSettingsShowMediaTimelineTitle)
|
||||||
|
.compoundListSectionHeader()
|
||||||
|
} footer: {
|
||||||
|
Text(L10n.screenAdvancedSettingsShowMediaTimelineSubtitle)
|
||||||
|
.compoundListSectionFooter()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension AppAppearance {
|
private extension AppAppearance {
|
||||||
|
|||||||
@@ -88,13 +88,21 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
|||||||
timelineControllerFactory: timelineControllerFactory,
|
timelineControllerFactory: timelineControllerFactory,
|
||||||
clientProxy: clientProxy)
|
clientProxy: clientProxy)
|
||||||
|
|
||||||
|
let hideTimelineMedia = switch appSettings.timelineMediaVisibility {
|
||||||
|
case .always:
|
||||||
|
false
|
||||||
|
case .privateOnly:
|
||||||
|
roomProxy.infoPublisher.value.isPublic
|
||||||
|
case .never:
|
||||||
|
true
|
||||||
|
}
|
||||||
super.init(initialViewState: TimelineViewState(timelineKind: timelineController.timelineKind,
|
super.init(initialViewState: TimelineViewState(timelineKind: timelineController.timelineKind,
|
||||||
roomID: roomProxy.id,
|
roomID: roomProxy.id,
|
||||||
isDirectOneToOneRoom: roomProxy.isDirectOneToOneRoom,
|
isDirectOneToOneRoom: roomProxy.isDirectOneToOneRoom,
|
||||||
timelineState: TimelineState(focussedEvent: focussedEventID.map { .init(eventID: $0, appearance: .immediate) }),
|
timelineState: TimelineState(focussedEvent: focussedEventID.map { .init(eventID: $0, appearance: .immediate) }),
|
||||||
ownUserID: roomProxy.ownUserID,
|
ownUserID: roomProxy.ownUserID,
|
||||||
isViewSourceEnabled: appSettings.viewSourceEnabled,
|
isViewSourceEnabled: appSettings.viewSourceEnabled,
|
||||||
hideTimelineMedia: appSettings.hideTimelineMedia,
|
hideTimelineMedia: hideTimelineMedia,
|
||||||
pinnedEventIDs: roomProxy.infoPublisher.value.pinnedEventIDs,
|
pinnedEventIDs: roomProxy.infoPublisher.value.pinnedEventIDs,
|
||||||
emojiProvider: emojiProvider,
|
emojiProvider: emojiProvider,
|
||||||
mapTilerConfiguration: appSettings.mapTilerConfiguration,
|
mapTilerConfiguration: appSettings.mapTilerConfiguration,
|
||||||
@@ -519,7 +527,21 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
|||||||
.weakAssign(to: \.state.isViewSourceEnabled, on: self)
|
.weakAssign(to: \.state.isViewSourceEnabled, on: self)
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
appSettings.$hideTimelineMedia
|
appSettings.$timelineMediaVisibility
|
||||||
|
.combineLatest(roomProxy.infoPublisher
|
||||||
|
.map(\.isPublic)
|
||||||
|
.removeDuplicates()
|
||||||
|
.receive(on: DispatchQueue.main))
|
||||||
|
.map { timelineMediaVisibility, isPublic in
|
||||||
|
switch timelineMediaVisibility {
|
||||||
|
case .always:
|
||||||
|
false
|
||||||
|
case .privateOnly:
|
||||||
|
isPublic
|
||||||
|
case .never:
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
.weakAssign(to: \.state.hideTimelineMedia, on: self)
|
.weakAssign(to: \.state.hideTimelineMedia, on: self)
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,9 @@ struct NotificationContentBuilder {
|
|||||||
let displayName = notificationItem.senderDisplayName ?? notificationItem.roomDisplayName
|
let displayName = notificationItem.senderDisplayName ?? notificationItem.roomDisplayName
|
||||||
notification.body = String(messageEventStringBuilder.buildAttributedString(for: messageType, senderDisplayName: displayName).characters)
|
notification.body = String(messageEventStringBuilder.buildAttributedString(for: messageType, senderDisplayName: displayName).characters)
|
||||||
|
|
||||||
guard !settings.hideTimelineMedia else { return notification }
|
// For now we are fine hiding all images if the visibility is not `always` while we wait for an `isPublic` flag
|
||||||
|
// to be implemented in the SDK.
|
||||||
|
guard settings.timelineMediaVisibility == .always else { return notification }
|
||||||
|
|
||||||
switch messageType {
|
switch messageType {
|
||||||
case .image(content: let content):
|
case .image(content: let content):
|
||||||
|
|||||||
Reference in New Issue
Block a user