Add ConversationsList bottom sheet

This commit is contained in:
benoit.martins 2024-02-14 17:59:21 +01:00
parent da9d90e368
commit cacc61252d
9 changed files with 321 additions and 26 deletions

View file

@ -16,6 +16,8 @@
66C491FF2B24D4AC00CEA16D /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FE2B24D4AC00CEA16D /* FileUtils.swift */; }; 66C491FF2B24D4AC00CEA16D /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FE2B24D4AC00CEA16D /* FileUtils.swift */; };
66C492012B24DB6900CEA16D /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C492002B24DB6900CEA16D /* Log.swift */; }; 66C492012B24DB6900CEA16D /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C492002B24DB6900CEA16D /* Log.swift */; };
D706BA822ADD72D100278F45 /* DeviceRotationViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D706BA812ADD72D100278F45 /* DeviceRotationViewModifier.swift */; }; D706BA822ADD72D100278F45 /* DeviceRotationViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D706BA812ADD72D100278F45 /* DeviceRotationViewModifier.swift */; };
D70A26EE2B7CF60B006CC8FC /* ConversationsListBottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70A26ED2B7CF60B006CC8FC /* ConversationsListBottomSheet.swift */; };
D70A26F02B7D02E6006CC8FC /* ConversationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70A26EF2B7D02E6006CC8FC /* ConversationViewModel.swift */; };
D70C93DE2AC2D0F60063CA3B /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = D70C93DD2AC2D0F60063CA3B /* Localizable.xcstrings */; }; D70C93DE2AC2D0F60063CA3B /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = D70C93DD2AC2D0F60063CA3B /* Localizable.xcstrings */; };
D717071E2AC5922E0037746F /* ColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D717071D2AC5922E0037746F /* ColorExtension.swift */; }; D717071E2AC5922E0037746F /* ColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D717071D2AC5922E0037746F /* ColorExtension.swift */; };
D71707202AC5989C0037746F /* TextExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D717071F2AC5989C0037746F /* TextExtension.swift */; }; D71707202AC5989C0037746F /* TextExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D717071F2AC5989C0037746F /* TextExtension.swift */; };
@ -114,6 +116,8 @@
66C491FE2B24D4AC00CEA16D /* FileUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileUtils.swift; sourceTree = "<group>"; }; 66C491FE2B24D4AC00CEA16D /* FileUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileUtils.swift; sourceTree = "<group>"; };
66C492002B24DB6900CEA16D /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; }; 66C492002B24DB6900CEA16D /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; };
D706BA812ADD72D100278F45 /* DeviceRotationViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceRotationViewModifier.swift; sourceTree = "<group>"; }; D706BA812ADD72D100278F45 /* DeviceRotationViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceRotationViewModifier.swift; sourceTree = "<group>"; };
D70A26ED2B7CF60B006CC8FC /* ConversationsListBottomSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationsListBottomSheet.swift; sourceTree = "<group>"; };
D70A26EF2B7D02E6006CC8FC /* ConversationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationViewModel.swift; sourceTree = "<group>"; };
D70C93DD2AC2D0F60063CA3B /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; }; D70C93DD2AC2D0F60063CA3B /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
D717071D2AC5922E0037746F /* ColorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorExtension.swift; sourceTree = "<group>"; }; D717071D2AC5922E0037746F /* ColorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorExtension.swift; sourceTree = "<group>"; };
D717071F2AC5989C0037746F /* TextExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextExtension.swift; sourceTree = "<group>"; }; D717071F2AC5989C0037746F /* TextExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextExtension.swift; sourceTree = "<group>"; };
@ -544,6 +548,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D7CEE0372B7A214F00FD79B7 /* ConversationsListViewModel.swift */, D7CEE0372B7A214F00FD79B7 /* ConversationsListViewModel.swift */,
D70A26EF2B7D02E6006CC8FC /* ConversationViewModel.swift */,
); );
path = ViewModel; path = ViewModel;
sourceTree = "<group>"; sourceTree = "<group>";
@ -553,6 +558,7 @@
children = ( children = (
D7CEE03A2B7A234200FD79B7 /* ConversationsFragment.swift */, D7CEE03A2B7A234200FD79B7 /* ConversationsFragment.swift */,
D7CEE03C2B7A23B200FD79B7 /* ConversationsListFragment.swift */, D7CEE03C2B7A23B200FD79B7 /* ConversationsListFragment.swift */,
D70A26ED2B7CF60B006CC8FC /* ConversationsListBottomSheet.swift */,
); );
path = Fragments; path = Fragments;
sourceTree = "<group>"; sourceTree = "<group>";
@ -741,6 +747,7 @@
D78290BB2ADD40B2004AA85C /* ContactViewModel.swift in Sources */, D78290BB2ADD40B2004AA85C /* ContactViewModel.swift in Sources */,
D7F4D9CB2B5FD27200CDCD76 /* CallsListFragment.swift in Sources */, D7F4D9CB2B5FD27200CDCD76 /* CallsListFragment.swift in Sources */,
D72992392ADD7F68003AF125 /* HistoryContactFragment.swift in Sources */, D72992392ADD7F68003AF125 /* HistoryContactFragment.swift in Sources */,
D70A26F02B7D02E6006CC8FC /* ConversationViewModel.swift in Sources */,
D7B5066D2AEFA9B900CEB4E9 /* ContactInnerFragment.swift in Sources */, D7B5066D2AEFA9B900CEB4E9 /* ContactInnerFragment.swift in Sources */,
D7E6D04D2AEBD77600A57AAF /* CustomBottomSheet.swift in Sources */, D7E6D04D2AEBD77600A57AAF /* CustomBottomSheet.swift in Sources */,
D7C48DF42AFA66F900D938CB /* EditContactController.swift in Sources */, D7C48DF42AFA66F900D938CB /* EditContactController.swift in Sources */,
@ -780,6 +787,7 @@
D7B99E9B2B29F7C300BE7BF2 /* ActivityIndicator.swift in Sources */, D7B99E9B2B29F7C300BE7BF2 /* ActivityIndicator.swift in Sources */,
D72343302ACEFEF8009AA24E /* QrCodeScannerFragment.swift in Sources */, D72343302ACEFEF8009AA24E /* QrCodeScannerFragment.swift in Sources */,
D726E43F2B19E56F0083C415 /* StartCallViewModel.swift in Sources */, D726E43F2B19E56F0083C415 /* StartCallViewModel.swift in Sources */,
D70A26EE2B7CF60B006CC8FC /* ConversationsListBottomSheet.swift in Sources */,
D7D1698C2AE66FA500109A5C /* MagicSearchSingleton.swift in Sources */, D7D1698C2AE66FA500109A5C /* MagicSearchSingleton.swift in Sources */,
D72250692ADFBF2D008FB426 /* SideMenu.swift in Sources */, D72250692ADFBF2D008FB426 /* SideMenu.swift in Sources */,
D7CEE0352B7A210300FD79B7 /* ConversationsView.swift in Sources */, D7CEE0352B7A210300FD79B7 /* ConversationsView.swift in Sources */,

View file

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "bell-slash.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="M53.92,34.62A8,8,0,1,0,42.08,45.38L58.82,63.8A79.59,79.59,0,0,0,48,104c0,35.34-8.26,62.38-13.81,71.94A16,16,0,0,0,48,200H88.8a40,40,0,0,0,78.4,0h15.44l19.44,21.38a8,8,0,1,0,11.84-10.76ZM128,216a24,24,0,0,1-22.62-16h45.24A24,24,0,0,1,128,216ZM48,184c7.7-13.24,16-43.92,16-80a63.65,63.65,0,0,1,6.26-27.62L168.09,184Zm166-4.73a8.13,8.13,0,0,1-2.93.55,8,8,0,0,1-7.44-5.08C196.35,156.19,192,129.75,192,104A64,64,0,0,0,96.43,48.31a8,8,0,0,1-7.9-13.91A80,80,0,0,1,208,104c0,35.35,8.05,58.59,10.52,64.88A8,8,0,0,1,214,179.25Z"></path></svg>

After

Width:  |  Height:  |  Size: 641 B

View file

@ -400,12 +400,18 @@
}, },
"Logs URL copied into clipboard" : { "Logs URL copied into clipboard" : {
},
"Marquer comme non lu" : {
}, },
"Message" : { "Message" : {
}, },
"Messages" : { "Messages" : {
},
"Mettre en sourdine" : {
}, },
"Missed call" : { "Missed call" : {
@ -489,6 +495,9 @@
}, },
"QR code validated!" : { "QR code validated!" : {
},
"Quitter la conversation" : {
}, },
"Record" : { "Record" : {
@ -558,6 +567,9 @@
}, },
"Suggestions" : { "Suggestions" : {
},
"Supprimer la conversation" : {
}, },
"TCP" : { "TCP" : {

View file

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

View file

@ -22,47 +22,34 @@ import SwiftUI
struct ConversationsFragment: View { struct ConversationsFragment: View {
@ObservedObject var conversationsListViewModel: ConversationsListViewModel @ObservedObject var conversationsListViewModel: ConversationsListViewModel
@ObservedObject var conversationViewModel: ConversationViewModel
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom } private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@State var showingSheet: Bool = false
var body: some View { var body: some View {
ZStack { ZStack {
if #available(iOS 16.0, *), idiom != .pad { if #available(iOS 16.0, *), idiom != .pad {
ConversationsListFragment(conversationsListViewModel: conversationsListViewModel) ConversationsListFragment(conversationsListViewModel: conversationsListViewModel, conversationViewModel: conversationViewModel,showingSheet: $showingSheet)
/*
.sheet(isPresented: $showingSheet) { .sheet(isPresented: $showingSheet) {
HistoryListBottomSheet( ConversationsListBottomSheet(
historyViewModel: historyViewModel, showingSheet: $showingSheet
contactViewModel: contactViewModel,
editContactViewModel: editContactViewModel,
historyListViewModel: historyListViewModel,
showingSheet: $showingSheet,
index: $index,
isShowEditContactFragment: $isShowEditContactFragment
) )
.presentationDetents([.fraction(0.2)]) .presentationDetents([.fraction(0.4)])
} }
*/
} else { } else {
ConversationsListFragment(conversationsListViewModel: conversationsListViewModel) ConversationsListFragment(conversationsListViewModel: conversationsListViewModel, conversationViewModel: conversationViewModel,showingSheet: $showingSheet)
/*
.halfSheet(showSheet: $showingSheet) { .halfSheet(showSheet: $showingSheet) {
HistoryListBottomSheet( ConversationsListBottomSheet(
historyViewModel: historyViewModel, showingSheet: $showingSheet
contactViewModel: contactViewModel,
editContactViewModel: editContactViewModel,
historyListViewModel: historyListViewModel,
showingSheet: $showingSheet,
index: $index,
isShowEditContactFragment: $isShowEditContactFragment
) )
} onDismiss: {} } onDismiss: {}
*/
} }
} }
} }
} }
#Preview { #Preview {
ConversationsFragment(conversationsListViewModel: ConversationsListViewModel()) ConversationsFragment(conversationsListViewModel: ConversationsListViewModel(), conversationViewModel: ConversationViewModel())
} }

View file

@ -0,0 +1,231 @@
/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import SwiftUI
struct ConversationsListBottomSheet: View {
@Environment(\.dismiss) var dismiss
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@State private var orientation = UIDevice.current.orientation
@Binding var showingSheet: Bool
var body: some View {
VStack(alignment: .leading) {
if idiom != .pad && (orientation == .landscapeLeft
|| orientation == .landscapeRight
|| UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) {
Spacer()
HStack {
Spacer()
Button("Close") {
if #available(iOS 16.0, *) {
showingSheet.toggle()
} else {
showingSheet.toggle()
dismiss()
}
}
}
.padding(.trailing)
}
Spacer()
Button {
if #available(iOS 16.0, *) {
if idiom != .pad {
showingSheet.toggle()
} else {
showingSheet.toggle()
dismiss()
}
} else {
showingSheet.toggle()
dismiss()
}
} label: {
HStack {
Image("envelope-simple")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.grayMain2c500)
.frame(width: 25, height: 25, alignment: .leading)
.padding(.all, 10)
Text("Marquer comme non lu")
.default_text_style(styleSize: 16)
Spacer()
}
.frame(maxHeight: .infinity)
}
.padding(.horizontal, 30)
.background(Color.gray100)
VStack {
Divider()
}
.frame(maxWidth: .infinity)
Button {
if #available(iOS 16.0, *) {
if idiom != .pad {
showingSheet.toggle()
} else {
showingSheet.toggle()
dismiss()
}
} else {
showingSheet.toggle()
dismiss()
}
} label: {
HStack {
Image("bell-slash")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.grayMain2c500)
.frame(width: 25, height: 25, alignment: .leading)
.padding(.all, 10)
Text("Mettre en sourdine")
.default_text_style(styleSize: 16)
Spacer()
}
.frame(maxHeight: .infinity)
}
.padding(.horizontal, 30)
.background(Color.gray100)
VStack {
Divider()
}
.frame(maxWidth: .infinity)
Button {
if #available(iOS 16.0, *) {
if idiom != .pad {
showingSheet.toggle()
} 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)
VStack {
Divider()
}
.frame(maxWidth: .infinity)
Button {
if #available(iOS 16.0, *) {
if idiom != .pad {
showingSheet.toggle()
} else {
showingSheet.toggle()
dismiss()
}
} else {
showingSheet.toggle()
dismiss()
}
} label: {
HStack {
Image("trash-simple")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.redDanger500)
.frame(width: 25, height: 25, alignment: .leading)
.padding(.all, 10)
Text("Supprimer la conversation")
.foregroundStyle(Color.redDanger500)
.default_text_style(styleSize: 16)
Spacer()
}
.frame(maxHeight: .infinity)
}
.padding(.horizontal, 30)
.background(Color.gray100)
VStack {
Divider()
}
.frame(maxWidth: .infinity)
Button {
if #available(iOS 16.0, *) {
if idiom != .pad {
showingSheet.toggle()
} else {
showingSheet.toggle()
dismiss()
}
} else {
showingSheet.toggle()
dismiss()
}
} label: {
HStack {
Image("sign-out")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.grayMain2c500)
.frame(width: 25, height: 25, alignment: .leading)
.padding(.all, 10)
Text("Quitter la conversation")
.default_text_style(styleSize: 16)
Spacer()
}
.frame(maxHeight: .infinity)
}
.padding(.horizontal, 30)
.background(Color.gray100)
}
.background(Color.gray100)
.frame(maxWidth: .infinity)
.onRotate { newOrientation in
orientation = newOrientation
}
}
}
#Preview {
ConversationsListBottomSheet(showingSheet: .constant(true))
}

View file

@ -25,6 +25,9 @@ struct ConversationsListFragment: View {
@ObservedObject var contactsManager = ContactsManager.shared @ObservedObject var contactsManager = ContactsManager.shared
@ObservedObject var conversationsListViewModel: ConversationsListViewModel @ObservedObject var conversationsListViewModel: ConversationsListViewModel
@ObservedObject var conversationViewModel: ConversationViewModel
@Binding var showingSheet: Bool
var body: some View { var body: some View {
VStack { VStack {
@ -217,6 +220,8 @@ struct ConversationsListFragment: View {
.onTapGesture { .onTapGesture {
} }
.onLongPressGesture(minimumDuration: 0.2) { .onLongPressGesture(minimumDuration: 0.2) {
conversationViewModel.selectedConversation = conversationsListViewModel.conversationsList[index]
showingSheet.toggle()
} }
} }
} }
@ -245,5 +250,5 @@ struct ConversationsListFragment: View {
} }
#Preview { #Preview {
ConversationsListFragment(conversationsListViewModel: ConversationsListViewModel()) ConversationsListFragment(conversationsListViewModel: ConversationsListViewModel(), conversationViewModel: ConversationViewModel(), showingSheet: .constant(false))
} }

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import Foundation
import linphonesw
class ConversationViewModel: ObservableObject {
@Published var displayedConversation: ChatRoom?
var selectedConversation: ChatRoom?
init() {}
}