diff --git a/Linphone/Assets.xcassets/mountain2.imageset/Contents.json b/Linphone/Assets.xcassets/mountain2.imageset/Contents.json
new file mode 100644
index 000000000..8372f4dbd
--- /dev/null
+++ b/Linphone/Assets.xcassets/mountain2.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "mountain2.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Linphone/Assets.xcassets/mountain2.imageset/mountain2.png b/Linphone/Assets.xcassets/mountain2.imageset/mountain2.png
new file mode 100644
index 000000000..d1880df74
Binary files /dev/null and b/Linphone/Assets.xcassets/mountain2.imageset/mountain2.png differ
diff --git a/Linphone/Localizable.xcstrings b/Linphone/Localizable.xcstrings
index f07797c31..38bff373a 100644
--- a/Linphone/Localizable.xcstrings
+++ b/Linphone/Localizable.xcstrings
@@ -1055,13 +1055,13 @@
"en" : {
"stringUnit" : {
"state" : "translated",
- "value" : "Some features require a %@ account, such as group messaging, video conferences…\\n\\nThese features are hidden when you register with a third party SIP account.\\n\\nTo enable it in a commercial project, please contact us."
+ "value" : "Some features require a %@ account, such as group messaging, video conferences…\n\nThese features are hidden when you register with a third party SIP account.\n\nTo enable it in a commercial project, please contact us."
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
- "value" : "Certaines fonctionnalités telles que les conversations de groupe, les vidéo-conférences, etc… nécessitent un compte %@.\\n\\nCes fonctionnalités seront masquées si vous utilisez un compte SIP tiers.\\n\\nPour les activer dans un projet commercial, merci de nous contacter."
+ "value" : "Certaines fonctionnalités telles que les conversations de groupe, les vidéo-conférences, etc… nécessitent un compte %@.\n\nCes fonctionnalités seront masquées si vous utilisez un compte SIP tiers.\n\nPour les activer dans un projet commercial, merci de nous contacter."
}
}
}
@@ -7677,12 +7677,12 @@
"en" : {
"stringUnit" : {
"state" : "translated",
- "value" : "Your communications are safe thanks to our end-to-end encryption."
+ "value" : "Your communications are safe thanks to our **end-to-end encryption**."
}
},
"fr" : {
"stringUnit" : {
- "state" : "translated",
+ "state" : "needs_review",
"value" : "Vos communications sont en sécurité grâce au **chiffrement de bout en bout**."
}
}
@@ -7709,12 +7709,12 @@
"en" : {
"stringUnit" : {
"state" : "translated",
- "value" : "A free and open source application since 2001."
+ "value" : "A **free** and open source application since **2001**."
}
},
"fr" : {
"stringUnit" : {
- "state" : "translated",
+ "state" : "needs_review",
"value" : "Une application open source et un **service gratuit** depuis **2001**."
}
}
diff --git a/Linphone/UI/Assistant/Fragments/LoginFragment.swift b/Linphone/UI/Assistant/Fragments/LoginFragment.swift
index ce93a7a25..8c74c3d17 100644
--- a/Linphone/UI/Assistant/Fragments/LoginFragment.swift
+++ b/Linphone/UI/Assistant/Fragments/LoginFragment.swift
@@ -45,251 +45,15 @@ struct LoginFragment: View {
NavigationView {
ZStack {
GeometryReader { geometry in
- ScrollView(.vertical) {
- VStack {
- ZStack {
- Image("mountain")
- .resizable()
- .scaledToFill()
- .frame(width: geometry.size.width, height: 100)
- .clipped()
-
- if isShowBack {
- VStack(alignment: .leading) {
- HStack {
- Image("caret-left")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .frame(width: 25, height: 25, alignment: .leading)
- .padding(.all, 10)
- .padding(.top, -75)
- .padding(.leading, -10)
- .onTapGesture {
- withAnimation {
- onBackPressed?()
- }
- }
-
- Spacer()
- }
- .padding(.leading)
- }
- .frame(width: geometry.size.width)
- }
-
- 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)
- .disableAutocorrection(true)
- .autocapitalization(.none)
- .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.orangeMain500 : Color.gray200, 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)
- .disableAutocorrection(true)
- .autocapitalization(.none)
- .frame(height: 25)
- .focused($isPasswordFocused)
- }
- }
-
- Button(action: {
- isSecured.toggle()
- }, label: {
- Image(self.isSecured ? "eye-slash" : "eye")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .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.orangeMain500 : Color.gray200, lineWidth: 1)
- )
- .padding(.bottom)
-
- Button(action: {
- sharedMainViewModel.changeDisplayProfileMode()
- self.accountLoginViewModel.login()
- coreContext.loggingInProgress = true
- }, label: {
- Text(coreContext.loggedIn ? "manage_account_delete" : "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.orangeMain100 : Color.orangeMain500)
- .cornerRadius(60)
- .disabled(accountLoginViewModel.username.isEmpty || accountLoginViewModel.passwd.isEmpty)
- .padding(.bottom)
-
- HStack {
- Text(.init(String(format: ("[%@](%@)"), String(localized: "assistant_forgotten_password"), "https://subscribe.linphone.org/")))
- .underline()
- .tint(Color.grayMain2c600)
- .default_text_style_600(styleSize: 15)
- .foregroundStyle(Color.grayMain2c500)
- }
- .frame(maxWidth: .infinity)
- .padding(.bottom, 30)
-
- HStack {
- VStack {
- Divider()
- }
- Text("or")
- .default_text_style(styleSize: 15)
- .foregroundStyle(Color.grayMain2c500)
- VStack {
- Divider()
- }
- }
- .padding(.bottom, 10)
-
- NavigationLink(destination: {
- QrCodeScannerFragment()
- }, label: {
- HStack {
- Image("qr-code")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.orangeMain500)
- .frame(width: 20, height: 20)
-
- Text("assistant_scan_qr_code")
- .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.orangeMain500, lineWidth: 1)
- )
- .padding(.bottom)
-
- NavigationLink(isActive: $isLinkSIPActive, destination: {
- ThirdPartySipAccountWarningFragment(accountLoginViewModel: accountLoginViewModel)
- }, label: {
- Text("assistant_login_third_party_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.orangeMain500, 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("assistant_no_account_yet")
- .default_text_style(styleSize: 15)
- .foregroundStyle(Color.grayMain2c700)
- .padding(.horizontal, 10)
-
- NavigationLink(destination: RegisterFragment(registerViewModel: RegisterViewModel()), isActive: $isLinkREGActive, label: { Text("assistant_account_register")
- .default_text_style_white_600(styleSize: 20)
- .frame(height: 35)
- })
- .disabled(!sharedMainViewModel.generalTermsAccepted)
- .padding(.horizontal, 20)
- .padding(.vertical, 10)
- .background(Color.orangeMain500)
- .cornerRadius(60)
- .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)
+ if #available(iOS 16.4, *) {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
+ }
+ .scrollBounceBehavior(.basedOnSize)
+ } else {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
}
- .frame(minHeight: geometry.size.height)
}
if self.isShowPopup {
@@ -336,10 +100,257 @@ struct LoginFragment: View {
}
.navigationTitle("")
.navigationBarHidden(true)
+ .edgesIgnoringSafeArea(.bottom)
+ .edgesIgnoringSafeArea(.horizontal)
}
.navigationViewStyle(StackNavigationViewStyle())
}
+ func innerScrollView(geometry: GeometryProxy) -> some View {
+ VStack {
+ ZStack {
+ HStack {
+ if isShowBack {
+ Image("caret-left")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 25, height: 25)
+ .padding(.all, 10)
+ .onTapGesture {
+ withAnimation {
+ onBackPressed?()
+ }
+ }
+ } else {
+ Color.clear
+ .frame(width: 25, height: 25)
+ .padding(.all, 10)
+ }
+
+ Spacer()
+ }
+
+ Text("assistant_account_login")
+ .default_text_style_800(styleSize: 20)
+ }
+ .frame(width: geometry.size.width)
+ .padding(.top, 10)
+ .padding(.bottom, 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)
+ .disableAutocorrection(true)
+ .autocapitalization(.none)
+ .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.orangeMain500 : Color.gray200, 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)
+ .disableAutocorrection(true)
+ .autocapitalization(.none)
+ .frame(height: 25)
+ .focused($isPasswordFocused)
+ }
+ }
+
+ Button(action: {
+ isSecured.toggle()
+ }, label: {
+ Image(self.isSecured ? "eye-slash" : "eye")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .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.orangeMain500 : Color.gray200, lineWidth: 1)
+ )
+ .padding(.bottom)
+
+ Button(action: {
+ sharedMainViewModel.changeDisplayProfileMode()
+ self.accountLoginViewModel.login()
+ coreContext.loggingInProgress = true
+ }, label: {
+ Text(coreContext.loggedIn ? "manage_account_delete" : "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.orangeMain100 : Color.orangeMain500)
+ .cornerRadius(60)
+ .disabled(accountLoginViewModel.username.isEmpty || accountLoginViewModel.passwd.isEmpty)
+ .padding(.bottom)
+
+ HStack {
+ Text(.init(String(format: ("[%@](%@)"), String(localized: "assistant_forgotten_password"), "https://subscribe.linphone.org/")))
+ .underline()
+ .tint(Color.grayMain2c600)
+ .default_text_style_600(styleSize: 15)
+ .foregroundStyle(Color.grayMain2c500)
+ }
+ .frame(maxWidth: .infinity)
+ .padding(.bottom, 30)
+
+ HStack {
+ VStack {
+ Divider()
+ }
+ Text("or")
+ .default_text_style(styleSize: 15)
+ .foregroundStyle(Color.grayMain2c500)
+ VStack {
+ Divider()
+ }
+ }
+ .padding(.bottom, 10)
+
+ NavigationLink(destination: {
+ QrCodeScannerFragment()
+ }, label: {
+ HStack {
+ Image("qr-code")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.orangeMain500)
+ .frame(width: 20, height: 20)
+
+ Text("assistant_scan_qr_code")
+ .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.orangeMain500, lineWidth: 1)
+ )
+ .padding(.bottom)
+
+ NavigationLink(isActive: $isLinkSIPActive, destination: {
+ ThirdPartySipAccountWarningFragment(accountLoginViewModel: accountLoginViewModel)
+ }, label: {
+ Text("assistant_login_third_party_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.orangeMain500, lineWidth: 1)
+ )
+ .padding(.bottom)
+ .simultaneousGesture(
+ TapGesture().onEnded {
+ self.linkActive = "SIP"
+ if !sharedMainViewModel.generalTermsAccepted {
+ withAnimation {
+ self.isShowPopup.toggle()
+ }
+ } else {
+ self.isLinkSIPActive = true
+ }
+ }
+ )
+ }
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ .padding(.horizontal, 20)
+
+ Spacer()
+
+ HStack(alignment: .center) {
+
+ Spacer()
+
+ Text("assistant_no_account_yet")
+ .default_text_style(styleSize: 15)
+ .foregroundStyle(Color.grayMain2c700)
+ .padding(.horizontal, 10)
+
+ NavigationLink(destination: RegisterFragment(registerViewModel: RegisterViewModel()), isActive: $isLinkREGActive, label: { Text("assistant_account_register")
+ .default_text_style_white_600(styleSize: 20)
+ .frame(height: 35)
+ })
+ .disabled(!sharedMainViewModel.generalTermsAccepted)
+ .padding(.horizontal, 20)
+ .padding(.vertical, 10)
+ .background(Color.orangeMain500)
+ .cornerRadius(60)
+ .padding(.horizontal, 10)
+ .simultaneousGesture(
+ TapGesture().onEnded {
+ self.linkActive = "REG"
+ if !sharedMainViewModel.generalTermsAccepted {
+ withAnimation {
+ self.isShowPopup.toggle()
+ }
+ } else {
+ self.isLinkREGActive = true
+ }
+ }
+ )
+
+ Spacer()
+ }
+ .padding(.bottom)
+
+ Image("mountain2")
+ .resizable()
+ .scaledToFill()
+ .frame(width: geometry.size.width, height: 60)
+ .clipped()
+ }
+ .frame(minHeight: geometry.size.height)
+ }
+
func acceptGeneralTerms() {
sharedMainViewModel.changeGeneralTerms()
self.isShowPopup.toggle()
diff --git a/Linphone/UI/Assistant/Fragments/PermissionsFragment.swift b/Linphone/UI/Assistant/Fragments/PermissionsFragment.swift
index dd1bc8836..d35a5594d 100644
--- a/Linphone/UI/Assistant/Fragments/PermissionsFragment.swift
+++ b/Linphone/UI/Assistant/Fragments/PermissionsFragment.swift
@@ -29,170 +29,21 @@ struct PermissionsFragment: View {
var body: some View {
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.grayMain2c500)
- .frame(width: 25, height: 25, alignment: .leading)
- .padding(.all, 10)
- .padding(.top, -75)
- .padding(.leading, -10)
- .onTapGesture {
- withAnimation {
- dismiss()
- }
- }
-
- Spacer()
- }
- .padding(.leading)
- }
- .frame(width: geometry.size.width)
-
- Text("assistant_permissions_title")
- .default_text_style_white_800(styleSize: 20)
- .padding(.top, 20)
- }
- .padding(.top, 35)
- .padding(.bottom, 10)
-
- Text(String(format: String(localized: "assistant_permissions_subtitle"), Bundle.main.displayName))
- .default_text_style(styleSize: 15)
- .multilineTextAlignment(.center)
-
- Spacer()
-
- VStack(alignment: .leading) {
- HStack {
- HStack(alignment: .center) {
- Image("bell-ringing")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .frame(width: 20, height: 20, alignment: .leading)
- }
- .padding(16)
- .background(Color.grayMain2c200)
- .cornerRadius(40)
-
- Text("assistant_permissions_post_notifications_title")
- .default_text_style(styleSize: 15)
- .padding(.leading, 10)
- }
- .padding(.bottom)
-
- HStack {
- HStack(alignment: .center) {
- Image("address-book")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .frame(width: 20, height: 20, alignment: .leading)
- }
- .padding(16)
- .background(Color.grayMain2c200)
- .cornerRadius(40)
- Text(.init(String(format: String(localized: "assistant_permissions_read_contacts_title"), Bundle.main.displayName)))
- .default_text_style(styleSize: 15)
- .padding(.leading, 10)
- }
- .padding(.bottom)
-
- HStack {
- HStack(alignment: .center) {
- Image("microphone")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .frame(width: 20, height: 20, alignment: .leading)
- }
- .padding(16)
- .background(Color.grayMain2c200)
- .cornerRadius(40)
-
- Text("assistant_permissions_record_audio_title")
- .default_text_style(styleSize: 15)
- .padding(.leading, 10)
- }
- .padding(.bottom)
-
- HStack {
- HStack(alignment: .center) {
- Image("video-camera")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .frame(width: 20, height: 20, alignment: .leading)
- }
- .padding(16)
- .background(Color.grayMain2c200)
- .cornerRadius(40)
-
- Text("assistant_permissions_access_camera_title")
- .default_text_style(styleSize: 15)
- .padding(.leading, 10)
- }
- .padding(.bottom)
- }
- .frame(maxWidth: sharedMainViewModel.maxWidth)
- .frame(maxHeight: .infinity)
- .padding(.horizontal, 20)
-
- Spacer()
-
- Button(action: {
- withAnimation {
- sharedMainViewModel.changeWelcomeView()
- }
- }, label: {
- Text("assistant_permissions_skip_permissions")
- .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.orangeMain500, lineWidth: 1)
- )
- .frame(maxWidth: sharedMainViewModel.maxWidth)
- .padding(.horizontal)
-
- Button {
- permissionManager.getPermissions()
- } label: {
- Text("assistant_permissions_grant_all_of_them")
- .default_text_style_white_600(styleSize: 20)
- .frame(height: 35)
- .frame(maxWidth: .infinity)
- }
- .padding(.horizontal, 20)
- .padding(.vertical, 10)
- .background(Color.orangeMain500)
- .cornerRadius(60)
- .frame(maxWidth: sharedMainViewModel.maxWidth)
- .padding(.horizontal)
- .padding(.bottom, geometry.safeAreaInsets.bottom.isEqual(to: 0.0) ? 20 : 0)
+ if #available(iOS 16.4, *) {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
+ }
+ .scrollBounceBehavior(.basedOnSize)
+ } else {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
}
- .frame(minHeight: geometry.size.height)
}
}
.navigationViewStyle(StackNavigationViewStyle())
.navigationBarHidden(true)
+ .edgesIgnoringSafeArea(.bottom)
+ .edgesIgnoringSafeArea(.horizontal)
.onReceive(permissionManager.$allPermissionsHaveBeenDisplayed, perform: { (granted) in
if granted {
withAnimation {
@@ -201,6 +52,161 @@ struct PermissionsFragment: View {
}
})
}
+
+ func innerScrollView(geometry: GeometryProxy) -> some View {
+ VStack {
+ ZStack {
+ HStack {
+ Image("caret-left")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 25, height: 25)
+ .padding(.all, 10)
+ .onTapGesture {
+ withAnimation {
+ dismiss()
+ }
+ }
+ Spacer()
+ }
+
+ Text("assistant_permissions_title")
+ .default_text_style_800(styleSize: 20)
+ }
+ .frame(width: geometry.size.width)
+ .padding(.top, 10)
+ .padding(.bottom, 20)
+
+ Text(String(format: String(localized: "assistant_permissions_subtitle"), Bundle.main.displayName))
+ .default_text_style(styleSize: 15)
+ .multilineTextAlignment(.center)
+
+ Spacer()
+
+ VStack(alignment: .leading) {
+ HStack {
+ HStack(alignment: .center) {
+ Image("bell-ringing")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 20, height: 20, alignment: .leading)
+ }
+ .padding(16)
+ .background(Color.grayMain2c200)
+ .cornerRadius(40)
+
+ Text("assistant_permissions_post_notifications_title")
+ .default_text_style(styleSize: 15)
+ .padding(.leading, 10)
+ }
+ .padding(.bottom)
+
+ HStack {
+ HStack(alignment: .center) {
+ Image("address-book")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 20, height: 20, alignment: .leading)
+ }
+ .padding(16)
+ .background(Color.grayMain2c200)
+ .cornerRadius(40)
+ Text(.init(String(format: String(localized: "assistant_permissions_read_contacts_title"), Bundle.main.displayName)))
+ .default_text_style(styleSize: 15)
+ .padding(.leading, 10)
+ }
+ .padding(.bottom)
+
+ HStack {
+ HStack(alignment: .center) {
+ Image("microphone")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 20, height: 20, alignment: .leading)
+ }
+ .padding(16)
+ .background(Color.grayMain2c200)
+ .cornerRadius(40)
+
+ Text("assistant_permissions_record_audio_title")
+ .default_text_style(styleSize: 15)
+ .padding(.leading, 10)
+ }
+ .padding(.bottom)
+
+ HStack {
+ HStack(alignment: .center) {
+ Image("video-camera")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 20, height: 20, alignment: .leading)
+ }
+ .padding(16)
+ .background(Color.grayMain2c200)
+ .cornerRadius(40)
+
+ Text("assistant_permissions_access_camera_title")
+ .default_text_style(styleSize: 15)
+ .padding(.leading, 10)
+ }
+ .padding(.bottom)
+ }
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ .frame(maxHeight: .infinity)
+ .padding(.horizontal, 20)
+
+ Spacer()
+
+ Button(action: {
+ withAnimation {
+ sharedMainViewModel.changeWelcomeView()
+ }
+ }, label: {
+ Text("assistant_permissions_skip_permissions")
+ .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.orangeMain500, lineWidth: 1)
+ )
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ .padding(.horizontal)
+
+ Button {
+ permissionManager.getPermissions()
+ } label: {
+ Text("assistant_permissions_grant_all_of_them")
+ .default_text_style_white_600(styleSize: 20)
+ .frame(height: 35)
+ .frame(maxWidth: .infinity)
+ }
+ .padding(.horizontal, 20)
+ .padding(.vertical, 10)
+ .background(Color.orangeMain500)
+ .cornerRadius(60)
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ .padding(.horizontal)
+ .padding(.bottom)
+
+ Image("mountain2")
+ .resizable()
+ .scaledToFill()
+ .frame(width: geometry.size.width, height: 60)
+ .clipped()
+ }
+ .frame(minHeight: geometry.size.height)
+ }
}
#Preview {
diff --git a/Linphone/UI/Assistant/Fragments/RegisterCodeConfirmationFragment.swift b/Linphone/UI/Assistant/Fragments/RegisterCodeConfirmationFragment.swift
index 374c362c6..837890bee 100644
--- a/Linphone/UI/Assistant/Fragments/RegisterCodeConfirmationFragment.swift
+++ b/Linphone/UI/Assistant/Fragments/RegisterCodeConfirmationFragment.swift
@@ -41,121 +41,14 @@ struct RegisterCodeConfirmationFragment: View {
NavigationView {
GeometryReader { geometry in
ZStack {
- 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.grayMain2c500)
- .frame(width: 25, height: 25, alignment: .leading)
- .padding(.all, 10)
- .padding(.top, -75)
- .padding(.leading, -10)
- .onTapGesture {
- withAnimation {
- dismiss()
- }
- }
-
- Spacer()
- }
- .padding(.leading)
- }
- .frame(width: geometry.size.width)
-
- Text("assistant_account_register")
- .default_text_style_white_800(styleSize: 20)
- .padding(.top, 20)
- }
- .padding(.top, 35)
- .padding(.bottom, 10)
-
- ZStack {
- VStack {
- Spacer()
- HStack {
- Spacer()
- Image("confirm_sms_code_illu")
- .padding(.bottom, -geometry.safeAreaInsets.bottom)
- }
- }
- VStack(alignment: .center) {
- Spacer()
-
- Text(String(format: NSLocalizedString("assistant_account_creation_sms_confirmation_explanation", comment: ""), registerViewModel.phoneNumber))
- .default_text_style(styleSize: 15)
- .foregroundStyle(Color.grayMain2c700)
- .padding(.horizontal, 10)
- .frame(maxWidth: .infinity, alignment: .center)
- .multilineTextAlignment(.center)
-
- VStack {
- ZStack {
-
- HStack(spacing: spaceBetweenBoxes) {
- otpText(text: registerViewModel.otp1, focused: registerViewModel.otpField.isEmpty)
- otpText(text: registerViewModel.otp2, focused: registerViewModel.otpField.count == 1)
- otpText(text: registerViewModel.otp3, focused: registerViewModel.otpField.count == 2)
- otpText(text: registerViewModel.otp4, focused: registerViewModel.otpField.count == 3)
- }
-
- TextField("", text: $registerViewModel.otpField)
- .default_text_style_600(styleSize: 80)
- .frame(width: isFocused ? 0 : textFieldOriginalWidth, height: textBoxHeight)
- .textContentType(.oneTimeCode)
- .foregroundColor(.clear)
- .accentColor(.clear)
- .background(.clear)
- .keyboardType(.numberPad)
- .focused($isFocused)
- .onChange(of: registerViewModel.otpField) { _ in
- limitText(textLimit)
- if registerViewModel.otpField.count > 3 {
- registerViewModel.validateCode()
- }
- }
- }
- }
- .frame(maxWidth: .infinity, alignment: .center)
- .padding(.vertical, 20)
-
- Button(action: {
- dismiss()
- }, label: {
- Text("assistant_account_creation_wrong_phone_number")
- .default_text_style_orange_600(styleSize: 15)
- .frame(height: 35)
- })
- .padding(.horizontal, 15)
- .padding(.vertical, 5)
- .cornerRadius(60)
- .overlay(
- RoundedRectangle(cornerRadius: 60)
- .inset(by: 0.5)
- .stroke(Color.orangeMain500, lineWidth: 1)
- )
- .padding(.bottom)
- .frame(maxWidth: .infinity)
-
- Spacer()
- Spacer()
- }
- .frame(maxWidth: sharedMainViewModel.maxWidth)
- .padding(.horizontal, 20)
- }
+ if #available(iOS 16.4, *) {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
}
- .frame(minHeight: geometry.size.height)
- .onAppear {
- registerViewModel.otpField = ""
+ .scrollBounceBehavior(.basedOnSize)
+ } else {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
}
}
@@ -167,12 +60,127 @@ struct RegisterCodeConfirmationFragment: View {
}
.navigationTitle("")
.navigationBarHidden(true)
+ .edgesIgnoringSafeArea(.bottom)
+ .edgesIgnoringSafeArea(.horizontal)
}
.navigationViewStyle(StackNavigationViewStyle())
.navigationTitle("")
.navigationBarHidden(true)
}
+ func innerScrollView(geometry: GeometryProxy) -> some View {
+ VStack {
+ ZStack {
+ HStack {
+ Image("caret-left")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 25, height: 25)
+ .padding(.all, 10)
+ .onTapGesture {
+ withAnimation {
+ dismiss()
+ }
+ }
+ Spacer()
+ }
+
+ Text("assistant_account_register")
+ .default_text_style_800(styleSize: 20)
+ }
+ .frame(width: geometry.size.width)
+ .padding(.top, 10)
+ .padding(.bottom, 20)
+
+ ZStack {
+ VStack {
+ Spacer()
+ HStack {
+ Spacer()
+ Image("confirm_sms_code_illu")
+ .padding(.bottom, -geometry.safeAreaInsets.bottom)
+ }
+ }
+ VStack(alignment: .center) {
+ Spacer()
+
+ Text(String(format: NSLocalizedString("assistant_account_creation_sms_confirmation_explanation", comment: ""), registerViewModel.phoneNumber))
+ .default_text_style(styleSize: 15)
+ .foregroundStyle(Color.grayMain2c700)
+ .padding(.horizontal, 10)
+ .frame(maxWidth: .infinity, alignment: .center)
+ .multilineTextAlignment(.center)
+
+ VStack {
+ ZStack {
+
+ HStack(spacing: spaceBetweenBoxes) {
+ otpText(text: registerViewModel.otp1, focused: registerViewModel.otpField.isEmpty)
+ otpText(text: registerViewModel.otp2, focused: registerViewModel.otpField.count == 1)
+ otpText(text: registerViewModel.otp3, focused: registerViewModel.otpField.count == 2)
+ otpText(text: registerViewModel.otp4, focused: registerViewModel.otpField.count == 3)
+ }
+
+ TextField("", text: $registerViewModel.otpField)
+ .default_text_style_600(styleSize: 80)
+ .frame(width: isFocused ? 0 : textFieldOriginalWidth, height: textBoxHeight)
+ .textContentType(.oneTimeCode)
+ .foregroundColor(.clear)
+ .accentColor(.clear)
+ .background(.clear)
+ .keyboardType(.numberPad)
+ .focused($isFocused)
+ .onChange(of: registerViewModel.otpField) { _ in
+ limitText(textLimit)
+ if registerViewModel.otpField.count > 3 {
+ registerViewModel.validateCode()
+ }
+ }
+ }
+ }
+ .frame(maxWidth: .infinity, alignment: .center)
+ .padding(.vertical, 20)
+
+ Button(action: {
+ dismiss()
+ }, label: {
+ Text("assistant_account_creation_wrong_phone_number")
+ .default_text_style_orange_600(styleSize: 15)
+ .frame(height: 35)
+ })
+ .padding(.horizontal, 15)
+ .padding(.vertical, 5)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(Color.orangeMain500, lineWidth: 1)
+ )
+ .padding(.bottom)
+ .frame(maxWidth: .infinity)
+
+ Spacer()
+ Spacer()
+ }
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ .padding(.horizontal, 20)
+ }
+
+ Spacer()
+
+ Image("mountain2")
+ .resizable()
+ .scaledToFill()
+ .frame(width: geometry.size.width, height: 60)
+ .clipped()
+ }
+ .frame(minHeight: geometry.size.height)
+ .onAppear {
+ registerViewModel.otpField = ""
+ }
+ }
+
private func otpText(text: String, focused: Bool) -> some View {
return Text(text)
diff --git a/Linphone/UI/Assistant/Fragments/RegisterFragment.swift b/Linphone/UI/Assistant/Fragments/RegisterFragment.swift
index 387220a66..946f9b48e 100644
--- a/Linphone/UI/Assistant/Fragments/RegisterFragment.swift
+++ b/Linphone/UI/Assistant/Fragments/RegisterFragment.swift
@@ -39,266 +39,15 @@ struct RegisterFragment: View {
NavigationView {
GeometryReader { geometry in
ZStack {
- 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.grayMain2c500)
- .frame(width: 25, height: 25, alignment: .leading)
- .padding(.all, 10)
- .padding(.top, -75)
- .padding(.leading, -10)
- .onTapGesture {
- withAnimation {
- dismiss()
- }
- }
-
- Spacer()
- }
- .padding(.leading)
- }
- .frame(width: geometry.size.width)
-
- Text("assistant_account_register")
- .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: $registerViewModel.username)
- .default_text_style(styleSize: 15)
- .disableAutocorrection(true)
- .autocapitalization(.none)
- .frame(height: 25)
- .padding(.horizontal, 20)
- .padding(.vertical, 15)
- .cornerRadius(60)
- .overlay(
- RoundedRectangle(cornerRadius: 60)
- .inset(by: 0.5)
- .stroke(isNameFocused ? Color.orangeMain500 : (!registerViewModel.usernameError.isEmpty ? Color.redDanger500 : Color.gray200), lineWidth: 1)
- )
- .focused($isNameFocused)
- .onChange(of: registerViewModel.username) { _ in
- if !registerViewModel.usernameError.isEmpty {
- registerViewModel.usernameError = ""
- }
- }
-
- Text(registerViewModel.usernameError)
- .foregroundStyle(Color.redDanger500)
- .default_text_style_600(styleSize: 15)
- .padding(.bottom)
-
- Text(String(localized: "phone_number")+"*")
- .default_text_style_700(styleSize: 15)
- .padding(.bottom, -5)
-
- HStack {
- Menu {
- Picker("", selection: $registerViewModel.dialPlanValueSelected) {
- ForEach(Array(registerViewModel.dialPlansLabelList.enumerated()), id: \.offset) { index, dialPlan in
- Text(dialPlan).tag(registerViewModel.dialPlansShortLabelList[index])
- }
- }
- } label: {
- HStack {
- Text(registerViewModel.dialPlanValueSelected)
-
- Image("caret-down")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.blue)
- .frame(width: 15, height: 15)
- }
- }
- .padding(.trailing, 5)
-
- Divider()
-
- TextField("phone_number", text: $registerViewModel.phoneNumber)
- .default_text_style(styleSize: 15)
- .disableAutocorrection(true)
- .autocapitalization(.none)
- .padding(.leading, 5)
- .keyboardType(.numberPad)
- .onChange(of: registerViewModel.phoneNumber) { _ in
- if !registerViewModel.phoneNumberError.isEmpty {
- registerViewModel.phoneNumberError = ""
- }
- }
- }
- .frame(height: 25)
- .padding(.horizontal, 20)
- .padding(.vertical, 15)
- .cornerRadius(60)
- .overlay(
- RoundedRectangle(cornerRadius: 60)
- .inset(by: 0.5)
- .stroke(isPhoneNumberFocused ? Color.orangeMain500 : (!registerViewModel.phoneNumberError.isEmpty ? Color.redDanger500 : Color.gray200), lineWidth: 1)
- )
- .focused($isPhoneNumberFocused)
-
- Text(registerViewModel.phoneNumberError)
- .foregroundStyle(Color.redDanger500)
- .default_text_style_600(styleSize: 15)
- .padding(.bottom)
-
- Text(String(localized: "password")+"*")
- .default_text_style_700(styleSize: 15)
- .padding(.bottom, -5)
-
- ZStack(alignment: .trailing) {
- Group {
- if isSecured {
- SecureField("password", text: $registerViewModel.passwd)
- .default_text_style(styleSize: 15)
- .frame(height: 25)
- .focused($isPasswordFocused)
- .onChange(of: registerViewModel.passwd) { _ in
- if !registerViewModel.passwordError.isEmpty {
- registerViewModel.passwordError = ""
- }
- }
- } else {
- TextField("password", text: $registerViewModel.passwd)
- .default_text_style(styleSize: 15)
- .disableAutocorrection(true)
- .autocapitalization(.none)
- .frame(height: 25)
- .focused($isPasswordFocused)
- .onChange(of: registerViewModel.passwd) { _ in
- if !registerViewModel.passwordError.isEmpty {
- registerViewModel.passwordError = ""
- }
- }
- }
- }
-
- Button(action: {
- isSecured.toggle()
- }, label: {
- Image(self.isSecured ? "eye-slash" : "eye")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .frame(width: 20, height: 20)
- })
- }
- .padding(.horizontal, 20)
- .padding(.vertical, 15)
- .cornerRadius(60)
- .overlay(
- RoundedRectangle(cornerRadius: 60)
- .inset(by: 0.5)
- .stroke(isPasswordFocused ? Color.orangeMain500 : (!registerViewModel.passwordError.isEmpty ? Color.redDanger500 : Color.gray200), lineWidth: 1)
- )
-
- Text(registerViewModel.passwordError)
- .foregroundStyle(Color.redDanger500)
- .default_text_style_600(styleSize: 15)
- .padding(.bottom)
-
- NavigationLink(isActive: $registerViewModel.isLinkActive, destination: {
- RegisterCodeConfirmationFragment(registerViewModel: registerViewModel)
- }, label: {
- Text("assistant_account_create")
- .default_text_style_white_600(styleSize: 20)
- .frame(height: 35)
- .frame(maxWidth: .infinity)
-
- })
- .padding(.horizontal, 20)
- .padding(.vertical, 10)
- .background((registerViewModel.username.isEmpty || registerViewModel.phoneNumber.isEmpty || registerViewModel.passwd.isEmpty) ? Color.orangeMain100 : Color.orangeMain500)
- .cornerRadius(60)
- .disabled(!registerViewModel.isLinkActive)
- .padding(.bottom)
- .simultaneousGesture(
- TapGesture().onEnded {
- if !(registerViewModel.username.isEmpty || registerViewModel.phoneNumber.isEmpty || registerViewModel.passwd.isEmpty) {
- withAnimation {
- self.isShowPopup = true
- }
- }
- }
- )
-
- Spacer()
-
- Text("assistant_create_account_using_email_on_our_web_platform")
- .default_text_style(styleSize: 15)
- .foregroundStyle(Color.grayMain2c700)
- .padding(.horizontal, 10)
- .frame(maxWidth: .infinity, alignment: .center)
-
- Button(action: {
- UIApplication.shared.open(URL(string: "https://subscribe.linphone.org/register/email")!)
- }, label: {
- Text("assistant_web_platform_link")
- .default_text_style_orange_600(styleSize: 15)
- .frame(height: 35)
- })
- .padding(.horizontal, 15)
- .padding(.vertical, 5)
- .cornerRadius(60)
- .overlay(
- RoundedRectangle(cornerRadius: 60)
- .inset(by: 0.5)
- .stroke(Color.orangeMain500, lineWidth: 1)
- )
- .padding(.bottom)
- .frame(maxWidth: .infinity)
-
- Spacer()
-
- HStack(alignment: .center) {
-
- Spacer()
-
- Text("assistant_already_have_an_account")
- .default_text_style(styleSize: 15)
- .foregroundStyle(Color.grayMain2c700)
- .padding(.horizontal, 10)
-
- Button(action: {
- dismiss()
- }, label: {
- Text("assistant_account_login")
- .default_text_style_white_600(styleSize: 20)
- .frame(height: 35)
- })
- .padding(.horizontal, 20)
- .padding(.vertical, 10)
- .background(Color.orangeMain500)
- .cornerRadius(60)
- .padding(.horizontal, 10)
-
- Spacer()
- }
- .padding(.bottom)
- }
- .frame(maxWidth: sharedMainViewModel.maxWidth)
- .padding(.horizontal, 20)
+ if #available(iOS 16.4, *) {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
+ }
+ .scrollBounceBehavior(.basedOnSize)
+ } else {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
}
- .frame(minHeight: geometry.size.height)
}
if self.isShowPopup {
@@ -335,11 +84,268 @@ struct RegisterFragment: View {
}
.navigationTitle("")
.navigationBarHidden(true)
+ .edgesIgnoringSafeArea(.bottom)
+ .edgesIgnoringSafeArea(.horizontal)
}
.navigationViewStyle(StackNavigationViewStyle())
.navigationTitle("")
.navigationBarHidden(true)
}
+
+ func innerScrollView(geometry: GeometryProxy) -> some View {
+ VStack {
+ ZStack {
+ HStack {
+ Image("caret-left")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 25, height: 25)
+ .padding(.all, 10)
+ .onTapGesture {
+ withAnimation {
+ dismiss()
+ }
+ }
+ Spacer()
+ }
+
+ Text("assistant_account_register")
+ .default_text_style_800(styleSize: 20)
+ }
+ .frame(width: geometry.size.width)
+ .padding(.top, 10)
+ .padding(.bottom, 20)
+
+ VStack(alignment: .leading) {
+ Text(String(localized: "username")+"*")
+ .default_text_style_700(styleSize: 15)
+ .padding(.bottom, -5)
+
+ TextField("username", text: $registerViewModel.username)
+ .default_text_style(styleSize: 15)
+ .disableAutocorrection(true)
+ .autocapitalization(.none)
+ .frame(height: 25)
+ .padding(.horizontal, 20)
+ .padding(.vertical, 15)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(isNameFocused ? Color.orangeMain500 : (!registerViewModel.usernameError.isEmpty ? Color.redDanger500 : Color.gray200), lineWidth: 1)
+ )
+ .focused($isNameFocused)
+ .onChange(of: registerViewModel.username) { _ in
+ if !registerViewModel.usernameError.isEmpty {
+ registerViewModel.usernameError = ""
+ }
+ }
+
+ Text(registerViewModel.usernameError)
+ .foregroundStyle(Color.redDanger500)
+ .default_text_style_600(styleSize: 15)
+ .padding(.bottom)
+
+ Text(String(localized: "phone_number")+"*")
+ .default_text_style_700(styleSize: 15)
+ .padding(.bottom, -5)
+
+ HStack {
+ Menu {
+ Picker("", selection: $registerViewModel.dialPlanValueSelected) {
+ ForEach(Array(registerViewModel.dialPlansLabelList.enumerated()), id: \.offset) { index, dialPlan in
+ Text(dialPlan).tag(registerViewModel.dialPlansShortLabelList[index])
+ }
+ }
+ } label: {
+ HStack {
+ Text(registerViewModel.dialPlanValueSelected)
+
+ Image("caret-down")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.blue)
+ .frame(width: 15, height: 15)
+ }
+ }
+ .padding(.trailing, 5)
+
+ Divider()
+
+ TextField("phone_number", text: $registerViewModel.phoneNumber)
+ .default_text_style(styleSize: 15)
+ .disableAutocorrection(true)
+ .autocapitalization(.none)
+ .padding(.leading, 5)
+ .keyboardType(.numberPad)
+ .onChange(of: registerViewModel.phoneNumber) { _ in
+ if !registerViewModel.phoneNumberError.isEmpty {
+ registerViewModel.phoneNumberError = ""
+ }
+ }
+ }
+ .frame(height: 25)
+ .padding(.horizontal, 20)
+ .padding(.vertical, 15)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(isPhoneNumberFocused ? Color.orangeMain500 : (!registerViewModel.phoneNumberError.isEmpty ? Color.redDanger500 : Color.gray200), lineWidth: 1)
+ )
+ .focused($isPhoneNumberFocused)
+
+ Text(registerViewModel.phoneNumberError)
+ .foregroundStyle(Color.redDanger500)
+ .default_text_style_600(styleSize: 15)
+ .padding(.bottom)
+
+ Text(String(localized: "password")+"*")
+ .default_text_style_700(styleSize: 15)
+ .padding(.bottom, -5)
+
+ ZStack(alignment: .trailing) {
+ Group {
+ if isSecured {
+ SecureField("password", text: $registerViewModel.passwd)
+ .default_text_style(styleSize: 15)
+ .frame(height: 25)
+ .focused($isPasswordFocused)
+ .onChange(of: registerViewModel.passwd) { _ in
+ if !registerViewModel.passwordError.isEmpty {
+ registerViewModel.passwordError = ""
+ }
+ }
+ } else {
+ TextField("password", text: $registerViewModel.passwd)
+ .default_text_style(styleSize: 15)
+ .disableAutocorrection(true)
+ .autocapitalization(.none)
+ .frame(height: 25)
+ .focused($isPasswordFocused)
+ .onChange(of: registerViewModel.passwd) { _ in
+ if !registerViewModel.passwordError.isEmpty {
+ registerViewModel.passwordError = ""
+ }
+ }
+ }
+ }
+
+ Button(action: {
+ isSecured.toggle()
+ }, label: {
+ Image(self.isSecured ? "eye-slash" : "eye")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 20, height: 20)
+ })
+ }
+ .padding(.horizontal, 20)
+ .padding(.vertical, 15)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(isPasswordFocused ? Color.orangeMain500 : (!registerViewModel.passwordError.isEmpty ? Color.redDanger500 : Color.gray200), lineWidth: 1)
+ )
+
+ Text(registerViewModel.passwordError)
+ .foregroundStyle(Color.redDanger500)
+ .default_text_style_600(styleSize: 15)
+ .padding(.bottom)
+
+ NavigationLink(isActive: $registerViewModel.isLinkActive, destination: {
+ RegisterCodeConfirmationFragment(registerViewModel: registerViewModel)
+ }, label: {
+ Text("assistant_account_create")
+ .default_text_style_white_600(styleSize: 20)
+ .frame(height: 35)
+ .frame(maxWidth: .infinity)
+
+ })
+ .padding(.horizontal, 20)
+ .padding(.vertical, 10)
+ .background((registerViewModel.username.isEmpty || registerViewModel.phoneNumber.isEmpty || registerViewModel.passwd.isEmpty) ? Color.orangeMain100 : Color.orangeMain500)
+ .cornerRadius(60)
+ .disabled(!registerViewModel.isLinkActive)
+ .padding(.bottom)
+ .simultaneousGesture(
+ TapGesture().onEnded {
+ if !(registerViewModel.username.isEmpty || registerViewModel.phoneNumber.isEmpty || registerViewModel.passwd.isEmpty) {
+ withAnimation {
+ self.isShowPopup = true
+ }
+ }
+ }
+ )
+
+ Spacer()
+
+ Text("assistant_create_account_using_email_on_our_web_platform")
+ .default_text_style(styleSize: 15)
+ .foregroundStyle(Color.grayMain2c700)
+ .padding(.horizontal, 10)
+ .frame(maxWidth: .infinity, alignment: .center)
+
+ Button(action: {
+ UIApplication.shared.open(URL(string: "https://subscribe.linphone.org/register/email")!)
+ }, label: {
+ Text("assistant_web_platform_link")
+ .default_text_style_orange_600(styleSize: 15)
+ .frame(height: 35)
+ })
+ .padding(.horizontal, 15)
+ .padding(.vertical, 5)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(Color.orangeMain500, lineWidth: 1)
+ )
+ .padding(.bottom)
+ .frame(maxWidth: .infinity)
+ }
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ .padding(.horizontal, 20)
+
+ Spacer()
+
+ HStack(alignment: .center) {
+
+ Spacer()
+
+ Text("assistant_already_have_an_account")
+ .default_text_style(styleSize: 15)
+ .foregroundStyle(Color.grayMain2c700)
+ .padding(.horizontal, 10)
+
+ Button(action: {
+ dismiss()
+ }, label: {
+ Text("assistant_account_login")
+ .default_text_style_white_600(styleSize: 20)
+ .frame(height: 35)
+ })
+ .padding(.horizontal, 20)
+ .padding(.vertical, 10)
+ .background(Color.orangeMain500)
+ .cornerRadius(60)
+ .padding(.horizontal, 10)
+
+ Spacer()
+ }
+ .padding(.bottom)
+
+ Image("mountain2")
+ .resizable()
+ .scaledToFill()
+ .frame(width: geometry.size.width, height: 60)
+ .clipped()
+ }
+ .frame(minHeight: geometry.size.height)
+ }
}
#Preview {
diff --git a/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountLoginFragment.swift b/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountLoginFragment.swift
index b814a2e25..8a728fc78 100644
--- a/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountLoginFragment.swift
+++ b/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountLoginFragment.swift
@@ -36,207 +36,216 @@ struct ThirdPartySipAccountLoginFragment: View {
var body: some View {
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.grayMain2c500)
- .frame(width: 25, height: 25, alignment: .leading)
- .padding(.all, 10)
- .padding(.top, -75)
- .padding(.leading, -10)
- .onTapGesture {
- withAnimation {
- accountLoginViewModel.domain = "sip.linphone.org"
- accountLoginViewModel.transportType = "TLS"
- dismiss()
- }
- }
-
- Spacer()
- }
- .padding(.leading)
- }
- .frame(width: geometry.size.width)
-
- Text("assistant_login_third_party_sip_account")
- .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)
- .disableAutocorrection(true)
- .autocapitalization(.none)
- .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.orangeMain500 : Color.gray200, 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)
- .disableAutocorrection(true)
- .autocapitalization(.none)
- .frame(height: 25)
- .focused($isPasswordFocused)
- }
- }
- Button(action: {
- isSecured.toggle()
- }, label: {
- Image(self.isSecured ? "eye-slash" : "eye")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .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.orangeMain500 : Color.gray200, lineWidth: 1)
- )
- .padding(.bottom)
-
- Text(String(localized: "sip_address_domain")+"*")
- .default_text_style_700(styleSize: 15)
- .padding(.bottom, -5)
-
- TextField("sip.linphone.org", text: $accountLoginViewModel.domain)
- .default_text_style(styleSize: 15)
- .disableAutocorrection(true)
- .autocapitalization(.none)
- .disabled(coreContext.loggedIn)
- .frame(height: 25)
- .padding(.horizontal, 20)
- .padding(.vertical, 15)
- .cornerRadius(60)
- .overlay(
- RoundedRectangle(cornerRadius: 60)
- .inset(by: 0.5)
- .stroke(isDomainFocused ? Color.orangeMain500 : Color.gray200, lineWidth: 1)
- )
- .padding(.bottom)
- .focused($isDomainFocused)
-
- Text(String(localized: "sip_address_display_name"))
- .default_text_style_700(styleSize: 15)
- .padding(.bottom, -5)
-
- TextField("sip_address_display_name", text: $accountLoginViewModel.displayName)
- .default_text_style(styleSize: 15)
- .disableAutocorrection(true)
- .autocapitalization(.none)
- .disabled(coreContext.loggedIn)
- .frame(height: 25)
- .padding(.horizontal, 20)
- .padding(.vertical, 15)
- .cornerRadius(60)
- .overlay(
- RoundedRectangle(cornerRadius: 60)
- .inset(by: 0.5)
- .stroke(isDisplayNameFocused ? Color.orangeMain500 : Color.gray200, lineWidth: 1)
- )
- .padding(.bottom)
- .focused($isDisplayNameFocused)
-
- Text(String(localized: "assistant_sip_account_transport_protocol"))
- .default_text_style_700(styleSize: 15)
- .padding(.bottom, -5)
-
- Menu {
- Button("TLS") {accountLoginViewModel.transportType = "TLS"}
- Button("TCP") {accountLoginViewModel.transportType = "TCP"}
- Button("UDP") {accountLoginViewModel.transportType = "UDP"}
- } label: {
- Text(accountLoginViewModel.transportType)
- .default_text_style(styleSize: 15)
- .frame(maxWidth: .infinity, alignment: .leading)
- Image("caret-down")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .frame(width: 20, height: 20)
- }
- .frame(height: 25)
- .padding(.horizontal, 20)
- .padding(.vertical, 15)
- .cornerRadius(60)
- .overlay(
- RoundedRectangle(cornerRadius: 60)
- .inset(by: 0.5)
- .stroke(Color.gray200, lineWidth: 1)
- )
- .padding(.bottom)
-
- Spacer()
-
- Button(action: {
- self.accountLoginViewModel.login()
- }, label: {
- Text(coreContext.loggedIn ? "manage_account_delete" : "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 || accountLoginViewModel.domain.isEmpty)
- ? Color.orangeMain100
- : Color.orangeMain500)
- .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)
+ if #available(iOS 16.4, *) {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
+ }
+ .scrollBounceBehavior(.basedOnSize)
+ } else {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
}
- .frame(minHeight: geometry.size.height)
}
}
+ .navigationTitle("")
.navigationBarHidden(true)
+ .edgesIgnoringSafeArea(.bottom)
+ .edgesIgnoringSafeArea(.horizontal)
+ }
+
+ func innerScrollView(geometry: GeometryProxy) -> some View {
+ VStack {
+ ZStack {
+ HStack {
+ Image("caret-left")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 25, height: 25)
+ .padding(.all, 10)
+ .onTapGesture {
+ withAnimation {
+ accountLoginViewModel.domain = "sip.linphone.org"
+ accountLoginViewModel.transportType = "TLS"
+ dismiss()
+ }
+ }
+ Spacer()
+ }
+
+ Text("assistant_login_third_party_sip_account")
+ .default_text_style_800(styleSize: 20)
+ }
+ .frame(width: geometry.size.width)
+ .padding(.top, 10)
+ .padding(.bottom, 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)
+ .disableAutocorrection(true)
+ .autocapitalization(.none)
+ .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.orangeMain500 : Color.gray200, 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)
+ .disableAutocorrection(true)
+ .autocapitalization(.none)
+ .frame(height: 25)
+ .focused($isPasswordFocused)
+ }
+ }
+ Button(action: {
+ isSecured.toggle()
+ }, label: {
+ Image(self.isSecured ? "eye-slash" : "eye")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .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.orangeMain500 : Color.gray200, lineWidth: 1)
+ )
+ .padding(.bottom)
+
+ Text(String(localized: "sip_address_domain")+"*")
+ .default_text_style_700(styleSize: 15)
+ .padding(.bottom, -5)
+
+ TextField("sip.linphone.org", text: $accountLoginViewModel.domain)
+ .default_text_style(styleSize: 15)
+ .disableAutocorrection(true)
+ .autocapitalization(.none)
+ .disabled(coreContext.loggedIn)
+ .frame(height: 25)
+ .padding(.horizontal, 20)
+ .padding(.vertical, 15)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(isDomainFocused ? Color.orangeMain500 : Color.gray200, lineWidth: 1)
+ )
+ .padding(.bottom)
+ .focused($isDomainFocused)
+
+ Text(String(localized: "sip_address_display_name"))
+ .default_text_style_700(styleSize: 15)
+ .padding(.bottom, -5)
+
+ TextField("sip_address_display_name", text: $accountLoginViewModel.displayName)
+ .default_text_style(styleSize: 15)
+ .disableAutocorrection(true)
+ .autocapitalization(.none)
+ .disabled(coreContext.loggedIn)
+ .frame(height: 25)
+ .padding(.horizontal, 20)
+ .padding(.vertical, 15)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(isDisplayNameFocused ? Color.orangeMain500 : Color.gray200, lineWidth: 1)
+ )
+ .padding(.bottom)
+ .focused($isDisplayNameFocused)
+
+ Text(String(localized: "assistant_sip_account_transport_protocol"))
+ .default_text_style_700(styleSize: 15)
+ .padding(.bottom, -5)
+
+ Menu {
+ Button("TLS") {accountLoginViewModel.transportType = "TLS"}
+ Button("TCP") {accountLoginViewModel.transportType = "TCP"}
+ Button("UDP") {accountLoginViewModel.transportType = "UDP"}
+ } label: {
+ Text(accountLoginViewModel.transportType)
+ .default_text_style(styleSize: 15)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ Image("caret-down")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 20, height: 20)
+ }
+ .frame(height: 25)
+ .padding(.horizontal, 20)
+ .padding(.vertical, 15)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(Color.gray200, lineWidth: 1)
+ )
+ .padding(.bottom)
+ }
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ .padding(.horizontal, 20)
+
+ Spacer()
+
+ Button(action: {
+ self.accountLoginViewModel.login()
+ }, label: {
+ Text(coreContext.loggedIn ? "manage_account_delete" : "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 || accountLoginViewModel.domain.isEmpty)
+ ? Color.orangeMain100
+ : Color.orangeMain500)
+ .cornerRadius(60)
+ .disabled(accountLoginViewModel.username.isEmpty || accountLoginViewModel.passwd.isEmpty || accountLoginViewModel.domain.isEmpty)
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ .padding(.horizontal)
+ .padding(.bottom)
+
+ Image("mountain2")
+ .resizable()
+ .scaledToFill()
+ .frame(width: geometry.size.width, height: 60)
+ .clipped()
+ }
+ .frame(minHeight: geometry.size.height)
}
}
diff --git a/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountWarningFragment.swift b/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountWarningFragment.swift
index 7e027730d..8ab788d7a 100644
--- a/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountWarningFragment.swift
+++ b/Linphone/UI/Assistant/Fragments/ThirdPartySipAccountWarningFragment.swift
@@ -30,154 +30,160 @@ struct ThirdPartySipAccountWarningFragment: View {
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.grayMain2c500)
- .frame(width: 25, height: 25, alignment: .leading)
- .padding(.all, 10)
- .padding(.top, -75)
- .padding(.leading, -10)
- .onTapGesture {
- withAnimation {
- dismiss()
- }
- }
-
- Spacer()
- }
- .padding(.leading)
- }
- .frame(width: geometry.size.width)
-
- Text("assistant_login_third_party_sip_account")
- .default_text_style_white_800(styleSize: 20)
- .padding(.top, 20)
- }
- .padding(.top, 35)
- .padding(.bottom, 10)
-
- Spacer()
-
- VStack(alignment: .leading) {
- HStack {
- Spacer()
- HStack(alignment: .center) {
- Image("chat-teardrop-text-slash")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .frame(width: 20, height: 20, alignment: .leading)
- }
- .padding(16)
- .background(Color.grayMain2c200)
- .cornerRadius(40)
- .padding(.horizontal)
-
- HStack(alignment: .center) {
- Image("video-camera-slash")
- .renderingMode(.template)
- .resizable()
- .foregroundStyle(Color.grayMain2c500)
- .frame(width: 20, height: 20, alignment: .leading)
- }
- .padding(16)
- .background(Color.grayMain2c200)
- .cornerRadius(40)
- .padding(.horizontal)
-
- Spacer()
- }
- .padding(.bottom, 40)
-
- Text(.init(String(format: String(localized: "assistant_third_party_sip_account_warning_explanation"), Bundle.main.displayName)))
- .default_text_style(styleSize: 15)
- .multilineTextAlignment(.center)
- .padding(.bottom)
-
- HStack {
- Spacer()
-
- HStack {
- Text("[linphone.org/contact](https://linphone.org/contact)")
- .tint(Color.orangeMain500)
- .default_text_style_orange_600(styleSize: 15)
- .frame(height: 35)
- }
- .padding(.horizontal, 15)
- .cornerRadius(60)
- .overlay(
- RoundedRectangle(cornerRadius: 60)
- .inset(by: 0.5)
- .stroke(Color.orangeMain500, lineWidth: 1)
- )
-
- Spacer()
- }
- .padding(.vertical)
- }
- .frame(maxWidth: sharedMainViewModel.maxWidth)
- .padding(.horizontal, 20)
-
- Spacer()
-
- Button(action: {
- dismiss()
- }, label: {
- Text("assistant_third_party_sip_account_create_linphone_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.orangeMain500, lineWidth: 1)
- )
- .frame(maxWidth: sharedMainViewModel.maxWidth)
- .padding(.horizontal)
-
- NavigationLink(destination: {
- ThirdPartySipAccountLoginFragment(accountLoginViewModel: accountLoginViewModel)
- }, label: {
- Text("assistant_third_party_sip_account_warning_ok")
- .default_text_style_white_600(styleSize: 20)
- .frame(height: 35)
- .frame(maxWidth: .infinity)
-
- })
- .padding(.horizontal, 20)
- .padding(.vertical, 10)
- .background(Color.orangeMain500)
- .cornerRadius(60)
- .frame(maxWidth: sharedMainViewModel.maxWidth)
- .padding(.horizontal)
- .padding(.bottom, geometry.safeAreaInsets.bottom.isEqual(to: 0.0) ? 20 : 0)
+ if #available(iOS 16.4, *) {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
+ }
+ .scrollBounceBehavior(.basedOnSize)
+ } else {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
}
- .frame(minHeight: geometry.size.height)
}
}
.navigationTitle("")
.navigationBarHidden(true)
+ .edgesIgnoringSafeArea(.bottom)
+ .edgesIgnoringSafeArea(.horizontal)
}
.navigationViewStyle(StackNavigationViewStyle())
.navigationTitle("")
.navigationBarHidden(true)
}
+
+ func innerScrollView(geometry: GeometryProxy) -> some View {
+ VStack {
+ ZStack {
+ HStack {
+ Image("caret-left")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 25, height: 25)
+ .padding(.all, 10)
+ .onTapGesture {
+ withAnimation {
+ dismiss()
+ }
+ }
+ Spacer()
+ }
+
+ Text("assistant_login_third_party_sip_account")
+ .default_text_style_800(styleSize: 20)
+ }
+ .frame(width: geometry.size.width)
+ .padding(.top, 10)
+ .padding(.bottom, 20)
+
+ Spacer()
+
+ VStack(alignment: .leading) {
+ HStack {
+ Spacer()
+ HStack(alignment: .center) {
+ Image("chat-teardrop-text-slash")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 25, height: 25, alignment: .leading)
+ }
+ .padding(20)
+ .background(Color.grayMain2c200)
+ .cornerRadius(40)
+ .padding(.horizontal)
+
+ HStack(alignment: .center) {
+ Image("video-camera-slash")
+ .renderingMode(.template)
+ .resizable()
+ .foregroundStyle(Color.grayMain2c500)
+ .frame(width: 25, height: 25, alignment: .leading)
+ }
+ .padding(20)
+ .background(Color.grayMain2c200)
+ .cornerRadius(40)
+ .padding(.horizontal)
+
+ Spacer()
+ }
+ .padding(.bottom, 40)
+
+ Text(.init(String(format: String(localized: "assistant_third_party_sip_account_warning_explanation"), Bundle.main.displayName)))
+ .default_text_style(styleSize: 15)
+ .multilineTextAlignment(.center)
+ .padding(.bottom)
+
+ HStack {
+ Spacer()
+
+ HStack {
+ Text("[linphone.org/contact](https://linphone.org/contact)")
+ .tint(Color.orangeMain500)
+ .default_text_style_orange_600(styleSize: 15)
+ .frame(height: 35)
+ }
+ .padding(.horizontal, 15)
+ .cornerRadius(60)
+ .overlay(
+ RoundedRectangle(cornerRadius: 60)
+ .inset(by: 0.5)
+ .stroke(Color.orangeMain500, lineWidth: 1)
+ )
+
+ Spacer()
+ }
+ .padding(.vertical)
+ }
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ .padding(.horizontal, 20)
+
+ Spacer()
+
+ Button(action: {
+ dismiss()
+ }, label: {
+ Text("assistant_third_party_sip_account_create_linphone_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.orangeMain500, lineWidth: 1)
+ )
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ .padding(.horizontal)
+
+ NavigationLink(destination: {
+ ThirdPartySipAccountLoginFragment(accountLoginViewModel: accountLoginViewModel)
+ }, label: {
+ Text("assistant_third_party_sip_account_warning_ok")
+ .default_text_style_white_600(styleSize: 20)
+ .frame(height: 35)
+ .frame(maxWidth: .infinity)
+
+ })
+ .padding(.horizontal, 20)
+ .padding(.vertical, 10)
+ .background(Color.orangeMain500)
+ .cornerRadius(60)
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ .padding(.horizontal)
+ .padding(.bottom)
+
+ Image("mountain2")
+ .resizable()
+ .scaledToFill()
+ .frame(width: geometry.size.width, height: 60)
+ .clipped()
+ }
+ .frame(minHeight: geometry.size.height)
+ }
}
#Preview {
diff --git a/Linphone/UI/Main/Viewmodel/SharedMainViewModel.swift b/Linphone/UI/Main/Viewmodel/SharedMainViewModel.swift
index 468d6aac9..588994bcf 100644
--- a/Linphone/UI/Main/Viewmodel/SharedMainViewModel.swift
+++ b/Linphone/UI/Main/Viewmodel/SharedMainViewModel.swift
@@ -33,7 +33,7 @@ class SharedMainViewModel: ObservableObject {
let displayProfileModeKey = "display_profile_mode"
let defaultAvatarKey = "default_avatar"
- var maxWidth = 400.0
+ var maxWidth = 600.0
private init() {
let preferences = UserDefaults.standard
diff --git a/Linphone/UI/Welcome/Fragments/WelcomePage1Fragment.swift b/Linphone/UI/Welcome/Fragments/WelcomePage1Fragment.swift
index ad318341f..9d04bfc51 100644
--- a/Linphone/UI/Welcome/Fragments/WelcomePage1Fragment.swift
+++ b/Linphone/UI/Welcome/Fragments/WelcomePage1Fragment.swift
@@ -39,7 +39,9 @@ struct WelcomePage1Fragment: View {
.multilineTextAlignment(.center)
}
- Spacer()
+ .padding(.horizontal)
+ .padding(.bottom, 60)
+
Spacer()
}
.frame(maxWidth: .infinity)
diff --git a/Linphone/UI/Welcome/Fragments/WelcomePage2Fragment.swift b/Linphone/UI/Welcome/Fragments/WelcomePage2Fragment.swift
index 0671ad332..3f9d45cfa 100644
--- a/Linphone/UI/Welcome/Fragments/WelcomePage2Fragment.swift
+++ b/Linphone/UI/Welcome/Fragments/WelcomePage2Fragment.swift
@@ -39,7 +39,9 @@ struct WelcomePage2Fragment: View {
.multilineTextAlignment(.center)
}
- Spacer()
+ .padding(.horizontal)
+ .padding(.bottom, 60)
+
Spacer()
}
.frame(maxWidth: .infinity)
diff --git a/Linphone/UI/Welcome/Fragments/WelcomePage3Fragment.swift b/Linphone/UI/Welcome/Fragments/WelcomePage3Fragment.swift
index 6dd0f61c4..6333a8302 100644
--- a/Linphone/UI/Welcome/Fragments/WelcomePage3Fragment.swift
+++ b/Linphone/UI/Welcome/Fragments/WelcomePage3Fragment.swift
@@ -39,7 +39,9 @@ struct WelcomePage3Fragment: View {
.multilineTextAlignment(.center)
}
- Spacer()
+ .padding(.horizontal)
+ .padding(.bottom, 60)
+
Spacer()
}
.frame(maxWidth: .infinity)
diff --git a/Linphone/UI/Welcome/WelcomeView.swift b/Linphone/UI/Welcome/WelcomeView.swift
index 73ef01cbf..d55cd0e5f 100644
--- a/Linphone/UI/Welcome/WelcomeView.swift
+++ b/Linphone/UI/Welcome/WelcomeView.swift
@@ -28,118 +28,131 @@ struct WelcomeView: View {
var body: some View {
NavigationView {
GeometryReader { geometry in
- ScrollView {
- VStack {
- ZStack {
- Image("mountain")
- .resizable()
- .scaledToFill()
- .frame(width: geometry.size.width, height: 100)
- .clipped()
-
- VStack(alignment: .trailing) {
- NavigationLink(destination: {
- PermissionsFragment()
- }, label: {
- Text("welcome_carousel_skip")
- .underline()
- .default_text_style_600(styleSize: 15)
-
- })
- .padding(.top, -35)
- .padding(.trailing, 20)
- .simultaneousGesture(
- TapGesture().onEnded {
- self.index = 2
- }
- )
- Text("welcome_page_title")
- .welcome_text_style_white_800(styleSize: 35)
- .padding(.trailing, 100)
- .frame(width: geometry.size.width)
- .padding(.bottom, -25)
- Text(String(format: String(localized: "welcome_page_subtitle"), Bundle.main.displayName))
- .welcome_text_style_white_800(styleSize: 25)
- .padding(.leading, 100)
- .frame(width: geometry.size.width)
- .padding(.bottom, -10)
- }
- .frame(width: geometry.size.width)
- }
- .padding(.top, 35)
- .padding(.bottom, 10)
-
- Spacer()
-
- VStack {
- TabView(selection: $index) {
- ForEach((0..<3), id: \.self) { index in
- if index == 0 {
- WelcomePage1Fragment()
- } else if index == 1 {
- WelcomePage2Fragment()
- } else if index == 2 {
- WelcomePage3Fragment()
- } else {
- WelcomePage1Fragment()
- }
- }
- }
- .tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
- .frame(minHeight: 300)
- .onAppear {
- setupAppearance()
- }
- }
-
- Spacer()
-
- if index == 2 {
- NavigationLink(destination: {
- PermissionsFragment()
- }, label: {
- Text("start")
- .default_text_style_white_600(styleSize: 20)
- .frame(height: 35)
- .frame(maxWidth: .infinity)
-
- })
- .padding(.horizontal, 20)
- .padding(.vertical, 10)
- .background(Color.orangeMain500)
- .cornerRadius(60)
- .padding(.horizontal)
- .padding(.bottom, geometry.safeAreaInsets.bottom.isEqual(to: 0.0) ? 20 : 0)
- .frame(maxWidth: sharedMainViewModel.maxWidth)
- } else {
- Button(action: {
- withAnimation {
- index += 1
- }
- }, label: {
- Text("next")
- .default_text_style_white_600(styleSize: 20)
- .frame(height: 35)
- .frame(maxWidth: .infinity)
- })
- .padding(.horizontal, 20)
- .padding(.vertical, 10)
- .background(Color.orangeMain500)
- .cornerRadius(60)
- .padding(.horizontal)
- .padding(.bottom, geometry.safeAreaInsets.bottom.isEqual(to: 0.0) ? 20 : 0)
- .frame(maxWidth: sharedMainViewModel.maxWidth)
- }
+ if #available(iOS 16.4, *) {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
+ }
+ .scrollBounceBehavior(.basedOnSize)
+ } else {
+ ScrollView(.vertical) {
+ innerScrollView(geometry: geometry)
}
- .frame(minHeight: geometry.size.height)
}
}
.navigationTitle("")
.navigationBarHidden(true)
+ .edgesIgnoringSafeArea(.bottom)
+ .edgesIgnoringSafeArea(.horizontal)
}
.navigationViewStyle(StackNavigationViewStyle())
}
+ func innerScrollView(geometry: GeometryProxy) -> some View {
+ VStack {
+ ZStack {
+ VStack(alignment: .trailing) {
+ NavigationLink(destination: {
+ PermissionsFragment()
+ }, label: {
+ Text("welcome_carousel_skip")
+ .underline()
+ .default_text_style_600(styleSize: 15)
+
+ })
+ .padding(.top, -35)
+ .padding(.trailing, 20)
+ .simultaneousGesture(
+ TapGesture().onEnded {
+ self.index = 2
+ }
+ )
+ Text("welcome_page_title")
+ .default_text_style_800(styleSize: 35)
+ .padding(.trailing, 100)
+ .frame(width: geometry.size.width)
+ .padding(.bottom, -25)
+ Text(String(format: String(localized: "welcome_page_subtitle"), Bundle.main.displayName))
+ .default_text_style_800(styleSize: 25)
+ .padding(.leading, 100)
+ .frame(width: geometry.size.width)
+ .padding(.bottom, -10)
+ }
+ .frame(width: geometry.size.width)
+ }
+ .padding(.top, 35)
+ .padding(.bottom, 10)
+
+ Spacer()
+
+ VStack {
+ TabView(selection: $index) {
+ ForEach((0..<3), id: \.self) { index in
+ if index == 0 {
+ WelcomePage1Fragment()
+ } else if index == 1 {
+ WelcomePage2Fragment()
+ } else if index == 2 {
+ WelcomePage3Fragment()
+ } else {
+ WelcomePage1Fragment()
+ }
+ }
+ }
+ .tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
+ .frame(minHeight: 300)
+ .onAppear {
+ setupAppearance()
+ }
+ }
+
+ Spacer()
+
+ if index == 2 {
+ NavigationLink(destination: {
+ PermissionsFragment()
+ }, label: {
+ Text("start")
+ .default_text_style_white_600(styleSize: 20)
+ .frame(height: 35)
+ .frame(maxWidth: .infinity)
+
+ })
+ .padding(.horizontal, 20)
+ .padding(.vertical, 10)
+ .background(Color.orangeMain500)
+ .cornerRadius(60)
+ .padding(.horizontal)
+ .padding(.bottom, geometry.safeAreaInsets.bottom.isEqual(to: 0.0) ? 20 : 0)
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ } else {
+ Button(action: {
+ withAnimation {
+ index += 1
+ }
+ }, label: {
+ Text("next")
+ .default_text_style_white_600(styleSize: 20)
+ .frame(height: 35)
+ .frame(maxWidth: .infinity)
+ })
+ .padding(.horizontal, 20)
+ .padding(.vertical, 10)
+ .background(Color.orangeMain500)
+ .cornerRadius(60)
+ .padding(.horizontal)
+ .padding(.bottom, geometry.safeAreaInsets.bottom.isEqual(to: 0.0) ? 20 : 0)
+ .frame(maxWidth: sharedMainViewModel.maxWidth)
+ }
+
+ Image("mountain2")
+ .resizable()
+ .scaledToFill()
+ .frame(width: geometry.size.width, height: 60)
+ .clipped()
+ }
+ .frame(minHeight: geometry.size.height)
+ }
+
func setupAppearance() {
UIPageControl.appearance().currentPageIndicatorTintColor = UIColor(Color.orangeMain500)
if #available(iOS 16.0, *) {