pr suggestions

This commit is contained in:
Mauro Romito
2026-02-19 22:03:23 +01:00
committed by Mauro
parent e9afb31172
commit 5e5fb19f42
6 changed files with 54 additions and 41 deletions

View File

@@ -124,7 +124,6 @@
12EC6BC99F373FE5C6EB9B64 /* TimelineMediaPreviewDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 467498BEA681758BE2F80826 /* TimelineMediaPreviewDetailsView.swift */; };
1307268DC41730E5BCF7D9A0 /* PollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638790D3F915F0909315C47A /* PollView.swift */; };
1318721F4E5F307586D98112 /* VoiceMessageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8516302ACCA94A0E680AB3B /* VoiceMessageButton.swift */; };
ES17LAX66UIQ5OAE6L2BQQE4 /* PlaybackSpeedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = HW13ISECOFUYATOTX2RU7GDG /* PlaybackSpeedButton.swift */; };
13C77FDF17C4C6627CFFC205 /* RoomTimelineItemFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D25A35764C7B3DB78954AB5 /* RoomTimelineItemFactoryProtocol.swift */; };
13CBC470FB619A6393A21908 /* RoomNotificationSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8296D6FB451E25CEC0767BBA /* RoomNotificationSettingsScreenCoordinator.swift */; };
1443CEEE42491CF7CD8A146A /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85A1941B874A3BE9CDDF43EF /* XCTestCase.swift */; };
@@ -496,6 +495,7 @@
5618ED25F092DF5712003829 /* KeychainControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */; };
562EFB9AB62B38830D9AA778 /* TimelineMediaFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 933B074F006F8E930DB98B4E /* TimelineMediaFrame.swift */; };
565868808A1DA565707394ED /* CurrentValuePublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127C8472672A5BA09EF1ACF8 /* CurrentValuePublisher.swift */; };
56C18ACF91DD20463B242460 /* AudioPlaybackSpeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = F78B4E56DBFFD4A7A39D10F5 /* AudioPlaybackSpeed.swift */; };
56DACDD379A86A1F5DEFE7BE /* AuthenticationServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E75948AA1FE1D1A7809931F /* AuthenticationServiceProtocol.swift */; };
56F0A22972A3BB519DA2261C /* HomeScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F5530B2212862FA4BEFF2D /* HomeScreenViewModelProtocol.swift */; };
5705511EBE083295EF98F998 /* FrequentlyUsedEmoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A2074C0449B83D5858BD2D7 /* FrequentlyUsedEmoji.swift */; };
@@ -627,6 +627,7 @@
6CD61FAF03E8986523C2ABB8 /* StartChatScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3005886F00029F058DB62BE /* StartChatScreenCoordinator.swift */; };
6DC8E43BA04AC2AC4EB2EB97 /* AnalyticsPromptScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18486B87745B1811E7FBD3D2 /* AnalyticsPromptScreenModels.swift */; };
6E03A710799E6C65C0AB36BC /* TargetConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D829FD8958376614504B18 /* TargetConfiguration.swift */; };
6E0C68918BEC5D27A4830BA6 /* PlaybackSpeedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBB8E5436E1BE0D6814BB7D /* PlaybackSpeedButton.swift */; };
6E391F7F628D984AF44385D9 /* RoomAttachmentPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 128501375217576AF0FE3E92 /* RoomAttachmentPicker.swift */; };
6E44638FDF7D4B0F80EFA7EA /* TraceLogPack.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7149BDDE47F8AD104E644E2 /* TraceLogPack.swift */; };
6E47D126DD7585E8F8237CE7 /* LoadableAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */; };
@@ -804,6 +805,7 @@
8B408C574E35E1C9B43A50CE /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 048A21188AB19349D026BECD /* PrivacyInfo.xcprivacy */; };
8B41D0357B91CD3B6F6A3BCA /* EmoteRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE378083653EF0C9B5E9D580 /* EmoteRoomTimelineItemContent.swift */; };
8B76191B9DDD1AC90A6E3A35 /* MediaFileHandleProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEC1D382565A4E9CAC2F14EA /* MediaFileHandleProxy.swift */; };
8B9C2890B6DD160A0662861E /* AudioPlaybackSpeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = F78B4E56DBFFD4A7A39D10F5 /* AudioPlaybackSpeed.swift */; };
8BC8EF6705A78946C1F22891 /* SoftLogoutScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71A7D4DDEEE5D2CA0C8D63CD /* SoftLogoutScreen.swift */; };
8BD22815DC34D7F9E9C1F2FE /* PillUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C537DE821FED94D23467B6C4 /* PillUtilities.swift */; };
8C050A8012E6078BEAEF5BC8 /* PillTextAttachmentData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 913C8E13B8B602C7B6C0C4AE /* PillTextAttachmentData.swift */; };
@@ -1205,6 +1207,7 @@
D26093BB80B69092B0E9AC7C /* PinnedItemsIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E66763BD54A3A1D9C6E6F2F1 /* PinnedItemsIndicatorView.swift */; };
D2825E013A8ECFB66D9A1DE6 /* RoomChangeRolesScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F841F219ACDFC1D3F42FEFB /* RoomChangeRolesScreenViewModelTests.swift */; };
D29E999538E5ABC00E1668F8 /* ElementNavigationStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = F03AEAA2F66E796C365EFD58 /* ElementNavigationStack.swift */; };
D2CBC380FEBCBF29263B8446 /* AudioPlaybackSpeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = F78B4E56DBFFD4A7A39D10F5 /* AudioPlaybackSpeed.swift */; };
D2D70B5DB1A5E4AF0CD88330 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 033DB41C51865A2E83174E87 /* target.yml */; };
D304343515CE0464C5089537 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD5523BDEDB247E29228476 /* AppSettings.swift */; };
D31B34B3902BC597593F3ABB /* preview_image.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 200626E8353AB2729444F991 /* preview_image.jpg */; };
@@ -2558,7 +2561,6 @@
B8108C8F0ACF6A7EB72D0117 /* RoomScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenCoordinator.swift; sourceTree = "<group>"; };
B81B6170DB690013CEB646F4 /* MapLibreModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLibreModels.swift; sourceTree = "<group>"; };
B8516302ACCA94A0E680AB3B /* VoiceMessageButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageButton.swift; sourceTree = "<group>"; };
HW13ISECOFUYATOTX2RU7GDG /* PlaybackSpeedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackSpeedButton.swift; sourceTree = "<group>"; };
B858A61F2A570DFB8DE570A7 /* AggregratedReaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AggregratedReaction.swift; sourceTree = "<group>"; };
B88CE0A058727BC68EEEC6B6 /* ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ShareExtension.entitlements; sourceTree = "<group>"; };
B8A3B7637DDBD6AA97AC2545 /* CameraPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPicker.swift; sourceTree = "<group>"; };
@@ -2580,6 +2582,7 @@
BC8AA23D4F37CC26564F63C5 /* LayoutMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutMocks.swift; sourceTree = "<group>"; };
BCDA016D05107DED3B9495CB /* TimelineItemDebugView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemDebugView.swift; sourceTree = "<group>"; };
BD5480F03306234FC086E93B /* HomeScreenNewSoundBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenNewSoundBanner.swift; sourceTree = "<group>"; };
BDBB8E5436E1BE0D6814BB7D /* PlaybackSpeedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackSpeedButton.swift; sourceTree = "<group>"; };
BDE3EDEA7E64D68FEB828F83 /* SpaceSettingsFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceSettingsFlowCoordinator.swift; sourceTree = "<group>"; };
BE148A4FFEE853C5A281500C /* UNNotificationContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNNotificationContent.swift; sourceTree = "<group>"; };
BE89A8BD65CCE3FCC925CA14 /* TimelineItemReplyDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemReplyDetails.swift; sourceTree = "<group>"; };
@@ -2894,6 +2897,7 @@
F64A8582F65567AC38C2976A /* PollFormScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenViewModel.swift; sourceTree = "<group>"; };
F72EFC8C634469F9262659C7 /* NSItemProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSItemProvider.swift; sourceTree = "<group>"; };
F7478623CECC9438014244BA /* ServerConfirmationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreen.swift; sourceTree = "<group>"; };
F78B4E56DBFFD4A7A39D10F5 /* AudioPlaybackSpeed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlaybackSpeed.swift; sourceTree = "<group>"; };
F7E247E29C7A0E421DB839D7 /* RoomPowerLevel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPowerLevel.swift; sourceTree = "<group>"; };
F875D71347DC81EAE7687446 /* NavigationRootCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRootCoordinatorTests.swift; sourceTree = "<group>"; };
F899D02CF26EA7675EEBE74C /* UserSessionScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionScreenTests.swift; sourceTree = "<group>"; };
@@ -5601,7 +5605,7 @@
isa = PBXGroup;
children = (
AD0FF64B0E6470F66F42E182 /* EstimatedWaveformView.swift */,
HW13ISECOFUYATOTX2RU7GDG /* PlaybackSpeedButton.swift */,
BDBB8E5436E1BE0D6814BB7D /* PlaybackSpeedButton.swift */,
B8516302ACCA94A0E680AB3B /* VoiceMessageButton.swift */,
FB9EABCA9348DFA27439A809 /* WaveformCursorView.swift */,
BFEE91FB8ABB5F5884B6D940 /* WaveformInteractionModifier.swift */,
@@ -6275,6 +6279,7 @@
353024006CB726E9F9187B3A /* AnalyticsConsentState.swift */,
0FD22AEFFA20065494ED2333 /* AppAppearance.swift */,
7BD5523BDEDB247E29228476 /* AppSettings.swift */,
F78B4E56DBFFD4A7A39D10F5 /* AudioPlaybackSpeed.swift */,
0A2074C0449B83D5858BD2D7 /* FrequentlyUsedEmoji.swift */,
8A1F2AAA3F0F2B72D2FFE4D0 /* MapTilerConfiguration.swift */,
E8D354D4232DED9649FD0FF4 /* OIDCConfiguration.swift */,
@@ -7511,6 +7516,7 @@
484202C5D50983442D24D061 /* AttributedString.swift in Sources */,
CDCA8A559E098503DDE29477 /* AttributedStringBuilder.swift in Sources */,
BA43D782BE85C7F5F20C624A /* AttributedStringBuilderProtocol.swift in Sources */,
D2CBC380FEBCBF29263B8446 /* AudioPlaybackSpeed.swift in Sources */,
F255083E18CDBFDF7E640FB1 /* Avatars.swift in Sources */,
A8E324E700E596E36B0A311B /* BootDetectionManager.swift in Sources */,
9A3B0CDF097E3838FB1B9595 /* Bundle.swift in Sources */,
@@ -7745,6 +7751,7 @@
88887E40301FF0543ED5B59F /* AppAppearance.swift in Sources */,
944EAB7BC2408B2C6570E722 /* AppHooks.swift in Sources */,
2CC3F27CD76DB00A747BEA6C /* AppSettings.swift in Sources */,
56C18ACF91DD20463B242460 /* AudioPlaybackSpeed.swift in Sources */,
2F2906AE9BC3D0E79A6F98F8 /* Bundle.swift in Sources */,
88A87AA16CD93F57143623F8 /* ClientBuilderHook.swift in Sources */,
D104B27C5DA0626B41CE78D3 /* CurrentValuePublisher.swift in Sources */,
@@ -7877,6 +7884,7 @@
2DA27D78560D5F79B917E163 /* AudioConverter.swift in Sources */,
F3F38062C6CA21CF403C5C90 /* AudioConverterProtocol.swift in Sources */,
77E33FF0E4A50B555BF3A8AA /* AudioFileEventsTimelineView.swift in Sources */,
8B9C2890B6DD160A0662861E /* AudioPlaybackSpeed.swift in Sources */,
46C9F8FE3810A04A005FE16B /* AudioPlayer.swift in Sources */,
086D01E79C8E8D3F004FAF21 /* AudioPlayerProtocol.swift in Sources */,
1471A080552631358D152C18 /* AudioPlayerState.swift in Sources */,
@@ -8345,6 +8353,7 @@
9D79B94493FB32249F7E472F /* PlaceholderAvatarImage.swift in Sources */,
1BA04D05EBC6646958B1BE60 /* PlaceholderScreenCoordinator.swift in Sources */,
EF0D0155DD104C7A41A2EB0E /* PlainMentionBuilder.swift in Sources */,
6E0C68918BEC5D27A4830BA6 /* PlaybackSpeedButton.swift in Sources */,
B79E8AB83EBBDCD476D0362F /* PollFormScreen.swift in Sources */,
3DAD62988F072607441CB7A5 /* PollFormScreenCoordinator.swift in Sources */,
70B83D44043293B4B77440B9 /* PollFormScreenModels.swift in Sources */,
@@ -8803,7 +8812,6 @@
2CA61BB208CD82EBDB58CD13 /* VideoRoomTimelineView.swift in Sources */,
6FC10A00D268FCD48B631E37 /* ViewFrameReader.swift in Sources */,
EED33AFD9334EFD7398707A6 /* VisualListItem.swift in Sources */,
ES17LAX66UIQ5OAE6L2BQQE4 /* PlaybackSpeedButton.swift in Sources */,
1318721F4E5F307586D98112 /* VoiceMessageButton.swift in Sources */,
4681820102DAC8BA586357D4 /* VoiceMessageCache.swift in Sources */,
4F2DF6138E87A4B8C2488CA3 /* VoiceMessageCacheProtocol.swift in Sources */,

View File

@@ -362,8 +362,8 @@ final class AppSettings {
@UserPreference(key: UserDefaultsKeys.optimizeMediaUploads, defaultValue: true, storageType: .userDefaults(store))
var optimizeMediaUploads
@UserPreference(key: UserDefaultsKeys.voiceMessagePlaybackSpeed, defaultValue: VoiceMessagePlaybackSpeed.default, storageType: .userDefaults(store))
var voiceMessagePlaybackSpeed: VoiceMessagePlaybackSpeed
@UserPreference(key: UserDefaultsKeys.voiceMessagePlaybackSpeed, defaultValue: AudioPlaybackSpeed.default, storageType: .userDefaults(store))
var voiceMessagePlaybackSpeed: AudioPlaybackSpeed
/// Whether or not to show a warning on the media caption composer so the user knows
/// that captions might not be visible to users who are using other Matrix clients.
@@ -452,23 +452,3 @@ final class AppSettings {
}
extension AppSettings: CommonSettingsProtocol { }
enum VoiceMessagePlaybackSpeed: Float, CaseIterable, Codable {
case `default` = 1.0
case fast = 1.5
case fastest = 2.0
case slow = 0.5
var label: String {
switch self {
case .default, .fastest:
rawValue.formatted(.number.precision(.fractionLength(0))) + "×"
case .fast, .slow:
rawValue.formatted(.number.precision(.fractionLength(1))) + "×"
}
}
var placeholder: String {
0.0.formatted(.number.precision(.fractionLength(1))) + "×"
}
}

View File

@@ -0,0 +1,33 @@
//
// Copyright 2026 Element Creations Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
enum AudioPlaybackSpeed: Float, CaseIterable, Codable {
case `default` = 1.0
case fast = 1.5
case fastest = 2.0
case slow = 0.5
var label: String {
switch self {
case .default, .fastest:
rawValue.formatted(.number.precision(.fractionLength(0))) + "×"
case .fast, .slow:
rawValue.formatted(.number.precision(.fractionLength(1))) + "×"
}
}
var placeholder: String {
0.0.formatted(.number.precision(.fractionLength(1))) + "×"
}
var next: Self {
guard let index = Self.allCases.firstIndex(of: self) else {
return .default
}
return Self.allCases[(index + 1) % Self.allCases.count]
}
}

View File

@@ -8,7 +8,7 @@
import SwiftUI
struct PlaybackSpeedButton: View {
let speed: VoiceMessagePlaybackSpeed
let speed: AudioPlaybackSpeed
let onTap: () -> Void
var body: some View {
@@ -35,7 +35,7 @@ struct PlaybackSpeedButton: View {
struct PlaybackSpeedButton_Previews: PreviewProvider, TestablePreview {
static var previews: some View {
HStack(spacing: 8) {
ForEach(VoiceMessagePlaybackSpeed.allCases, id: \.self) { speed in
ForEach(AudioPlaybackSpeed.allCases, id: \.self) { speed in
PlaybackSpeedButton(speed: speed) { }
}
}

View File

@@ -419,15 +419,7 @@ class TimelineInteractionHandler {
// MARK: Audio Playback
func changePlaybackSpeed(for itemID: TimelineItemIdentifier) {
let availableSpeeds = VoiceMessagePlaybackSpeed.allCases
guard let currentIndex = availableSpeeds.firstIndex(of: appSettings.voiceMessagePlaybackSpeed) else {
appSettings.voiceMessagePlaybackSpeed = .default
audioPlayerState(for: itemID)?.setPlaybackSpeed(VoiceMessagePlaybackSpeed.default)
return
}
let nextIndex = (currentIndex + 1) % availableSpeeds.count
let nextSpeed = availableSpeeds[nextIndex]
let nextSpeed = appSettings.voiceMessagePlaybackSpeed.next
appSettings.voiceMessagePlaybackSpeed = nextSpeed
audioPlayerState(for: itemID)?.setPlaybackSpeed(nextSpeed)
}

View File

@@ -36,7 +36,7 @@ class AudioPlayerState: ObservableObject, Identifiable {
/// It's similar to `playbackState`, with the a difference: `.loading`
/// updates are delayed by a fixed amount of time
@Published private(set) var playerButtonPlaybackState: AudioPlayerPlaybackState
@Published private(set) var playbackSpeed: VoiceMessagePlaybackSpeed
@Published private(set) var playbackSpeed: AudioPlaybackSpeed
private weak var audioPlayer: AudioPlayerProtocol?
private var audioPlayerSubscription: AnyCancellable?
@@ -63,8 +63,8 @@ class AudioPlayerState: ObservableObject, Identifiable {
duration: Double,
waveform: EstimatedWaveform? = nil,
progress: Double = 0.0,
playbackSpeed: VoiceMessagePlaybackSpeed = .default,
playbackSpeedPublisher: AnyPublisher<VoiceMessagePlaybackSpeed, Never>? = nil) {
playbackSpeed: AudioPlaybackSpeed = .default,
playbackSpeedPublisher: AnyPublisher<AudioPlaybackSpeed, Never>? = nil) {
self.id = id
self.title = title
self.duration = duration
@@ -120,7 +120,7 @@ class AudioPlayerState: ObservableObject, Identifiable {
playbackState = .error
}
func setPlaybackSpeed(_ speed: VoiceMessagePlaybackSpeed) {
func setPlaybackSpeed(_ speed: AudioPlaybackSpeed) {
playbackSpeed = speed
audioPlayer?.setPlaybackSpeed(speed.rawValue)
}