Fix conversations list view when receiving a message or a new chat room

This commit is contained in:
Benoit Martins 2024-02-15 15:19:46 +01:00
parent cacc61252d
commit 61c2c048bb
10 changed files with 143 additions and 53 deletions

View file

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "bell.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M221.8,175.94C216.25,166.38,208,139.33,208,104a80,80,0,1,0-160,0c0,35.34-8.26,62.38-13.81,71.94A16,16,0,0,0,48,200H88.81a40,40,0,0,0,78.38,0H208a16,16,0,0,0,13.8-24.06ZM128,216a24,24,0,0,1-22.62-16h45.24A24,24,0,0,1,128,216ZM48,184c7.7-13.24,16-43.92,16-80a64,64,0,1,1,128,0c0,36.05,8.28,66.73,16,80Z"></path></svg>

After

Width:  |  Height:  |  Size: 424 B

View file

@ -66,7 +66,8 @@ struct LinphoneApp: App {
&& historyViewModel != nil
&& historyListViewModel != nil
&& startCallViewModel != nil
&& callViewModel != nil {
&& callViewModel != nil
&& conversationsListViewModel != nil{
ContentView(
contactViewModel: contactViewModel!,
editContactViewModel: editContactViewModel!,

View file

@ -244,6 +244,9 @@
},
"Contacts" : {
},
"Content" : {
},
"Continue" : {
@ -498,6 +501,9 @@
},
"Quitter la conversation" : {
},
"Réactiver les notifications" : {
},
"Record" : {
@ -582,6 +588,9 @@
},
"This contact will be deleted definitively." : {
},
"Title" : {
},
"TLS" : {

View file

@ -47,5 +47,5 @@ struct ConversationsView: View {
}
#Preview {
ConversationsListFragment(conversationsListViewModel: ConversationsListViewModel(), conversationViewModel: ConversationViewModel(), showingSheet: .constant(false))
ConversationsListFragment(conversationsListViewModel: ConversationsListViewModel(), showingSheet: .constant(false))
}

View file

@ -22,7 +22,6 @@ import SwiftUI
struct ConversationsFragment: View {
@ObservedObject var conversationsListViewModel: ConversationsListViewModel
@ObservedObject var conversationViewModel: ConversationViewModel
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@ -31,17 +30,19 @@ struct ConversationsFragment: View {
var body: some View {
ZStack {
if #available(iOS 16.0, *), idiom != .pad {
ConversationsListFragment(conversationsListViewModel: conversationsListViewModel, conversationViewModel: conversationViewModel,showingSheet: $showingSheet)
ConversationsListFragment(conversationsListViewModel: conversationsListViewModel, showingSheet: $showingSheet)
.sheet(isPresented: $showingSheet) {
ConversationsListBottomSheet(
conversationsListViewModel: conversationsListViewModel,
showingSheet: $showingSheet
)
.presentationDetents([.fraction(0.4)])
}
} else {
ConversationsListFragment(conversationsListViewModel: conversationsListViewModel, conversationViewModel: conversationViewModel,showingSheet: $showingSheet)
ConversationsListFragment(conversationsListViewModel: conversationsListViewModel, showingSheet: $showingSheet)
.halfSheet(showSheet: $showingSheet) {
ConversationsListBottomSheet(
conversationsListViewModel: conversationsListViewModel,
showingSheet: $showingSheet
)
} onDismiss: {}
@ -51,5 +52,5 @@ struct ConversationsFragment: View {
}
#Preview {
ConversationsFragment(conversationsListViewModel: ConversationsListViewModel(), conversationViewModel: ConversationViewModel())
ConversationsFragment(conversationsListViewModel: ConversationsListViewModel())
}

View file

@ -18,6 +18,7 @@
*/
import SwiftUI
import linphonesw
struct ConversationsListBottomSheet: View {
@ -27,6 +28,8 @@ struct ConversationsListBottomSheet: View {
@State private var orientation = UIDevice.current.orientation
@ObservedObject var conversationsListViewModel: ConversationsListViewModel
@Binding var showingSheet: Bool
var body: some View {
@ -52,6 +55,12 @@ struct ConversationsListBottomSheet: View {
Spacer()
Button {
if conversationsListViewModel.selectedConversation != nil {
conversationsListViewModel.objectWillChange.send()
conversationsListViewModel.selectedConversation!.markAsRead()
conversationsListViewModel.updateUnreadMessagesCount()
}
if #available(iOS 16.0, *) {
if idiom != .pad {
showingSheet.toggle()
@ -86,6 +95,11 @@ struct ConversationsListBottomSheet: View {
.frame(maxWidth: .infinity)
Button {
if conversationsListViewModel.selectedConversation != nil {
conversationsListViewModel.objectWillChange.send()
conversationsListViewModel.selectedConversation!.muted.toggle()
}
if #available(iOS 16.0, *) {
if idiom != .pad {
showingSheet.toggle()
@ -99,13 +113,13 @@ struct ConversationsListBottomSheet: View {
}
} label: {
HStack {
Image("bell-slash")
Image(conversationsListViewModel.selectedConversation!.muted ? "bell" : "bell-slash")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.grayMain2c500)
.frame(width: 25, height: 25, alignment: .leading)
.padding(.all, 10)
Text("Mettre en sourdine")
Text(conversationsListViewModel.selectedConversation!.muted ? "Réactiver les notifications" : "Mettre en sourdine")
.default_text_style(styleSize: 16)
Spacer()
}
@ -119,42 +133,58 @@ struct ConversationsListBottomSheet: View {
}
.frame(maxWidth: .infinity)
Button {
if #available(iOS 16.0, *) {
if idiom != .pad {
showingSheet.toggle()
if conversationsListViewModel.selectedConversation != nil
&& conversationsListViewModel.selectedConversation!.hasCapability(mask: ChatRoom.Capabilities.OneToOne.rawValue) {
Button {
if conversationsListViewModel.selectedConversation!.participants.first != nil {
TelecomManager.shared.doCallWithCore(
addr: conversationsListViewModel.selectedConversation!.participants.first!.address!, isVideo: false
)
}
if #available(iOS 16.0, *) {
if idiom != .pad {
showingSheet.toggle()
} else {
showingSheet.toggle()
dismiss()
}
} else {
showingSheet.toggle()
dismiss()
}
} else {
showingSheet.toggle()
dismiss()
} label: {
HStack {
Image("phone")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.grayMain2c500)
.frame(width: 25, height: 25, alignment: .leading)
.padding(.all, 10)
Text("Appel")
.default_text_style(styleSize: 16)
Spacer()
}
.frame(maxHeight: .infinity)
}
.padding(.horizontal, 30)
.background(Color.gray100)
} label: {
HStack {
Image("phone")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.grayMain2c500)
.frame(width: 25, height: 25, alignment: .leading)
.padding(.all, 10)
Text("Appel")
.default_text_style(styleSize: 16)
Spacer()
VStack {
Divider()
}
.frame(maxHeight: .infinity)
.frame(maxWidth: .infinity)
}
.padding(.horizontal, 30)
.background(Color.gray100)
VStack {
Divider()
}
.frame(maxWidth: .infinity)
Button {
if conversationsListViewModel.selectedConversation != nil {
CoreContext.shared.doOnCoreQueue { core in
core.deleteChatRoom(chatRoom: conversationsListViewModel.selectedConversation!)
//conversationsListViewModel.computeChatRoomsList(filter: "")
}
}
if #available(iOS 16.0, *) {
if idiom != .pad {
showingSheet.toggle()
@ -190,6 +220,10 @@ struct ConversationsListBottomSheet: View {
.frame(maxWidth: .infinity)
Button {
if conversationsListViewModel.selectedConversation != nil {
conversationsListViewModel.selectedConversation!.leave()
}
if #available(iOS 16.0, *) {
if idiom != .pad {
showingSheet.toggle()
@ -227,5 +261,5 @@ struct ConversationsListBottomSheet: View {
}
#Preview {
ConversationsListBottomSheet(showingSheet: .constant(true))
ConversationsListBottomSheet(conversationsListViewModel: ConversationsListViewModel(), showingSheet: .constant(true))
}

View file

@ -25,7 +25,6 @@ struct ConversationsListFragment: View {
@ObservedObject var contactsManager = ContactsManager.shared
@ObservedObject var conversationsListViewModel: ConversationsListViewModel
@ObservedObject var conversationViewModel: ConversationViewModel
@Binding var showingSheet: Bool
@ -174,6 +173,22 @@ struct ConversationsListFragment: View {
Spacer()
HStack {
if conversationsListViewModel.conversationsList[index].muted == false
&& !(conversationsListViewModel.conversationsList[index].lastMessageInHistory != nil
&& conversationsListViewModel.conversationsList[index].lastMessageInHistory!.isOutgoing == true)
&& conversationsListViewModel.conversationsList[index].unreadMessagesCount == 0 {
Text("")
.frame(width: 18, height: 18, alignment: .trailing)
}
if conversationsListViewModel.conversationsList[index].muted {
Image("bell-slash")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.orangeMain500)
.frame(width: 18, height: 18, alignment: .trailing)
}
if conversationsListViewModel.conversationsList[index].lastMessageInHistory != nil
&& conversationsListViewModel.conversationsList[index].lastMessageInHistory!.isOutgoing == true {
let imageName = LinphoneUtils.getChatIconState(chatState: conversationsListViewModel.conversationsList[index].lastMessageInHistory!.state)
@ -199,13 +214,6 @@ struct ConversationsListFragment: View {
.background(Color.redDanger500)
.cornerRadius(50)
}
if !(conversationsListViewModel.conversationsList[index].lastMessageInHistory != nil
&& conversationsListViewModel.conversationsList[index].lastMessageInHistory!.isOutgoing == true)
&& conversationsListViewModel.conversationsList[index].unreadMessagesCount == 0 {
Text("")
.frame(width: 18, height: 18, alignment: .trailing)
}
}
Spacer()
@ -220,7 +228,7 @@ struct ConversationsListFragment: View {
.onTapGesture {
}
.onLongPressGesture(minimumDuration: 0.2) {
conversationViewModel.selectedConversation = conversationsListViewModel.conversationsList[index]
conversationsListViewModel.selectedConversation = conversationsListViewModel.conversationsList[index]
showingSheet.toggle()
}
}
@ -250,5 +258,5 @@ struct ConversationsListFragment: View {
}
#Preview {
ConversationsListFragment(conversationsListViewModel: ConversationsListViewModel(), conversationViewModel: ConversationViewModel(), showingSheet: .constant(false))
ConversationsListFragment(conversationsListViewModel: ConversationsListViewModel(), showingSheet: .constant(false))
}

View file

@ -22,9 +22,5 @@ import linphonesw
class ConversationViewModel: ObservableObject {
@Published var displayedConversation: ChatRoom?
var selectedConversation: ChatRoom?
init() {}
}

View file

@ -31,6 +31,10 @@ class ConversationsListViewModel: ObservableObject {
@Published var conversationsList: [ChatRoom] = []
@Published var unreadMessages: Int = 0
@Published var displayedConversation: ChatRoom?
var selectedConversation: ChatRoom?
init() {
computeChatRoomsList(filter: "")
addConversationDelegate()
@ -45,6 +49,8 @@ class ConversationsListViewModel: ObservableObject {
self.conversationsList = []
chatRooms.forEach { chatRoom in
//let disabledBecauseNotSecured = (account?.isInSecureMode() == true && !chatRoom.hasCapability) ? Capabilities.Encrypted.toInt() : 0
if chatRoom.hasCapability(mask: ChatRoom.Capabilities.OneToOne.rawValue) {
}
if filter.isEmpty {
//val model = ConversationModel(chatRoom, disabledBecauseNotSecured)
@ -85,11 +91,11 @@ class ConversationsListViewModel: ObservableObject {
func addConversationDelegate() {
coreContext.doOnCoreQueue { core in
self.mCoreSuscriptions.insert(core.publisher?.onChatRoomStateChanged?.postOnMainQueue { (cbValue: (_: Core, chatRoom: ChatRoom, state: ChatRoom.State)) in
self.mCoreSuscriptions.insert(core.publisher?.onChatRoomStateChanged?.postOnMainQueue { (cbValue: (core: Core, chatRoom: ChatRoom, state: ChatRoom.State)) in
//Log.info("[ConversationsListViewModel] Conversation [${LinphoneUtils.getChatRoomId(chatRoom)}] state changed [$state]")
switch cbValue.state {
case ChatRoom.State.Created:
self.computeChatRoomsList(filter: "")
self.addChatRoom(cbChatRoom: cbValue.chatRoom)
case ChatRoom.State.Deleted:
self.computeChatRoomsList(filter: "")
//ToastViewModel.shared.toastMessage = "toast_conversation_deleted"
@ -100,15 +106,28 @@ class ConversationsListViewModel: ObservableObject {
})
self.mCoreSuscriptions.insert(core.publisher?.onMessageSent?.postOnMainQueue { _ in
self.reorderChatRooms()
self.computeChatRoomsList(filter: "")
})
self.mCoreSuscriptions.insert(core.publisher?.onMessagesReceived?.postOnMainQueue { _ in
self.reorderChatRooms()
self.computeChatRoomsList(filter: "")
})
}
}
func addChatRoom(cbChatRoom: ChatRoom) {
Log.info("[ConversationsListViewModel] Re-ordering conversations")
var sortedList: [ChatRoom] = []
sortedList.append(cbChatRoom)
sortedList.append(contentsOf: self.conversationsList)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.conversationsList = sortedList.sorted { $0.lastUpdateTime > $1.lastUpdateTime }
}
updateUnreadMessagesCount()
}
func reorderChatRooms() {
Log.info("[ConversationsListViewModel] Re-ordering conversations")
var sortedList: [ChatRoom] = []