diff --git a/Linphone.xcodeproj/project.pbxproj b/Linphone.xcodeproj/project.pbxproj index f086c50b4..47c1b6328 100644 --- a/Linphone.xcodeproj/project.pbxproj +++ b/Linphone.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ D74C9CFC2ACACF370021626A /* WelcomePage3Fragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74C9CFB2ACACF370021626A /* WelcomePage3Fragment.swift */; }; D74C9CFF2ACAEC5E0021626A /* PopupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74C9CFE2ACAEC5E0021626A /* PopupView.swift */; }; D74C9D012ACB098C0021626A /* PermissionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74C9D002ACB098C0021626A /* PermissionManager.swift */; }; + D750D3392AD3E6EE00EC99C5 /* PopupLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D750D3382AD3E6EE00EC99C5 /* PopupLoadingView.swift */; }; D7702EF22AC7205000557C00 /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7702EF12AC7205000557C00 /* WelcomeView.swift */; }; D7A03FBD2ACC2DB60081A588 /* ContactsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A03FBC2ACC2DB60081A588 /* ContactsView.swift */; }; D7A03FC02ACC2E390081A588 /* HistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7A03FBF2ACC2E390081A588 /* HistoryView.swift */; }; @@ -42,6 +43,7 @@ D7D24D182AC1B4E800C6F35B /* NotoSans-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7D24D122AC1B4E800C6F35B /* NotoSans-ExtraBold.ttf */; }; D7DA67622ACCB2FA00E95002 /* LoginFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DA67612ACCB2FA00E95002 /* LoginFragment.swift */; }; D7DA67642ACCB31700E95002 /* ProfileModeFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DA67632ACCB31700E95002 /* ProfileModeFragment.swift */; }; + D7FB55112AD447FD00A5AB15 /* RegisterFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7FB55102AD447FD00A5AB15 /* RegisterFragment.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -70,6 +72,7 @@ D74C9CFB2ACACF370021626A /* WelcomePage3Fragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomePage3Fragment.swift; sourceTree = ""; }; D74C9CFE2ACAEC5E0021626A /* PopupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupView.swift; sourceTree = ""; }; D74C9D002ACB098C0021626A /* PermissionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermissionManager.swift; sourceTree = ""; }; + D750D3382AD3E6EE00EC99C5 /* PopupLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupLoadingView.swift; sourceTree = ""; }; D7702EF12AC7205000557C00 /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = ""; }; D7A03FBC2ACC2DB60081A588 /* ContactsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsView.swift; sourceTree = ""; }; D7A03FBF2ACC2E390081A588 /* HistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryView.swift; sourceTree = ""; }; @@ -84,6 +87,7 @@ D7D24D122AC1B4E800C6F35B /* NotoSans-ExtraBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSans-ExtraBold.ttf"; sourceTree = ""; }; D7DA67612ACCB2FA00E95002 /* LoginFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginFragment.swift; sourceTree = ""; }; D7DA67632ACCB31700E95002 /* ProfileModeFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileModeFragment.swift; sourceTree = ""; }; + D7FB55102AD447FD00A5AB15 /* RegisterFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterFragment.swift; sourceTree = ""; }; FBDE73581C1DC4F98CC3DF3A /* Pods-Linphone.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Linphone.debug.xcconfig"; path = "Target Support Files/Pods-Linphone/Pods-Linphone.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -235,6 +239,7 @@ children = ( D74C9CFE2ACAEC5E0021626A /* PopupView.swift */, D72343352AD037AF009AA24E /* ToastView.swift */, + D750D3382AD3E6EE00EC99C5 /* PopupLoadingView.swift */, ); path = Fragments; sourceTree = ""; @@ -293,6 +298,7 @@ D748BF2B2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift */, D748BF2D2ACD82E7004844EB /* ThirdPartySipAccountWarningFragment.swift */, D723432F2ACEFEF8009AA24E /* QrCodeScannerFragment.swift */, + D7FB55102AD447FD00A5AB15 /* RegisterFragment.swift */, ); path = Fragments; sourceTree = ""; @@ -420,6 +426,7 @@ files = ( D71707202AC5989C0037746F /* TextExtension.swift in Sources */, D719ABB92ABC67BF00B41C10 /* ContentView.swift in Sources */, + D750D3392AD3E6EE00EC99C5 /* PopupLoadingView.swift in Sources */, D719ABC92ABC6FD700B41C10 /* CoreContext.swift in Sources */, D7A03FBD2ACC2DB60081A588 /* ContactsView.swift in Sources */, D719ABCF2ABC779A00B41C10 /* AccountLoginViewModel.swift in Sources */, @@ -433,6 +440,7 @@ D748BF2C2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift in Sources */, D74C9CF82ACACECE0021626A /* WelcomePage1Fragment.swift in Sources */, D72343362AD037AF009AA24E /* ToastView.swift in Sources */, + D7FB55112AD447FD00A5AB15 /* RegisterFragment.swift in Sources */, D72343322ACEFF58009AA24E /* QRScannerController.swift in Sources */, D72343342ACEFFC3009AA24E /* QRScanner.swift in Sources */, D72343302ACEFEF8009AA24E /* QrCodeScannerFragment.swift in Sources */, diff --git a/Linphone/Core/CoreContext.swift b/Linphone/Core/CoreContext.swift index 444526dac..cfa03dd68 100644 --- a/Linphone/Core/CoreContext.swift +++ b/Linphone/Core/CoreContext.swift @@ -29,7 +29,8 @@ final class CoreContext : ObservableObject { var coreVersion: String = Core.getVersion @Published var loggedIn : Bool = false - @Published var configuringSuccessful : String = "" + @Published var loggingInProgress : Bool = false + @Published var toastMessage : String = "" private init() {} @@ -49,9 +50,9 @@ final class CoreContext : ObservableObject { onConfiguringStatus: { (core: Core, state: Config.ConfiguringState, message: String) in NSLog("New configuration state is \(state) = \(message)\n") if (state == .Successful) { - self.configuringSuccessful = "Successful" + self.toastMessage = "Successful" } else { - self.configuringSuccessful = "Failed" + self.toastMessage = "Failed" } }, @@ -60,8 +61,13 @@ final class CoreContext : ObservableObject { // Otherwise, we will be Failed. NSLog("New registration state is \(state) for user id \( String(describing: account.params?.identityAddress?.asString()))\n") if (state == .Ok) { + self.loggingInProgress = false self.loggedIn = true - } else if (state == .Cleared) { + } else if (state == .Progress) { + self.loggingInProgress = true + } else { + self.toastMessage = "Registration failed" + self.loggingInProgress = false self.loggedIn = false } } diff --git a/Linphone/LinphoneApp.swift b/Linphone/LinphoneApp.swift index e63f62ae4..56b0c0ad3 100644 --- a/Linphone/LinphoneApp.swift +++ b/Linphone/LinphoneApp.swift @@ -29,7 +29,7 @@ struct LinphoneApp: App { WindowGroup { if isActive { ContentView(sharedMainViewModel: SharedMainViewModel()) - .toast(isShowing: $coreContext.configuringSuccessful) + .toast(isShowing: $coreContext.toastMessage) }else { SplashScreen(isActive: $isActive) } diff --git a/Linphone/Localizable.xcstrings b/Linphone/Localizable.xcstrings index de219faee..c46a0bdf1 100644 --- a/Linphone/Localizable.xcstrings +++ b/Linphone/Localizable.xcstrings @@ -140,6 +140,9 @@ } } } + }, + "Error" : { + }, "History View" : { @@ -176,6 +179,9 @@ }, "Open source" : { + }, + "Opération en cours..." : { + }, "password" : { "extractionState" : "manual", @@ -229,6 +235,9 @@ }, "Texte explicatif du interoperable mode : lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam velit sapien, egestas sit amet dictum eget, condimentum a ligula." : { + }, + "The user name or password is incorrects" : { + }, "TLS" : { diff --git a/Linphone/SplashScreen.swift b/Linphone/SplashScreen.swift index cbcc3298b..4f537a833 100644 --- a/Linphone/SplashScreen.swift +++ b/Linphone/SplashScreen.swift @@ -1,9 +1,21 @@ -// -// SplashScreen.swift -// Linphone -// -// Created by Benoît Martins on 03/10/2023. -// +/* +* Copyright (c) 2010-2023 Belledonne Communications SARL. +* +* This file is part of Linphone +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ import SwiftUI diff --git a/Linphone/UI/Assistant/AssistantView.swift b/Linphone/UI/Assistant/AssistantView.swift index a974cce31..57da277ae 100644 --- a/Linphone/UI/Assistant/AssistantView.swift +++ b/Linphone/UI/Assistant/AssistantView.swift @@ -22,13 +22,14 @@ import SwiftUI struct AssistantView: View { @ObservedObject var sharedMainViewModel : SharedMainViewModel + @ObservedObject private var coreContext = CoreContext.shared var body: some View { - if sharedMainViewModel.displayProfileMode != true { - LoginFragment(accountLoginViewModel: AccountLoginViewModel(), sharedMainViewModel: sharedMainViewModel) - } else { + if (sharedMainViewModel.displayProfileMode && coreContext.loggedIn){ ProfileModeFragment(sharedMainViewModel: sharedMainViewModel) - } + } else { + LoginFragment(accountLoginViewModel: AccountLoginViewModel(), sharedMainViewModel: sharedMainViewModel) + } } } diff --git a/Linphone/UI/Assistant/Fragments/LoginFragment.swift b/Linphone/UI/Assistant/Fragments/LoginFragment.swift index 10c3c9201..d11ff1b79 100644 --- a/Linphone/UI/Assistant/Fragments/LoginFragment.swift +++ b/Linphone/UI/Assistant/Fragments/LoginFragment.swift @@ -20,222 +20,305 @@ import SwiftUI struct LoginFragment: View { - - @ObservedObject private var coreContext = CoreContext.shared - @ObservedObject var accountLoginViewModel : AccountLoginViewModel - @ObservedObject var sharedMainViewModel : SharedMainViewModel - - @State private var isSecured: Bool = true - - @FocusState var isNameFocused:Bool - @FocusState var isPasswordFocused:Bool - - var body: some View { - NavigationView { - GeometryReader { geometry in - ScrollView(.vertical) { - VStack { - ZStack { - Image("mountain") - .resizable() - .scaledToFill() - .frame(width: geometry.size.width, height: 100) - .clipped() - Text("assistant_account_login") - .default_text_style_white_800(styleSize: 20) - .padding(.top, 20) - } - .padding(.top, 35) - .padding(.bottom, 10) - - VStack(alignment: .leading) { - Text(String(localized: "username")+"*") - .default_text_style_700(styleSize: 15) - .padding(.bottom, -5) - - TextField("username", text : $accountLoginViewModel.username) - .default_text_style(styleSize: 15) - .disabled(coreContext.loggedIn) - .frame(height: 25) - .padding(.horizontal, 20) - .padding(.vertical, 15) - .cornerRadius(60) - .overlay( - RoundedRectangle(cornerRadius: 60) - .inset(by: 0.5) - .stroke(isNameFocused ? Color.orange_main_500 : Color.gray_200, lineWidth: 1) - ) - .padding(.bottom) - .focused($isNameFocused) - - Text(String(localized: "password")+"*") - .default_text_style_700(styleSize: 15) - .padding(.bottom, -5) - - ZStack(alignment: .trailing) { - Group { - if isSecured { - SecureField("password", text: $accountLoginViewModel.passwd) - .default_text_style(styleSize: 15) - .frame(height: 25) - .focused($isPasswordFocused) - } else { - TextField("password", text: $accountLoginViewModel.passwd) - .default_text_style(styleSize: 15) - .frame(height: 25) - .focused($isPasswordFocused) - } - } - Button(action: { - isSecured.toggle() - }) { - Image(self.isSecured ? "eye-slash" : "eye") - .renderingMode(.template) - .resizable() - .foregroundStyle(Color.gray_main2_500) - .frame(width: 20, height: 20) - } - } - .disabled(coreContext.loggedIn) - .padding(.horizontal, 20) - .padding(.vertical, 15) - .cornerRadius(60) - .overlay( - RoundedRectangle(cornerRadius: 60) - .inset(by: 0.5) - .stroke(isPasswordFocused ? Color.orange_main_500 : Color.gray_200, lineWidth: 1) - ) - .padding(.bottom) - - Button(action: { - sharedMainViewModel.displayProfileMode = true - if (self.coreContext.loggedIn){ - self.accountLoginViewModel.unregister() - self.accountLoginViewModel.delete() - } else { - self.accountLoginViewModel.login() - } - }) { - Text(coreContext.loggedIn ? "Log out" : "assistant_account_login") - .default_text_style_white_600(styleSize: 20) - .frame(height: 35) - .frame(maxWidth: .infinity) - } - .padding(.horizontal, 20) - .padding(.vertical, 10) - .background((accountLoginViewModel.username.isEmpty || accountLoginViewModel.passwd.isEmpty) ? Color.orange_main_100 : Color.orange_main_500) - .cornerRadius(60) - .disabled(accountLoginViewModel.username.isEmpty || accountLoginViewModel.passwd.isEmpty) - .padding(.bottom) - - HStack { - Text("[Forgotten password?](https://subscribe.linphone.org/)") - .underline() - .tint(Color.gray_main2_600) - .default_text_style_600(styleSize: 15) - .foregroundStyle(Color.gray_main2_500) - } - .frame(maxWidth: .infinity) - .padding(.bottom, 30) - - HStack { - VStack{ - Divider() - } - Text(" or ") - .default_text_style(styleSize: 15) - .foregroundStyle(Color.gray_main2_500) - VStack{ - Divider() - } - } - .padding(.bottom, 10) + + @ObservedObject private var coreContext = CoreContext.shared + @ObservedObject var accountLoginViewModel : AccountLoginViewModel + @ObservedObject var sharedMainViewModel : SharedMainViewModel + + @State private var isSecured: Bool = true + + @FocusState var isNameFocused:Bool + @FocusState var isPasswordFocused:Bool + + @State private var isShowPopup = false + + @State private var linkActive = "" + + @State private var isLinkQRActive = false + @State private var isLinkSIPActive = false + @State private var isLinkREGActive = false + + var body: some View { + NavigationView { + ZStack { + GeometryReader { geometry in + ScrollView(.vertical) { + VStack { + ZStack { + Image("mountain") + .resizable() + .scaledToFill() + .frame(width: geometry.size.width, height: 100) + .clipped() + Text("assistant_account_login") + .default_text_style_white_800(styleSize: 20) + .padding(.top, 20) + } + .padding(.top, 35) + .padding(.bottom, 10) - NavigationLink(destination: { - QrCodeScannerFragment() - }, label: { - HStack { - Image("qr-code") - .renderingMode(.template) - .resizable() - .foregroundStyle(Color.orange_main_500) - .frame(width: 20, height: 20) - - Text("Scan QR code") - .default_text_style_orange_600(styleSize: 20) + VStack(alignment: .leading) { + Text(String(localized: "username")+"*") + .default_text_style_700(styleSize: 15) + .padding(.bottom, -5) + + TextField("username", text : $accountLoginViewModel.username) + .default_text_style(styleSize: 15) + .disabled(coreContext.loggedIn) + .frame(height: 25) + .padding(.horizontal, 20) + .padding(.vertical, 15) + .cornerRadius(60) + .overlay( + RoundedRectangle(cornerRadius: 60) + .inset(by: 0.5) + .stroke(isNameFocused ? Color.orange_main_500 : Color.gray_200, lineWidth: 1) + ) + .padding(.bottom) + .focused($isNameFocused) + + Text(String(localized: "password")+"*") + .default_text_style_700(styleSize: 15) + .padding(.bottom, -5) + + ZStack(alignment: .trailing) { + Group { + if isSecured { + SecureField("password", text: $accountLoginViewModel.passwd) + .default_text_style(styleSize: 15) + .frame(height: 25) + .focused($isPasswordFocused) + } else { + TextField("password", text: $accountLoginViewModel.passwd) + .default_text_style(styleSize: 15) + .frame(height: 25) + .focused($isPasswordFocused) + } + } + Button(action: { + isSecured.toggle() + }) { + Image(self.isSecured ? "eye-slash" : "eye") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.gray_main2_500) + .frame(width: 20, height: 20) + } + } + .disabled(coreContext.loggedIn) + .padding(.horizontal, 20) + .padding(.vertical, 15) + .cornerRadius(60) + .overlay( + RoundedRectangle(cornerRadius: 60) + .inset(by: 0.5) + .stroke(isPasswordFocused ? Color.orange_main_500 : Color.gray_200, lineWidth: 1) + ) + .padding(.bottom) + + Button(action: { + if (self.coreContext.loggedIn){ + self.accountLoginViewModel.unregister() + self.accountLoginViewModel.delete() + } else { + self.accountLoginViewModel.login() + } + }) { + Text(coreContext.loggedIn ? "Log out" : "assistant_account_login") + .default_text_style_white_600(styleSize: 20) .frame(height: 35) + .frame(maxWidth: .infinity) + } + .padding(.horizontal, 20) + .padding(.vertical, 10) + .background((accountLoginViewModel.username.isEmpty || accountLoginViewModel.passwd.isEmpty) ? Color.orange_main_100 : Color.orange_main_500) + .cornerRadius(60) + .disabled(accountLoginViewModel.username.isEmpty || accountLoginViewModel.passwd.isEmpty) + .padding(.bottom) + + HStack { + Text("[Forgotten password?](https://subscribe.linphone.org/)") + .underline() + .tint(Color.gray_main2_600) + .default_text_style_600(styleSize: 15) + .foregroundStyle(Color.gray_main2_500) } .frame(maxWidth: .infinity) + .padding(.bottom, 30) - }) + HStack { + VStack{ + Divider() + } + Text(" or ") + .default_text_style(styleSize: 15) + .foregroundStyle(Color.gray_main2_500) + VStack{ + Divider() + } + } + .padding(.bottom, 10) + + NavigationLink(isActive: $isLinkQRActive, destination: { + QrCodeScannerFragment() + }, label: { + HStack { + Image("qr-code") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orange_main_500) + .frame(width: 20, height: 20) + + Text("Scan QR code") + .default_text_style_orange_600(styleSize: 20) + .frame(height: 35) + } + .frame(maxWidth: .infinity) + + }) + .disabled(!sharedMainViewModel.generalTermsAccepted) + .padding(.horizontal, 20) + .padding(.vertical, 10) + .cornerRadius(60) + .overlay( + RoundedRectangle(cornerRadius: 60) + .inset(by: 0.5) + .stroke(Color.orange_main_500, lineWidth: 1) + ) + .padding(.bottom) + .simultaneousGesture(TapGesture().onEnded{ + self.linkActive = "QR" + if !sharedMainViewModel.generalTermsAccepted { + withAnimation { + self.isShowPopup.toggle() + } + } else { + self.isLinkQRActive = true + } + }) + + NavigationLink(isActive: $isLinkSIPActive, destination: { + ThirdPartySipAccountWarningFragment(sharedMainViewModel: sharedMainViewModel, accountLoginViewModel: accountLoginViewModel) + }, label: { + Text("Use SIP Account") + .default_text_style_orange_600(styleSize: 20) + .frame(height: 35) + .frame(maxWidth: .infinity) + + }) + .disabled(!sharedMainViewModel.generalTermsAccepted) + .padding(.horizontal, 20) + .padding(.vertical, 10) + .cornerRadius(60) + .overlay( + RoundedRectangle(cornerRadius: 60) + .inset(by: 0.5) + .stroke(Color.orange_main_500, lineWidth: 1) + ) + .padding(.bottom) + .simultaneousGesture(TapGesture().onEnded{ + self.linkActive = "SIP" + if !sharedMainViewModel.generalTermsAccepted { + withAnimation { + self.isShowPopup.toggle() + } + } else { + self.isLinkSIPActive = true + } + }) + + Spacer() + + HStack(alignment: .center) { + + Spacer() + + Text("Not account yet?") + .default_text_style(styleSize: 15) + .foregroundStyle(Color.gray_main2_700) + .padding(.horizontal, 10) + + NavigationLink(destination: RegisterFragment(), isActive: $isLinkREGActive, label: {Text("Register") + .default_text_style_orange_600(styleSize: 20) + .frame(height: 35) + }) + .disabled(!sharedMainViewModel.generalTermsAccepted) + .padding(.horizontal, 20) + .padding(.vertical, 10) + .cornerRadius(60) + .overlay( + RoundedRectangle(cornerRadius: 60) + .inset(by: 0.5) + .stroke(Color.orange_main_500, lineWidth: 1) + ) + .padding(.horizontal, 10) + .simultaneousGesture(TapGesture().onEnded{ + self.linkActive = "REG" + if !sharedMainViewModel.generalTermsAccepted { + withAnimation { + self.isShowPopup.toggle() + } + } else { + self.isLinkREGActive = true + } + }) + + Spacer() + } + .padding(.bottom) + } + .frame(maxWidth: sharedMainViewModel.maxWidth) .padding(.horizontal, 20) - .padding(.vertical, 10) - .cornerRadius(60) - .overlay( - RoundedRectangle(cornerRadius: 60) - .inset(by: 0.5) - .stroke(Color.orange_main_500, lineWidth: 1) - ) - .padding(.bottom) - - NavigationLink(destination: { - ThirdPartySipAccountWarningFragment(accountLoginViewModel: accountLoginViewModel) - }, label: { - Text("Use SIP Account") - .default_text_style_orange_600(styleSize: 20) - .frame(height: 35) - .frame(maxWidth: .infinity) - - }) - .padding(.horizontal, 20) - .padding(.vertical, 10) - .cornerRadius(60) - .overlay( - RoundedRectangle(cornerRadius: 60) - .inset(by: 0.5) - .stroke(Color.orange_main_500, lineWidth: 1) - ) - .padding(.bottom) - - HStack(alignment: .center) { - - Spacer() - - Text("Not account yet?") - .default_text_style(styleSize: 15) - .foregroundStyle(Color.gray_main2_700) - .padding(.horizontal, 10) - - Button(action: { - - }) { - Text("Register") - .default_text_style_orange_600(styleSize: 20) - .frame(height: 35) - } - .padding(.horizontal, 20) - .padding(.vertical, 10) - .cornerRadius(60) - .overlay( - RoundedRectangle(cornerRadius: 60) - .inset(by: 0.5) - .stroke(Color.orange_main_500, lineWidth: 1) - ) - .padding(.horizontal, 10) - - Spacer() - } - .padding(.bottom) - } - .padding(.horizontal, 20) - } - } - } - } + } + .frame(minHeight: geometry.size.height) + } + + if self.isShowPopup { + PopupView(sharedMainViewModel: sharedMainViewModel, isShowPopup: $isShowPopup, title: Text("Conditions de service"), content: Text("En continuant, vous acceptez ces conditions, \(Text("[notre politique de confidentialité](https://linphone.org/privacy-policy)").underline()) et \(Text("[nos conditions d’utilisation](https://linphone.org/general-terms)").underline())."), titleFirstButton: Text("Deny all"), actionFirstButton: {self.isShowPopup.toggle()}, titleSecondButton: Text("Accept all"), actionSecondButton: {acceptGeneralTerms()}) + .background(.black.opacity(0.65)) + .onTapGesture { + self.isShowPopup.toggle() + } + } + } + .onAppear{ + sharedMainViewModel.changeDisplayProfileMode() + } + + if coreContext.loggingInProgress { + PopupLoadingView(sharedMainViewModel: sharedMainViewModel) + .background(.black.opacity(0.65)) + } + + if !coreContext.loggingInProgress && !coreContext.loggedIn { + ZStack{ + + }.onAppear { + self.accountLoginViewModel.unregister() + self.accountLoginViewModel.delete() + } + } + } + } .navigationViewStyle(StackNavigationViewStyle()) - } + } + + func acceptGeneralTerms(){ + sharedMainViewModel.changeGeneralTerms() + self.isShowPopup.toggle() + switch linkActive { + case "QR": + self.isLinkQRActive = true + case "SIP": + self.isLinkSIPActive = true + case "REG": + self.isLinkREGActive = true + default: + print("Link Not Active") + } + } } #Preview { - LoginFragment(accountLoginViewModel: AccountLoginViewModel(), sharedMainViewModel: SharedMainViewModel()) + LoginFragment(accountLoginViewModel: AccountLoginViewModel(), sharedMainViewModel: SharedMainViewModel()) } diff --git a/Linphone/UI/Assistant/Fragments/ProfileModeFragment.swift b/Linphone/UI/Assistant/Fragments/ProfileModeFragment.swift index 447fae4e8..8f07c6c28 100644 --- a/Linphone/UI/Assistant/Fragments/ProfileModeFragment.swift +++ b/Linphone/UI/Assistant/Fragments/ProfileModeFragment.swift @@ -114,12 +114,13 @@ struct ProfileModeFragment: View { .background(Color.gray_100) .cornerRadius(15) } + .frame(maxWidth: sharedMainViewModel.maxWidth) .padding() Spacer() Button(action: { - sharedMainViewModel.displayProfileMode = false + sharedMainViewModel.changeHideProfileMode() }) { Text("Continue") .default_text_style_white_600(styleSize: 20) @@ -131,12 +132,17 @@ struct ProfileModeFragment: View { .background(Color.orange_main_500) .cornerRadius(60) .padding(.horizontal) + .padding(.bottom, geometry.safeAreaInsets.bottom.isEqual(to: 0.0) ? 20 : 0) + .frame(maxWidth: sharedMainViewModel.maxWidth) } .frame(minHeight: geometry.size.height) } + .onAppear { + UserDefaults.standard.set(false, forKey: "display_profile_mode") + } if self.isShowPopup { - PopupView(isShowPopup: $isShowPopup, title: Text(isShowPopupForDefault ? "Default mode" : "Interoperable mode"), content: Text(isShowPopupForDefault ? "Texte explicatif du default mode : lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam velit sapien, egestas sit amet dictum eget, condimentum a ligula." : "Texte explicatif du interoperable mode : lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam velit sapien, egestas sit amet dictum eget, condimentum a ligula."), titleFirstButton: nil, actionFirstButton: {}, titleSecondButton: Text("Close"), actionSecondButton: {self.isShowPopup.toggle()}) + PopupView(sharedMainViewModel: sharedMainViewModel, isShowPopup: $isShowPopup, title: Text(isShowPopupForDefault ? "Default mode" : "Interoperable mode"), content: Text(isShowPopupForDefault ? "Texte explicatif du default mode : lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam velit sapien, egestas sit amet dictum eget, condimentum a ligula." : "Texte explicatif du interoperable mode : lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam velit sapien, egestas sit amet dictum eget, condimentum a ligula."), titleFirstButton: nil, actionFirstButton: {}, titleSecondButton: Text("Close"), actionSecondButton: {self.isShowPopup.toggle()}) .background(.black.opacity(0.65)) .onTapGesture { self.isShowPopup.toggle() diff --git a/Linphone/UI/Assistant/Fragments/QrCodeScannerFragment.swift b/Linphone/UI/Assistant/Fragments/QrCodeScannerFragment.swift index 03f9fe288..08bde763e 100644 --- a/Linphone/UI/Assistant/Fragments/QrCodeScannerFragment.swift +++ b/Linphone/UI/Assistant/Fragments/QrCodeScannerFragment.swift @@ -1,9 +1,21 @@ -// -// QrCodeScannerFragment.swift -// Linphone -// -// Created by Benoît Martins on 05/10/2023. -// +/* +* Copyright (c) 2010-2023 Belledonne Communications SARL. +* +* This file is part of Linphone +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ import SwiftUI @@ -42,7 +54,7 @@ struct QrCodeScannerFragment: View { .edgesIgnoringSafeArea(.all) .navigationBarHidden(true) - if coreContext.configuringSuccessful == "Successful" { + if coreContext.toastMessage == "Successful" { ZStack{ }.onAppear { diff --git a/Linphone/UI/Assistant/Fragments/RegisterFragment.swift b/Linphone/UI/Assistant/Fragments/RegisterFragment.swift new file mode 100644 index 000000000..ac7146ce7 --- /dev/null +++ b/Linphone/UI/Assistant/Fragments/RegisterFragment.swift @@ -0,0 +1,64 @@ +// +// RegisterFragment.swift +// Linphone +// +// Created by Benoît Martins on 09/10/2023. +// + +import SwiftUI + +struct RegisterFragment: View { + + @Environment(\.dismiss) var dismiss + + var body: some View { + NavigationView { + GeometryReader { geometry in + ScrollView(.vertical) { + VStack { + ZStack { + Image("mountain") + .resizable() + .scaledToFill() + .frame(width: geometry.size.width, height: 100) + .clipped() + + VStack (alignment: .leading) { + HStack { + Image("caret-left") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.gray_main2_500) + .frame(width: 25, height: 25, alignment: .leading) + .padding(.top, -65) + .onTapGesture { + withAnimation { + dismiss() + } + } + + Spacer() + } + .padding(.leading) + } + .frame(width: geometry.size.width) + + Text("Register") + .default_text_style_white_800(styleSize: 20) + .padding(.top, 20) + } + .padding(.top, 35) + .padding(.bottom, 10) + + } + } + } + } + .navigationViewStyle(StackNavigationViewStyle()) + .navigationBarHidden(true) + } +} + +#Preview { + RegisterFragment() +} diff --git a/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountLoginFragment.swift b/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountLoginFragment.swift index e2a80eff9..77aeacdf6 100644 --- a/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountLoginFragment.swift +++ b/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountLoginFragment.swift @@ -20,7 +20,8 @@ import SwiftUI struct ThirdPartySipAccountLoginFragment: View { - + + @ObservedObject var sharedMainViewModel : SharedMainViewModel @ObservedObject private var coreContext = CoreContext.shared @ObservedObject var accountLoginViewModel : AccountLoginViewModel @@ -222,7 +223,9 @@ struct ThirdPartySipAccountLoginFragment: View { .background((accountLoginViewModel.username.isEmpty || accountLoginViewModel.passwd.isEmpty || accountLoginViewModel.domain.isEmpty) ? Color.orange_main_100 : Color.orange_main_500) .cornerRadius(60) .disabled(accountLoginViewModel.username.isEmpty || accountLoginViewModel.passwd.isEmpty || accountLoginViewModel.domain.isEmpty) + .padding(.bottom, geometry.safeAreaInsets.bottom.isEqual(to: 0.0) ? 20 : 0) } + .frame(maxWidth: sharedMainViewModel.maxWidth) .padding(.horizontal, 20) } .frame(minHeight: geometry.size.height) @@ -233,5 +236,5 @@ struct ThirdPartySipAccountLoginFragment: View { } #Preview { - ThirdPartySipAccountLoginFragment(accountLoginViewModel: AccountLoginViewModel()) + ThirdPartySipAccountLoginFragment(sharedMainViewModel: SharedMainViewModel(), accountLoginViewModel: AccountLoginViewModel()) } diff --git a/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountWarningFragment.swift b/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountWarningFragment.swift index 98b8c6478..63fe6d911 100644 --- a/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountWarningFragment.swift +++ b/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountWarningFragment.swift @@ -20,7 +20,8 @@ import SwiftUI struct ThirdPartySipAccountWarningFragment: View { - + + @ObservedObject var sharedMainViewModel : SharedMainViewModel @ObservedObject private var coreContext = CoreContext.shared @ObservedObject var accountLoginViewModel : AccountLoginViewModel @@ -134,6 +135,7 @@ struct ThirdPartySipAccountWarningFragment: View { } .padding(.vertical) } + .frame(maxWidth: sharedMainViewModel.maxWidth) .padding(.horizontal, 20) Spacer() @@ -154,10 +156,11 @@ struct ThirdPartySipAccountWarningFragment: View { .inset(by: 0.5) .stroke(Color.orange_main_500, lineWidth: 1) ) + .frame(maxWidth: sharedMainViewModel.maxWidth) .padding(.horizontal) NavigationLink(destination: { - ThirdPartySipAccountLoginFragment(accountLoginViewModel: accountLoginViewModel) + ThirdPartySipAccountLoginFragment(sharedMainViewModel: sharedMainViewModel, accountLoginViewModel: accountLoginViewModel) }, label: { Text("I understand") .default_text_style_white_600(styleSize: 20) @@ -169,7 +172,9 @@ struct ThirdPartySipAccountWarningFragment: View { .padding(.vertical, 10) .background(Color.orange_main_500) .cornerRadius(60) + .frame(maxWidth: sharedMainViewModel.maxWidth) .padding(.horizontal) + .padding(.bottom, geometry.safeAreaInsets.bottom.isEqual(to: 0.0) ? 20 : 0) } .frame(minHeight: geometry.size.height) } @@ -181,5 +186,5 @@ struct ThirdPartySipAccountWarningFragment: View { } #Preview { - ThirdPartySipAccountWarningFragment(accountLoginViewModel: AccountLoginViewModel()) + ThirdPartySipAccountWarningFragment(sharedMainViewModel: SharedMainViewModel(), accountLoginViewModel: AccountLoginViewModel()) } diff --git a/Linphone/UI/Assistant/Viewmodel/QRScanner.swift b/Linphone/UI/Assistant/Viewmodel/QRScanner.swift index 3e9b46419..2d754e89d 100644 --- a/Linphone/UI/Assistant/Viewmodel/QRScanner.swift +++ b/Linphone/UI/Assistant/Viewmodel/QRScanner.swift @@ -1,9 +1,21 @@ -// -// QRScanner.swift -// Linphone -// -// Created by Benoît Martins on 05/10/2023. -// +/* +* Copyright (c) 2010-2023 Belledonne Communications SARL. +* +* This file is part of Linphone +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ import Foundation import SwiftUI @@ -66,10 +78,10 @@ class Coordinator: NSObject, AVCaptureMetadataOutputObjectsDelegate { } } else { - coreContext.configuringSuccessful = "Invalide URI" + coreContext.toastMessage = "Invalide URI" } } else { - coreContext.configuringSuccessful = "Invalide URI" + coreContext.toastMessage = "Invalide URI" } } } diff --git a/Linphone/UI/Main/ContentView.swift b/Linphone/UI/Main/ContentView.swift index c0404cd2f..4290116a5 100644 --- a/Linphone/UI/Main/ContentView.swift +++ b/Linphone/UI/Main/ContentView.swift @@ -25,7 +25,7 @@ struct ContentView: View { @ObservedObject private var coreContext = CoreContext.shared var body: some View { - if UserDefaults.standard.bool(forKey: "general_terms") == false { + if !sharedMainViewModel.welcomeViewDisplayed { WelcomeView(sharedMainViewModel: sharedMainViewModel) } else if coreContext.mCore.defaultAccount == nil || sharedMainViewModel.displayProfileMode { AssistantView(sharedMainViewModel: sharedMainViewModel) diff --git a/Linphone/UI/Main/Fragments/PopupLoadingView.swift b/Linphone/UI/Main/Fragments/PopupLoadingView.swift new file mode 100644 index 000000000..60c921245 --- /dev/null +++ b/Linphone/UI/Main/Fragments/PopupLoadingView.swift @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2010-2023 Belledonne Communications SARL. +* +* This file is part of Linphone +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +import SwiftUI + +struct PopupLoadingView: View { + + @ObservedObject var sharedMainViewModel : SharedMainViewModel + + var body: some View { + GeometryReader { geometry in + VStack (alignment: .leading){ + + ProgressView() + .controlSize(.large) + .progressViewStyle(CircularProgressViewStyle(tint: Color.orange_main_500)) + .frame(maxWidth: .infinity) + .padding(.top) + .padding(.bottom) + + Text("Opération en cours...") + .tint(Color.gray_main2_600) + .default_text_style(styleSize: 15) + .frame(maxWidth: .infinity) + } + .padding(.horizontal, 20) + .padding(.vertical, 20) + .background(.white) + .cornerRadius(20) + .padding(.horizontal) + .frame(maxHeight: .infinity) + .frame(maxWidth: .infinity) + .shadow(color: Color.orange_main_500, radius: 0, x: 0, y: 2) + .frame(maxWidth: sharedMainViewModel.maxWidth) + .position(x: geometry.size.width / 2, y: geometry.size.height / 2) + } + } +} + +#Preview { + PopupLoadingView(sharedMainViewModel: SharedMainViewModel()) + .background(.black.opacity(0.65)) +} diff --git a/Linphone/UI/Main/Fragments/PopupView.swift b/Linphone/UI/Main/Fragments/PopupView.swift index 178e817ab..b3a521285 100644 --- a/Linphone/UI/Main/Fragments/PopupView.swift +++ b/Linphone/UI/Main/Fragments/PopupView.swift @@ -22,11 +22,13 @@ import Photos struct PopupView: View { + @ObservedObject var sharedMainViewModel : SharedMainViewModel + var permissionManager = PermissionManager.shared @Binding var isShowPopup: Bool var title: Text - var content: Text + var content: Text? var titleFirstButton: Text? var actionFirstButton: () -> () @@ -42,10 +44,13 @@ struct PopupView: View { .frame(alignment: .leading) .padding(.bottom, 2) - content - .tint(Color.gray_main2_600) - .default_text_style(styleSize: 15) - .padding(.bottom, 20) + + if content != nil { + content + .tint(Color.gray_main2_600) + .default_text_style(styleSize: 15) + .padding(.bottom, 20) + } if titleFirstButton != nil { Button(action: { @@ -89,10 +94,13 @@ struct PopupView: View { .padding(.horizontal) .frame(maxHeight: .infinity) .shadow(color: Color.orange_main_500, radius: 0, x: 0, y: 2) + .frame(maxWidth: sharedMainViewModel.maxWidth) + .position(x: geometry.size.width / 2, y: geometry.size.height / 2) } } } #Preview { - PopupView(isShowPopup: .constant(true), title: Text("Title"), content: Text("Content"), titleFirstButton: Text("Deny all"), actionFirstButton: {}, titleSecondButton: Text("Accept all"), actionSecondButton: {}) + PopupView(sharedMainViewModel: SharedMainViewModel(), isShowPopup: .constant(true), title: Text("Title"), content: Text("Content"), titleFirstButton: Text("Deny all"), actionFirstButton: {}, titleSecondButton: Text("Accept all"), actionSecondButton: {}) + .background(.black.opacity(0.65)) } diff --git a/Linphone/UI/Main/Fragments/ToastView.swift b/Linphone/UI/Main/Fragments/ToastView.swift index fff782c09..16b4c9bbd 100644 --- a/Linphone/UI/Main/Fragments/ToastView.swift +++ b/Linphone/UI/Main/Fragments/ToastView.swift @@ -1,14 +1,28 @@ -// -// ToastView.swift -// Linphone -// -// Created by Benoît Martins on 06/10/2023. -// +/* +* Copyright (c) 2010-2023 Belledonne Communications SARL. +* +* This file is part of Linphone +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ import SwiftUI struct ToastView: ViewModifier { + @ObservedObject var sharedMainViewModel : SharedMainViewModel + @Binding var isShowing: String func body(content: Content) -> some View { @@ -26,14 +40,44 @@ struct ToastView: ViewModifier { .resizable() .frame(width: 25, height: 25, alignment: .leading) - Text(isShowing == "Successful" ? "QR code validated!" : (isShowing == "Failed" ? "Invalid QR code!" : "Invalide URI")) - .multilineTextAlignment(.center) - .foregroundStyle(isShowing == "Successful" ? Color.green_success_500 : Color.red_danger_500) - .default_text_style(styleSize: 15) - .padding(8) + switch isShowing { + case "Successful": + Text("QR code validated!") + .multilineTextAlignment(.center) + .foregroundStyle(Color.green_success_500) + .default_text_style(styleSize: 15) + .padding(8) + + case "Failed": + Text("Invalid QR code!") + .multilineTextAlignment(.center) + .foregroundStyle(Color.red_danger_500) + .default_text_style(styleSize: 15) + .padding(8) + + case "Invalide URI": + Text("Invalide URI") + .multilineTextAlignment(.center) + .foregroundStyle(Color.red_danger_500) + .default_text_style(styleSize: 15) + .padding(8) + + case "Registration failed": + Text("The user name or password is incorrects") + .multilineTextAlignment(.center) + .foregroundStyle(Color.red_danger_500) + .default_text_style(styleSize: 15) + .padding(8) + + default: + Text("Error") + .multilineTextAlignment(.center) + .foregroundStyle(Color.red_danger_500) + .default_text_style(styleSize: 15) + .padding(8) + } } .frame(maxWidth: .infinity) - .frame(height: 40) .background(.white) .cornerRadius(50) .overlay( @@ -52,6 +96,7 @@ struct ToastView: ViewModifier { } Spacer() } + .frame(maxWidth: sharedMainViewModel.maxWidth) .padding(.horizontal, 16) .padding(.bottom, 18) .animation(.linear(duration: 0.3), value: isShowing) @@ -61,10 +106,6 @@ struct ToastView: ViewModifier { extension View { func toast(isShowing: Binding) -> some View { - self.modifier(ToastView(isShowing: isShowing)) + self.modifier(ToastView(sharedMainViewModel: SharedMainViewModel(), isShowing: isShowing)) } } - -//#Preview { -//ToastView() -//} diff --git a/Linphone/UI/Main/History/HistoryView.swift b/Linphone/UI/Main/History/HistoryView.swift index 3e9cf4ba0..a42cc26a2 100644 --- a/Linphone/UI/Main/History/HistoryView.swift +++ b/Linphone/UI/Main/History/HistoryView.swift @@ -1,9 +1,21 @@ -// -// HistoryView.swift -// Linphone -// -// Created by Benoît Martins on 03/10/2023. -// +/* +* Copyright (c) 2010-2023 Belledonne Communications SARL. +* +* This file is part of Linphone +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ import SwiftUI diff --git a/Linphone/UI/Main/Viewmodel/SharedMainViewModel.swift b/Linphone/UI/Main/Viewmodel/SharedMainViewModel.swift index ac654f468..ffde7651c 100644 --- a/Linphone/UI/Main/Viewmodel/SharedMainViewModel.swift +++ b/Linphone/UI/Main/Viewmodel/SharedMainViewModel.swift @@ -20,14 +20,24 @@ import linphonesw class SharedMainViewModel : ObservableObject { - - @Published var displayProfileMode : Bool = false - + + @Published var welcomeViewDisplayed = false @Published var generalTermsAccepted = false + @Published var displayProfileMode = false + + var maxWidth = 400.0 init() { let preferences = UserDefaults.standard + let welcomeViewKey = "welcome_view" + + if preferences.object(forKey: welcomeViewKey) == nil { + preferences.set(welcomeViewDisplayed, forKey: welcomeViewKey) + } else { + welcomeViewDisplayed = preferences.bool(forKey: welcomeViewKey) + } + let generalTermsKey = "general_terms" if preferences.object(forKey: generalTermsKey) == nil { @@ -35,6 +45,22 @@ class SharedMainViewModel : ObservableObject { } else { generalTermsAccepted = preferences.bool(forKey: generalTermsKey) } + + let displayProfileModeKey = "display_profile_mode" + + if preferences.object(forKey: displayProfileModeKey) == nil { + preferences.set(displayProfileMode, forKey: displayProfileModeKey) + } else { + displayProfileMode = preferences.bool(forKey: displayProfileModeKey) + } + } + + func changeWelcomeView(){ + let preferences = UserDefaults.standard + + welcomeViewDisplayed = true + let welcomeViewKey = "welcome_view" + preferences.set(welcomeViewDisplayed, forKey: welcomeViewKey) } func changeGeneralTerms(){ @@ -44,4 +70,20 @@ class SharedMainViewModel : ObservableObject { let generalTermsKey = "general_terms" preferences.set(generalTermsAccepted, forKey: generalTermsKey) } + + func changeDisplayProfileMode(){ + let preferences = UserDefaults.standard + + displayProfileMode = true + let displayProfileModeKey = "display_profile_mode" + preferences.set(displayProfileMode, forKey: displayProfileModeKey) + } + + func changeHideProfileMode(){ + let preferences = UserDefaults.standard + + displayProfileMode = false + let displayProfileModeKey = "display_profile_mode" + preferences.set(displayProfileMode, forKey: displayProfileModeKey) + } } diff --git a/Linphone/UI/Welcome/WelcomeView.swift b/Linphone/UI/Welcome/WelcomeView.swift index 7ec1e7ae9..7797f187e 100644 --- a/Linphone/UI/Welcome/WelcomeView.swift +++ b/Linphone/UI/Welcome/WelcomeView.swift @@ -26,7 +26,6 @@ struct WelcomeView: View{ var permissionManager = PermissionManager.shared @State private var index = 0 - @State private var isShowPopup = false var body: some View { GeometryReader { geometry in @@ -48,7 +47,7 @@ struct WelcomeView: View{ .onTapGesture { withAnimation { self.index = 2 - self.isShowPopup.toggle() + permissionManager.cameraRequestPermission() } } Text("Welcome") @@ -98,9 +97,7 @@ struct WelcomeView: View{ index += 1 } } else if index == 2 { - withAnimation{ - self.isShowPopup.toggle() - } + permissionManager.cameraRequestPermission() } }) { Text(index == 2 ? "Start" : "Next") @@ -113,22 +110,16 @@ struct WelcomeView: View{ .background(Color.orange_main_500) .cornerRadius(60) .padding(.horizontal) + .padding(.bottom, geometry.safeAreaInsets.bottom.isEqual(to: 0.0) ? 20 : 0) + .frame(maxWidth: sharedMainViewModel.maxWidth) } .frame(minHeight: geometry.size.height) } - - if self.isShowPopup { - PopupView(isShowPopup: $isShowPopup, title: Text("Conditions de service"), content: Text("En continuant, vous acceptez ces conditions, \(Text("[notre politique de confidentialité](https://linphone.org/privacy-policy)").underline()) et \(Text("[nos conditions d’utilisation](https://linphone.org/general-terms)").underline())."), titleFirstButton: Text("Deny all"), actionFirstButton: {self.isShowPopup.toggle()}, titleSecondButton: Text("Accept all"), actionSecondButton: {permissionManager.cameraRequestPermission()}) - .background(.black.opacity(0.65)) - .onTapGesture { - self.isShowPopup.toggle() - } - } } .onReceive(permissionManager.$cameraPermissionGranted, perform: { (granted) in if granted { withAnimation { - sharedMainViewModel.changeGeneralTerms() + sharedMainViewModel.changeWelcomeView() } } }) diff --git a/Linphone/Utils/QRScannerController.swift b/Linphone/Utils/QRScannerController.swift index 7d37f2cb5..9bf9f3e7e 100644 --- a/Linphone/Utils/QRScannerController.swift +++ b/Linphone/Utils/QRScannerController.swift @@ -1,9 +1,21 @@ -// -// QRScannerController.swift -// Linphone -// -// Created by Benoît Martins on 05/10/2023. -// +/* +* Copyright (c) 2010-2023 Belledonne Communications SARL. +* +* This file is part of Linphone +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ import Foundation import SwiftUI