Add a toggle in the developer options to optimise the media uploads. (#3408)

This commit is contained in:
Doug
2024-10-14 14:48:59 +01:00
committed by GitHub
parent b1b2297972
commit 98a5ee5b48
18 changed files with 109 additions and 34 deletions
@@ -42,9 +42,9 @@ final class AppSettings {
// Feature flags
case slidingSyncDiscovery
case optimizeMediaUploads
case publicSearchEnabled
case fuzzyRoomListSearchEnabled
case pinningEnabled
case enableOnlySignedDeviceIsolationMode
case identityPinningViolationNotificationsEnabled
case knockingEnabled
@@ -281,6 +281,9 @@ final class AppSettings {
@UserPreference(key: UserDefaultsKeys.slidingSyncDiscovery, defaultValue: .native, storageType: .userDefaults(store))
var slidingSyncDiscovery: SlidingSyncDiscovery
@UserPreference(key: UserDefaultsKeys.optimizeMediaUploads, defaultValue: false, storageType: .userDefaults(store))
var optimizeMediaUploads
@UserPreference(key: UserDefaultsKeys.identityPinningViolationNotificationsEnabled, defaultValue: isDevelopmentBuild, storageType: .userDefaults(store))
var identityPinningViolationNotificationsEnabled
@@ -810,6 +810,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let roomDetailsEditParameters = RoomDetailsEditScreenCoordinatorParameters(roomProxy: roomProxy,
mediaProvider: userSession.mediaProvider,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: appSettings),
navigationStackCoordinator: stackCoordinator,
userIndicatorController: userIndicatorController,
orientationManager: appMediator.windowManager)
@@ -895,7 +896,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let parameters = MediaUploadPreviewScreenCoordinatorParameters(userIndicatorController: userIndicatorController,
roomProxy: roomProxy,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(),
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: appSettings),
title: url.lastPathComponent,
url: url)
@@ -165,6 +165,7 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
let coordinator = UserDetailsEditScreenCoordinator(parameters: .init(orientationManager: parameters.windowManager,
clientProxy: parameters.userSession.clientProxy,
mediaProvider: parameters.userSession.mediaProvider,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: parameters.appSettings),
navigationStackCoordinator: navigationStackCoordinator,
userIndicatorController: parameters.userIndicatorController))
@@ -542,7 +542,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
userSession: userSession,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
navigationStackCoordinator: startChatNavigationStackCoordinator,
userDiscoveryService: userDiscoveryService)
userDiscoveryService: userDiscoveryService,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: appSettings))
let coordinator = StartChatScreenCoordinator(parameters: parameters)
coordinator.actions.sink { [weak self] action in
@@ -116,7 +116,7 @@ private class PreviewItem: NSObject, QLPreviewItem {
struct MediaUploadPreviewScreen_Previews: PreviewProvider, TestablePreview {
static let viewModel = MediaUploadPreviewScreenViewModel(userIndicatorController: UserIndicatorControllerMock.default,
roomProxy: JoinedRoomProxyMock(),
mediaUploadingPreprocessor: MediaUploadingPreprocessor(),
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings),
title: "some random file name",
url: URL.picturesDirectory)
static var previews: some View {
@@ -11,6 +11,7 @@ import SwiftUI
struct RoomDetailsEditScreenCoordinatorParameters {
let roomProxy: JoinedRoomProxyProtocol
let mediaProvider: MediaProviderProtocol
let mediaUploadingPreprocessor: MediaUploadingPreprocessor
weak var navigationStackCoordinator: NavigationStackCoordinator?
let userIndicatorController: UserIndicatorControllerProtocol
let orientationManager: OrientationManagerProtocol
@@ -35,6 +36,7 @@ final class RoomDetailsEditScreenCoordinator: CoordinatorProtocol {
viewModel = RoomDetailsEditScreenViewModel(roomProxy: parameters.roomProxy,
mediaProvider: parameters.mediaProvider,
mediaUploadingPreprocessor: parameters.mediaUploadingPreprocessor,
userIndicatorController: parameters.userIndicatorController)
}
@@ -14,7 +14,7 @@ class RoomDetailsEditScreenViewModel: RoomDetailsEditScreenViewModelType, RoomDe
private let actionsSubject: PassthroughSubject<RoomDetailsEditScreenViewModelAction, Never> = .init()
private let roomProxy: JoinedRoomProxyProtocol
private let userIndicatorController: UserIndicatorControllerProtocol
private let mediaPreprocessor: MediaUploadingPreprocessor = .init()
private let mediaUploadingPreprocessor: MediaUploadingPreprocessor
var actions: AnyPublisher<RoomDetailsEditScreenViewModelAction, Never> {
actionsSubject.eraseToAnyPublisher()
@@ -22,8 +22,10 @@ class RoomDetailsEditScreenViewModel: RoomDetailsEditScreenViewModelType, RoomDe
init(roomProxy: JoinedRoomProxyProtocol,
mediaProvider: MediaProviderProtocol,
mediaUploadingPreprocessor: MediaUploadingPreprocessor,
userIndicatorController: UserIndicatorControllerProtocol) {
self.roomProxy = roomProxy
self.mediaUploadingPreprocessor = mediaUploadingPreprocessor
self.userIndicatorController = userIndicatorController
let roomAvatar = roomProxy.avatarURL
@@ -76,7 +78,7 @@ class RoomDetailsEditScreenViewModel: RoomDetailsEditScreenViewModelType, RoomDe
title: L10n.commonLoading,
persistent: true))
let mediaResult = await mediaPreprocessor.processMedia(at: url)
let mediaResult = await mediaUploadingPreprocessor.processMedia(at: url)
switch mediaResult {
case .success(.image):
@@ -154,6 +154,7 @@ struct RoomDetailsEditScreen_Previews: PreviewProvider, TestablePreview {
return RoomDetailsEditScreenViewModel(roomProxy: roomProxy,
mediaProvider: MediaProviderMock(configuration: .init()),
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings),
userIndicatorController: UserIndicatorControllerMock.default)
}()
@@ -164,6 +165,7 @@ struct RoomDetailsEditScreen_Previews: PreviewProvider, TestablePreview {
return RoomDetailsEditScreenViewModel(roomProxy: roomProxy,
mediaProvider: MediaProviderMock(configuration: .init()),
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings),
userIndicatorController: UserIndicatorControllerMock.default)
}()
@@ -46,6 +46,7 @@ protocol DeveloperOptionsProtocol: AnyObject {
var hideUnreadMessagesBadge: Bool { get set }
var fuzzyRoomListSearchEnabled: Bool { get set }
var hideTimelineMedia: Bool { get set }
var optimizeMediaUploads: Bool { get set }
var enableOnlySignedDeviceIsolationMode: Bool { get set }
var elementCallBaseURLOverride: URL? { get set }
var identityPinningViolationNotificationsEnabled: Bool { get set }
@@ -62,6 +62,12 @@ struct DeveloperOptionsScreen: View {
}
}
Section("Media") {
Toggle(isOn: $context.optimizeMediaUploads) {
Text("Optimise for upload")
}
}
Section {
Toggle(isOn: $context.enableOnlySignedDeviceIsolationMode) {
Text("Exclude insecure devices when sending/receiving messages")
@@ -12,6 +12,7 @@ struct UserDetailsEditScreenCoordinatorParameters {
let orientationManager: OrientationManagerProtocol
let clientProxy: ClientProxyProtocol
let mediaProvider: MediaProviderProtocol
let mediaUploadingPreprocessor: MediaUploadingPreprocessor
weak var navigationStackCoordinator: NavigationStackCoordinator?
let userIndicatorController: UserIndicatorControllerProtocol
}
@@ -26,6 +27,7 @@ final class UserDetailsEditScreenCoordinator: CoordinatorProtocol {
viewModel = UserDetailsEditScreenViewModel(clientProxy: parameters.clientProxy,
mediaProvider: parameters.mediaProvider,
mediaUploadingPreprocessor: parameters.mediaUploadingPreprocessor,
userIndicatorController: parameters.userIndicatorController)
}
@@ -14,7 +14,7 @@ class UserDetailsEditScreenViewModel: UserDetailsEditScreenViewModelType, UserDe
private let actionsSubject: PassthroughSubject<UserDetailsEditScreenViewModelAction, Never> = .init()
private let clientProxy: ClientProxyProtocol
private let userIndicatorController: UserIndicatorControllerProtocol
private let mediaPreprocessor: MediaUploadingPreprocessor = .init()
private let mediaUploadingPreprocessor: MediaUploadingPreprocessor
var actions: AnyPublisher<UserDetailsEditScreenViewModelAction, Never> {
actionsSubject.eraseToAnyPublisher()
@@ -22,8 +22,10 @@ class UserDetailsEditScreenViewModel: UserDetailsEditScreenViewModelType, UserDe
init(clientProxy: ClientProxyProtocol,
mediaProvider: MediaProviderProtocol,
mediaUploadingPreprocessor: MediaUploadingPreprocessor,
userIndicatorController: UserIndicatorControllerProtocol) {
self.clientProxy = clientProxy
self.mediaUploadingPreprocessor = mediaUploadingPreprocessor
self.userIndicatorController = userIndicatorController
super.init(initialViewState: UserDetailsEditScreenViewState(userID: clientProxy.userID,
@@ -88,7 +90,7 @@ class UserDetailsEditScreenViewModel: UserDetailsEditScreenViewModelType, UserDe
title: L10n.commonLoading,
persistent: true))
let mediaResult = await mediaPreprocessor.processMedia(at: url)
let mediaResult = await mediaUploadingPreprocessor.processMedia(at: url)
switch mediaResult {
case .success(.image):
@@ -117,6 +117,7 @@ struct UserDetailsEditScreen: View {
struct UserDetailsEditScreen_Previews: PreviewProvider, TestablePreview {
static let viewModel = UserDetailsEditScreenViewModel(clientProxy: ClientProxyMock(.init(userID: "@stefan:matrix.org")),
mediaProvider: MediaProviderMock(configuration: .init()),
mediaUploadingPreprocessor: .init(appSettings: ServiceLocator.shared.settings),
userIndicatorController: UserIndicatorControllerMock.default)
static var previews: some View {
@@ -14,6 +14,7 @@ struct StartChatScreenCoordinatorParameters {
let userIndicatorController: UserIndicatorControllerProtocol
weak var navigationStackCoordinator: NavigationStackCoordinator?
let userDiscoveryService: UserDiscoveryServiceProtocol
let mediaUploadingPreprocessor: MediaUploadingPreprocessor
}
enum StartChatScreenCoordinatorAction {
@@ -134,7 +135,6 @@ final class StartChatScreenCoordinator: CoordinatorProtocol {
// MARK: - Private
let mediaUploadingPreprocessor = MediaUploadingPreprocessor()
private func displayMediaPickerWithSource(_ source: MediaPickerScreenSource) {
let stackCoordinator = NavigationStackCoordinator()
@@ -159,7 +159,7 @@ final class StartChatScreenCoordinator: CoordinatorProtocol {
Task { [weak self] in
guard let self else { return }
do {
let media = try await mediaUploadingPreprocessor.processMedia(at: url).get()
let media = try await parameters.mediaUploadingPreprocessor.processMedia(at: url).get()
var parameters = createRoomParameters.value
parameters.avatarImageMedia = media
createRoomParameters.send(parameters)
@@ -82,6 +82,8 @@ private struct VideoProcessingInfo {
}
struct MediaUploadingPreprocessor {
let appSettings: AppSettings
enum Constants {
static let maximumThumbnailSize = CGSize(width: 800, height: 600)
static let thumbnailCompressionQuality = 0.8
@@ -368,8 +370,9 @@ struct MediaUploadingPreprocessor {
/// - Returns: the URL for the resulting video and its media info as a `VideoProcessingResult`
private func convertVideoToMP4(_ url: URL, targetFileSize: UInt = 0) async -> Result<VideoProcessingInfo, MediaUploadingPreprocessorError> {
let asset = AVURLAsset(url: url)
let presetName = appSettings.optimizeMediaUploads ? AVAssetExportPreset640x480 : AVAssetExportPreset1920x1080
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPreset1920x1080) else {
guard let exportSession = AVAssetExportSession(asset: asset, presetName: presetName) else {
return .failure(.failedConvertingVideo)
}
@@ -581,7 +581,8 @@ class MockScreen: Identifiable {
userSession: userSession,
userIndicatorController: UserIndicatorControllerMock(),
navigationStackCoordinator: navigationStackCoordinator,
userDiscoveryService: userDiscoveryMock)
userDiscoveryService: userDiscoveryMock,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings))
let coordinator = StartChatScreenCoordinator(parameters: parameters)
navigationStackCoordinator.setRootCoordinator(coordinator)
return navigationStackCoordinator
@@ -595,7 +596,8 @@ class MockScreen: Identifiable {
userSession: userSession,
userIndicatorController: UserIndicatorControllerMock(),
navigationStackCoordinator: navigationStackCoordinator,
userDiscoveryService: userDiscoveryMock))
userDiscoveryService: userDiscoveryMock,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings)))
navigationStackCoordinator.setRootCoordinator(coordinator)
return navigationStackCoordinator
case .createRoom: