mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 02:58:07 +00:00
Refactored ConversationFragment
This commit is contained in:
parent
dcd80e14bc
commit
0d149c7b54
21 changed files with 456 additions and 220 deletions
|
|
@ -2245,7 +2245,7 @@ struct CallView: View {
|
|||
.onDisappear {
|
||||
if SharedMainViewModel.shared.displayedConversation != nil {
|
||||
SharedMainViewModel.shared.changeIndexView(indexViewInt: 2)
|
||||
//self.conversationViewModel.changeDisplayedChatRoom(conversationModel: SharedMainViewModel.shared.displayedConversation!)
|
||||
callViewModel.changeDisplayedChatRoom(conversationModel: SharedMainViewModel.shared.displayedConversation!)
|
||||
SharedMainViewModel.shared.displayedConversation = nil
|
||||
withAnimation {
|
||||
telecomManager.callDisplayed = false
|
||||
|
|
@ -2615,7 +2615,12 @@ struct CallView: View {
|
|||
.frame(width: 32, height: 32, alignment: .center)
|
||||
.onDisappear {
|
||||
if SharedMainViewModel.shared.displayedConversation != nil {
|
||||
//conversationViewModel.changeDisplayedChatRoom(conversationModel: SharedMainViewModel.shared.displayedConversation!)
|
||||
SharedMainViewModel.shared.changeIndexView(indexViewInt: 2)
|
||||
callViewModel.changeDisplayedChatRoom(conversationModel: SharedMainViewModel.shared.displayedConversation!)
|
||||
SharedMainViewModel.shared.displayedConversation = nil
|
||||
withAnimation {
|
||||
telecomManager.callDisplayed = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class CallViewModel: ObservableObject {
|
|||
|
||||
var coreContext = CoreContext.shared
|
||||
var telecomManager = TelecomManager.shared
|
||||
var sharedMainViewModel = SharedMainViewModel.shared
|
||||
|
||||
@Published var displayName: String = ""
|
||||
@Published var direction: Call.Dir = .Outgoing
|
||||
|
|
@ -1394,6 +1395,32 @@ class CallViewModel: ObservableObject {
|
|||
})
|
||||
chatRoom.addDelegate(delegate: self.chatRoomDelegate!)
|
||||
}
|
||||
|
||||
func changeDisplayedChatRoom(conversationModel: ConversationModel) {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
let nilParams: ConferenceParams? = nil
|
||||
if let newChatRoom = core.searchChatRoom(params: nilParams, localAddr: nil, remoteAddr: conversationModel.chatRoom.peerAddress, participants: nil) {
|
||||
if LinphoneUtils.getChatRoomId(room: newChatRoom) == conversationModel.id {
|
||||
if self.sharedMainViewModel.displayedConversation == nil {
|
||||
DispatchQueue.main.async {
|
||||
withAnimation {
|
||||
self.sharedMainViewModel.displayedConversation = conversationModel
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
self.sharedMainViewModel.displayedConversation = nil
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
withAnimation {
|
||||
self.sharedMainViewModel.displayedConversation = conversationModel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// swiftlint:enable type_body_length
|
||||
// swiftlint:enable line_length
|
||||
|
|
|
|||
|
|
@ -94,18 +94,22 @@ struct ContactRow: View {
|
|||
.listRowSeparator(.hidden)
|
||||
.background(.white)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
SharedMainViewModel.shared.displayedFriend = contactAvatarModel
|
||||
}
|
||||
|
||||
if SharedMainViewModel.shared.indexView == 0 {
|
||||
withAnimation {
|
||||
SharedMainViewModel.shared.displayedFriend = contactAvatarModel
|
||||
}
|
||||
}
|
||||
|
||||
if contactAvatarModel.friend != nil
|
||||
&& contactAvatarModel.friend!.address != nil {
|
||||
startCallFunc(contactAvatarModel.friend!.address!)
|
||||
}
|
||||
}
|
||||
.onLongPressGesture(minimumDuration: 0.2) {
|
||||
contactsListViewModel.selectedFriend = contactAvatarModel
|
||||
showingSheet.toggle()
|
||||
if SharedMainViewModel.shared.indexView == 0 {
|
||||
contactsListViewModel.selectedFriend = contactAvatarModel
|
||||
showingSheet.toggle()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ class ContactsListViewModel: ObservableObject {
|
|||
var selectedFriendToShare: ContactAvatarModel?
|
||||
var selectedFriendToDelete: ContactAvatarModel?
|
||||
|
||||
@Published var operationInProgress: Bool = false
|
||||
@Published var displayedConversation: ConversationModel?
|
||||
|
||||
private var contactChatRoomDelegate: ChatRoomDelegate?
|
||||
|
|
@ -49,7 +48,7 @@ class ContactsListViewModel: ObservableObject {
|
|||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.operationInProgress = true
|
||||
SharedMainViewModel.shared.operationInProgress = true
|
||||
}
|
||||
|
||||
do {
|
||||
|
|
@ -87,7 +86,7 @@ class ContactsListViewModel: ObservableObject {
|
|||
)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.operationInProgress = false
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
|
||||
ToastViewModel.shared.displayToast = true
|
||||
}
|
||||
|
|
@ -113,7 +112,7 @@ class ContactsListViewModel: ObservableObject {
|
|||
let model = ConversationModel(chatRoom: chatRoom)
|
||||
DispatchQueue.main.async {
|
||||
self.displayedConversation = model
|
||||
self.operationInProgress = false
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
}
|
||||
} else {
|
||||
Log.info("\(ConversationForwardMessageViewModel.TAG) Conversation isn't in Created state yet (state is \(state)), wait for it")
|
||||
|
|
@ -126,14 +125,14 @@ class ContactsListViewModel: ObservableObject {
|
|||
let model = ConversationModel(chatRoom: chatRoom)
|
||||
DispatchQueue.main.async {
|
||||
self.displayedConversation = model
|
||||
self.operationInProgress = false
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Log.error("\(ConversationForwardMessageViewModel.TAG) Failed to create 1-1 conversation with \(remote.asStringUriOnly())")
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.operationInProgress = false
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
|
||||
ToastViewModel.shared.displayToast = true
|
||||
}
|
||||
|
|
@ -145,7 +144,7 @@ class ContactsListViewModel: ObservableObject {
|
|||
let model = ConversationModel(chatRoom: existingChatRoom!)
|
||||
DispatchQueue.main.async {
|
||||
self.displayedConversation = model
|
||||
self.operationInProgress = false
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
|
|
@ -164,7 +163,7 @@ class ContactsListViewModel: ObservableObject {
|
|||
self.contactChatRoomDelegate = nil
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
self.operationInProgress = false
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
|
||||
ToastViewModel.shared.displayToast = true
|
||||
}
|
||||
|
|
@ -180,18 +179,18 @@ class ContactsListViewModel: ObservableObject {
|
|||
self.contactChatRoomDelegate = nil
|
||||
}
|
||||
let model = ConversationModel(chatRoom: chatRoom)
|
||||
if self.operationInProgress == false {
|
||||
if SharedMainViewModel.shared.operationInProgress == false {
|
||||
DispatchQueue.main.async {
|
||||
self.operationInProgress = true
|
||||
SharedMainViewModel.shared.operationInProgress = true
|
||||
}
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
self.operationInProgress = false
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
self.displayedConversation = model
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
self.operationInProgress = false
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
self.displayedConversation = model
|
||||
}
|
||||
}
|
||||
|
|
@ -203,7 +202,7 @@ class ContactsListViewModel: ObservableObject {
|
|||
self.contactChatRoomDelegate = nil
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
self.operationInProgress = false
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
|
||||
ToastViewModel.shared.displayToast = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,17 +40,13 @@ struct ContentView: View {
|
|||
@State private var contactsListViewModel: ContactsListViewModel?
|
||||
@State private var historyListViewModel: HistoryListViewModel?
|
||||
@State private var conversationsListViewModel: ConversationsListViewModel?
|
||||
//@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
|
||||
//@ObservedObject var startConversationViewModel: StartConversationViewModel
|
||||
//@ObservedObject var meetingWaitingRoomViewModel: MeetingWaitingRoomViewModel
|
||||
|
||||
|
||||
//@ObservedObject var meetingsListViewModel: MeetingsListViewModel
|
||||
//@ObservedObject var meetingViewModel: MeetingViewModel
|
||||
|
||||
//@ObservedObject var conversationForwardMessageViewModel: ConversationForwardMessageViewModel
|
||||
|
||||
|
||||
//@Binding var index: Int
|
||||
@State private var orientation = UIDevice.current.orientation
|
||||
|
|
@ -969,37 +965,30 @@ struct ContentView: View {
|
|||
.frame(maxWidth: .infinity)
|
||||
.background(Color.gray100)
|
||||
.ignoresSafeArea(.keyboard)
|
||||
} else if let historyListVM = historyListViewModel, let displayedFriend = sharedMainViewModel.displayedFriend, sharedMainViewModel.indexView == 1 {
|
||||
} else if let historyListVM = historyListViewModel, let displayedCall = sharedMainViewModel.displayedCall, sharedMainViewModel.indexView == 1 {
|
||||
HistoryContactFragment(
|
||||
isShowDeleteAllHistoryPopup: $isShowDeleteAllHistoryPopup,
|
||||
isShowEditContactFragment: $isShowEditContactFragment,
|
||||
isShowEditContactFragmentAddress: $isShowEditContactFragmentAddress
|
||||
)
|
||||
.environmentObject(historyListVM)
|
||||
.environmentObject(displayedFriend)
|
||||
.environmentObject(displayedCall)
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(Color.gray100)
|
||||
.ignoresSafeArea(.keyboard)
|
||||
} else if sharedMainViewModel.indexView == 2 {
|
||||
/*
|
||||
} else if let conversationsListVM = conversationsListViewModel, sharedMainViewModel.indexView == 2 {
|
||||
ConversationFragment(
|
||||
conversationViewModel: conversationViewModel,
|
||||
conversationsListViewModel: conversationsListViewModel,
|
||||
conversationForwardMessageViewModel: conversationForwardMessageViewModel,
|
||||
contactsListViewModel: contactsListViewModel,
|
||||
editContactViewModel: editContactViewModel,
|
||||
meetingViewModel: meetingViewModel,
|
||||
accountProfileViewModel: accountProfileViewModel,
|
||||
isShowConversationFragment: $isShowConversationFragment,
|
||||
isShowStartCallGroupPopup: $isShowStartCallGroupPopup,
|
||||
isShowEditContactFragment: $isShowEditContactFragment,
|
||||
indexPage: $index,
|
||||
isShowEditContactFragmentAddress: $isShowEditContactFragmentAddress,
|
||||
isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment
|
||||
)
|
||||
.environmentObject(conversationsListVM)
|
||||
.environmentObject(accountProfileViewModel)
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(Color.gray100)
|
||||
.ignoresSafeArea(.keyboard)
|
||||
*/
|
||||
} else if sharedMainViewModel.indexView == 3 {
|
||||
/*
|
||||
MeetingFragment(meetingViewModel: meetingViewModel, meetingsListViewModel: meetingsListViewModel, isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment, isShowSendCancelMeetingNotificationPopup: $isShowSendCancelMeetingNotificationPopup)
|
||||
|
|
@ -1090,17 +1079,14 @@ struct ContentView: View {
|
|||
.transition(.opacity.combined(with: .move(edge: .bottom)))
|
||||
}
|
||||
|
||||
/*
|
||||
if isShowStartConversationFragment {
|
||||
if let conversationsListVM = conversationsListViewModel, isShowStartConversationFragment {
|
||||
StartConversationFragment(
|
||||
startConversationViewModel: startConversationViewModel,
|
||||
conversationViewModel: conversationViewModel,
|
||||
isShowStartConversationFragment: $isShowStartConversationFragment
|
||||
)
|
||||
.environmentObject(conversationsListVM)
|
||||
.zIndex(6)
|
||||
.transition(.opacity.combined(with: .move(edge: .bottom)))
|
||||
}
|
||||
*/
|
||||
|
||||
if let contactsListVM = contactsListViewModel, isShowDeleteContactPopup {
|
||||
PopupView(
|
||||
|
|
@ -1196,26 +1182,60 @@ struct ContentView: View {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if contactsListViewModel.operationInProgress {
|
||||
if sharedMainViewModel.operationInProgress {
|
||||
PopupLoadingView()
|
||||
.background(.black.opacity(0.65))
|
||||
.zIndex(3)
|
||||
.onDisappear {
|
||||
if contactsListViewModel.displayedConversation != nil {
|
||||
if let contactsListVM = contactsListViewModel, let displayedConversation = contactsListVM.displayedConversation {
|
||||
sharedMainViewModel.displayedFriend = nil
|
||||
sharedMainViewModel.displayedCall = nil
|
||||
sharedMainViewModel.changeIndexView(indexViewInt: 2)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
withAnimation {
|
||||
self.conversationViewModel.changeDisplayedChatRoom(conversationModel: contactsListViewModel.displayedConversation!)
|
||||
|
||||
if let conversationsListVM = self.conversationsListViewModel {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
withAnimation {
|
||||
conversationsListVM.changeDisplayedChatRoom(conversationModel: displayedConversation)
|
||||
}
|
||||
contactsListVM.displayedConversation = nil
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
if let conversationsListVM = self.conversationsListViewModel {
|
||||
withAnimation {
|
||||
conversationsListVM.changeDisplayedChatRoom(conversationModel: displayedConversation)
|
||||
}
|
||||
}
|
||||
contactsListVM.displayedConversation = nil
|
||||
}
|
||||
}
|
||||
} else if let historyListVM = historyListViewModel, let displayedConversation = historyListVM.displayedConversation {
|
||||
sharedMainViewModel.displayedFriend = nil
|
||||
sharedMainViewModel.displayedCall = nil
|
||||
sharedMainViewModel.changeIndexView(indexViewInt: 2)
|
||||
|
||||
if let conversationsListVM = self.conversationsListViewModel {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
withAnimation {
|
||||
conversationsListVM.changeDisplayedChatRoom(conversationModel: displayedConversation)
|
||||
}
|
||||
historyListVM.displayedConversation = nil
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
if let conversationsListVM = self.conversationsListViewModel {
|
||||
withAnimation {
|
||||
conversationsListVM.changeDisplayedChatRoom(conversationModel: displayedConversation)
|
||||
}
|
||||
}
|
||||
historyListVM.displayedConversation = nil
|
||||
}
|
||||
contactsListViewModel.displayedConversation = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if isShowScheduleMeetingFragment {
|
||||
ScheduleMeetingFragment(
|
||||
meetingViewModel: meetingViewModel,
|
||||
|
|
@ -1282,6 +1302,7 @@ struct ContentView: View {
|
|||
self.isShowSendCancelMeetingNotificationPopup.toggle()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if isShowStartCallGroupPopup {
|
||||
PopupView(
|
||||
|
|
@ -1307,30 +1328,7 @@ struct ContentView: View {
|
|||
}
|
||||
}
|
||||
|
||||
if isShowStartCallGroupPopup {
|
||||
PopupView(
|
||||
isShowPopup: $isShowStartCallGroupPopup,
|
||||
title: Text("conversation_info_confirm_start_group_call_dialog_title"),
|
||||
content: Text("conversation_info_confirm_start_group_call_dialog_message"),
|
||||
titleFirstButton: Text("dialog_cancel"),
|
||||
actionFirstButton: {
|
||||
self.isShowStartCallGroupPopup.toggle()
|
||||
},
|
||||
titleSecondButton: Text("dialog_ok"),
|
||||
actionSecondButton: {
|
||||
if sharedMainViewModel.displayedConversation != nil {
|
||||
sharedMainViewModel.displayedConversation!.createGroupCall()
|
||||
}
|
||||
self.isShowStartCallGroupPopup.toggle()
|
||||
}
|
||||
)
|
||||
.background(.black.opacity(0.65))
|
||||
.zIndex(3)
|
||||
.onTapGesture {
|
||||
self.isShowStartCallGroupPopup.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if conversationViewModel.isShowConversationInfoPopup {
|
||||
PopupViewWithTextField(conversationViewModel: conversationViewModel)
|
||||
.background(.black.opacity(0.65))
|
||||
|
|
@ -1453,8 +1451,6 @@ class NavigationManager: ObservableObject {
|
|||
#Preview {
|
||||
ContentView(
|
||||
//meetingWaitingRoomViewModel: MeetingWaitingRoomViewModel(),
|
||||
//conversationsListViewModel: ConversationsListViewModel(),
|
||||
//conversationViewModel: ConversationViewModel(),
|
||||
//meetingsListViewModel: MeetingsListViewModel(),
|
||||
//meetingViewModel: MeetingViewModel(),
|
||||
//conversationForwardMessageViewModel: ConversationForwardMessageViewModel(),
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ struct ChatBubbleView: View {
|
|||
|
||||
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
|
||||
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@EnvironmentObject var conversationViewModel: ConversationViewModel
|
||||
|
||||
let eventLogMessage: EventLogMessage
|
||||
|
||||
|
|
@ -603,9 +603,9 @@ struct ChatBubbleView: View {
|
|||
.clipped()
|
||||
} else if eventLogMessage.message.attachments.first!.type == .voiceRecording {
|
||||
CustomSlider(
|
||||
conversationViewModel: conversationViewModel,
|
||||
eventLogMessage: eventLogMessage
|
||||
)
|
||||
.environmentObject(conversationViewModel)
|
||||
.frame(width: geometryProxy.size.width - 160, height: 50)
|
||||
} else {
|
||||
HStack {
|
||||
|
|
@ -990,7 +990,7 @@ extension View {
|
|||
}
|
||||
|
||||
struct CustomSlider: View {
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@EnvironmentObject var conversationViewModel: ConversationViewModel
|
||||
|
||||
let eventLogMessage: EventLogMessage
|
||||
|
||||
|
|
@ -1183,7 +1183,7 @@ struct CachedAsyncImage<Placeholder: View>: View {
|
|||
|
||||
/*
|
||||
#Preview {
|
||||
ChatBubbleView(conversationViewModel: ConversationViewModel(), index: 0)
|
||||
ChatBubbleView(index: 0)
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,10 @@ struct ConversationForwardMessageFragment: View {
|
|||
@ObservedObject var contactsManager = ContactsManager.shared
|
||||
@ObservedObject var magicSearch = MagicSearchSingleton.shared
|
||||
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@ObservedObject var conversationsListViewModel: ConversationsListViewModel
|
||||
@ObservedObject var conversationForwardMessageViewModel: ConversationForwardMessageViewModel
|
||||
@EnvironmentObject var conversationViewModel: ConversationViewModel
|
||||
@EnvironmentObject var conversationsListViewModel: ConversationsListViewModel
|
||||
|
||||
@StateObject private var conversationForwardMessageViewModel: ConversationForwardMessageViewModel
|
||||
|
||||
@Binding var isShowConversationForwardMessageFragment: Bool
|
||||
|
||||
|
|
@ -36,6 +37,11 @@ struct ConversationForwardMessageFragment: View {
|
|||
|
||||
@FocusState var isMessageTextFocused: Bool
|
||||
|
||||
init(conversationsList: [ConversationModel], selectedMessage: EventLogMessage?, isShowConversationForwardMessageFragment: Binding<Bool>) {
|
||||
_conversationForwardMessageViewModel = StateObject(wrappedValue: ConversationForwardMessageViewModel(conversationsList: conversationsList, selectedMessage: selectedMessage))
|
||||
self._isShowConversationForwardMessageFragment = isShowConversationForwardMessageFragment
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
ZStack {
|
||||
|
|
@ -337,11 +343,10 @@ struct ConversationForwardMessageFragment: View {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#Preview {
|
||||
ConversationForwardMessageFragment(
|
||||
conversationViewModel: ConversationViewModel(),
|
||||
conversationsListViewModel: ConversationsListViewModel(),
|
||||
conversationForwardMessageViewModel: ConversationForwardMessageViewModel(),
|
||||
isShowConversationForwardMessageFragment: .constant(true)
|
||||
)
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -31,14 +31,11 @@ struct ConversationFragment: View {
|
|||
@EnvironmentObject var navigationManager: NavigationManager
|
||||
|
||||
@ObservedObject var contactsManager = ContactsManager.shared
|
||||
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@ObservedObject var conversationsListViewModel: ConversationsListViewModel
|
||||
@ObservedObject var conversationForwardMessageViewModel: ConversationForwardMessageViewModel
|
||||
@ObservedObject var contactsListViewModel: ContactsListViewModel
|
||||
@ObservedObject var editContactViewModel: EditContactViewModel
|
||||
@ObservedObject var meetingViewModel: MeetingViewModel
|
||||
@ObservedObject var accountProfileViewModel: AccountProfileViewModel
|
||||
|
||||
@EnvironmentObject var conversationsListViewModel: ConversationsListViewModel
|
||||
@EnvironmentObject var accountProfileViewModel: AccountProfileViewModel
|
||||
|
||||
@StateObject private var conversationViewModel = ConversationViewModel()
|
||||
|
||||
@State var isMenuOpen = false
|
||||
@State private var isMuted: Bool = false
|
||||
|
|
@ -49,9 +46,6 @@ struct ConversationFragment: View {
|
|||
|
||||
private let ids: [String] = []
|
||||
|
||||
@StateObject private var viewModel = ChatViewModel()
|
||||
@StateObject private var paginationState = PaginationState()
|
||||
|
||||
@State private var displayFloatingButton = false
|
||||
|
||||
@State private var areFilePickersOpen = false
|
||||
|
|
@ -73,9 +67,11 @@ struct ConversationFragment: View {
|
|||
@State private var selectedCategoryIndex = 0
|
||||
|
||||
@Binding var isShowEditContactFragment: Bool
|
||||
@Binding var indexPage: Int
|
||||
@Binding var isShowEditContactFragmentAddress: String
|
||||
|
||||
@Binding var isShowScheduleMeetingFragment: Bool
|
||||
|
||||
@State private var cachedConversation: ConversationModel?
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
|
|
@ -97,7 +93,8 @@ struct ConversationFragment: View {
|
|||
.sheet(isPresented: $conversationViewModel.isShowSelectedMessageToDisplayDetails, onDismiss: {
|
||||
conversationViewModel.isShowSelectedMessageToDisplayDetails = false
|
||||
}, content: {
|
||||
ImdnOrReactionsSheet(conversationViewModel: conversationViewModel, selectedCategoryIndex: $selectedCategoryIndex)
|
||||
ImdnOrReactionsSheet(selectedCategoryIndex: $selectedCategoryIndex)
|
||||
.environmentObject(conversationViewModel)
|
||||
.presentationDetents([.medium])
|
||||
.presentationDragIndicator(.visible)
|
||||
})
|
||||
|
|
@ -137,7 +134,8 @@ struct ConversationFragment: View {
|
|||
.edgesIgnoringSafeArea(.all)
|
||||
})
|
||||
.fullScreenCover(isPresented: $isShowCamera) {
|
||||
ImagePicker(conversationViewModel: conversationViewModel, selectedMedia: self.$conversationViewModel.mediasToSend)
|
||||
ImagePicker(selectedMedia: self.$conversationViewModel.mediasToSend)
|
||||
.environmentObject(conversationViewModel)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
}
|
||||
.background(Color.gray100.ignoresSafeArea(.keyboard))
|
||||
|
|
@ -156,7 +154,8 @@ struct ConversationFragment: View {
|
|||
conversationViewModel.removeConversationDelegate()
|
||||
}
|
||||
.halfSheet(showSheet: $conversationViewModel.isShowSelectedMessageToDisplayDetails) {
|
||||
ImdnOrReactionsSheet(conversationViewModel: conversationViewModel, selectedCategoryIndex: $selectedCategoryIndex)
|
||||
ImdnOrReactionsSheet(selectedCategoryIndex: $selectedCategoryIndex)
|
||||
.environmentObject(conversationViewModel)
|
||||
} onDismiss: {
|
||||
conversationViewModel.isShowSelectedMessageToDisplayDetails = false
|
||||
}
|
||||
|
|
@ -179,7 +178,8 @@ struct ConversationFragment: View {
|
|||
.edgesIgnoringSafeArea(.all)
|
||||
})
|
||||
.fullScreenCover(isPresented: $isShowCamera) {
|
||||
ImagePicker(conversationViewModel: conversationViewModel, selectedMedia: self.$conversationViewModel.mediasToSend)
|
||||
ImagePicker(selectedMedia: self.$conversationViewModel.mediasToSend)
|
||||
.environmentObject(conversationViewModel)
|
||||
}
|
||||
.background(Color.gray100.ignoresSafeArea(.keyboard))
|
||||
}
|
||||
|
|
@ -193,6 +193,11 @@ struct ConversationFragment: View {
|
|||
}
|
||||
}
|
||||
.navigationViewStyle(.stack)
|
||||
.onAppear {
|
||||
if let conv = SharedMainViewModel.shared.displayedConversation {
|
||||
cachedConversation = conv
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:disable cyclomatic_complexity
|
||||
|
|
@ -201,7 +206,7 @@ struct ConversationFragment: View {
|
|||
func innerView(geometry: GeometryProxy) -> some View {
|
||||
ZStack {
|
||||
VStack(spacing: 1) {
|
||||
if SharedMainViewModel.shared.displayedConversation != nil {
|
||||
if SharedMainViewModel.shared.displayedConversation != nil || cachedConversation != nil {
|
||||
Rectangle()
|
||||
.foregroundColor(Color.orangeMain500)
|
||||
.edgesIgnoringSafeArea(.top)
|
||||
|
|
@ -228,11 +233,11 @@ struct ConversationFragment: View {
|
|||
}
|
||||
}
|
||||
|
||||
Avatar(contactAvatarModel: SharedMainViewModel.shared.displayedConversation!.avatarModel, avatarSize: 50)
|
||||
Avatar(contactAvatarModel: SharedMainViewModel.shared.displayedConversation?.avatarModel ?? cachedConversation!.avatarModel, avatarSize: 50)
|
||||
.padding(.top, 4)
|
||||
|
||||
VStack(spacing: 1) {
|
||||
Text(SharedMainViewModel.shared.displayedConversation!.subject)
|
||||
Text(SharedMainViewModel.shared.displayedConversation?.subject ?? cachedConversation!.subject)
|
||||
.default_text_style(styleSize: 16)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.top, 4)
|
||||
|
|
@ -276,7 +281,7 @@ struct ConversationFragment: View {
|
|||
|
||||
Spacer()
|
||||
|
||||
if !SharedMainViewModel.shared.displayedConversation!.isReadOnly {
|
||||
if !(SharedMainViewModel.shared.displayedConversation?.isReadOnly ?? cachedConversation!.isReadOnly) {
|
||||
Button {
|
||||
if SharedMainViewModel.shared.displayedConversation!.isGroup {
|
||||
isShowStartCallGroupPopup.toggle()
|
||||
|
|
@ -313,7 +318,7 @@ struct ConversationFragment: View {
|
|||
}
|
||||
}
|
||||
|
||||
if !SharedMainViewModel.shared.displayedConversation!.isReadOnly {
|
||||
if !(SharedMainViewModel.shared.displayedConversation?.isReadOnly ?? cachedConversation!.isReadOnly) {
|
||||
Button {
|
||||
isMenuOpen = false
|
||||
SharedMainViewModel.shared.displayedConversation!.toggleMute()
|
||||
|
|
@ -375,13 +380,11 @@ struct ConversationFragment: View {
|
|||
if #available(iOS 16.0, *) {
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
UIList(
|
||||
viewModel: viewModel,
|
||||
paginationState: paginationState,
|
||||
conversationViewModel: conversationViewModel,
|
||||
conversationsListViewModel: conversationsListViewModel,
|
||||
geometryProxy: geometry,
|
||||
sections: conversationViewModel.conversationMessagesSection
|
||||
)
|
||||
.environmentObject(conversationViewModel)
|
||||
.environmentObject(conversationsListViewModel)
|
||||
}
|
||||
/*
|
||||
.onAppear {
|
||||
|
|
@ -398,7 +401,8 @@ struct ConversationFragment: View {
|
|||
if conversationViewModel.conversationMessagesSection.first != nil {
|
||||
let counter = conversationViewModel.conversationMessagesSection.first!.rows.count
|
||||
ForEach(0..<counter, id: \.self) { index in
|
||||
ChatBubbleView(conversationViewModel: conversationViewModel, eventLogMessage: conversationViewModel.conversationMessagesSection.first!.rows[index], geometryProxy: geometry)
|
||||
ChatBubbleView(eventLogMessage: conversationViewModel.conversationMessagesSection.first!.rows[index], geometryProxy: geometry)
|
||||
.environmentObject(conversationViewModel)
|
||||
.id(conversationViewModel.conversationMessagesSection.first!.rows[index].message.id)
|
||||
.listRowInsets(EdgeInsets(top: 2, leading: 10, bottom: 2, trailing: 10))
|
||||
.listRowSeparator(.hidden)
|
||||
|
|
@ -502,7 +506,7 @@ struct ConversationFragment: View {
|
|||
.transition(.move(edge: .bottom))
|
||||
}
|
||||
|
||||
if SharedMainViewModel.shared.displayedConversation != nil && !SharedMainViewModel.shared.displayedConversation!.isReadOnly {
|
||||
if !(SharedMainViewModel.shared.displayedConversation?.isReadOnly ?? cachedConversation!.isReadOnly) {
|
||||
if conversationViewModel.messageToReply != nil {
|
||||
ZStack(alignment: .top) {
|
||||
HStack {
|
||||
|
|
@ -830,7 +834,8 @@ struct ConversationFragment: View {
|
|||
)
|
||||
.padding(.horizontal, 4)
|
||||
} else {
|
||||
VoiceRecorderPlayer(conversationViewModel: conversationViewModel, voiceRecordingInProgress: $voiceRecordingInProgress)
|
||||
VoiceRecorderPlayer(voiceRecordingInProgress: $voiceRecordingInProgress)
|
||||
.environmentObject(conversationViewModel)
|
||||
.frame(maxHeight: 60)
|
||||
}
|
||||
}
|
||||
|
|
@ -934,7 +939,8 @@ struct ConversationFragment: View {
|
|||
.padding(.leading, SharedMainViewModel.shared.displayedConversation!.isGroup ? 43 : 0)
|
||||
.shadow(color: .black.opacity(0.1), radius: 10)
|
||||
|
||||
ChatBubbleView(conversationViewModel: conversationViewModel, eventLogMessage: conversationViewModel.selectedMessage!, geometryProxy: geometry)
|
||||
ChatBubbleView(eventLogMessage: conversationViewModel.selectedMessage!, geometryProxy: geometry)
|
||||
.environmentObject(conversationViewModel)
|
||||
.padding(.horizontal, 10)
|
||||
.padding(.vertical, 1)
|
||||
.shadow(color: .black.opacity(0.1), radius: 10)
|
||||
|
|
@ -992,9 +998,6 @@ struct ConversationFragment: View {
|
|||
}
|
||||
|
||||
Button {
|
||||
conversationForwardMessageViewModel.initConversationsLists(convsList: conversationsListViewModel.conversationsList)
|
||||
conversationForwardMessageViewModel.selectedMessage = conversationViewModel.selectedMessage
|
||||
conversationViewModel.selectedMessage = nil
|
||||
withAnimation {
|
||||
isShowConversationForwardMessageFragment = true
|
||||
}
|
||||
|
|
@ -1068,40 +1071,39 @@ struct ConversationFragment: View {
|
|||
|
||||
if isShowConversationForwardMessageFragment {
|
||||
ConversationForwardMessageFragment(
|
||||
conversationViewModel: conversationViewModel,
|
||||
conversationsListViewModel: conversationsListViewModel,
|
||||
conversationForwardMessageViewModel: conversationForwardMessageViewModel,
|
||||
conversationsList: conversationsListViewModel.conversationsList,
|
||||
selectedMessage: conversationViewModel.selectedMessage,
|
||||
isShowConversationForwardMessageFragment: $isShowConversationForwardMessageFragment
|
||||
)
|
||||
.environmentObject(conversationViewModel)
|
||||
.environmentObject(conversationsListViewModel)
|
||||
.zIndex(5)
|
||||
.transition(.move(edge: .trailing))
|
||||
.onAppear {
|
||||
conversationViewModel.selectedMessage = nil
|
||||
}
|
||||
}
|
||||
|
||||
if isShowInfoConversationFragment {
|
||||
ConversationInfoFragment(
|
||||
conversationViewModel: conversationViewModel,
|
||||
conversationsListViewModel: conversationsListViewModel,
|
||||
contactsListViewModel: contactsListViewModel,
|
||||
editContactViewModel: editContactViewModel,
|
||||
meetingViewModel: meetingViewModel,
|
||||
accountProfileViewModel: accountProfileViewModel,
|
||||
isMuted: $isMuted,
|
||||
isShowEphemeralFragment: $isShowEphemeralFragment,
|
||||
isShowStartCallGroupPopup: $isShowStartCallGroupPopup,
|
||||
isShowInfoConversationFragment: $isShowInfoConversationFragment,
|
||||
isShowEditContactFragment: $isShowEditContactFragment,
|
||||
indexPage: $indexPage,
|
||||
isShowEditContactFragmentAddress: $isShowEditContactFragmentAddress,
|
||||
isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment
|
||||
)
|
||||
.environmentObject(conversationViewModel)
|
||||
.zIndex(5)
|
||||
.transition(.move(edge: .trailing))
|
||||
}
|
||||
|
||||
|
||||
if isShowEphemeralFragment {
|
||||
EphemeralFragment(
|
||||
conversationViewModel: conversationViewModel,
|
||||
isShowEphemeralFragment: $isShowEphemeralFragment
|
||||
)
|
||||
.environmentObject(conversationViewModel)
|
||||
.zIndex(5)
|
||||
.transition(.move(edge: .trailing))
|
||||
}
|
||||
|
|
@ -1112,7 +1114,7 @@ struct ConversationFragment: View {
|
|||
}
|
||||
|
||||
struct ImdnOrReactionsSheet: View {
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@EnvironmentObject var conversationViewModel: ConversationViewModel
|
||||
|
||||
@Binding var selectedCategoryIndex: Int
|
||||
|
||||
|
|
@ -1181,7 +1183,7 @@ struct ImdnOrReactionsSheet: View {
|
|||
}
|
||||
|
||||
struct ImagePicker: UIViewControllerRepresentable {
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@EnvironmentObject var conversationViewModel: ConversationViewModel
|
||||
@Binding var selectedMedia: [Attachment]
|
||||
@Environment(\.presentationMode) private var presentationMode
|
||||
|
||||
|
|
@ -1263,7 +1265,7 @@ struct ImagePicker: UIViewControllerRepresentable {
|
|||
}
|
||||
|
||||
struct VoiceRecorderPlayer: View {
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@EnvironmentObject var conversationViewModel: ConversationViewModel
|
||||
|
||||
@Binding var voiceRecordingInProgress: Bool
|
||||
|
||||
|
|
@ -1445,7 +1447,7 @@ struct VoiceRecorderPlayer: View {
|
|||
}
|
||||
/*
|
||||
#Preview {
|
||||
ConversationFragment(conversationViewModel: ConversationViewModel(), conversationsListViewModel: ConversationsListViewModel(), sections: [MessagesSection], ids: [""])
|
||||
ConversationFragment(sections: [MessagesSection], ids: [""])
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -25,12 +25,9 @@ struct ConversationInfoFragment: View {
|
|||
|
||||
@ObservedObject var contactsManager = ContactsManager.shared
|
||||
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@ObservedObject var conversationsListViewModel: ConversationsListViewModel
|
||||
@ObservedObject var contactsListViewModel: ContactsListViewModel
|
||||
@ObservedObject var editContactViewModel: EditContactViewModel
|
||||
@ObservedObject var meetingViewModel: MeetingViewModel
|
||||
@ObservedObject var accountProfileViewModel: AccountProfileViewModel
|
||||
@EnvironmentObject var conversationViewModel: ConversationViewModel
|
||||
@EnvironmentObject var conversationsListViewModel: ConversationsListViewModel
|
||||
@EnvironmentObject var accountProfileViewModel: AccountProfileViewModel
|
||||
|
||||
@State var addParticipantsViewModel = AddParticipantsViewModel()
|
||||
|
||||
|
|
@ -39,7 +36,7 @@ struct ConversationInfoFragment: View {
|
|||
@Binding var isShowStartCallGroupPopup: Bool
|
||||
@Binding var isShowInfoConversationFragment: Bool
|
||||
@Binding var isShowEditContactFragment: Bool
|
||||
@Binding var indexPage: Int
|
||||
@Binding var isShowEditContactFragmentAddress: String
|
||||
|
||||
@Binding var isShowScheduleMeetingFragment: Bool
|
||||
|
||||
|
|
@ -222,10 +219,12 @@ struct ConversationInfoFragment: View {
|
|||
|
||||
Button(action: {
|
||||
if SharedMainViewModel.shared.displayedConversation != nil {
|
||||
/*
|
||||
meetingViewModel.subject = SharedMainViewModel.shared.displayedConversation!.subject
|
||||
meetingViewModel.participants = conversationViewModel.participants
|
||||
*/
|
||||
SharedMainViewModel.shared.displayedConversation = nil
|
||||
indexPage = 3
|
||||
SharedMainViewModel.shared.changeIndexView(indexViewInt: 3)
|
||||
withAnimation {
|
||||
isShowScheduleMeetingFragment = true
|
||||
}
|
||||
|
|
@ -351,21 +350,18 @@ struct ConversationInfoFragment: View {
|
|||
|
||||
let friendIndex = contactsManager.avatarListModel.first(
|
||||
where: {$0.addresses.contains(where: {$0 == addressConv})})
|
||||
|
||||
SharedMainViewModel.shared.displayedCall = nil
|
||||
SharedMainViewModel.shared.changeIndexView(indexViewInt: 0)
|
||||
|
||||
if friendIndex != nil {
|
||||
withAnimation {
|
||||
SharedMainViewModel.shared.displayedConversation = nil
|
||||
indexPage = 0
|
||||
SharedMainViewModel.shared.displayedFriend = friendIndex
|
||||
}
|
||||
} else {
|
||||
withAnimation {
|
||||
SharedMainViewModel.shared.displayedConversation = nil
|
||||
indexPage = 0
|
||||
|
||||
isShowEditContactFragment.toggle()
|
||||
editContactViewModel.sipAddresses.removeAll()
|
||||
editContactViewModel.sipAddresses.append(String(participantConversationModel.address.dropFirst(4) ?? ""))
|
||||
editContactViewModel.sipAddresses.append("")
|
||||
isShowEditContactFragmentAddress = String(participantConversationModel.address.dropFirst(4))
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -526,26 +522,24 @@ struct ConversationInfoFragment: View {
|
|||
Button(
|
||||
action: {
|
||||
if SharedMainViewModel.shared.displayedConversation != nil {
|
||||
|
||||
let addressConv = conversationViewModel.participantConversationModel.first?.address ?? ""
|
||||
|
||||
let friendIndex = contactsManager.avatarListModel.first(
|
||||
where: {$0.addresses.contains(where: {$0 == addressConv})})
|
||||
if friendIndex != nil {
|
||||
withAnimation {
|
||||
SharedMainViewModel.shared.displayedConversation = nil
|
||||
indexPage = 0
|
||||
SharedMainViewModel.shared.displayedFriend = friendIndex
|
||||
}
|
||||
} else {
|
||||
withAnimation {
|
||||
SharedMainViewModel.shared.displayedConversation = nil
|
||||
indexPage = 0
|
||||
|
||||
isShowEditContactFragment.toggle()
|
||||
editContactViewModel.sipAddresses.removeAll()
|
||||
editContactViewModel.sipAddresses.append(String(conversationViewModel.participantConversationModel.first?.address.dropFirst(4) ?? ""))
|
||||
editContactViewModel.sipAddresses.append("")
|
||||
if let participantConversationModel = conversationViewModel.participantConversationModel.first {
|
||||
let addressConv = participantConversationModel.address
|
||||
|
||||
let friendIndex = contactsManager.avatarListModel.first(
|
||||
where: {$0.addresses.contains(where: {$0 == addressConv})})
|
||||
|
||||
SharedMainViewModel.shared.displayedCall = nil
|
||||
SharedMainViewModel.shared.changeIndexView(indexViewInt: 0)
|
||||
|
||||
if friendIndex != nil {
|
||||
withAnimation {
|
||||
SharedMainViewModel.shared.displayedFriend = friendIndex
|
||||
}
|
||||
} else {
|
||||
withAnimation {
|
||||
isShowEditContactFragment.toggle()
|
||||
isShowEditContactFragmentAddress = String(participantConversationModel.address.dropFirst(4))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -696,19 +690,12 @@ struct ConversationInfoFragment: View {
|
|||
|
||||
#Preview {
|
||||
ConversationInfoFragment(
|
||||
conversationViewModel: ConversationViewModel(),
|
||||
conversationsListViewModel: ConversationsListViewModel(),
|
||||
contactsListViewModel: ContactsListViewModel(),
|
||||
editContactViewModel: EditContactViewModel(),
|
||||
meetingViewModel: MeetingViewModel(),
|
||||
accountProfileViewModel: AccountProfileViewModel(),
|
||||
addParticipantsViewModel: AddParticipantsViewModel(),
|
||||
isMuted: .constant(false),
|
||||
isShowEphemeralFragment: .constant(false),
|
||||
isShowStartCallGroupPopup: .constant(false),
|
||||
isShowInfoConversationFragment: .constant(true),
|
||||
isShowEditContactFragment: .constant(false),
|
||||
indexPage: .constant(0),
|
||||
isShowEditContactFragmentAddress: .constant(""),
|
||||
isShowScheduleMeetingFragment: .constant(false)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import SwiftUI
|
|||
import linphonesw
|
||||
|
||||
struct EphemeralFragment: View {
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@EnvironmentObject var conversationViewModel: ConversationViewModel
|
||||
|
||||
@State private var selectedOption = NSLocalizedString("conversation_ephemeral_messages_duration_disabled", comment: "")
|
||||
let options = [
|
||||
|
|
@ -151,7 +151,6 @@ struct EphemeralFragment: View {
|
|||
|
||||
#Preview {
|
||||
EphemeralFragment(
|
||||
conversationViewModel: ConversationViewModel(),
|
||||
isShowEphemeralFragment: .constant(true)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,9 @@ struct StartConversationFragment: View {
|
|||
@ObservedObject var contactsManager = ContactsManager.shared
|
||||
@ObservedObject var magicSearch = MagicSearchSingleton.shared
|
||||
|
||||
@ObservedObject var startConversationViewModel: StartConversationViewModel
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@StateObject private var startConversationViewModel = StartConversationViewModel()
|
||||
|
||||
@EnvironmentObject var conversationsListViewModel: ConversationsListViewModel
|
||||
|
||||
@Binding var isShowStartConversationFragment: Bool
|
||||
|
||||
|
|
@ -136,7 +137,8 @@ struct StartConversationFragment: View {
|
|||
.padding(.horizontal)
|
||||
|
||||
NavigationLink(destination: {
|
||||
StartGroupConversationFragment(startConversationViewModel: startConversationViewModel)
|
||||
StartGroupConversationFragment()
|
||||
.environmentObject(startConversationViewModel)
|
||||
}, label: {
|
||||
HStack {
|
||||
HStack(alignment: .center) {
|
||||
|
|
@ -233,9 +235,8 @@ struct StartConversationFragment: View {
|
|||
|
||||
isShowStartConversationFragment = false
|
||||
|
||||
if startConversationViewModel.displayedConversation != nil {
|
||||
self.conversationViewModel.changeDisplayedChatRoom(conversationModel: startConversationViewModel.displayedConversation!)
|
||||
|
||||
if let displayedConversation = startConversationViewModel.displayedConversation {
|
||||
self.conversationsListViewModel.changeDisplayedChatRoom(conversationModel: displayedConversation)
|
||||
startConversationViewModel.displayedConversation = nil
|
||||
}
|
||||
}
|
||||
|
|
@ -397,8 +398,6 @@ struct StartConversationFragment: View {
|
|||
|
||||
#Preview {
|
||||
StartConversationFragment(
|
||||
startConversationViewModel: StartConversationViewModel(),
|
||||
conversationViewModel: ConversationViewModel(),
|
||||
isShowStartConversationFragment: .constant(true)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@
|
|||
import SwiftUI
|
||||
|
||||
struct StartGroupConversationFragment: View {
|
||||
@ObservedObject var startConversationViewModel: StartConversationViewModel
|
||||
|
||||
@EnvironmentObject var startConversationViewModel: StartConversationViewModel
|
||||
@EnvironmentObject var conversationsListViewModel: ConversationsListViewModel
|
||||
|
||||
@State var addParticipantsViewModel = AddParticipantsViewModel()
|
||||
|
||||
var body: some View {
|
||||
|
|
@ -32,5 +35,5 @@ struct StartGroupConversationFragment: View {
|
|||
}
|
||||
|
||||
#Preview {
|
||||
StartGroupConversationFragment(startConversationViewModel: StartConversationViewModel())
|
||||
StartGroupConversationFragment()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,10 +102,11 @@ struct UIList: UIViewRepresentable {
|
|||
|
||||
private static var sharedCoordinator: Coordinator?
|
||||
|
||||
@ObservedObject var viewModel: ChatViewModel
|
||||
@ObservedObject var paginationState: PaginationState
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@ObservedObject var conversationsListViewModel: ConversationsListViewModel
|
||||
@StateObject private var viewModel = ChatViewModel()
|
||||
@StateObject private var paginationState = PaginationState()
|
||||
|
||||
@EnvironmentObject var conversationViewModel: ConversationViewModel
|
||||
@EnvironmentObject var conversationsListViewModel: ConversationsListViewModel
|
||||
|
||||
let geometryProxy: GeometryProxy
|
||||
let sections: [MessagesSection]
|
||||
|
|
@ -445,7 +446,8 @@ struct UIList: UIViewRepresentable {
|
|||
let row = sections[indexPath.section].rows[indexPath.row]
|
||||
if #available(iOS 16.0, *) {
|
||||
tableViewCell.contentConfiguration = UIHostingConfiguration {
|
||||
ChatBubbleView(conversationViewModel: parent.conversationViewModel, eventLogMessage: row, geometryProxy: geometryProxy)
|
||||
ChatBubbleView(eventLogMessage: row, geometryProxy: geometryProxy)
|
||||
.environmentObject(parent.conversationViewModel)
|
||||
.padding(.vertical, 2)
|
||||
.padding(.horizontal, 10)
|
||||
.onTapGesture { }
|
||||
|
|
|
|||
|
|
@ -39,7 +39,10 @@ class ConversationForwardMessageViewModel: ObservableObject {
|
|||
|
||||
private var chatRoomDelegate: ChatRoomDelegate?
|
||||
|
||||
init() {}
|
||||
init(conversationsList: [ConversationModel], selectedMessage: EventLogMessage?) {
|
||||
self.conversationsList = conversationsList
|
||||
self.selectedMessage = selectedMessage
|
||||
}
|
||||
|
||||
func initConversationsLists(convsList: [ConversationModel]) {
|
||||
conversationsListTmp = convsList
|
||||
|
|
|
|||
|
|
@ -120,14 +120,10 @@ class ConversationViewModel: ObservableObject {
|
|||
}
|
||||
|
||||
init() {
|
||||
// TODO a check si utile
|
||||
/*
|
||||
self.selectedMessage = nil
|
||||
self.resetMessage()
|
||||
self.removeConversationDelegate()
|
||||
self.addConversationDelegate(chatRoom: newChatRoom)
|
||||
self.getMessages()
|
||||
*/
|
||||
if let chatroom = self.sharedMainViewModel.displayedConversation?.chatRoom {
|
||||
self.addConversationDelegate(chatRoom: chatroom)
|
||||
self.getMessages()
|
||||
}
|
||||
}
|
||||
|
||||
func addConversationDelegate() {
|
||||
|
|
@ -180,7 +176,7 @@ class ConversationViewModel: ObservableObject {
|
|||
}, onChatMessagesReceived: { (_: ChatRoom, eventLogs: [EventLog]) in
|
||||
self.getNewMessages(eventLogs: eventLogs)
|
||||
}, onChatMessageSending: { (_: ChatRoom, eventLog: EventLog) in
|
||||
if self.conversationMessagesSection[0].rows.isEmpty {
|
||||
if self.conversationMessagesSection.isEmpty || self.conversationMessagesSection[0].rows.isEmpty {
|
||||
self.sendFirstMessage(eventLog: eventLog)
|
||||
} else {
|
||||
self.getNewMessages(eventLogs: [eventLog])
|
||||
|
|
|
|||
|
|
@ -117,8 +117,25 @@ class ConversationsListViewModel: ObservableObject {
|
|||
conversationModel.subject = contactAvatarModel.name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if !conversationModel.isGroup {
|
||||
if let address = conversationModel.participantsAddress.first {
|
||||
let avatarModelTmp = ContactsManager.shared.avatarListModel.first(where: {
|
||||
guard let friend = $0.friend else { return false }
|
||||
return friend.name == conversationModel.subject &&
|
||||
friend.address?.asStringUriOnly() == address
|
||||
}) ?? ContactAvatarModel(
|
||||
friend: nil,
|
||||
name: conversationModel.subject,
|
||||
address: address,
|
||||
withPresence: false
|
||||
)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
conversationModel.avatarModel = avatarModelTmp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -460,11 +477,22 @@ class ConversationsListViewModel: ObservableObject {
|
|||
let nilParams: ConferenceParams? = nil
|
||||
if let newChatRoom = core.searchChatRoom(params: nilParams, localAddr: nil, remoteAddr: conversationModel.chatRoom.peerAddress, participants: nil) {
|
||||
if LinphoneUtils.getChatRoomId(room: newChatRoom) == conversationModel.id {
|
||||
DispatchQueue.main.async {
|
||||
withAnimation {
|
||||
self.sharedMainViewModel.displayedConversation = conversationModel
|
||||
}
|
||||
}
|
||||
if self.sharedMainViewModel.displayedConversation == nil {
|
||||
DispatchQueue.main.async {
|
||||
withAnimation {
|
||||
self.sharedMainViewModel.displayedConversation = conversationModel
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
self.sharedMainViewModel.displayedConversation = nil
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
withAnimation {
|
||||
self.sharedMainViewModel.displayedConversation = conversationModel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ class StartConversationViewModel: ObservableObject {
|
|||
"\(StartConversationViewModel.TAG) Account is in secure mode, can't chat with SIP address of different domain \(remote.asStringUriOnly())"
|
||||
)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
self.operationInProgress = false
|
||||
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
|
||||
ToastViewModel.shared.displayToast = true
|
||||
|
|
@ -218,7 +218,7 @@ class StartConversationViewModel: ObservableObject {
|
|||
Log.info("\(StartConversationViewModel.TAG) 1-1 conversation \(chatRoomId) has been created")
|
||||
|
||||
let model = ConversationModel(chatRoom: chatRoom)
|
||||
DispatchQueue.main.async {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
self.displayedConversation = model
|
||||
self.operationInProgress = false
|
||||
}
|
||||
|
|
@ -231,7 +231,7 @@ class StartConversationViewModel: ObservableObject {
|
|||
Log.info("\(StartConversationViewModel.TAG) Conversation successfully created \(chatRoomId)")
|
||||
|
||||
let model = ConversationModel(chatRoom: chatRoom)
|
||||
DispatchQueue.main.async {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
self.displayedConversation = model
|
||||
self.operationInProgress = false
|
||||
}
|
||||
|
|
@ -239,7 +239,7 @@ class StartConversationViewModel: ObservableObject {
|
|||
} catch {
|
||||
Log.error("\(StartConversationViewModel.TAG) Failed to create 1-1 conversation with \(remote.asStringUriOnly())")
|
||||
|
||||
DispatchQueue.main.async {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
self.operationInProgress = false
|
||||
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
|
||||
ToastViewModel.shared.displayToast = true
|
||||
|
|
@ -250,7 +250,7 @@ class StartConversationViewModel: ObservableObject {
|
|||
"\(StartConversationViewModel.TAG) A 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) for given parameters already exists!"
|
||||
)
|
||||
let model = ConversationModel(chatRoom: existingChatRoom!)
|
||||
DispatchQueue.main.async {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
self.displayedConversation = model
|
||||
self.operationInProgress = false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import SwiftUI
|
|||
|
||||
struct PopupViewWithTextField: View {
|
||||
|
||||
@ObservedObject var conversationViewModel: ConversationViewModel
|
||||
@EnvironmentObject var conversationViewModel: ConversationViewModel
|
||||
|
||||
@FocusState var isMessageTextFocused: Bool
|
||||
|
||||
|
|
@ -81,5 +81,5 @@ struct PopupViewWithTextField: View {
|
|||
}
|
||||
|
||||
#Preview {
|
||||
PopupViewWithTextField(conversationViewModel: ConversationViewModel())
|
||||
PopupViewWithTextField()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ struct HistoryContactFragment: View {
|
|||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
//contactsListViewModel.createOneToOneChatRoomWith(remote: historyModel.addressLinphone)
|
||||
historyListViewModel.createOneToOneChatRoomWith(remote: historyModel.addressLinphone)
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ class HistoryListViewModel: ObservableObject {
|
|||
|
||||
@Published var selectedCall: HistoryModel?
|
||||
|
||||
@Published var displayedConversation: ConversationModel?
|
||||
|
||||
private var historyChatRoomDelegate: ChatRoomDelegate?
|
||||
|
||||
init() {
|
||||
computeCallLogsList()
|
||||
updateMissedCallsCount()
|
||||
|
|
@ -255,4 +259,178 @@ class HistoryListViewModel: ObservableObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createOneToOneChatRoomWith(remote: Address) {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
let account = core.defaultAccount
|
||||
if account == nil {
|
||||
Log.error(
|
||||
"\(ConversationForwardMessageViewModel.TAG) No default account found, can't create conversation with \(remote.asStringUriOnly())"
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
SharedMainViewModel.shared.operationInProgress = true
|
||||
}
|
||||
|
||||
do {
|
||||
let params = try core.createConferenceParams(conference: nil)
|
||||
params.chatEnabled = true
|
||||
params.groupEnabled = false
|
||||
params.subject = NSLocalizedString("conversation_one_to_one_hidden_subject", comment: "")
|
||||
params.account = account
|
||||
|
||||
guard let chatParams = params.chatParams else { return }
|
||||
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
|
||||
let sameDomain = remote.domain == CorePreferences.defaultDomain && remote.domain == account!.params?.domain
|
||||
if account!.params != nil && (account!.params!.instantMessagingEncryptionMandatory && sameDomain) {
|
||||
Log.info("\(ConversationForwardMessageViewModel.TAG) Account is in secure mode & domain matches, creating an E2E encrypted conversation")
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else if account!.params != nil && (!account!.params!.instantMessagingEncryptionMandatory) {
|
||||
if LinphoneUtils.isEndToEndEncryptedChatAvailable(core: core) {
|
||||
Log.info(
|
||||
"\(ConversationForwardMessageViewModel.TAG) Account is in interop mode but LIME is available, creating an E2E encrypted conversation"
|
||||
)
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else {
|
||||
Log.info(
|
||||
"\(ConversationForwardMessageViewModel.TAG) Account is in interop mode but LIME isn't available, creating a SIP simple conversation"
|
||||
)
|
||||
chatParams.backend = ChatRoom.Backend.Basic
|
||||
params.securityLevel = Conference.SecurityLevel.None
|
||||
}
|
||||
} else {
|
||||
Log.error(
|
||||
"\(ConversationForwardMessageViewModel.TAG) Account is in secure mode, can't chat with SIP address of different domain \(remote.asStringUriOnly())"
|
||||
)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
|
||||
ToastViewModel.shared.displayToast = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let participants = [remote]
|
||||
let localAddress = account?.params?.identityAddress
|
||||
let existingChatRoom = core.searchChatRoom(params: params, localAddr: localAddress, remoteAddr: nil, participants: participants)
|
||||
if existingChatRoom == nil {
|
||||
Log.info(
|
||||
"\(ConversationForwardMessageViewModel.TAG) No existing 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) was found for given parameters, let's create it"
|
||||
)
|
||||
|
||||
do {
|
||||
let chatRoom = try core.createChatRoom(params: params, participants: participants)
|
||||
if chatParams.backend == ChatRoom.Backend.FlexisipChat {
|
||||
let state = chatRoom.state
|
||||
if state == ChatRoom.State.Created {
|
||||
let chatRoomId = LinphoneUtils.getConversationId(chatRoom: chatRoom)
|
||||
Log.info("\(ConversationForwardMessageViewModel.TAG) 1-1 conversation \(chatRoomId) has been created")
|
||||
|
||||
let model = ConversationModel(chatRoom: chatRoom)
|
||||
DispatchQueue.main.async {
|
||||
self.displayedConversation = model
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
}
|
||||
} else {
|
||||
Log.info("\(ConversationForwardMessageViewModel.TAG) Conversation isn't in Created state yet (state is \(state)), wait for it")
|
||||
self.chatRoomAddDelegate(core: core, chatRoom: chatRoom)
|
||||
}
|
||||
} else {
|
||||
let chatRoomId = LinphoneUtils.getConversationId(chatRoom: chatRoom)
|
||||
Log.info("\(ConversationForwardMessageViewModel.TAG) Conversation successfully created \(chatRoomId)")
|
||||
|
||||
let model = ConversationModel(chatRoom: chatRoom)
|
||||
DispatchQueue.main.async {
|
||||
self.displayedConversation = model
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Log.error("\(ConversationForwardMessageViewModel.TAG) Failed to create 1-1 conversation with \(remote.asStringUriOnly())")
|
||||
|
||||
DispatchQueue.main.async {
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
|
||||
ToastViewModel.shared.displayToast = true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.warn(
|
||||
"\(ConversationForwardMessageViewModel.TAG) A 1-1 conversation between local account \(localAddress?.asStringUriOnly() ?? "") and remote \(remote.asStringUriOnly()) for given parameters already exists!"
|
||||
)
|
||||
let model = ConversationModel(chatRoom: existingChatRoom!)
|
||||
DispatchQueue.main.async {
|
||||
self.displayedConversation = model
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func chatRoomAddDelegate(core: Core, chatRoom: ChatRoom) {
|
||||
historyChatRoomDelegate = ChatRoomDelegateStub(onStateChanged: { (chatRoom: ChatRoom, state: ChatRoom.State) in
|
||||
let state = chatRoom.state
|
||||
let id = LinphoneUtils.getChatRoomId(room: chatRoom)
|
||||
if state == ChatRoom.State.CreationFailed {
|
||||
Log.error("\(StartConversationViewModel.TAG) Conversation \(id) creation has failed!")
|
||||
if let delegate = self.historyChatRoomDelegate {
|
||||
chatRoom.removeDelegate(delegate: delegate)
|
||||
self.historyChatRoomDelegate = nil
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
|
||||
ToastViewModel.shared.displayToast = true
|
||||
}
|
||||
}
|
||||
}, onConferenceJoined: { (chatRoom: ChatRoom, _: EventLog) in
|
||||
let state = chatRoom.state
|
||||
let id = LinphoneUtils.getChatRoomId(room: chatRoom)
|
||||
Log.info("\(StartConversationViewModel.TAG) Conversation \(id) \(chatRoom.subject ?? "") state changed: \(state)")
|
||||
if state == ChatRoom.State.Created {
|
||||
Log.info("\(StartConversationViewModel.TAG) Conversation \(id) successfully created")
|
||||
if let delegate = self.historyChatRoomDelegate {
|
||||
chatRoom.removeDelegate(delegate: delegate)
|
||||
self.historyChatRoomDelegate = nil
|
||||
}
|
||||
let model = ConversationModel(chatRoom: chatRoom)
|
||||
if SharedMainViewModel.shared.operationInProgress == false {
|
||||
DispatchQueue.main.async {
|
||||
SharedMainViewModel.shared.operationInProgress = true
|
||||
}
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
self.displayedConversation = model
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
self.displayedConversation = model
|
||||
}
|
||||
}
|
||||
} else if state == ChatRoom.State.CreationFailed {
|
||||
Log.error("\(StartConversationViewModel.TAG) Conversation \(id) creation has failed!")
|
||||
|
||||
if let delegate = self.historyChatRoomDelegate {
|
||||
chatRoom.removeDelegate(delegate: delegate)
|
||||
self.historyChatRoomDelegate = nil
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
SharedMainViewModel.shared.operationInProgress = false
|
||||
ToastViewModel.shared.toastMessage = "Failed_to_create_conversation_error"
|
||||
ToastViewModel.shared.displayToast = true
|
||||
}
|
||||
}
|
||||
})
|
||||
chatRoom.addDelegate(delegate: historyChatRoomDelegate!)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ class SharedMainViewModel: ObservableObject {
|
|||
@Published var dialPlansLabelList: [String] = []
|
||||
@Published var dialPlansShortLabelList: [String] = []
|
||||
|
||||
|
||||
@Published var operationInProgress = false
|
||||
|
||||
let welcomeViewKey = "welcome_view"
|
||||
let generalTermsKey = "general_terms"
|
||||
let displayProfileModeKey = "display_profile_mode"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue