diff --git a/Linphone.xcodeproj/project.pbxproj b/Linphone.xcodeproj/project.pbxproj index d810a9fc1..dea1d116b 100644 --- a/Linphone.xcodeproj/project.pbxproj +++ b/Linphone.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ 2B416B2E7C90375B792A28AE /* Pods_Linphone.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C08FB4788AD667D35BAE64D /* Pods_Linphone.framework */; }; D70C93DE2AC2D0F60063CA3B /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = D70C93DD2AC2D0F60063CA3B /* Localizable.xcstrings */; }; + D717071E2AC5922E0037746F /* ColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D717071D2AC5922E0037746F /* ColorExtension.swift */; }; + D71707202AC5989C0037746F /* TextExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D717071F2AC5989C0037746F /* TextExtension.swift */; }; D719ABB72ABC67BF00B41C10 /* LinphoneApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = D719ABB62ABC67BF00B41C10 /* LinphoneApp.swift */; }; D719ABB92ABC67BF00B41C10 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D719ABB82ABC67BF00B41C10 /* ContentView.swift */; }; D719ABBB2ABC67BF00B41C10 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D719ABBA2ABC67BF00B41C10 /* Assets.xcassets */; }; @@ -29,6 +31,8 @@ 2C08FB4788AD667D35BAE64D /* Pods_Linphone.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Linphone.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BC39A28B26EDB00C91AB7756 /* Pods-Linphone.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Linphone.release.xcconfig"; path = "Target Support Files/Pods-Linphone/Pods-Linphone.release.xcconfig"; sourceTree = ""; }; D70C93DD2AC2D0F60063CA3B /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; + D717071D2AC5922E0037746F /* ColorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorExtension.swift; sourceTree = ""; }; + D717071F2AC5989C0037746F /* TextExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextExtension.swift; sourceTree = ""; }; D719ABB32ABC67BF00B41C10 /* Linphone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Linphone.app; sourceTree = BUILT_PRODUCTS_DIR; }; D719ABB62ABC67BF00B41C10 /* LinphoneApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinphoneApp.swift; sourceTree = ""; }; D719ABB82ABC67BF00B41C10 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -78,6 +82,15 @@ path = Pods; sourceTree = ""; }; + D717071C2AC591EF0037746F /* utils */ = { + isa = PBXGroup; + children = ( + D717071D2AC5922E0037746F /* ColorExtension.swift */, + D717071F2AC5989C0037746F /* TextExtension.swift */, + ); + path = utils; + sourceTree = ""; + }; D719ABAA2ABC67BF00B41C10 = { isa = PBXGroup; children = ( @@ -101,6 +114,7 @@ children = ( D719ABC72ABC6FB200B41C10 /* core */, D719ABC52ABC6EE800B41C10 /* ui */, + D717071C2AC591EF0037746F /* utils */, D719ABB62ABC67BF00B41C10 /* LinphoneApp.swift */, D719ABBA2ABC67BF00B41C10 /* Assets.xcassets */, D719ABBC2ABC67BF00B41C10 /* Linphone.entitlements */, @@ -174,12 +188,12 @@ D7D24D0C2AC1B4C700C6F35B /* Fonts */ = { isa = PBXGroup; children = ( + D7D24D0F2AC1B4E800C6F35B /* NotoSans-Light.ttf */, + D7D24D0E2AC1B4E800C6F35B /* NotoSans-Regular.ttf */, + D7D24D0D2AC1B4E800C6F35B /* NotoSans-Medium.ttf */, + D7D24D102AC1B4E800C6F35B /* NotoSans-SemiBold.ttf */, D7D24D112AC1B4E800C6F35B /* NotoSans-Bold.ttf */, D7D24D122AC1B4E800C6F35B /* NotoSans-ExtraBold.ttf */, - D7D24D0F2AC1B4E800C6F35B /* NotoSans-Light.ttf */, - D7D24D0D2AC1B4E800C6F35B /* NotoSans-Medium.ttf */, - D7D24D0E2AC1B4E800C6F35B /* NotoSans-Regular.ttf */, - D7D24D102AC1B4E800C6F35B /* NotoSans-SemiBold.ttf */, ); path = Fonts; sourceTree = ""; @@ -305,11 +319,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + D71707202AC5989C0037746F /* TextExtension.swift in Sources */, D719ABB92ABC67BF00B41C10 /* ContentView.swift in Sources */, D719ABC92ABC6FD700B41C10 /* CoreContext.swift in Sources */, D719ABCF2ABC779A00B41C10 /* AccountLoginViewModel.swift in Sources */, D719ABB72ABC67BF00B41C10 /* LinphoneApp.swift in Sources */, D7A2EDD62AC18115005D90FC /* SharedMainViewModel.swift in Sources */, + D717071E2AC5922E0037746F /* ColorExtension.swift in Sources */, D719ABCC2ABC769C00B41C10 /* AssistantView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Linphone/Assets.xcassets/eye-slash.imageset/Contents.json b/Linphone/Assets.xcassets/eye-slash.imageset/Contents.json new file mode 100644 index 000000000..ea1110e56 --- /dev/null +++ b/Linphone/Assets.xcassets/eye-slash.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "eye-slash.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Linphone/Assets.xcassets/eye-slash.imageset/eye-slash.svg b/Linphone/Assets.xcassets/eye-slash.imageset/eye-slash.svg new file mode 100644 index 000000000..6dc0e47a4 --- /dev/null +++ b/Linphone/Assets.xcassets/eye-slash.imageset/eye-slash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Linphone/Assets.xcassets/eye.imageset/Contents.json b/Linphone/Assets.xcassets/eye.imageset/Contents.json new file mode 100644 index 000000000..d5696cab8 --- /dev/null +++ b/Linphone/Assets.xcassets/eye.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "eye.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Linphone/Assets.xcassets/eye.imageset/eye.svg b/Linphone/Assets.xcassets/eye.imageset/eye.svg new file mode 100644 index 000000000..36ed4da10 --- /dev/null +++ b/Linphone/Assets.xcassets/eye.imageset/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Linphone/Assets.xcassets/qr-code.imageset/Contents.json b/Linphone/Assets.xcassets/qr-code.imageset/Contents.json new file mode 100644 index 000000000..12ceab544 --- /dev/null +++ b/Linphone/Assets.xcassets/qr-code.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "qr-code.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Linphone/Assets.xcassets/qr-code.imageset/qr-code.svg b/Linphone/Assets.xcassets/qr-code.imageset/qr-code.svg new file mode 100644 index 000000000..d5cd44274 --- /dev/null +++ b/Linphone/Assets.xcassets/qr-code.imageset/qr-code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Linphone/Localizable.xcstrings b/Linphone/Localizable.xcstrings index e80c25f45..4b684b10d 100644 --- a/Linphone/Localizable.xcstrings +++ b/Linphone/Localizable.xcstrings @@ -3,6 +3,9 @@ "strings" : { "" : { + }, + " or " : { + }, "%lld Book (Example)" : { "extractionState" : "manual", @@ -74,19 +77,13 @@ } } }, - "Core Version is %@" : { + "Forgotten password?" : { }, - "Create & \nlog in account" : { + "Log out" : { }, - "Log out & \ndelete account" : { - - }, - "Login State : " : { - - }, - "Looged in" : { + "Not account yet?" : { }, "password" : { @@ -105,6 +102,12 @@ } } } + }, + "Register" : { + + }, + "Scan QR code" : { + }, "TCP" : { @@ -112,7 +115,7 @@ "TLS" : { }, - "Unregistered" : { + "Use SIP Account" : { }, "username" : { diff --git a/Linphone/ui/assistant/AssistantView.swift b/Linphone/ui/assistant/AssistantView.swift index c44ca1eb8..aa219ef92 100644 --- a/Linphone/ui/assistant/AssistantView.swift +++ b/Linphone/ui/assistant/AssistantView.swift @@ -1,180 +1,238 @@ /* -* 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 . -*/ + * 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 AssistantView: View { - - @ObservedObject private var coreContext = CoreContext.shared - @ObservedObject var accountLoginViewModel : AccountLoginViewModel - - var body: some View { - VStack { - ZStack { - Image("Mountain") - .resizable() - .frame(width: 1080, height: 108) - Text("assistant_account_login") - .font(Font.custom("NotoSans-ExtraBold", size: 20)) - .foregroundColor(.white) - } - .padding(.top, 35) - - HStack(alignment: .center, spacing: 0) { - VStack(alignment: .leading, spacing: 0) { - Text(String(localized: "username")+"*") - .font(Font.custom("Noto Sans", size: 15) - .weight(.bold)) - .padding(.bottom, 5) - - TextField("username", text : $accountLoginViewModel.username) - .font(Font.custom("Noto Sans", size: 15)) - .disabled(coreContext.loggedIn) - .frame(height: 20) - .padding(.horizontal, 20) - .padding(.vertical, 15) - .frame(maxWidth: .infinity, alignment: .leading) - .background(Color(red: 0.98, green: 0.98, blue: 0.98)) - .cornerRadius(60) - .overlay( - RoundedRectangle(cornerRadius: 63) - .inset(by: 0.5) - .stroke(Color(red: 0.93, green: 0.93, blue: 0.93), lineWidth: 1) - ) - .padding(.bottom, 15) - - Text(String(localized: "password")+"*") - .font(Font.custom("Noto Sans", size: 15) - .weight(.bold)) - .padding(.bottom, 5) - - SecureInputView(String(localized: "password"), text: $accountLoginViewModel.passwd) - .disabled(coreContext.loggedIn) - .frame(height: 20) - .padding(.horizontal, 20) - .padding(.vertical, 15) - .frame(maxWidth: .infinity, alignment: .leading) - .background(Color(red: 0.98, green: 0.98, blue: 0.98)) - .cornerRadius(63) - .overlay( - RoundedRectangle(cornerRadius: 63) - .inset(by: 0.5) - .stroke(Color(red: 0.93, green: 0.93, blue: 0.93), lineWidth: 1) - ) - .padding(.bottom, 32) - - Button(action: accountLoginViewModel.login) { - Text("assistant_account_login") - .font(Font.custom("NotoSans-ExtraBold", size: 20)) - .foregroundColor(.white) - } - .disabled(coreContext.loggedIn) - .padding(.horizontal, 20) - .padding(.vertical, 10) - .frame(maxWidth: .infinity, alignment: .center) - .background(Color(red: 1, green: 0.37, blue: 0)) - .cornerRadius(63) - .overlay( - RoundedRectangle(cornerRadius: 63) - .inset(by: 0.5) - .stroke(Color(red: 1, green: 0.37, blue: 0), lineWidth: 1) - ) - - } - } - .padding(.top, 5) - .padding(.bottom, 20) - - VStack { - HStack { - Button(action: { - if (self.coreContext.loggedIn) - { - self.accountLoginViewModel.unregister() - self.accountLoginViewModel.delete() - } else { - self.accountLoginViewModel.login() - } - }) - { - Text(coreContext.loggedIn ? "Log out & \ndelete account" : "Create & \nlog in account") - .font(.largeTitle) - .foregroundColor(Color.white) - .frame(width: 220.0, height: 90) - .background(Color.gray) + + @ObservedObject private var coreContext = CoreContext.shared + @ObservedObject var accountLoginViewModel : AccountLoginViewModel + + @State private var isSecured: Bool = true + + @FocusState var isNameFocused:Bool + @FocusState var isPasswordFocused:Bool + + var body: some View { + 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: { + 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) + + Button(action: { + + }) { + Text("Forgotten password?") + .underline() + .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) + + Button(action: { + + }) { + 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) + } + .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) + + Button(action: { + + }) { + 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) } - HStack { - Text("Login State : ") - .font(.footnote) - Text(coreContext.loggedIn ? "Looged in" : "Unregistered") - .font(.footnote) - .foregroundColor(coreContext.loggedIn ? Color.green : Color.black) - }.padding(.top, 10.0) } - Group { - Spacer() - Text("Core Version is \(coreContext.coreVersion)") - } - } - .padding() - } + } + } } struct AssistantView_Previews: PreviewProvider { - - static var previews: some View { - AssistantView(accountLoginViewModel: AccountLoginViewModel()) - } -} - - -struct SecureInputView: View { - - @Binding private var text: String - @State private var isSecured: Bool = true - private var title: String - - init(_ title: String, text: Binding) { - self.title = title - self._text = text - } - - var body: some View { - ZStack(alignment: .trailing) { - Group { - if isSecured { - SecureField(title, text: $text) - .font(Font.custom("Noto Sans", size: 15)) - } else { - TextField(title, text: $text) - .font(Font.custom("Noto Sans", size: 15)) - } - }.padding(.trailing, 32) - - Button(action: { - isSecured.toggle() - }) { - Image(systemName: self.isSecured ? "eye.slash" : "eye") - .accentColor(.gray) - } - } - } + + static var previews: some View { + AssistantView(accountLoginViewModel: AccountLoginViewModel()) + } } diff --git a/Linphone/ui/assistant/viewmodel/AccountLoginViewModel.swift b/Linphone/ui/assistant/viewmodel/AccountLoginViewModel.swift index 184a8e713..3920bce13 100644 --- a/Linphone/ui/assistant/viewmodel/AccountLoginViewModel.swift +++ b/Linphone/ui/assistant/viewmodel/AccountLoginViewModel.swift @@ -17,8 +17,8 @@ * along with this program. If not, see . */ -import SwiftUI import linphonesw +import SwiftUI class AccountLoginViewModel : ObservableObject { diff --git a/Linphone/utils/ColorExtension.swift b/Linphone/utils/ColorExtension.swift new file mode 100644 index 000000000..4846fbfb1 --- /dev/null +++ b/Linphone/utils/ColorExtension.swift @@ -0,0 +1,91 @@ +/* +* 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 + +extension Color { + + static let transparent_color = Color(hex: "#00000000") + static let black = Color(hex: "#000000") + static let white = Color(hex: "#FFFFFF") + + static let orange_main_700 = Color(hex: "#B72D00") + static let orange_main_500 = Color(hex: "#FF5E00") + static let orange_main_300 = Color(hex: "#FFB266") + static let orange_main_100 = Color(hex: "#FFEACB") + static let orange_main_100_alpha_50 = Color(hex: "#80FFEACB") + + static let gray_main2_800 = Color(hex: "#22334D") + static let gray_main2_800_alpha_65 = Color(hex: "#A622334D") + static let gray_main2_700 = Color(hex: "#364860") + static let gray_main2_600 = Color(hex: "#4E6074") + static let gray_main2_500 = Color(hex: "#6C7A87") + static let gray_main2_400 = Color(hex: "#9AABB5") + static let gray_main2_300 = Color(hex: "#C0D1D9") + static let gray_main2_200 = Color(hex: "#DFECF2") + static let gray_main2_100 = Color(hex: "#EEF6F8") + + static let gray_100 = Color(hex: "#F9F9F9") + static let gray_200 = Color(hex: "#EDEDED") + static let gray_300 = Color(hex: "#C9C9C9") + static let gray_400 = Color(hex: "#949494") + static let gray_500 = Color(hex: "#4E4E4E") + static let gray_600 = Color(hex: "#2E3030") + static let gray_900 = Color(hex: "#070707") + + static let red_danger_200 = Color(hex: "#F5CCBE") + static let red_danger_500 = Color(hex: "#DD5F5F") + static let red_danger_700 = Color(hex: "#9E3548") + + static let green_success_500 = Color(hex: "#4FAE80") + static let green_success_700 = Color(hex: "#377D71") + static let green_success_200 = Color(hex: "#ACF5C1") + + static let blue_info_500 = Color(hex: "#4AA8FF") + + static let orange_warning_600 = Color(hex: "#DBB820") + + static let orange_away = Color(hex: "#FFA645") + + init(hex: String) { + let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) + var int: UInt64 = 0 + Scanner(string: hex).scanHexInt64(&int) + let a, r, g, b: UInt64 + switch hex.count { + case 3: // RGB (12-bit) + (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) + case 6: // RGB (24-bit) + (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) + case 8: // ARGB (32-bit) + (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) + default: + (a, r, g, b) = (1, 1, 1, 0) + } + + self.init( + .sRGB, + red: Double(r) / 255, + green: Double(g) / 255, + blue: Double(b) / 255, + opacity: Double(a) / 255 + ) + } +} diff --git a/Linphone/utils/TextExtension.swift b/Linphone/utils/TextExtension.swift new file mode 100644 index 000000000..b48850251 --- /dev/null +++ b/Linphone/utils/TextExtension.swift @@ -0,0 +1,114 @@ +/* + * 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 + +extension View { + + func default_text_style_300(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Light", size: styleSize)) + .foregroundStyle(Color.gray_main2_600) + } + + func default_text_style(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Regular", size: styleSize)) + .foregroundStyle(Color.gray_main2_600) + } + + func default_text_style_500(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Medium", size: styleSize)) + .foregroundStyle(Color.gray_main2_600) + } + + func default_text_style_600(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-SemiBold", size: styleSize)) + .foregroundStyle(Color.gray_main2_600) + } + + func default_text_style_700(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Bold", size: styleSize)) + .foregroundStyle(Color.gray_main2_600) + } + + func default_text_style_800(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-ExtraBold", size: styleSize)) + .foregroundStyle(Color.gray_main2_600) + } + + func default_text_style_white_300(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Light", size: styleSize)) + .foregroundStyle(Color.white) + } + + func default_text_style_white(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Regular", size: styleSize)) + .foregroundStyle(Color.white) + } + + func default_text_style_white_500(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Medium", size: styleSize)) + .foregroundStyle(Color.white) + } + + func default_text_style_white_600(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-SemiBold", size: styleSize)) + .foregroundStyle(Color.white) + } + + func default_text_style_white_700(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Bold", size: styleSize)) + .foregroundStyle(Color.white) + } + + func default_text_style_white_800(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-ExtraBold", size: styleSize)) + .foregroundStyle(Color.white) + } + + func default_text_style_orange_300(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Light", size: styleSize)) + .foregroundStyle(Color.orange_main_500) + } + + func default_text_style_orange(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Regular", size: styleSize)) + .foregroundStyle(Color.orange_main_500) + } + + func default_text_style_orange_500(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Medium", size: styleSize)) + .foregroundStyle(Color.orange_main_500) + } + + func default_text_style_orange_600(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-SemiBold", size: styleSize)) + .foregroundStyle(Color.orange_main_500) + } + + func default_text_style_orange_700(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-Bold", size: styleSize)) + .foregroundStyle(Color.orange_main_500) + } + + func default_text_style_orange_800(styleSize: CGFloat) -> some View { + self.font(Font.custom("NotoSans-ExtraBold", size: styleSize)) + .foregroundStyle(Color.orange_main_500) + } +}