Converting SharedMainViewModel class into singleton

This commit is contained in:
Benoit Martins 2023-11-20 13:29:22 +01:00
parent 773d9584f4
commit 81a9dd9124
24 changed files with 99 additions and 54 deletions

View file

@ -24,11 +24,11 @@ import Combine
final class CoreContext: ObservableObject {
static let shared = CoreContext()
private var sharedMainViewModel = SharedMainViewModel.shared
var coreVersion: String = Core.getVersion
@Published var loggedIn: Bool = false
@Published var loggingInProgress: Bool = false
@Published var toastMessage: String = ""
@Published var defaultAccount: Account?
private var mCore: Core!
@ -71,9 +71,9 @@ final class CoreContext: ObservableObject {
self.mCore.publisher?.onConfiguringStatus?.postOnMainQueue { (cbVal: (core: Core, status: Config.ConfiguringState, message: String)) in
NSLog("New configuration state is \(cbVal.status) = \(cbVal.message)\n")
if cbVal.status == Config.ConfiguringState.Successful {
self.toastMessage = "Successful"
self.sharedMainViewModel.toastMessage = "Successful"
} else {
self.toastMessage = "Failed"
self.sharedMainViewModel.toastMessage = "Failed"
}
}
@ -90,7 +90,7 @@ final class CoreContext: ObservableObject {
} else if cbVal.state == .Progress {
self.loggingInProgress = true
} else {
self.toastMessage = "Registration failed"
self.sharedMainViewModel.toastMessage = "Registration failed"
self.loggingInProgress = false
self.loggedIn = false
}

View file

@ -23,7 +23,7 @@ import SwiftUI
struct LinphoneApp: App {
@ObservedObject private var coreContext = CoreContext.shared
@ObservedObject private var sharedMainViewModel = SharedMainViewModel()
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@State private var isActive = false
@ -31,10 +31,10 @@ struct LinphoneApp: App {
WindowGroup {
if isActive {
if !sharedMainViewModel.welcomeViewDisplayed {
WelcomeView(sharedMainViewModel: sharedMainViewModel)
WelcomeView()
} else if coreContext.defaultAccount == nil || sharedMainViewModel.displayProfileMode {
AssistantView(sharedMainViewModel: sharedMainViewModel)
.toast(isShowing: $coreContext.toastMessage)
AssistantView()
.toast(isShowing: $sharedMainViewModel.toastMessage)
} else if coreContext.defaultAccount != nil {
ContentView(
contactViewModel: ContactViewModel(),
@ -42,7 +42,7 @@ struct LinphoneApp: App {
historyViewModel: HistoryViewModel(),
historyListViewModel: HistoryListViewModel()
)
.toast(isShowing: $coreContext.toastMessage)
.toast(isShowing: $sharedMainViewModel.toastMessage)
}
} else {
SplashScreen(isActive: $isActive)

View file

@ -262,6 +262,9 @@
},
"First name*" : {
},
"History has been deleted" : {
},
"I prefere create an account" : {
@ -414,6 +417,9 @@
},
"SIP address :" : {
},
"SIP address copied into clipboard" : {
},
"sip.linphone.org" : {

View file

@ -21,18 +21,18 @@ import SwiftUI
struct AssistantView: View {
@ObservedObject var sharedMainViewModel: SharedMainViewModel
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@ObservedObject private var coreContext = CoreContext.shared
var body: some View {
if sharedMainViewModel.displayProfileMode && coreContext.loggedIn {
ProfileModeFragment(sharedMainViewModel: sharedMainViewModel)
ProfileModeFragment()
} else {
LoginFragment(accountLoginViewModel: AccountLoginViewModel(), sharedMainViewModel: sharedMainViewModel)
LoginFragment(accountLoginViewModel: AccountLoginViewModel())
}
}
}
#Preview {
LoginFragment(accountLoginViewModel: AccountLoginViewModel(), sharedMainViewModel: SharedMainViewModel())
LoginFragment(accountLoginViewModel: AccountLoginViewModel())
}

View file

@ -22,8 +22,8 @@ import SwiftUI
struct LoginFragment: View {
@ObservedObject private var coreContext = CoreContext.shared
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@ObservedObject var accountLoginViewModel: AccountLoginViewModel
@ObservedObject var sharedMainViewModel: SharedMainViewModel
@State private var isSecured: Bool = true
@ -183,7 +183,7 @@ struct LoginFragment: View {
.padding(.bottom)
NavigationLink(isActive: $isLinkSIPActive, destination: {
ThirdPartySipAccountWarningFragment(sharedMainViewModel: sharedMainViewModel, accountLoginViewModel: accountLoginViewModel)
ThirdPartySipAccountWarningFragment(accountLoginViewModel: accountLoginViewModel)
}, label: {
Text("Use SIP Account")
.default_text_style_orange_600(styleSize: 20)
@ -268,7 +268,7 @@ struct LoginFragment: View {
let contentPopup3 = Text(" et ")
let contentPopup4 = Text("[nos conditions dutilisation](https://linphone.org/general-terms)").underline()
let contentPopup5 = Text(".")
PopupView(sharedMainViewModel: sharedMainViewModel, isShowPopup: $isShowPopup,
PopupView(isShowPopup: $isShowPopup,
title: Text("Conditions de service"),
content: contentPopup1 + contentPopup2 + contentPopup3 + contentPopup4 + contentPopup5,
titleFirstButton: Text("Deny all"),
@ -283,7 +283,7 @@ struct LoginFragment: View {
}
if coreContext.loggingInProgress {
PopupLoadingView(sharedMainViewModel: sharedMainViewModel)
PopupLoadingView()
.background(.black.opacity(0.65))
}
}
@ -306,5 +306,5 @@ struct LoginFragment: View {
}
#Preview {
LoginFragment(accountLoginViewModel: AccountLoginViewModel(), sharedMainViewModel: SharedMainViewModel())
LoginFragment(accountLoginViewModel: AccountLoginViewModel())
}

View file

@ -21,7 +21,7 @@ import SwiftUI
struct PermissionsFragment: View {
@ObservedObject var sharedMainViewModel: SharedMainViewModel
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
var permissionManager = PermissionManager.shared
@ -204,5 +204,5 @@ struct PermissionsFragment: View {
}
#Preview {
PermissionsFragment(sharedMainViewModel: SharedMainViewModel())
PermissionsFragment()
}

View file

@ -21,7 +21,7 @@ import SwiftUI
struct ProfileModeFragment: View {
@ObservedObject var sharedMainViewModel: SharedMainViewModel
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@State var options: Int = 1
@State private var isShowPopup = false
@ -142,7 +142,7 @@ struct ProfileModeFragment: View {
}
if self.isShowPopup {
PopupView(sharedMainViewModel: sharedMainViewModel, isShowPopup: $isShowPopup,
PopupView(isShowPopup: $isShowPopup,
title: Text(isShowPopupForDefault ? "Default mode" : "Interoperable mode"),
content: Text(
isShowPopupForDefault
@ -167,5 +167,5 @@ struct ProfileModeFragment: View {
}
#Preview {
ProfileModeFragment(sharedMainViewModel: SharedMainViewModel())
ProfileModeFragment()
}

View file

@ -22,6 +22,7 @@ import SwiftUI
struct QrCodeScannerFragment: View {
@ObservedObject private var coreContext = CoreContext.shared
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@Environment(\.dismiss) var dismiss
@ -54,7 +55,7 @@ struct QrCodeScannerFragment: View {
.edgesIgnoringSafeArea(.all)
.navigationBarHidden(true)
if coreContext.toastMessage == "Successful" {
if sharedMainViewModel.toastMessage == "Successful" {
ZStack {
}.onAppear {

View file

@ -21,7 +21,7 @@ import SwiftUI
struct ThirdPartySipAccountLoginFragment: View {
@ObservedObject var sharedMainViewModel: SharedMainViewModel
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@ObservedObject private var coreContext = CoreContext.shared
@ObservedObject var accountLoginViewModel: AccountLoginViewModel
@ -233,5 +233,5 @@ struct ThirdPartySipAccountLoginFragment: View {
}
#Preview {
ThirdPartySipAccountLoginFragment(sharedMainViewModel: SharedMainViewModel(), accountLoginViewModel: AccountLoginViewModel())
ThirdPartySipAccountLoginFragment(accountLoginViewModel: AccountLoginViewModel())
}

View file

@ -21,7 +21,7 @@ import SwiftUI
struct ThirdPartySipAccountWarningFragment: View {
@ObservedObject var sharedMainViewModel: SharedMainViewModel
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@ObservedObject private var coreContext = CoreContext.shared
@ObservedObject var accountLoginViewModel: AccountLoginViewModel
@ -152,7 +152,7 @@ struct ThirdPartySipAccountWarningFragment: View {
.padding(.horizontal)
NavigationLink(destination: {
ThirdPartySipAccountLoginFragment(sharedMainViewModel: sharedMainViewModel, accountLoginViewModel: accountLoginViewModel)
ThirdPartySipAccountLoginFragment(accountLoginViewModel: accountLoginViewModel)
}, label: {
Text("I understand")
.default_text_style_white_600(styleSize: 20)
@ -178,5 +178,5 @@ struct ThirdPartySipAccountWarningFragment: View {
}
#Preview {
ThirdPartySipAccountWarningFragment(sharedMainViewModel: SharedMainViewModel(), accountLoginViewModel: AccountLoginViewModel())
ThirdPartySipAccountWarningFragment(accountLoginViewModel: AccountLoginViewModel())
}

View file

@ -43,6 +43,7 @@ struct QRScanner: UIViewControllerRepresentable {
class Coordinator: NSObject, AVCaptureMetadataOutputObjectsDelegate {
private var coreContext = CoreContext.shared
private var sharedMainViewModel = SharedMainViewModel.shared
@Binding var scanResult: String
private var lastResult: String = ""
@ -76,10 +77,10 @@ class Coordinator: NSObject, AVCaptureMetadataOutputObjectsDelegate {
try? core.start()
}
} else {
coreContext.toastMessage = "Invalide URI"
sharedMainViewModel.toastMessage = "Invalide URI"
}
} else {
coreContext.toastMessage = "Invalide URI"
sharedMainViewModel.toastMessage = "Invalide URI"
}
}
}

View file

@ -23,7 +23,7 @@ import ContactsUI
struct ContactInnerFragment: View {
@ObservedObject private var sharedMainViewModel = SharedMainViewModel()
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@ObservedObject var magicSearch = MagicSearchSingleton.shared

View file

@ -25,6 +25,7 @@ struct ContactListBottomSheet: View {
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@ObservedObject var magicSearch = MagicSearchSingleton.shared
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@ObservedObject var contactViewModel: ContactViewModel
@ -68,6 +69,9 @@ struct ContactListBottomSheet: View {
showingSheet.toggle()
dismiss()
}
sharedMainViewModel.toastMessage = "Success_copied_into_clipboard"
} label: {
HStack {
Image("copy")

View file

@ -23,7 +23,7 @@ import linphonesw
struct EditContactFragment: View {
@ObservedObject var editContactViewModel: EditContactViewModel
@ObservedObject private var sharedMainViewModel = SharedMainViewModel()
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@Environment(\.dismiss) var dismiss

View file

@ -488,7 +488,7 @@ struct ContentView: View {
}
if isShowDeleteContactPopup {
PopupView(sharedMainViewModel: SharedMainViewModel(), isShowPopup: $isShowDeleteContactPopup,
PopupView(isShowPopup: $isShowDeleteContactPopup,
title: Text(
contactViewModel.selectedFriend != nil
? "Delete \(contactViewModel.selectedFriend!.name!)?"
@ -530,7 +530,7 @@ struct ContentView: View {
}
if isShowDeleteAllHistoryPopup {
PopupView(sharedMainViewModel: SharedMainViewModel(), isShowPopup: $isShowDeleteContactPopup,
PopupView(isShowPopup: $isShowDeleteContactPopup,
title: Text("Do you really want to delete all calls history?"),
content: Text("All calls will be removed from the history."),
titleFirstButton: Text("Cancel"),
@ -552,7 +552,7 @@ struct ContentView: View {
}
if isShowDismissPopup {
PopupView(sharedMainViewModel: SharedMainViewModel(), isShowPopup: $isShowDismissPopup,
PopupView(isShowPopup: $isShowDismissPopup,
title: Text("Dont save modifications?"),
content: Text("All modifications will be canceled."),
titleFirstButton: Text("Cancel"),

View file

@ -21,7 +21,7 @@ import SwiftUI
struct PopupLoadingView: View {
@ObservedObject var sharedMainViewModel: SharedMainViewModel
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
var body: some View {
GeometryReader { geometry in
@ -54,6 +54,6 @@ struct PopupLoadingView: View {
}
#Preview {
PopupLoadingView(sharedMainViewModel: SharedMainViewModel())
PopupLoadingView()
.background(.black.opacity(0.65))
}

View file

@ -22,7 +22,7 @@ import Photos
struct PopupView: View {
@ObservedObject var sharedMainViewModel: SharedMainViewModel
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
var permissionManager = PermissionManager.shared
@ -100,7 +100,7 @@ struct PopupView: View {
}
#Preview {
PopupView(sharedMainViewModel: SharedMainViewModel(), isShowPopup: .constant(true),
PopupView(isShowPopup: .constant(true),
title: Text("Title"),
content: Text("Content"),
titleFirstButton: Text("Deny all"),

View file

@ -21,7 +21,7 @@ import SwiftUI
struct ToastView: ViewModifier {
@ObservedObject var sharedMainViewModel: SharedMainViewModel
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@Binding var isShowing: String
@ -29,6 +29,7 @@ struct ToastView: ViewModifier {
ZStack {
content
toastView
.padding(.top, 60)
}
}
@ -36,11 +37,11 @@ struct ToastView: ViewModifier {
VStack {
if !isShowing.isEmpty {
HStack {
Image(isShowing == "Successful" ? "smiley" : "warning-circle")
Image(isShowing.contains("Success") ? "check" : "warning-circle")
.resizable()
.renderingMode(.template)
.frame(width: 25, height: 25, alignment: .leading)
.foregroundStyle(isShowing == "Successful" ? Color.greenSuccess500 : Color.redDanger500)
.foregroundStyle(isShowing.contains("Success") ? Color.greenSuccess500 : Color.redDanger500)
switch isShowing {
case "Successful":
@ -50,6 +51,20 @@ struct ToastView: ViewModifier {
.default_text_style(styleSize: 15)
.padding(8)
case "Success_remove_call_logs":
Text("History has been deleted")
.multilineTextAlignment(.center)
.foregroundStyle(Color.greenSuccess500)
.default_text_style(styleSize: 15)
.padding(8)
case "Success_copied_into_clipboard":
Text("SIP address copied into clipboard")
.multilineTextAlignment(.center)
.foregroundStyle(Color.greenSuccess500)
.default_text_style(styleSize: 15)
.padding(8)
case "Failed":
Text("Invalid QR code!")
.multilineTextAlignment(.center)
@ -85,7 +100,7 @@ struct ToastView: ViewModifier {
.overlay(
RoundedRectangle(cornerRadius: 50)
.inset(by: 0.5)
.stroke(isShowing == "Successful" ? Color.greenSuccess500 : Color.redDanger500, lineWidth: 1)
.stroke(isShowing.contains("Success") ? Color.greenSuccess500 : Color.redDanger500, lineWidth: 1)
)
.onTapGesture {
isShowing = ""
@ -108,6 +123,6 @@ struct ToastView: ViewModifier {
extension View {
func toast(isShowing: Binding<String>) -> some View {
self.modifier(ToastView(sharedMainViewModel: SharedMainViewModel(), isShowing: isShowing))
self.modifier(ToastView(isShowing: isShowing))
}
}

View file

@ -24,7 +24,7 @@ struct HistoryContactFragment: View {
@State private var orientation = UIDevice.current.orientation
@ObservedObject var sharedMainViewModel = SharedMainViewModel()
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@ObservedObject var historyViewModel: HistoryViewModel
@ObservedObject var historyListViewModel: HistoryListViewModel
@ObservedObject var contactViewModel: ContactViewModel
@ -131,6 +131,8 @@ struct HistoryContactFragment: View {
forPasteboardType: UTType.plainText.identifier
)
}
sharedMainViewModel.toastMessage = "Success_copied_into_clipboard"
} label: {
HStack {
Text("Copy SIP address")

View file

@ -26,6 +26,8 @@ struct HistoryListBottomSheet: View {
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@ObservedObject var historyViewModel: HistoryViewModel
@ObservedObject var contactViewModel: ContactViewModel
@ObservedObject var editContactViewModel: EditContactViewModel
@ -161,6 +163,9 @@ struct HistoryListBottomSheet: View {
showingSheet.toggle()
dismiss()
}
sharedMainViewModel.toastMessage = "Success_copied_into_clipboard"
} label: {
HStack {
Image("copy")

View file

@ -42,7 +42,7 @@ struct HistoryView: View {
)
Button {
SharedMainViewModel.shared.toastMessage = "Success_remove_call_logs"
} label: {
Image("phone-plus")
.padding()

View file

@ -155,8 +155,11 @@ class HistoryListViewModel: ObservableObject {
} else {
core.clearCallLogs()
}
self.callLogs.removeAll()
self.callLogsTmp.removeAll()
DispatchQueue.main.async {
self.callLogs.removeAll()
self.callLogsTmp.removeAll()
}
}
} else {
removeCallLogsWithAddress()
@ -167,6 +170,10 @@ class HistoryListViewModel: ObservableObject {
func removeCallLogsWithAddress() {
self.callLogs.filter { $0.toAddress!.asStringUriOnly() == callLogsAddressToDelete || $0.fromAddress!.asStringUriOnly() == callLogsAddressToDelete }.forEach { callLog in
removeCallLog(callLog: callLog)
coreContext.doOnCoreQueue { core in
core.removeCallLog(callLog: callLog)
}
}
}

View file

@ -21,6 +21,10 @@ import linphonesw
class SharedMainViewModel: ObservableObject {
static let shared = SharedMainViewModel()
@Published var toastMessage: String = ""
@Published var welcomeViewDisplayed = false
@Published var generalTermsAccepted = false
@Published var displayProfileMode = false
@ -31,7 +35,7 @@ class SharedMainViewModel: ObservableObject {
var maxWidth = 400.0
init() {
private init() {
let preferences = UserDefaults.standard
if preferences.object(forKey: welcomeViewKey) == nil {

View file

@ -21,7 +21,7 @@ import SwiftUI
struct WelcomeView: View {
@ObservedObject var sharedMainViewModel: SharedMainViewModel
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
@State private var index = 0
@ -39,7 +39,7 @@ struct WelcomeView: View {
VStack(alignment: .trailing) {
NavigationLink(destination: {
PermissionsFragment(sharedMainViewModel: sharedMainViewModel)
PermissionsFragment()
}, label: {
Text("Skip")
.underline()
@ -96,7 +96,7 @@ struct WelcomeView: View {
if index == 2 {
NavigationLink(destination: {
PermissionsFragment(sharedMainViewModel: sharedMainViewModel)
PermissionsFragment()
}, label: {
Text("Start")
.default_text_style_white_600(styleSize: 20)
@ -158,5 +158,5 @@ struct WelcomeView: View {
}
#Preview {
WelcomeView(sharedMainViewModel: SharedMainViewModel())
WelcomeView()
}