diff --git a/IceCubesApp.xcodeproj/project.pbxproj b/IceCubesApp.xcodeproj/project.pbxproj index 912d29e3..0ecd0fbc 100644 --- a/IceCubesApp.xcodeproj/project.pbxproj +++ b/IceCubesApp.xcodeproj/project.pbxproj @@ -16,6 +16,14 @@ 7429BCE2297C55D00069A946 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 7429BCE4297C55D00069A946 /* Localizable.stringsdict */; }; 7429BCE5297C5A750069A946 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 7429BCE4297C55D00069A946 /* Localizable.stringsdict */; }; 7429BCE6297C5A750069A946 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 7429BCE4297C55D00069A946 /* Localizable.stringsdict */; }; + 9F18801229AE477F00D85459 /* tabSelection.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F18800A29AE477E00D85459 /* tabSelection.wav */; }; + 9F18801329AE477F00D85459 /* share.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F18800B29AE477E00D85459 /* share.wav */; }; + 9F18801429AE477F00D85459 /* bookmark.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F18800C29AE477E00D85459 /* bookmark.wav */; }; + 9F18801529AE477F00D85459 /* pull.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F18800D29AE477E00D85459 /* pull.wav */; }; + 9F18801629AE477F00D85459 /* refresh.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F18800E29AE477E00D85459 /* refresh.wav */; }; + 9F18801729AE477F00D85459 /* boost.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F18800F29AE477E00D85459 /* boost.wav */; }; + 9F18801829AE477F00D85459 /* favorite.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F18801029AE477F00D85459 /* favorite.wav */; }; + 9F18801929AE477F00D85459 /* tootSent.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F18801129AE477F00D85459 /* tootSent.wav */; }; 9F1E8B47298EBCBB00609F80 /* HapticSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F1E8B46298EBCBB00609F80 /* HapticSettingsView.swift */; }; 9F24EEB829360C330042359D /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9F24EEB729360C330042359D /* Preview Assets.xcassets */; }; 9F295540292B6C3400E0E81B /* Timeline in Frameworks */ = {isa = PBXBuildFile; productRef = 9F29553F292B6C3400E0E81B /* Timeline */; }; @@ -162,6 +170,14 @@ 8C27D979298471E900CDF593 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 9606B7A1297AD2BB00C1FB75 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 9664F1A8299BA5F700CBE70E /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + 9F18800A29AE477E00D85459 /* tabSelection.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = tabSelection.wav; sourceTree = ""; }; + 9F18800B29AE477E00D85459 /* share.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = share.wav; sourceTree = ""; }; + 9F18800C29AE477E00D85459 /* bookmark.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = bookmark.wav; sourceTree = ""; }; + 9F18800D29AE477E00D85459 /* pull.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = pull.wav; sourceTree = ""; }; + 9F18800E29AE477E00D85459 /* refresh.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = refresh.wav; sourceTree = ""; }; + 9F18800F29AE477E00D85459 /* boost.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = boost.wav; sourceTree = ""; }; + 9F18801029AE477F00D85459 /* favorite.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = favorite.wav; sourceTree = ""; }; + 9F18801129AE477F00D85459 /* tootSent.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = tootSent.wav; sourceTree = ""; }; 9F1E8B46298EBCBB00609F80 /* HapticSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticSettingsView.swift; sourceTree = ""; }; 9F24EEB729360C330042359D /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 9F29553D292B67B600E0E81B /* Network */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Network; path = Packages/Network; sourceTree = ""; }; @@ -387,6 +403,14 @@ 9FA0D2AC29921C1F008A143B /* Embeds */ = { isa = PBXGroup; children = ( + 9F18800C29AE477E00D85459 /* bookmark.wav */, + 9F18800F29AE477E00D85459 /* boost.wav */, + 9F18801029AE477F00D85459 /* favorite.wav */, + 9F18800D29AE477E00D85459 /* pull.wav */, + 9F18800E29AE477E00D85459 /* refresh.wav */, + 9F18800A29AE477E00D85459 /* tabSelection.wav */, + 9F18800B29AE477E00D85459 /* share.wav */, + 9F18801129AE477F00D85459 /* tootSent.wav */, 069709A3298C8545006E4CB5 /* Atkinson-Hyperlegible-Regular-102.ttf */, 069709A7298C87B5006E4CB5 /* OpenDyslexic-Regular.otf */, 9F2A542D296B1CC0009B2D7C /* glass.wav */, @@ -733,13 +757,21 @@ buildActionMask = 2147483647; files = ( 069709A5298C8545006E4CB5 /* Atkinson-Hyperlegible-Regular-102.ttf in Resources */, + 9F18801329AE477F00D85459 /* share.wav in Resources */, + 9F18801729AE477F00D85459 /* boost.wav in Resources */, 9F2A542C296B1177009B2D7C /* glass.caf in Resources */, E9B576C329743F4C00BCE646 /* Localizable.strings in Resources */, + 9F18801529AE477F00D85459 /* pull.wav in Resources */, 9FD34823293D06E800DB0EE9 /* Assets.xcassets in Resources */, 7429BCE2297C55D00069A946 /* Localizable.stringsdict in Resources */, + 9F18801829AE477F00D85459 /* favorite.wav in Resources */, 9F24EEB829360C330042359D /* Preview Assets.xcassets in Resources */, 069709A8298C87B5006E4CB5 /* OpenDyslexic-Regular.otf in Resources */, 9FAD85832971BF7200496AB1 /* Secret.plist in Resources */, + 9F18801229AE477F00D85459 /* tabSelection.wav in Resources */, + 9F18801429AE477F00D85459 /* bookmark.wav in Resources */, + 9F18801629AE477F00D85459 /* refresh.wav in Resources */, + 9F18801929AE477F00D85459 /* tootSent.wav in Resources */, 9F2A542E296B1CC0009B2D7C /* glass.wav in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/IceCubesApp/App/IceCubesApp.swift b/IceCubesApp/App/IceCubesApp.swift index 0c8a9b4c..fd015eb3 100644 --- a/IceCubesApp/App/IceCubesApp.swift +++ b/IceCubesApp/App/IceCubesApp.swift @@ -175,6 +175,7 @@ struct IceCubesApp: App { } } HapticManager.shared.fireHaptic(of: .tabSelection) + SoundEffectManager.shared.playSound(of: .tabSelection) })) { ForEach(availableTabs) { tab in tab.makeContentView(popToRootTab: $popToRootTab) diff --git a/IceCubesApp/App/SideBarView.swift b/IceCubesApp/App/SideBarView.swift index b7dba1d7..fcf7cb3b 100644 --- a/IceCubesApp/App/SideBarView.swift +++ b/IceCubesApp/App/SideBarView.swift @@ -69,6 +69,7 @@ struct SideBarView: View { Button { if account.id == appAccounts.currentAccount.id { selectedTab = .profile + SoundEffectManager.shared.playSound(of: .tabSelection) } else { var transation = Transaction() transation.disablesAnimations = true @@ -103,6 +104,7 @@ struct SideBarView: View { } } selectedTab = tab + SoundEffectManager.shared.playSound(of: .tabSelection) if tab == .notifications { if let token = appAccounts.currentAccount.oauthToken { userPreferences.setNotification(count: 0, token: token) diff --git a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift index 493a987e..2dbc1476 100644 --- a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift +++ b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift @@ -179,6 +179,9 @@ struct SettingsTabs: View { Toggle(isOn: $preferences.isSocialKeyboardEnabled) { Label("settings.other.social-keyboard", systemImage: "keyboard") } + Toggle(isOn: $preferences.soundEffectEnabled) { + Label("settings.other.sound-effect", systemImage: "hifispeaker") + } } .listRowBackground(theme.primaryBackgroundColor) } diff --git a/IceCubesApp/Resources/Localization/be.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/be.lproj/Localizable.strings index 024b0140..6c8d25bc 100644 --- a/IceCubesApp/Resources/Localization/be.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/be.lproj/Localizable.strings @@ -152,6 +152,7 @@ "settings.section.other" = "Іншае"; "settings.other.hide-openai" = "Уключыць 🤖 памочніка"; "settings.other.social-keyboard" = "Уключыць сацыяльную клавіятуру"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "Выпраўляльнік дублікатаў апавяшчэнняў"; "settings.push.duplicate.footer" = "Атрымліваеш падвоеныя апавяшчэнні? Паспрабуй гэтую чароўную кнопку каб выправіць"; "settings.push.duplicate.button.fix" = "🪄 Выправіць"; diff --git a/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings index 7b68a83d..cbe1a8ab 100644 --- a/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings @@ -147,6 +147,7 @@ "settings.section.other" = "Altres opcions"; "settings.other.hide-openai" = "Activa l'ajudant 🤖"; "settings.other.social-keyboard" = "Activa el teclat social"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "Solucionador de notificacions duplicades"; "settings.push.duplicate.footer" = "Rebeu les notificacions duplicades? Proveu aquest botó màgic per a solucionar-ho"; "settings.push.duplicate.button.fix" = "🪄 Soluciona-ho"; diff --git a/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings index fcd87239..b9358733 100644 --- a/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings @@ -128,6 +128,7 @@ "settings.section.other" = "Anderes"; "settings.other.hide-openai" = "Aktiviere 🤖-Helfer"; "settings.other.social-keyboard" = "Soziale Tastatur aktivieren"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.general.content" = "Inhaltseinstellungen"; "settings.system" = "Systemeinstellungen"; "settings.content.navigation-title" = "Inhaltseinstellungen"; diff --git a/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings index ba188317..b8d3096a 100644 --- a/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings @@ -153,6 +153,7 @@ "settings.section.other" = "Other"; "settings.other.hide-openai" = "Enable 🤖 Helper"; "settings.other.social-keyboard" = "Enable Social Keyboard"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "Duplicate Notifications Fixer"; "settings.push.duplicate.footer" = "Receiving duplicate notifications? Try this magic button in order to fix it"; "settings.push.duplicate.button.fix" = "🪄 Fix It"; diff --git a/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings index de900106..6f45199f 100644 --- a/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings @@ -152,6 +152,7 @@ "settings.section.other" = "Other"; "settings.other.hide-openai" = "Enable 🤖 Helper"; "settings.other.social-keyboard" = "Enable Social Keyboard"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "Duplicate Notifications Fixer"; "settings.push.duplicate.footer" = "Receiving duplicate notifications? Try this magic button in order to fix it"; "settings.push.duplicate.button.fix" = "🪄 Fix It"; diff --git a/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings index 6fc43418..9200b9c6 100644 --- a/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings @@ -128,6 +128,7 @@ "settings.section.other" = "Otras opciones"; "settings.other.hide-openai" = "Activar ayudante 🤖"; "settings.other.social-keyboard" = "Activar teclado social"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.general.content" = "Ajustes de contenido"; "settings.system" = "Ajustes del sistema"; "settings.content.navigation-title" = "Ajustes de contenido"; diff --git a/IceCubesApp/Resources/Localization/eu.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/eu.lproj/Localizable.strings index e1935672..f5b1d9fd 100644 --- a/IceCubesApp/Resources/Localization/eu.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/eu.lproj/Localizable.strings @@ -128,6 +128,7 @@ "settings.section.other" = "Besteak"; "settings.other.hide-openai" = "Gaitu 🤖 laguntzailea"; "settings.other.social-keyboard" = "Gaitu teklatu soziala"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.general.content" = "Edukiaren ezarpenak"; "settings.system" = "Sistemaren ezarpenak"; "settings.content.navigation-title" = "Edukiaren ezarpenak"; diff --git a/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings index e77c7ed5..53b33dd6 100644 --- a/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings @@ -148,6 +148,7 @@ "settings.section.other" = "Autres"; "settings.other.hide-openai" = "Activer 🤖 aide"; "settings.other.social-keyboard" = "Activer le clavier social"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "Correcteur de notifications en double"; "settings.push.duplicate.footer" = "Recevez-vous des notifications en double ? Essayez ce bouton magique pour résoudre le problème"; "settings.push.duplicate.button.fix" = "🪄 Résoudre"; diff --git a/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings index 7b073b16..18a5a059 100644 --- a/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings @@ -128,6 +128,7 @@ "settings.section.other" = "Altro"; "settings.other.hide-openai" = "Abilita l'aiuto del 🤖"; "settings.other.social-keyboard" = "Abilita social keyboard"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.general.content" = "Impostazioni dei contenuti"; "settings.system" = "Vai alle impostazioni di sistema"; "settings.content.navigation-title" = "Impostazioni dei contenuti"; diff --git a/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings index 4b2f7dd7..047b11b0 100644 --- a/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings @@ -152,6 +152,7 @@ "settings.section.other" = "その他"; "settings.other.hide-openai" = "AI支援機能の有効化"; "settings.other.social-keyboard" = "ソーシャルメディア向けキーボードの有効化"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "重複通知修正ツール"; "settings.push.duplicate.footer" = "重複して通知を受け取っていませんか?修正するためにこの魔法のボタンを試してみて"; "settings.push.duplicate.button.fix" = "🪄 修正する"; diff --git a/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings index 949935ad..92471839 100644 --- a/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings @@ -148,6 +148,7 @@ "settings.section.other" = "기타"; "settings.other.hide-openai" = "글 작성 도우미 🤖"; "settings.other.social-keyboard" = "SNS 키보드"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "중복 알림 해결사"; "settings.push.duplicate.footer" = "같은 알림이 여러 번 오나요? 위에 있는 버튼을 누르면 마법처럼 해결될 거에요."; "settings.push.duplicate.button.fix" = "🪄 고치기"; diff --git a/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings index a29be6c8..7a05e272 100644 --- a/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings @@ -152,6 +152,7 @@ "settings.section.other" = "Annet"; "settings.other.hide-openai" = "Aktiver 🤖-hjelper"; "settings.other.social-keyboard" = "Aktiver sosialt tastatur"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "Reparasjon av dupliserte varslinger"; "settings.push.duplicate.footer" = "Får du dupliserte varsler? Prøv denne magiske knappen for å fikse det."; "settings.push.duplicate.button.fix" = "🪄 Fiks det"; diff --git a/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings index 9bd74d49..82e93eb6 100644 --- a/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings @@ -128,6 +128,7 @@ "settings.section.other" = "Overig"; "settings.other.hide-openai" = "Gebruik 🤖-hulp"; "settings.other.social-keyboard" = "Gebruik socialmedia-toetsenbord"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.general.content" = "Inhoud"; "settings.system" = "Systeeminstellingen"; "settings.content.navigation-title" = "Inhoud"; diff --git a/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings index 6e093013..9e9c8d11 100644 --- a/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings @@ -148,6 +148,7 @@ "settings.section.other" = "Inne"; "settings.other.hide-openai" = "Włącz 🤖 pomocnik"; "settings.other.social-keyboard" = "Włącz klawiaturę społecznościową"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "Korektor duplikatów powiadomień"; "settings.push.duplicate.footer" = "Otrzymujesz zduplikowane powiadomienia? Spróbuj tego magicznego przycisku, aby to naprawić"; "settings.push.duplicate.button.fix" = "🪄 Napraw to"; diff --git a/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings index ecf4efa1..958834b6 100644 --- a/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings @@ -148,6 +148,7 @@ "settings.section.other" = "Outros"; "settings.other.hide-openai" = "Habilitar 🤖 ajudante"; "settings.other.social-keyboard" = "Habilitar Teclado Social"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "Corretor de notificações duplicadas"; "settings.push.duplicate.footer" = "Recebendo notificações duplicadas? Tente este botão mágico para tentar corrigir"; "settings.push.duplicate.button.fix" = "🪄 Corrigir"; diff --git a/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings index 1e8aa90d..47ecc3f9 100644 --- a/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings @@ -148,6 +148,7 @@ "settings.section.other" = "Diğer"; "settings.other.hide-openai" = "Yardımcıyı 🤖 Aktive Et"; "settings.other.social-keyboard" = "Sosyal Klavyeyi Aktive Et"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "Duplicate notifications fixer"; "settings.push.duplicate.footer" = "Receiving duplicate notifications? Try this magic button in order to fix it"; "settings.push.duplicate.button.fix" = "🪄 Fix it"; diff --git a/IceCubesApp/Resources/Localization/uk.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/uk.lproj/Localizable.strings index f8ec7900..1033b3a4 100644 --- a/IceCubesApp/Resources/Localization/uk.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/uk.lproj/Localizable.strings @@ -152,6 +152,7 @@ "settings.section.other" = "Інше"; "settings.other.hide-openai" = "Увімкнути 🤖 помічника"; "settings.other.social-keyboard" = "Увімкнути Social Keyboard"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.push.duplicate.title" = "Виправити задвоєння сповіщень"; "settings.push.duplicate.footer" = "Отримуєте сповіщення двічі? Спробуйте цю чарівну кнопку, щоб виправити це!"; "settings.push.duplicate.button.fix" = "🪄 Виправити!"; diff --git a/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings index 6a80e618..12862836 100644 --- a/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings @@ -128,6 +128,7 @@ "settings.section.other" = "其他"; "settings.other.hide-openai" = "启用写作助手 🤖"; "settings.other.social-keyboard" = "启用社交键盘"; +"settings.other.sound-effect" = "Enable Sound Effects"; "settings.general.content" = "内容设置"; "settings.system" = "系统设置"; diff --git a/Packages/Account/Sources/Account/AccountDetailView.swift b/Packages/Account/Sources/Account/AccountDetailView.swift index 37cf8be7..219f73e0 100644 --- a/Packages/Account/Sources/Account/AccountDetailView.swift +++ b/Packages/Account/Sources/Account/AccountDetailView.swift @@ -101,8 +101,12 @@ public struct AccountDetailView: View { } .refreshable { Task { + SoundEffectManager.shared.playSound(of: .pull) + HapticManager.shared.fireHaptic(of: .dataRefresh(intensity: 0.3)) await viewModel.fetchAccount() await viewModel.fetchNewestStatuses() + HapticManager.shared.fireHaptic(of: .dataRefresh(intensity: 0.7)) + SoundEffectManager.shared.playSound(of: .refresh) } } .onChange(of: watcher.latestEvent?.id) { _ in diff --git a/Packages/Conversations/Sources/Conversations/List/ConversationsListView.swift b/Packages/Conversations/Sources/Conversations/List/ConversationsListView.swift index 1e57c4b5..eec80a53 100644 --- a/Packages/Conversations/Sources/Conversations/List/ConversationsListView.swift +++ b/Packages/Conversations/Sources/Conversations/List/ConversationsListView.swift @@ -91,7 +91,11 @@ public struct ConversationsListView: View { // note: this Task wrapper should not be necessary, but it reportedly crashes without it // when refreshing on an empty list Task { + SoundEffectManager.shared.playSound(of: .pull) + HapticManager.shared.fireHaptic(of: .dataRefresh(intensity: 0.3)) await viewModel.fetchConversations() + HapticManager.shared.fireHaptic(of: .dataRefresh(intensity: 0.7)) + SoundEffectManager.shared.playSound(of: .refresh) } } .onAppear { diff --git a/Packages/Env/Sources/Env/SoundEffectManager.swift b/Packages/Env/Sources/Env/SoundEffectManager.swift new file mode 100644 index 00000000..ca45295b --- /dev/null +++ b/Packages/Env/Sources/Env/SoundEffectManager.swift @@ -0,0 +1,30 @@ +import CoreHaptics +import UIKit +import AVKit + +public class SoundEffectManager { + public static let shared: SoundEffectManager = .init() + + public enum SoundEffect: String { + case pull, refresh + case tootSent + case tabSelection + case bookmark, boost, favorite, share + } + + private let userPreferences = UserPreferences.shared + + private var currentPlayer: AVAudioPlayer? + + private init() {} + + @MainActor + public func playSound(of type: SoundEffect) { + guard userPreferences.soundEffectEnabled else { return } + if let url = Bundle.main.url(forResource: type.rawValue, withExtension: "wav") { + currentPlayer = try? .init(contentsOf: url) + currentPlayer?.prepareToPlay() + currentPlayer?.play() + } + } +} diff --git a/Packages/Env/Sources/Env/UserPreferences.swift b/Packages/Env/Sources/Env/UserPreferences.swift index 85e35697..57f6cfc5 100644 --- a/Packages/Env/Sources/Env/UserPreferences.swift +++ b/Packages/Env/Sources/Env/UserPreferences.swift @@ -34,6 +34,7 @@ public class UserPreferences: ObservableObject { @AppStorage("haptic_tab") public var hapticTabSelectionEnabled = true @AppStorage("haptic_timeline") public var hapticTimelineEnabled = true @AppStorage("haptic_button_press") public var hapticButtonPressEnabled = true + @AppStorage("sound_effect_enabled") public var soundEffectEnabled = true @AppStorage("show_tab_label_iphone") public var showiPhoneTabLabel = true @AppStorage("show_alt_text_for_media") public var showAltTextForMedia = true diff --git a/Packages/Explore/Sources/Explore/ExploreView.swift b/Packages/Explore/Sources/Explore/ExploreView.swift index a21deb3c..7cb4cd22 100644 --- a/Packages/Explore/Sources/Explore/ExploreView.swift +++ b/Packages/Explore/Sources/Explore/ExploreView.swift @@ -68,7 +68,11 @@ public struct ExploreView: View { } .refreshable { Task { + SoundEffectManager.shared.playSound(of: .pull) + HapticManager.shared.fireHaptic(of: .dataRefresh(intensity: 0.3)) await viewModel.fetchTrending() + HapticManager.shared.fireHaptic(of: .dataRefresh(intensity: 0.7)) + SoundEffectManager.shared.playSound(of: .refresh) } } .listStyle(.grouped) diff --git a/Packages/Notifications/Sources/Notifications/NotificationsListView.swift b/Packages/Notifications/Sources/Notifications/NotificationsListView.swift index 3ba53aa4..65556877 100644 --- a/Packages/Notifications/Sources/Notifications/NotificationsListView.swift +++ b/Packages/Notifications/Sources/Notifications/NotificationsListView.swift @@ -64,7 +64,11 @@ public struct NotificationsListView: View { await viewModel.fetchNotifications() } .refreshable { + SoundEffectManager.shared.playSound(of: .pull) + HapticManager.shared.fireHaptic(of: .dataRefresh(intensity: 0.3)) await viewModel.fetchNotifications() + HapticManager.shared.fireHaptic(of: .dataRefresh(intensity: 0.7)) + SoundEffectManager.shared.playSound(of: .refresh) } .onChange(of: watcher.latestEvent?.id, perform: { _ in if let latestEvent = watcher.latestEvent { diff --git a/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift b/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift index c32ed4f9..83072fb2 100644 --- a/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift +++ b/Packages/Status/Sources/Status/Row/Subviews/StatusRowActionsView.swift @@ -154,12 +154,16 @@ struct StatusRowActionsView: View { switch action { case .respond: viewModel.routerPath.presentedSheet = .replyToStatusEditor(status: viewModel.localStatus ?? viewModel.status) + SoundEffectManager.shared.playSound(of: .share) case .favorite: await statusDataController.toggleFavorite() + SoundEffectManager.shared.playSound(of: .favorite) case .bookmark: await statusDataController.toggleBookmark() + SoundEffectManager.shared.playSound(of: .bookmark) case .boost: await statusDataController.toggleReblog() + SoundEffectManager.shared.playSound(of: .boost) default: break } diff --git a/Packages/Timeline/Sources/Timeline/TimelineView.swift b/Packages/Timeline/Sources/Timeline/TimelineView.swift index 5d8c27ab..efe52aca 100644 --- a/Packages/Timeline/Sources/Timeline/TimelineView.swift +++ b/Packages/Timeline/Sources/Timeline/TimelineView.swift @@ -114,9 +114,11 @@ public struct TimelineView: View { viewModel.isTimelineVisible = false } .refreshable { + SoundEffectManager.shared.playSound(of: .pull) HapticManager.shared.fireHaptic(of: .dataRefresh(intensity: 0.3)) await viewModel.pullToRefresh() HapticManager.shared.fireHaptic(of: .dataRefresh(intensity: 0.7)) + SoundEffectManager.shared.playSound(of: .refresh) } .onChange(of: watcher.latestEvent?.id) { _ in if let latestEvent = watcher.latestEvent {