diff --git a/LiTranslate.xcodeproj/project.pbxproj b/LiTranslate.xcodeproj/project.pbxproj index aa577f4..3ac6966 100644 --- a/LiTranslate.xcodeproj/project.pbxproj +++ b/LiTranslate.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ 4E4E5CCB28A69D76005B5195 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E4E5CCA28A69D76005B5195 /* HomeView.swift */; }; 4E4E5CCD28A69D77005B5195 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4E4E5CCC28A69D77005B5195 /* Assets.xcassets */; }; 4E4E5CD028A69D77005B5195 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4E4E5CCF28A69D77005B5195 /* Preview Assets.xcassets */; }; + 4E6360D2290546C800200706 /* ScrollContentBackgroundModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E6360D1290546C800200706 /* ScrollContentBackgroundModifier.swift */; }; 4E8DC28C28C0CEE0005FC3FB /* LanguageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E8DC28B28C0CEE0005FC3FB /* LanguageView.swift */; }; 4E8DC28E28C20788005FC3FB /* SearchBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E8DC28D28C20788005FC3FB /* SearchBarView.swift */; }; 4E8DC29028C212DB005FC3FB /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E8DC28F28C212DB005FC3FB /* Colors.swift */; }; @@ -66,6 +67,7 @@ 4E4E5CCA28A69D76005B5195 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; 4E4E5CCC28A69D77005B5195 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 4E4E5CCF28A69D77005B5195 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 4E6360D1290546C800200706 /* ScrollContentBackgroundModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollContentBackgroundModifier.swift; sourceTree = ""; }; 4E8DC28B28C0CEE0005FC3FB /* LanguageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageView.swift; sourceTree = ""; }; 4E8DC28D28C20788005FC3FB /* SearchBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBarView.swift; sourceTree = ""; }; 4E8DC28F28C212DB005FC3FB /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = ""; }; @@ -181,9 +183,18 @@ path = "Preview Content"; sourceTree = ""; }; + 4E6360D0290546A400200706 /* Modifiers */ = { + isa = PBXGroup; + children = ( + 4E6360D1290546C800200706 /* ScrollContentBackgroundModifier.swift */, + ); + path = Modifiers; + sourceTree = ""; + }; 4E8E26AA28A6AE780075598D /* Component */ = { isa = PBXGroup; children = ( + 4E6360D0290546A400200706 /* Modifiers */, 4E2D0BF128AEA27D00006797 /* UIViewRepresantable */, 4E8E26C128AA7D4A0075598D /* Languages */, 4EDDD1E528B4017000A634EE /* Settings */, @@ -378,6 +389,7 @@ 4E8E26B928A7A2FB0075598D /* Numbers.swift in Sources */, 4E2D0BFC28AEBB6400006797 /* Keys.swift in Sources */, 4E4E5CC928A69D76005B5195 /* LiTranslateApp.swift in Sources */, + 4E6360D2290546C800200706 /* ScrollContentBackgroundModifier.swift in Sources */, 4E8E26AC28A6B3F10075598D /* ChooseLanguagesView.swift in Sources */, 4EB16E8E28AD189200B0F205 /* ScanButton.swift in Sources */, 4E99599F28B528C000510672 /* LanguagesListView.swift in Sources */, @@ -517,7 +529,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"LiTranslate/Resources/Preview Content\""; DEVELOPMENT_TEAM = Q4KRU37RTG; ENABLE_PREVIEWS = YES; @@ -533,7 +545,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 1.1; PRODUCT_BUNDLE_IDENTIFIER = viktorkalyniuk.LiTranslate; PRODUCT_NAME = LiTranslate; SWIFT_EMIT_LOC_STRINGS = YES; @@ -548,7 +560,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"LiTranslate/Resources/Preview Content\""; DEVELOPMENT_TEAM = Q4KRU37RTG; ENABLE_PREVIEWS = YES; @@ -564,7 +576,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 1.1; PRODUCT_BUNDLE_IDENTIFIER = viktorkalyniuk.LiTranslate; PRODUCT_NAME = LiTranslate; SWIFT_EMIT_LOC_STRINGS = YES; diff --git a/LiTranslate/Application/SpeechSynthesis.swift b/LiTranslate/Application/SpeechSynthesis.swift index 56c8be9..3c12466 100644 --- a/LiTranslate/Application/SpeechSynthesis.swift +++ b/LiTranslate/Application/SpeechSynthesis.swift @@ -8,14 +8,23 @@ import Foundation import AVFoundation -struct SpeechSynthesis { - static func play(_ string: String, language: Languages) { +class SpeechSynthesis { + private let synthesize = AVSpeechSynthesizer() + + func play(_ string: String, language: Languages) { let utterance = AVSpeechUtterance(string: string) + + do { + try AVAudioSession.sharedInstance().setCategory(.playback,mode: .default) + } catch let error { + print("\(error.localizedDescription)") + } + utterance.voice = AVSpeechSynthesisVoice(language: language.rawValue) - AVSpeechSynthesizer().speak(utterance) + synthesize.speak(utterance) } - static func canSynthesis(language: Languages) -> Bool { + func canSynthesis(language: Languages) -> Bool { let speechVoices = AVSpeechSynthesisVoice.speechVoices() for speechVoice in speechVoices { if speechVoice.language.prefix(2) == language.rawValue { diff --git a/LiTranslate/Constants/Links.swift b/LiTranslate/Constants/Links.swift index 2a5d247..a385a6c 100644 --- a/LiTranslate/Constants/Links.swift +++ b/LiTranslate/Constants/Links.swift @@ -24,7 +24,7 @@ struct Links { static let libreTranslateHosting: String = "https://github.com/LibreTranslate/LibreTranslate#install-and-run" static let sourceCode: String = "https://github.com/viktorkalyniuk/LiTranslate-iOS" static let license: String = "https://www.gnu.org/licenses/agpl-3.0.en.html" - static let privacy: String = "https://github.com/viktorkalyniuk/LiTranslate-iOS/blob/dev/PRIVACY.md" + static let privacy: String = "https://github.com/viktorkalyniuk/LiTranslate-iOS/blob/main/PRIVACY.md" static let liTranslateAppStore: String = "https://apps.apple.com/us/app/litranslate/id1644385339" } } diff --git a/LiTranslate/Presentation/BookmarksView.swift b/LiTranslate/Presentation/BookmarksView.swift index 495c647..53546a5 100644 --- a/LiTranslate/Presentation/BookmarksView.swift +++ b/LiTranslate/Presentation/BookmarksView.swift @@ -14,6 +14,13 @@ struct BookmarksView: View { var body: some View { List { + Color(uiColor: Colors.UIColors.Background.main) + .frame(height: 1) + .frame(maxWidth: .infinity) + .listRowInsets(EdgeInsets()) + .listRowSeparatorTint(.clear) + .listRowSeparator(.hidden) + .listRowBackground(Colors.Background.mainView) ForEach(bookmarksData.array, id: \.self) { bookmark in let bookmarkModel = BookmarkModel( inputLanguage: bookmark.inputLanguage, @@ -23,16 +30,20 @@ struct BookmarksView: View { BookmarkView(tabSelection: $tabSelection, bookmarkModel: bookmarkModel) + .listRowBackground(Color.clear) .buttonStyle(.plain) .background(Colors.Background.primaryView) .cornerRadius(CGFloat(Numbers.twentyFive)) + .listRowSeparator(.hidden) } .onDelete { IndexSet in bookmarksData.array.remove(atOffsets: IndexSet) } } + .environment(\.defaultMinListRowHeight, 1) + .modifier(ScrollContentBackgroundModifier()) .background(Color(uiColor: .systemGray5)) - .listStyle(SidebarListStyle()) + .listStyle(.sidebar) } } diff --git a/LiTranslate/Presentation/Component/Languages/BottomButtonsPanels/InputBottomButtons.swift b/LiTranslate/Presentation/Component/Languages/BottomButtonsPanels/InputBottomButtons.swift index e86c57d..a5c3930 100644 --- a/LiTranslate/Presentation/Component/Languages/BottomButtonsPanels/InputBottomButtons.swift +++ b/LiTranslate/Presentation/Component/Languages/BottomButtonsPanels/InputBottomButtons.swift @@ -16,15 +16,17 @@ struct InputBottomButtons: View { private let translateButtonFontSize: CGFloat = CGFloat(Numbers.fourteen) + private let synthesize = SpeechSynthesis() + var body: some View { HStack() { Button { - SpeechSynthesis.play(textData.input, language: selection.input) + synthesize.play(textData.input, language: selection.input) } label: { Image(systemName: SystemNames.speakerWave2) .padding() } - .disabled(!SpeechSynthesis.canSynthesis(language: selection.input)) + .disabled(!synthesize.canSynthesis(language: selection.input)) Button { UIApplication.shared.sendAction(#selector(UIApplication.resignFirstResponder), to: nil, from: nil, for: nil) } label: { diff --git a/LiTranslate/Presentation/Component/Languages/BottomButtonsPanels/OutputBottomButtons.swift b/LiTranslate/Presentation/Component/Languages/BottomButtonsPanels/OutputBottomButtons.swift index 7aa4c22..5bae259 100644 --- a/LiTranslate/Presentation/Component/Languages/BottomButtonsPanels/OutputBottomButtons.swift +++ b/LiTranslate/Presentation/Component/Languages/BottomButtonsPanels/OutputBottomButtons.swift @@ -12,16 +12,18 @@ struct OutputBottomButtons: View { @EnvironmentObject private var textData: TextData @State private var isSharePresented: Bool = false + + private let synthesize = SpeechSynthesis() var body: some View { HStack() { Button { - SpeechSynthesis.play(textData.output, language: selection.output) + synthesize.play(textData.output, language: selection.output) } label: { Image(systemName: SystemNames.speakerWave2) .padding() } - .disabled(!SpeechSynthesis.canSynthesis(language: selection.output)) + .disabled(!synthesize.canSynthesis(language: selection.output)) Spacer() Button { UIPasteboard.general.string = textData.output diff --git a/LiTranslate/Presentation/Component/Languages/InputTranslationView.swift b/LiTranslate/Presentation/Component/Languages/InputTranslationView.swift index cfe332c..46710cc 100644 --- a/LiTranslate/Presentation/Component/Languages/InputTranslationView.swift +++ b/LiTranslate/Presentation/Component/Languages/InputTranslationView.swift @@ -20,6 +20,7 @@ struct InputTranslationView: View, KeyboardReadable { .background(Colors.Background.chooseLanguageView.ignoresSafeArea()) HStack(alignment: .top) { TextEditor(text: $textData.input) + .modifier(ScrollContentBackgroundModifier()) .padding([.leading, .trailing]) .onReceive(keyboardPublisher) { isVisible in isKeyboardVisible = isVisible diff --git a/LiTranslate/Presentation/Component/Languages/LanguagesListView.swift b/LiTranslate/Presentation/Component/Languages/LanguagesListView.swift index 1da0848..eb8987c 100644 --- a/LiTranslate/Presentation/Component/Languages/LanguagesListView.swift +++ b/LiTranslate/Presentation/Component/Languages/LanguagesListView.swift @@ -71,6 +71,7 @@ struct LanguagesListView: View { } .textCase(nil) } + .modifier(ScrollContentBackgroundModifier()) .id(listID) .background(Colors.Background.mainView) .navigationBarTitleDisplayMode(.inline) diff --git a/LiTranslate/Presentation/Component/Modifiers/ScrollContentBackgroundModifier.swift b/LiTranslate/Presentation/Component/Modifiers/ScrollContentBackgroundModifier.swift new file mode 100644 index 0000000..20bb36f --- /dev/null +++ b/LiTranslate/Presentation/Component/Modifiers/ScrollContentBackgroundModifier.swift @@ -0,0 +1,23 @@ +// +// ScrollContentBackgroundModifier.swift +// LiTranslate +// +// Created by Marian König. +// Found on: +// https://stackoverflow.com/questions/72649907/ios-16-swiftui-list-background. +// + +import SwiftUI + +struct ScrollContentBackgroundModifier: ViewModifier { + + @ViewBuilder + func body(content: Content) -> some View { + if #available(iOS 16.0, *) { + content + .scrollContentBackground(.hidden) + } else { + content + } + } +} diff --git a/LiTranslate/Presentation/Component/Settings/SelfHostingView.swift b/LiTranslate/Presentation/Component/Settings/SelfHostingView.swift index 9f22a6c..150b318 100644 --- a/LiTranslate/Presentation/Component/Settings/SelfHostingView.swift +++ b/LiTranslate/Presentation/Component/Settings/SelfHostingView.swift @@ -55,6 +55,7 @@ struct SelfHostingView: View { .listRowBackground(Colors.Background.primaryView) .textCase(nil) } + .modifier(ScrollContentBackgroundModifier()) .background(Colors.Background.mainView) .toolbar { Button { diff --git a/LiTranslate/Presentation/ContentView.swift b/LiTranslate/Presentation/ContentView.swift index 30b4347..66842fe 100644 --- a/LiTranslate/Presentation/ContentView.swift +++ b/LiTranslate/Presentation/ContentView.swift @@ -48,7 +48,7 @@ struct ContentView: View { .environmentObject(instance) .environmentObject(recentlyUsedLanguages) .tabItem { - Image(Names.Images.liTranslateIcon).font(.system(size: 28)) + Image(Names.Images.liTranslateIcon).font(.system(.title)) Text(Names.translateTabItemName) } .tag(Numbers.one) diff --git a/LiTranslate/Presentation/SettingsView.swift b/LiTranslate/Presentation/SettingsView.swift index 57f03fa..344ccd5 100644 --- a/LiTranslate/Presentation/SettingsView.swift +++ b/LiTranslate/Presentation/SettingsView.swift @@ -53,6 +53,7 @@ struct SettingsView: View { } .textCase(nil) } + .modifier(ScrollContentBackgroundModifier()) .background(Colors.Background.mainView) } } diff --git a/README.md b/README.md index 0b76830..05ae87c 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ LiTranslate is an application which purpose is a convenient use of open source t ## For developers Any help to improve this application will be appreciated:)\ +Please PR to the dev branch (without assets).\ Assets can be found on [assets branch](https://github.com/viktorkalyniuk/LiTranslate-iOS/tree/assets). ## Licence