mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
Extract AddParticipantsViewModel from the ScheduleMeetingViewModel to be used for other future views
This commit is contained in:
parent
1f0c3fa5f7
commit
19da4e0d64
5 changed files with 71 additions and 41 deletions
|
|
@ -13,6 +13,7 @@
|
|||
6613A0B02BAEB7F4008923A4 /* MeetingsListFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A0AF2BAEB7F4008923A4 /* MeetingsListFragment.swift */; };
|
||||
6613A0B42BAEBE3F008923A4 /* MeetingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A0B32BAEBE3F008923A4 /* MeetingViewModel.swift */; };
|
||||
6613A0B62BAEBE5C008923A4 /* ScheduleMeetingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A0B52BAEBE5C008923A4 /* ScheduleMeetingViewModel.swift */; };
|
||||
66162A202BDFC2F900DCE913 /* AddParticipantsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66162A1F2BDFC2F900DCE913 /* AddParticipantsViewModel.swift */; };
|
||||
662B69D92B25DE18007118BF /* TelecomManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662B69D82B25DE18007118BF /* TelecomManager.swift */; };
|
||||
662B69DB2B25DE25007118BF /* ProviderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662B69DA2B25DE25007118BF /* ProviderDelegate.swift */; };
|
||||
6646A7A32BB2E224006B842A /* ScheduleMeetingFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6646A7A22BB2E224006B842A /* ScheduleMeetingFragment.swift */; };
|
||||
|
|
@ -167,6 +168,7 @@
|
|||
6613A0AF2BAEB7F4008923A4 /* MeetingsListFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingsListFragment.swift; sourceTree = "<group>"; };
|
||||
6613A0B32BAEBE3F008923A4 /* MeetingViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeetingViewModel.swift; sourceTree = "<group>"; };
|
||||
6613A0B52BAEBE5C008923A4 /* ScheduleMeetingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScheduleMeetingViewModel.swift; sourceTree = "<group>"; };
|
||||
66162A1F2BDFC2F900DCE913 /* AddParticipantsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddParticipantsViewModel.swift; sourceTree = "<group>"; };
|
||||
662B69D82B25DE18007118BF /* TelecomManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelecomManager.swift; sourceTree = "<group>"; };
|
||||
662B69DA2B25DE25007118BF /* ProviderDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProviderDelegate.swift; sourceTree = "<group>"; };
|
||||
6646A7A22BB2E224006B842A /* ScheduleMeetingFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScheduleMeetingFragment.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -658,6 +660,7 @@
|
|||
D7A2EDD42AC180FE005D90FC /* Viewmodel */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
66162A1F2BDFC2F900DCE913 /* AddParticipantsViewModel.swift */,
|
||||
D7A2EDD52AC18115005D90FC /* SharedMainViewModel.swift */,
|
||||
D796F1FF2B0BB61A0041115F /* ToastViewModel.swift */,
|
||||
);
|
||||
|
|
@ -980,6 +983,7 @@
|
|||
D734499B2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift in Sources */,
|
||||
D719ABB72ABC67BF00B41C10 /* LinphoneApp.swift in Sources */,
|
||||
66E50A4B2BD12B7800AD61CA /* MeetingsFragment.swift in Sources */,
|
||||
66162A202BDFC2F900DCE913 /* AddParticipantsViewModel.swift in Sources */,
|
||||
D732A91B2B061BD900DB42BA /* HistoryListBottomSheet.swift in Sources */,
|
||||
D72250632ADE9615008FB426 /* HistoryViewModel.swift in Sources */,
|
||||
66E56BC92BA4A6D7006CE56F /* MeetingsListViewModel.swift in Sources */,
|
||||
|
|
@ -1252,7 +1256,7 @@
|
|||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||
CODE_SIGN_ENTITLEMENTS = Linphone/Linphone.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 4;
|
||||
CURRENT_PROJECT_VERSION = 10;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Linphone/Preview Content\"";
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ struct AddParticipantsFragment: View {
|
|||
|
||||
@ObservedObject var contactsManager = ContactsManager.shared
|
||||
@ObservedObject var magicSearch = MagicSearchSingleton.shared
|
||||
@ObservedObject var scheduleMeetingViewModel: ScheduleMeetingViewModel
|
||||
@ObservedObject var addParticipantsViewModel: AddParticipantsViewModel
|
||||
var confirmAddParticipantsFunc: ([SelectedAddressModel]) -> Void
|
||||
|
||||
@State private var delayedColor = Color.white
|
||||
@FocusState var isSearchFieldFocused: Bool
|
||||
|
|
@ -50,7 +51,7 @@ struct AddParticipantsFragment: View {
|
|||
.padding(.top, 2)
|
||||
.padding(.leading, -10)
|
||||
.onTapGesture {
|
||||
scheduleMeetingViewModel.participantsToAdd = []
|
||||
addParticipantsViewModel.reset()
|
||||
dismiss()
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +60,7 @@ struct AddParticipantsFragment: View {
|
|||
.multilineTextAlignment(.leading)
|
||||
.default_text_style_orange_800(styleSize: 16)
|
||||
.padding(.top, 20)
|
||||
Text("\($scheduleMeetingViewModel.participants.count) selected participants")
|
||||
Text("\($addParticipantsViewModel.participantsToAdd.count) selected participants")
|
||||
.default_text_style_300(styleSize: 12)
|
||||
}
|
||||
Spacer()
|
||||
|
|
@ -72,12 +73,12 @@ struct AddParticipantsFragment: View {
|
|||
|
||||
ScrollView(.horizontal) {
|
||||
HStack {
|
||||
ForEach(0..<scheduleMeetingViewModel.participantsToAdd.count, id: \.self) { index in
|
||||
ForEach(0..<addParticipantsViewModel.participantsToAdd.count, id: \.self) { index in
|
||||
ZStack(alignment: .topTrailing) {
|
||||
VStack {
|
||||
Avatar(contactAvatarModel: scheduleMeetingViewModel.participantsToAdd[index].avatarModel, avatarSize: 50)
|
||||
Avatar(contactAvatarModel: addParticipantsViewModel.participantsToAdd[index].avatarModel, avatarSize: 50)
|
||||
|
||||
Text(scheduleMeetingViewModel.participantsToAdd[index].avatarModel.name)
|
||||
Text(addParticipantsViewModel.participantsToAdd[index].avatarModel.name)
|
||||
.default_text_style(styleSize: 12)
|
||||
.frame(minWidth: 60, maxWidth:80)
|
||||
}
|
||||
|
|
@ -87,7 +88,7 @@ struct AddParticipantsFragment: View {
|
|||
.foregroundStyle(Color.grayMain2c500)
|
||||
.frame(width: 25, height: 25)
|
||||
.onTapGesture {
|
||||
scheduleMeetingViewModel.participantsToAdd.remove(at: index)
|
||||
addParticipantsViewModel.participantsToAdd.remove(at: index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -96,12 +97,12 @@ struct AddParticipantsFragment: View {
|
|||
.padding(.leading, 16)
|
||||
|
||||
ZStack(alignment: .trailing) {
|
||||
TextField("Search contact", text: $scheduleMeetingViewModel.searchField)
|
||||
TextField("Search contact", text: $addParticipantsViewModel.searchField)
|
||||
.default_text_style(styleSize: 15)
|
||||
.frame(height: 25)
|
||||
.focused($isSearchFieldFocused)
|
||||
.padding(.horizontal, 30)
|
||||
.onChange(of: scheduleMeetingViewModel.searchField) { newValue in
|
||||
.onChange(of: addParticipantsViewModel.searchField) { newValue in
|
||||
magicSearch.currentFilterSuggestions = newValue
|
||||
magicSearch.searchForSuggestions()
|
||||
}.onAppear {
|
||||
|
|
@ -120,9 +121,9 @@ struct AddParticipantsFragment: View {
|
|||
|
||||
Spacer()
|
||||
|
||||
if !scheduleMeetingViewModel.searchField.isEmpty {
|
||||
if !addParticipantsViewModel.searchField.isEmpty {
|
||||
Button(action: {
|
||||
scheduleMeetingViewModel.searchField = ""
|
||||
addParticipantsViewModel.searchField = ""
|
||||
magicSearch.currentFilterSuggestions = ""
|
||||
magicSearch.searchForSuggestions()
|
||||
isSearchFieldFocused = false
|
||||
|
|
@ -199,7 +200,7 @@ struct AddParticipantsFragment: View {
|
|||
.background(.white)
|
||||
.onTapGesture {
|
||||
if let addr = contactsManager.lastSearch[index].address {
|
||||
scheduleMeetingViewModel.selectParticipant(addr: addr)
|
||||
addParticipantsViewModel.selectParticipant(addr: addr)
|
||||
}
|
||||
}
|
||||
.buttonStyle(.borderless)
|
||||
|
|
@ -220,7 +221,7 @@ struct AddParticipantsFragment: View {
|
|||
}
|
||||
Button {
|
||||
withAnimation {
|
||||
scheduleMeetingViewModel.addParticipants()
|
||||
confirmAddParticipantsFunc(addParticipantsViewModel.participantsToAdd)
|
||||
dismiss()
|
||||
}
|
||||
} label: {
|
||||
|
|
@ -248,7 +249,7 @@ struct AddParticipantsFragment: View {
|
|||
ForEach(0..<contactsManager.lastSearchSuggestions.count, id: \.self) { index in
|
||||
Button {
|
||||
if let addr = contactsManager.lastSearchSuggestions[index].address {
|
||||
scheduleMeetingViewModel.selectParticipant(addr: addr)
|
||||
addParticipantsViewModel.selectParticipant(addr: addr)
|
||||
}
|
||||
} label: {
|
||||
HStack {
|
||||
|
|
@ -288,5 +289,5 @@ struct AddParticipantsFragment: View {
|
|||
}
|
||||
|
||||
#Preview {
|
||||
AddParticipantsFragment(scheduleMeetingViewModel: ScheduleMeetingViewModel())
|
||||
AddParticipantsFragment(addParticipantsViewModel: AddParticipantsViewModel(), confirmAddParticipantsFunc: {_ in } )
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ struct ScheduleMeetingFragment: View {
|
|||
@State var selectedHours: Int = 0
|
||||
@State var selectedMinutes: Int = 0
|
||||
|
||||
@State var addParticipantsViewModel = AddParticipantsViewModel()
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
|
|
@ -284,7 +286,10 @@ struct ScheduleMeetingFragment: View {
|
|||
|
||||
VStack {
|
||||
NavigationLink(destination: {
|
||||
AddParticipantsFragment(scheduleMeetingViewModel: scheduleMeetingViewModel)
|
||||
AddParticipantsFragment(addParticipantsViewModel: addParticipantsViewModel, confirmAddParticipantsFunc: scheduleMeetingViewModel.addParticipants)
|
||||
.onAppear {
|
||||
addParticipantsViewModel.participantsToAdd = scheduleMeetingViewModel.participants
|
||||
}
|
||||
}, label: {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
Image("users")
|
||||
|
|
@ -300,6 +305,7 @@ struct ScheduleMeetingFragment: View {
|
|||
Spacer()
|
||||
}
|
||||
})
|
||||
|
||||
if !scheduleMeetingViewModel.participants.isEmpty {
|
||||
ScrollView {
|
||||
ForEach(0..<scheduleMeetingViewModel.participants.count, id: \.self) { index in
|
||||
|
|
|
|||
|
|
@ -21,16 +21,6 @@ import Foundation
|
|||
import linphonesw
|
||||
import Combine
|
||||
|
||||
class SelectedAddressModel: ObservableObject {
|
||||
var address: Address
|
||||
var avatarModel: ContactAvatarModel
|
||||
|
||||
init (addr: Address, avModel: ContactAvatarModel) {
|
||||
address = addr
|
||||
avatarModel = avModel
|
||||
}
|
||||
}
|
||||
|
||||
class ScheduleMeetingViewModel: ObservableObject {
|
||||
static let TAG = "[ScheduleMeetingViewModel]"
|
||||
|
||||
|
|
@ -45,13 +35,10 @@ class ScheduleMeetingViewModel: ObservableObject {
|
|||
@Published var toTime: String = ""
|
||||
@Published var timezone: String = ""
|
||||
@Published var sendInvitations: Bool = true
|
||||
@Published var participantsToAdd: [SelectedAddressModel] = []
|
||||
@Published var participants: [SelectedAddressModel] = []
|
||||
@Published var operationInProgress: Bool = false
|
||||
@Published var conferenceCreatedEvent: Bool = false
|
||||
|
||||
@Published var searchField: String = ""
|
||||
|
||||
var conferenceScheduler: ConferenceScheduler?
|
||||
private var mSchedulerSubscriptions = Set<AnyCancellable?>()
|
||||
var conferenceInfoToEdit: ConferenceInfo?
|
||||
|
|
@ -75,11 +62,9 @@ class ScheduleMeetingViewModel: ObservableObject {
|
|||
allDayMeeting = false
|
||||
timezone = ""
|
||||
sendInvitations = true
|
||||
participantsToAdd = []
|
||||
participants = []
|
||||
operationInProgress = false
|
||||
conferenceCreatedEvent = false
|
||||
searchField = ""
|
||||
|
||||
fromDate = Calendar.current.date(byAdding: .hour, value: 1, to: Date.now)!
|
||||
toDate = Calendar.current.date(byAdding: .hour, value: 2, to: Date.now)!
|
||||
|
|
@ -113,14 +98,7 @@ class ScheduleMeetingViewModel: ObservableObject {
|
|||
// TODO
|
||||
}
|
||||
|
||||
func selectParticipant(addr: Address) {
|
||||
if let idx = participantsToAdd.firstIndex(where: {$0.address.weakEqual(address2: addr)}) {
|
||||
participantsToAdd.remove(at: idx)
|
||||
} else {
|
||||
participantsToAdd.append(SelectedAddressModel(addr: addr, avModel: ContactAvatarModel.getAvatarModelFromAddress(address: addr)))
|
||||
}
|
||||
}
|
||||
func addParticipants() {
|
||||
func addParticipants(participantsToAdd: [SelectedAddressModel]) {
|
||||
var list = participants
|
||||
for selectedAddr in participantsToAdd {
|
||||
if let found = list.first(where: { $0.address.weakEqual(address2: selectedAddr.address) }) {
|
||||
|
|
@ -134,7 +112,6 @@ class ScheduleMeetingViewModel: ObservableObject {
|
|||
Log.info("\(ScheduleMeetingViewModel.TAG) [\(list.count - participants.count) participants added, now there are \(list.count) participants in list")
|
||||
|
||||
participants = list
|
||||
participantsToAdd = []
|
||||
}
|
||||
|
||||
private func fillConferenceInfo(confInfo: ConferenceInfo) {
|
||||
|
|
|
|||
42
Linphone/UI/Main/Viewmodel/AddParticipantsViewModel.swift
Normal file
42
Linphone/UI/Main/Viewmodel/AddParticipantsViewModel.swift
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// AddParticipantsViewModel.swift
|
||||
// Linphone
|
||||
//
|
||||
// Created by QuentinArguillere on 29/04/2024.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import linphonesw
|
||||
import Combine
|
||||
|
||||
class SelectedAddressModel: ObservableObject {
|
||||
var address: Address
|
||||
var avatarModel: ContactAvatarModel
|
||||
|
||||
init (addr: Address, avModel: ContactAvatarModel) {
|
||||
address = addr
|
||||
avatarModel = avModel
|
||||
}
|
||||
}
|
||||
|
||||
class AddParticipantsViewModel: ObservableObject {
|
||||
static let TAG = "[AddParticipantsViewModel]"
|
||||
|
||||
@Published var participantsToAdd: [SelectedAddressModel] = []
|
||||
@Published var searchField: String = ""
|
||||
|
||||
func selectParticipant(addr: Address) {
|
||||
if let idx = participantsToAdd.firstIndex(where: {$0.address.weakEqual(address2: addr)}) {
|
||||
Log.info("[\(AddParticipantsViewModel.TAG)] Removing participant \(addr.asStringUriOnly()) from selection")
|
||||
participantsToAdd.remove(at: idx)
|
||||
} else {
|
||||
Log.info("[\(AddParticipantsViewModel.TAG)] Adding participant \(addr.asStringUriOnly()) to selection")
|
||||
participantsToAdd.append(SelectedAddressModel(addr: addr, avModel: ContactAvatarModel.getAvatarModelFromAddress(address: addr)))
|
||||
}
|
||||
}
|
||||
|
||||
func reset() {
|
||||
participantsToAdd = []
|
||||
searchField = ""
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue