Fix sound effects + upgrade swift concurrency settings

This commit is contained in:
Thomas Ricouard 2023-09-14 11:04:14 +02:00
parent 53b442eb33
commit 1bbb0dc82d
14 changed files with 112 additions and 47 deletions

View file

@ -686,7 +686,7 @@
attributes = { attributes = {
BuildIndependentTargetsInParallel = 1; BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1420; LastSwiftUpdateCheck = 1420;
LastUpgradeCheck = 1420; LastUpgradeCheck = 1500;
TargetAttributes = { TargetAttributes = {
9F2A5415296AB631009B2D7C = { 9F2A5415296AB631009B2D7C = {
CreatedOnToolsVersion = 14.2; CreatedOnToolsVersion = 14.2;
@ -1089,6 +1089,7 @@
baseConfigurationReference = DD31E2E5297FB68B00A4BE29 /* IceCubesApp.xcconfig */; baseConfigurationReference = DD31E2E5297FB68B00A4BE29 /* IceCubesApp.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@ -1123,6 +1124,7 @@
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO; GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
@ -1142,6 +1144,7 @@
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_STRICT_CONCURRENCY = complete;
}; };
name = Debug; name = Debug;
}; };
@ -1150,6 +1153,7 @@
baseConfigurationReference = 9F7D939529800B0300EE6B7A /* IceCubesApp-release.xcconfig */; baseConfigurationReference = 9F7D939529800B0300EE6B7A /* IceCubesApp-release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@ -1184,6 +1188,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -1196,6 +1201,7 @@
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
SWIFT_COMPILATION_MODE = wholemodule; SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_STRICT_CONCURRENCY = complete;
}; };
name = Release; name = Release;
}; };
@ -1246,7 +1252,7 @@
SUPPORTS_MACCATALYST = NO; SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_STRICT_CONCURRENCY = targeted; SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
@ -1299,7 +1305,7 @@
SUPPORTS_MACCATALYST = NO; SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_STRICT_CONCURRENCY = targeted; SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };

View file

@ -50,8 +50,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/RevenueCat/purchases-ios.git", "location" : "https://github.com/RevenueCat/purchases-ios.git",
"state" : { "state" : {
"revision" : "4601c1e0c246f3d74094229737e894a9f2339e6a", "revision" : "78d2f159d6d647f26ae5a9dd38276ea06403e7ec",
"version" : "4.25.7" "version" : "4.25.9"
} }
}, },
{ {
@ -86,8 +86,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/siteline/SwiftUI-Introspect.git", "location" : "https://github.com/siteline/SwiftUI-Introspect.git",
"state" : { "state" : {
"revision" : "9da0f9b7bffe96a7c98a0128f1e214f62728a39a", "revision" : "3ba734dd20faada0e3234b68e78db97005315f0e",
"version" : "0.11.1" "version" : "1.0.0"
} }
}, },
{ {

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1420" LastUpgradeVersion = "1500"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View file

@ -21,6 +21,7 @@ struct QuickLookPreview: UIViewControllerRepresentable {
) {} ) {}
} }
@MainActor
class AppQLPreviewController: UIViewController { class AppQLPreviewController: UIViewController {
let selectedURL: URL let selectedURL: URL
let urls: [URL] let urls: [URL]
@ -51,26 +52,30 @@ class AppQLPreviewController: UIViewController {
} }
extension AppQLPreviewController: QLPreviewControllerDataSource { extension AppQLPreviewController: QLPreviewControllerDataSource {
func numberOfPreviewItems(in _: QLPreviewController) -> Int { nonisolated func numberOfPreviewItems(in _: QLPreviewController) -> Int {
return urls.count return urls.count
} }
func previewController(_: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem { nonisolated func previewController(_: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
return urls[index] as QLPreviewItem return urls[index] as QLPreviewItem
} }
} }
extension AppQLPreviewController: QLPreviewControllerDelegate { extension AppQLPreviewController: QLPreviewControllerDelegate {
func previewController(_: QLPreviewController, editingModeFor _: QLPreviewItem) -> QLPreviewItemEditingMode { nonisolated func previewController(_: QLPreviewController, editingModeFor _: QLPreviewItem) -> QLPreviewItemEditingMode {
.createCopy .createCopy
} }
func previewControllerWillDismiss(_: QLPreviewController) { nonisolated func previewControllerWillDismiss(_: QLPreviewController) {
dismiss(animated: true) Task { @MainActor in
dismiss(animated: true)
}
} }
func previewControllerDidDismiss(_: QLPreviewController) { nonisolated func previewControllerDidDismiss(_: QLPreviewController) {
dismiss(animated: true) Task { @MainActor in
dismiss(animated: true)
}
} }
} }

View file

@ -4,11 +4,12 @@ import SafariServices
import SwiftUI import SwiftUI
extension View { extension View {
func withSafariRouter() -> some View { @MainActor func withSafariRouter() -> some View {
modifier(SafariRouter()) modifier(SafariRouter())
} }
} }
@MainActor
private struct SafariRouter: ViewModifier { private struct SafariRouter: ViewModifier {
@EnvironmentObject private var theme: Theme @EnvironmentObject private var theme: Theme
@EnvironmentObject private var preferences: UserPreferences @EnvironmentObject private var preferences: UserPreferences
@ -56,6 +57,7 @@ private struct SafariRouter: ViewModifier {
} }
} }
@MainActor
private class InAppSafariManager: NSObject, ObservableObject, SFSafariViewControllerDelegate { private class InAppSafariManager: NSObject, ObservableObject, SFSafariViewControllerDelegate {
var windowScene: UIWindowScene? var windowScene: UIWindowScene?
let viewController: UIViewController = .init() let viewController: UIViewController = .init()
@ -99,10 +101,12 @@ private class InAppSafariManager: NSObject, ObservableObject, SFSafariViewContro
return window return window
} }
func safariViewControllerDidFinish(_: SFSafariViewController) { nonisolated func safariViewControllerDidFinish(_: SFSafariViewController) {
window?.resignKey() Task { @MainActor in
window?.isHidden = false window?.resignKey()
window = nil window?.isHidden = false
window = nil
}
} }
} }

View file

@ -176,7 +176,7 @@ private struct SideBarIcon: View {
} }
extension View { extension View {
func hideKeyboard() { @MainActor func hideKeyboard() {
let resign = #selector(UIResponder.resignFirstResponder) let resign = #selector(UIResponder.resignFirstResponder)
UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil) UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil)
} }

View file

@ -307,7 +307,9 @@ struct SettingsTabs: View {
_ = preferences.remoteLocalTimelines.remove(at: index) _ = preferences.remoteLocalTimelines.remove(at: index)
} }
} }
.onMove(perform: moveTimelineItems) .onMove(perform: { indices, newOffset in
moveTimelineItems(from: indices, to: newOffset)
})
.listRowBackground(theme.primaryBackgroundColor) .listRowBackground(theme.primaryBackgroundColor)
Button { Button {
routerPath.presentedSheet = .addRemoteLocalTimeline routerPath.presentedSheet = .addRemoteLocalTimeline
@ -324,6 +326,7 @@ struct SettingsTabs: View {
} }
} }
private func moveTimelineItems(from source: IndexSet, to destination: Int) { private func moveTimelineItems(from source: IndexSet, to destination: Int) {
preferences.remoteLocalTimelines.move(fromOffsets: source, toOffset: destination) preferences.remoteLocalTimelines.move(fromOffsets: source, toOffset: destination)
} }

View file

@ -25,7 +25,9 @@ struct TranslationSettingsView: View {
SecureField("settings.translation.user-api-key", text: $apiKey) SecureField("settings.translation.user-api-key", text: $apiKey)
.textContentType(.password) .textContentType(.password)
} }
.onAppear(perform: readValue) .onAppear {
readValue()
}
.listRowBackground(theme.primaryBackgroundColor) .listRowBackground(theme.primaryBackgroundColor)
if apiKey.isEmpty { if apiKey.isEmpty {

View file

@ -5,12 +5,13 @@ import Foundation
import Status import Status
import SwiftUI import SwiftUI
@MainActor
enum Tab: Int, Identifiable, Hashable { enum Tab: Int, Identifiable, Hashable {
case timeline, notifications, mentions, explore, messages, settings, other case timeline, notifications, mentions, explore, messages, settings, other
case trending, federated, local case trending, federated, local
case profile case profile
var id: Int { nonisolated var id: Int {
rawValue rawValue
} }

View file

@ -1,7 +1,8 @@
import Foundation import Foundation
@MainActor
public extension CGFloat { public extension CGFloat {
static var layoutPadding: CGFloat = 20 static let layoutPadding: CGFloat = 20
static let dividerPadding: CGFloat = 2 static let dividerPadding: CGFloat = 2
static let statusColumnsSpacing: CGFloat = 8 static let statusColumnsSpacing: CGFloat = 8
static let secondaryColumnWidth: CGFloat = 400 static let secondaryColumnWidth: CGFloat = 400

View file

@ -14,7 +14,7 @@ public extension Color {
} }
static var label: Color { static var label: Color {
Color("label", bundle: .module) Color(.label)
} }
} }

View file

@ -1,32 +1,75 @@
import AVKit import AVKit
import CoreHaptics import CoreHaptics
import UIKit import UIKit
import AudioToolbox
@MainActor
public class SoundEffectManager { public class SoundEffectManager {
public static let shared: SoundEffectManager = .init() public static let shared: SoundEffectManager = .init()
public enum SoundEffect: String { public enum SoundEffect: String, CaseIterable {
case pull, refresh case pull, refresh, tootSent, tabSelection, bookmark, boost, favorite, share
case tootSent
case tabSelection
case bookmark, boost, favorite, share
} }
var pullId: SystemSoundID = 0
var refreshId: SystemSoundID = 1
var tootSentId: SystemSoundID = 2
var tabSelectionId: SystemSoundID = 3
var bookmarkId: SystemSoundID = 4
var boostId: SystemSoundID = 5
var favoriteId: SystemSoundID = 6
var shareId: SystemSoundID = 7
private let userPreferences = UserPreferences.shared private let userPreferences = UserPreferences.shared
private var currentPlayer: AVAudioPlayer? private init() {
registerSounds()
}
private init() {} private func registerSounds() {
for effect in SoundEffect.allCases {
if let url = Bundle.main.url(forResource: effect.rawValue, withExtension: "wav") {
switch effect {
case .pull:
AudioServicesCreateSystemSoundID(url as CFURL, &pullId)
case .refresh:
AudioServicesCreateSystemSoundID(url as CFURL, &refreshId)
case .tootSent:
AudioServicesCreateSystemSoundID(url as CFURL, &tootSentId)
case .tabSelection:
AudioServicesCreateSystemSoundID(url as CFURL, &tabSelectionId)
case .bookmark:
AudioServicesCreateSystemSoundID(url as CFURL, &bookmarkId)
case .boost:
AudioServicesCreateSystemSoundID(url as CFURL, &boostId)
case .favorite:
AudioServicesCreateSystemSoundID(url as CFURL, &favoriteId)
case .share:
AudioServicesCreateSystemSoundID(url as CFURL, &shareId)
}
}
}
}
@MainActor
public func playSound(of type: SoundEffect) { public func playSound(of type: SoundEffect) {
guard userPreferences.soundEffectEnabled else { return } guard userPreferences.soundEffectEnabled else { return }
if let url = Bundle.main.url(forResource: type.rawValue, withExtension: "wav") { switch type {
try? AVAudioSession.sharedInstance().setCategory(.ambient) case .pull:
try? AVAudioSession.sharedInstance().setActive(true) AudioServicesPlaySystemSound(pullId)
currentPlayer = try? .init(contentsOf: url) case .refresh:
currentPlayer?.prepareToPlay() AudioServicesPlaySystemSound(refreshId)
currentPlayer?.play() case .tootSent:
AudioServicesPlaySystemSound(tootSentId)
case .tabSelection:
AudioServicesPlaySystemSound(tabSelectionId)
case .bookmark:
AudioServicesPlaySystemSound(bookmarkId)
case .boost:
AudioServicesPlaySystemSound(boostId)
case .favorite:
AudioServicesPlaySystemSound(favoriteId)
case .share:
AudioServicesPlaySystemSound(shareId)
} }
} }
} }

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1420" LastUpgradeVersion = "1500"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View file

@ -21,7 +21,7 @@ let package = Package(
.package(name: "Env", path: "../Env"), .package(name: "Env", path: "../Env"),
.package(name: "Status", path: "../Status"), .package(name: "Status", path: "../Status"),
.package(name: "DesignSystem", path: "../DesignSystem"), .package(name: "DesignSystem", path: "../DesignSystem"),
.package(url: "https://github.com/siteline/SwiftUI-Introspect.git", from: "0.9.1"), .package(url: "https://github.com/siteline/SwiftUI-Introspect.git", from: "1.0.0"),
.package(url: "https://github.com/mergesort/Bodega", from: "2.0.2"), .package(url: "https://github.com/mergesort/Bodega", from: "2.0.2"),
], ],
targets: [ targets: [