mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-04-18 04:38:27 +00:00
Add SipAddressesPopup to StartCallFragment, StartConversationFragment, and AddParticipantsFragment
This commit is contained in:
parent
54b8ae4b02
commit
b84bd1faf3
8 changed files with 511 additions and 42 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import Foundation
|
||||
|
||||
public enum AppGitInfo {
|
||||
public static let branch = "master"
|
||||
public static let commit = "b82156d2f"
|
||||
public static let branch = "feature/address_selector"
|
||||
public static let commit = "dcfa42329"
|
||||
public static let tag = "6.1.0-alpha"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,14 +150,14 @@ struct ContactInnerFragment: View {
|
|||
|
||||
Button(action: {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
if contactAvatarModel.addresses.count == 1 {
|
||||
if contactAvatarModel.addresses.count == 1 && contactAvatarModel.phoneNumbersWithLabel.isEmpty {
|
||||
do {
|
||||
let address = try Factory.Instance.createAddress(addr: contactAvatarModel.address)
|
||||
telecomManager.doCallOrJoinConf(address: address, isVideo: false)
|
||||
} catch {
|
||||
Log.error("[ContactInnerFragment] unable to create address for a new outgoing call : \(contactAvatarModel.address) \(error) ")
|
||||
}
|
||||
} else if contactAvatarModel.addresses.count < 1 && contactAvatarModel.phoneNumbersWithLabel.count == 1 {
|
||||
} else if contactAvatarModel.addresses.isEmpty && contactAvatarModel.phoneNumbersWithLabel.count == 1 {
|
||||
if let firstPhoneNumbersWithLabel = contactAvatarModel.phoneNumbersWithLabel.first, let address = core.interpretUrl(url: firstPhoneNumbersWithLabel.phoneNumber, applyInternationalPrefix: LinphoneUtils.applyInternationalPrefix(core: core)) {
|
||||
telecomManager.doCallOrJoinConf(address: address, isVideo: false)
|
||||
}
|
||||
|
|
@ -191,14 +191,14 @@ struct ContactInnerFragment: View {
|
|||
|
||||
Button(action: {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
if contactAvatarModel.addresses.count == 1 {
|
||||
if contactAvatarModel.addresses.count == 1 && contactAvatarModel.phoneNumbersWithLabel.isEmpty {
|
||||
do {
|
||||
let address = try Factory.Instance.createAddress(addr: contactAvatarModel.address)
|
||||
contactsListViewModel.createOneToOneChatRoomWith(remote: address)
|
||||
} catch {
|
||||
Log.error("[ContactInnerFragment] unable to create address for a new outgoing call : \(contactAvatarModel.address) \(error) ")
|
||||
}
|
||||
} else if contactAvatarModel.addresses.count < 1 && contactAvatarModel.phoneNumbersWithLabel.count == 1 {
|
||||
} else if contactAvatarModel.addresses.isEmpty && contactAvatarModel.phoneNumbersWithLabel.count == 1 {
|
||||
if let firstPhoneNumbersWithLabel = contactAvatarModel.phoneNumbersWithLabel.first, let address = core.interpretUrl(url: firstPhoneNumbersWithLabel.phoneNumber, applyInternationalPrefix: LinphoneUtils.applyInternationalPrefix(core: core)) {
|
||||
contactsListViewModel.createOneToOneChatRoomWith(remote: address)
|
||||
}
|
||||
|
|
@ -233,14 +233,14 @@ struct ContactInnerFragment: View {
|
|||
if !SharedMainViewModel.shared.disableVideoCall {
|
||||
Button(action: {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
if contactAvatarModel.addresses.count == 1 {
|
||||
if contactAvatarModel.addresses.count == 1 && contactAvatarModel.phoneNumbersWithLabel.isEmpty {
|
||||
do {
|
||||
let address = try Factory.Instance.createAddress(addr: contactAvatarModel.address)
|
||||
telecomManager.doCallOrJoinConf(address: address, isVideo: true)
|
||||
} catch {
|
||||
Log.error("[ContactInnerFragment] unable to create address for a new outgoing call : \(contactAvatarModel.address) \(error) ")
|
||||
}
|
||||
} else if contactAvatarModel.addresses.count < 1 && contactAvatarModel.phoneNumbersWithLabel.count == 1 {
|
||||
} else if contactAvatarModel.addresses.isEmpty && contactAvatarModel.phoneNumbersWithLabel.count == 1 {
|
||||
if let firstPhoneNumbersWithLabel = contactAvatarModel.phoneNumbersWithLabel.first, let address = core.interpretUrl(url: firstPhoneNumbersWithLabel.phoneNumber, applyInternationalPrefix: LinphoneUtils.applyInternationalPrefix(core: core)) {
|
||||
telecomManager.doCallOrJoinConf(address: address, isVideo: true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,51 @@ struct SipAddressesPopup: View {
|
|||
}
|
||||
}
|
||||
} catch {
|
||||
Log.error("[ContactInnerActionsFragment] unable to create address for a new outgoing call : \(contactAvatarModel.addresses[index]) \(error) ")
|
||||
Log.error("[SipAddressesPopup] unable to create address for a new outgoing call : \(contactAvatarModel.addresses[index]) \(error) ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ForEach(0..<contactAvatarModel.phoneNumbersWithLabel.count, id: \.self) { index in
|
||||
HStack {
|
||||
HStack {
|
||||
VStack {
|
||||
Text(String(localized: "phone_number") + ":")
|
||||
.default_text_style_700(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
Text(contactAvatarModel.phoneNumbersWithLabel[index].phoneNumber)
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(1)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.vertical, 15)
|
||||
.padding(.horizontal, 10)
|
||||
}
|
||||
.background(.white)
|
||||
.onTapGesture {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
if let address = core.interpretUrl(url: contactAvatarModel.phoneNumbersWithLabel[index].phoneNumber, applyInternationalPrefix: LinphoneUtils.applyInternationalPrefix(core: core)) {
|
||||
DispatchQueue.main.async {
|
||||
if isShowSipAddressesPopupType != 1 {
|
||||
withAnimation {
|
||||
isShowSipAddressesPopup = false
|
||||
telecomManager.doCallOrJoinConf(address: address, isVideo: isShowSipAddressesPopupType == 2)
|
||||
isShowSipAddressesPopupType = 0
|
||||
}
|
||||
} else {
|
||||
withAnimation {
|
||||
isShowSipAddressesPopup = false
|
||||
contactsListViewModel.createOneToOneChatRoomWith(remote: address)
|
||||
isShowSipAddressesPopupType = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.error("[SipAddressesPopup] unable to create address (interpret Url for phone number) for a new outgoing call : \(contactAvatarModel.addresses[index])")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +141,7 @@ struct SipAddressesPopup: View {
|
|||
.frame(maxHeight: .infinity)
|
||||
.shadow(color: Color.orangeMain500, radius: 0, x: 0, y: 2)
|
||||
.frame(maxWidth: SharedMainViewModel.shared.maxWidth)
|
||||
.padding(.horizontal, 20)
|
||||
.position(x: geometry.size.width / 2, y: geometry.size.height / 2)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1276,8 +1276,8 @@ struct ContentView: View {
|
|||
|
||||
if isShowStartCallFragment {
|
||||
StartCallFragment(
|
||||
isShowStartCallFragment: $isShowStartCallFragment,
|
||||
showingDialer: $showingDialer,
|
||||
isShowStartCallFragment: $isShowStartCallFragment,
|
||||
resetCallView: {callViewModel.resetCallView()}
|
||||
)
|
||||
.environmentObject(callViewModel)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ struct StartConversationFragment: View {
|
|||
|
||||
@Binding var isShowStartConversationFragment: Bool
|
||||
|
||||
@State private var contactAvatarModel: ContactAvatarModel? = nil
|
||||
@State private var isShowSipAddressesPopup: Bool = false
|
||||
|
||||
@FocusState var isSearchFieldFocused: Bool
|
||||
@State private var delayedColor = Color.white
|
||||
|
||||
|
|
@ -184,7 +187,24 @@ struct StartConversationFragment: View {
|
|||
}
|
||||
|
||||
ContactsListFragment(showingSheet: .constant(false), startCallFunc: { addr in
|
||||
startConversationViewModel.createOneToOneChatRoomWith(remote: addr)
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
ContactAvatarModel.getAvatarModelFromAddress(address: addr) { contactAvatarModel in
|
||||
self.contactAvatarModel = contactAvatarModel
|
||||
DispatchQueue.main.async {
|
||||
if contactAvatarModel.addresses.count == 1 && contactAvatarModel.phoneNumbersWithLabel.isEmpty {
|
||||
startConversationViewModel.createOneToOneChatRoomWith(remote: addr)
|
||||
} else if contactAvatarModel.addresses.isEmpty && contactAvatarModel.phoneNumbersWithLabel.count == 1 {
|
||||
if let firstPhoneNumbersWithLabel = contactAvatarModel.phoneNumbersWithLabel.first, let phoneAddr = core.interpretUrl(url: firstPhoneNumbersWithLabel.phoneNumber, applyInternationalPrefix: LinphoneUtils.applyInternationalPrefix(core: core)) {
|
||||
startConversationViewModel.createOneToOneChatRoomWith(remote: phoneAddr)
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
isShowSipAddressesPopup = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.padding(.horizontal, 16)
|
||||
|
||||
|
|
@ -213,6 +233,100 @@ struct StartConversationFragment: View {
|
|||
}
|
||||
.background(.white)
|
||||
|
||||
if isShowSipAddressesPopup && contactAvatarModel != nil {
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
Text("contact_dialog_pick_phone_number_or_sip_address_title")
|
||||
.default_text_style_800(styleSize: 16)
|
||||
.padding(.bottom, 2)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image("x")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
.frame(width: 25, height: 25)
|
||||
.padding(.all, 10)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
ForEach(0..<contactAvatarModel!.addresses.count, id: \.self) { index in
|
||||
HStack {
|
||||
HStack {
|
||||
VStack {
|
||||
Text(String(localized: "sip_address") + ":")
|
||||
.default_text_style_700(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
Text(contactAvatarModel!.addresses[index].dropFirst(4))
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(1)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.vertical, 15)
|
||||
.padding(.horizontal, 10)
|
||||
}
|
||||
.background(.white)
|
||||
.onTapGesture {
|
||||
do {
|
||||
let addr = try Factory.Instance.createAddress(addr: contactAvatarModel!.addresses[index])
|
||||
startConversationViewModel.createOneToOneChatRoomWith(remote: addr)
|
||||
} catch {
|
||||
Log.error("[StartConversationFragment] unable to create address for a new outgoing call : \(contactAvatarModel!.addresses[index]) \(error) ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ForEach(0..<contactAvatarModel!.phoneNumbersWithLabel.count, id: \.self) { index in
|
||||
HStack {
|
||||
HStack {
|
||||
VStack {
|
||||
Text(String(localized: "phone_number") + ":")
|
||||
.default_text_style_700(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
Text(contactAvatarModel!.phoneNumbersWithLabel[index].phoneNumber)
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(1)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.vertical, 15)
|
||||
.padding(.horizontal, 10)
|
||||
}
|
||||
.background(.white)
|
||||
.onTapGesture {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
if let phoneAddr = core.interpretUrl(url: contactAvatarModel!.phoneNumbersWithLabel[index].phoneNumber, applyInternationalPrefix: LinphoneUtils.applyInternationalPrefix(core: core)) {
|
||||
DispatchQueue.main.async {
|
||||
startConversationViewModel.createOneToOneChatRoomWith(remote: phoneAddr)
|
||||
}
|
||||
} else {
|
||||
Log.error("[StartConversationFragment] unable to create address (interpret Url for phone number) for a new outgoing call : \(contactAvatarModel!.addresses[index])")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.vertical, 20)
|
||||
.background(.white)
|
||||
.cornerRadius(20)
|
||||
.frame(maxHeight: .infinity)
|
||||
.shadow(color: Color.orangeMain500, radius: 0, x: 0, y: 2)
|
||||
.frame(maxWidth: SharedMainViewModel.shared.maxWidth)
|
||||
.padding(.horizontal, 20)
|
||||
.background(.black.opacity(0.65))
|
||||
.zIndex(3)
|
||||
.onTapGesture {
|
||||
isShowSipAddressesPopup.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
if startConversationViewModel.operationOneToOneInProgress {
|
||||
PopupLoadingView()
|
||||
.background(.black.opacity(0.65))
|
||||
|
|
|
|||
|
|
@ -232,6 +232,7 @@ struct HistoryContactFragment: View {
|
|||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, 10)
|
||||
.padding(.bottom, 2)
|
||||
.padding(.horizontal, 10)
|
||||
.background(Color.gray100)
|
||||
|
||||
HStack {
|
||||
|
|
|
|||
|
|
@ -29,14 +29,18 @@ struct StartCallFragment: View {
|
|||
@ObservedObject private var telecomManager = TelecomManager.shared
|
||||
|
||||
@EnvironmentObject var callViewModel: CallViewModel
|
||||
@EnvironmentObject var conversationsListViewModel: ConversationsListViewModel
|
||||
|
||||
@StateObject private var startCallViewModel = StartCallViewModel()
|
||||
|
||||
@State private var contactAvatarModel: ContactAvatarModel? = nil
|
||||
|
||||
@State private var transferAddress: Address? = nil
|
||||
@State private var isShowTransferPopup: Bool = false
|
||||
@State private var isShowSipAddressesPopup: Bool = false
|
||||
|
||||
@Binding var isShowStartCallFragment: Bool
|
||||
@Binding var showingDialer: Bool
|
||||
@Binding var isShowStartCallFragment: Bool
|
||||
|
||||
@FocusState var isSearchFieldFocused: Bool
|
||||
@State private var delayedColor = Color.white
|
||||
|
|
@ -290,28 +294,68 @@ struct StartCallFragment: View {
|
|||
|
||||
ContactsListFragment(showingSheet: .constant(false)
|
||||
, startCallFunc: { addr in
|
||||
if callViewModel.isTransferInsteadCall {
|
||||
self.transferAddress = addr
|
||||
self.isShowTransferPopup = true
|
||||
} else {
|
||||
showingDialer = false
|
||||
|
||||
startCallViewModel.searchField = ""
|
||||
magicSearch.currentFilter = ""
|
||||
|
||||
magicSearch.searchForContacts()
|
||||
|
||||
if callViewModel.isTransferInsteadCall == true {
|
||||
callViewModel.isTransferInsteadCall = false
|
||||
}
|
||||
|
||||
resetCallView()
|
||||
|
||||
delayColorDismiss()
|
||||
|
||||
withAnimation {
|
||||
isShowStartCallFragment.toggle()
|
||||
telecomManager.doCallOrJoinConf(address: addr)
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
ContactAvatarModel.getAvatarModelFromAddress(address: addr) { contactAvatarModel in
|
||||
self.contactAvatarModel = contactAvatarModel
|
||||
DispatchQueue.main.async {
|
||||
if contactAvatarModel.addresses.count == 1 && contactAvatarModel.phoneNumbersWithLabel.isEmpty {
|
||||
if callViewModel.isTransferInsteadCall {
|
||||
self.transferAddress = addr
|
||||
self.isShowTransferPopup = true
|
||||
} else {
|
||||
showingDialer = false
|
||||
|
||||
startCallViewModel.searchField = ""
|
||||
magicSearch.currentFilter = ""
|
||||
|
||||
magicSearch.searchForContacts()
|
||||
|
||||
if callViewModel.isTransferInsteadCall == true {
|
||||
callViewModel.isTransferInsteadCall = false
|
||||
}
|
||||
|
||||
resetCallView()
|
||||
|
||||
delayColorDismiss()
|
||||
|
||||
withAnimation {
|
||||
isShowStartCallFragment.toggle()
|
||||
telecomManager.doCallOrJoinConf(address: addr)
|
||||
}
|
||||
}
|
||||
} else if contactAvatarModel.addresses.isEmpty && contactAvatarModel.phoneNumbersWithLabel.count == 1 {
|
||||
if let firstPhoneNumbersWithLabel = contactAvatarModel.phoneNumbersWithLabel.first, let addr = core.interpretUrl(url: firstPhoneNumbersWithLabel.phoneNumber, applyInternationalPrefix: LinphoneUtils.applyInternationalPrefix(core: core)) {
|
||||
if callViewModel.isTransferInsteadCall {
|
||||
self.transferAddress = addr
|
||||
self.isShowTransferPopup = true
|
||||
} else {
|
||||
showingDialer = false
|
||||
|
||||
startCallViewModel.searchField = ""
|
||||
magicSearch.currentFilter = ""
|
||||
|
||||
magicSearch.searchForContacts()
|
||||
|
||||
if callViewModel.isTransferInsteadCall == true {
|
||||
callViewModel.isTransferInsteadCall = false
|
||||
}
|
||||
|
||||
resetCallView()
|
||||
|
||||
delayColorDismiss()
|
||||
|
||||
withAnimation {
|
||||
isShowStartCallFragment.toggle()
|
||||
telecomManager.doCallOrJoinConf(address: addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
isShowSipAddressesPopup = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -342,6 +386,151 @@ struct StartCallFragment: View {
|
|||
}
|
||||
.background(.white)
|
||||
|
||||
if isShowSipAddressesPopup && contactAvatarModel != nil {
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
Text("contact_dialog_pick_phone_number_or_sip_address_title")
|
||||
.default_text_style_800(styleSize: 16)
|
||||
.padding(.bottom, 2)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image("x")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
.frame(width: 25, height: 25)
|
||||
.padding(.all, 10)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
ForEach(0..<contactAvatarModel!.addresses.count, id: \.self) { index in
|
||||
HStack {
|
||||
HStack {
|
||||
VStack {
|
||||
Text(String(localized: "sip_address") + ":")
|
||||
.default_text_style_700(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
Text(contactAvatarModel!.addresses[index].dropFirst(4))
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(1)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.vertical, 15)
|
||||
.padding(.horizontal, 10)
|
||||
}
|
||||
.background(.white)
|
||||
.onTapGesture {
|
||||
do {
|
||||
let addr = try Factory.Instance.createAddress(addr: contactAvatarModel!.addresses[index])
|
||||
|
||||
if callViewModel.isTransferInsteadCall {
|
||||
self.isShowSipAddressesPopup = false
|
||||
self.transferAddress = addr
|
||||
self.isShowTransferPopup = true
|
||||
} else {
|
||||
showingDialer = false
|
||||
|
||||
startCallViewModel.searchField = ""
|
||||
magicSearch.currentFilter = ""
|
||||
|
||||
magicSearch.searchForContacts()
|
||||
|
||||
if callViewModel.isTransferInsteadCall == true {
|
||||
callViewModel.isTransferInsteadCall = false
|
||||
}
|
||||
|
||||
resetCallView()
|
||||
|
||||
delayColorDismiss()
|
||||
|
||||
withAnimation {
|
||||
isShowSipAddressesPopup = false
|
||||
isShowStartCallFragment.toggle()
|
||||
telecomManager.doCallOrJoinConf(address: addr)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Log.error("[StartCallFragment] unable to create address for a new outgoing call : \(contactAvatarModel!.addresses[index]) \(error) ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ForEach(0..<contactAvatarModel!.phoneNumbersWithLabel.count, id: \.self) { index in
|
||||
HStack {
|
||||
HStack {
|
||||
VStack {
|
||||
Text(String(localized: "phone_number") + ":")
|
||||
.default_text_style_700(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
Text(contactAvatarModel!.phoneNumbersWithLabel[index].phoneNumber)
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(1)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.vertical, 15)
|
||||
.padding(.horizontal, 10)
|
||||
}
|
||||
.background(.white)
|
||||
.onTapGesture {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
if let addr = core.interpretUrl(url: contactAvatarModel!.phoneNumbersWithLabel[index].phoneNumber, applyInternationalPrefix: LinphoneUtils.applyInternationalPrefix(core: core)) {
|
||||
DispatchQueue.main.async {
|
||||
if callViewModel.isTransferInsteadCall {
|
||||
self.isShowSipAddressesPopup = false
|
||||
self.transferAddress = addr
|
||||
self.isShowTransferPopup = true
|
||||
} else {
|
||||
showingDialer = false
|
||||
|
||||
startCallViewModel.searchField = ""
|
||||
magicSearch.currentFilter = ""
|
||||
|
||||
magicSearch.searchForContacts()
|
||||
|
||||
if callViewModel.isTransferInsteadCall == true {
|
||||
callViewModel.isTransferInsteadCall = false
|
||||
}
|
||||
|
||||
resetCallView()
|
||||
|
||||
delayColorDismiss()
|
||||
|
||||
withAnimation {
|
||||
isShowSipAddressesPopup = false
|
||||
isShowStartCallFragment.toggle()
|
||||
telecomManager.doCallOrJoinConf(address: addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.error("[StartCallFragment] unable to create address (interpret Url for phone number) for a new outgoing call : \(contactAvatarModel!.addresses[index])")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.vertical, 20)
|
||||
.background(.white)
|
||||
.cornerRadius(20)
|
||||
.frame(maxHeight: .infinity)
|
||||
.shadow(color: Color.orangeMain500, radius: 0, x: 0, y: 2)
|
||||
.frame(maxWidth: SharedMainViewModel.shared.maxWidth)
|
||||
.padding(.horizontal, 20)
|
||||
.background(.black.opacity(0.65))
|
||||
.zIndex(3)
|
||||
.onTapGesture {
|
||||
isShowSipAddressesPopup.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
if isShowTransferPopup {
|
||||
PopupView(
|
||||
isShowPopup: $isShowTransferPopup,
|
||||
|
|
@ -559,8 +748,8 @@ struct StartCallFragment: View {
|
|||
|
||||
#Preview {
|
||||
StartCallFragment(
|
||||
isShowStartCallFragment: .constant(true),
|
||||
showingDialer: .constant(false),
|
||||
isShowStartCallFragment: .constant(true),
|
||||
resetCallView: {}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ struct AddParticipantsFragment: View {
|
|||
|
||||
@FocusState var isSearchFieldFocused: Bool
|
||||
|
||||
@State private var isShowSipAddressesPopup: Bool = false
|
||||
@State private var contactAvatarModel: ContactAvatarModel? = nil
|
||||
|
||||
var dismissOnCheckClick: Bool
|
||||
|
||||
var body: some View {
|
||||
|
|
@ -208,6 +211,11 @@ struct AddParticipantsFragment: View {
|
|||
|
||||
if addParticipantsViewModel.participantsToAdd.contains(where: {
|
||||
$0.address.asStringUriOnly() == contactsManager.avatarListModel[index].address
|
||||
|| $0.avatarModel.address == contactsManager.avatarListModel[index].address
|
||||
|| phoneListsEqual(
|
||||
$0.avatarModel.phoneNumbersWithLabel,
|
||||
contactsManager.avatarListModel[index].phoneNumbersWithLabel
|
||||
)
|
||||
}) {
|
||||
Image("check")
|
||||
.renderingMode(.template)
|
||||
|
|
@ -221,13 +229,20 @@ struct AddParticipantsFragment: View {
|
|||
.background(.white)
|
||||
.onTapGesture {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
if !contactsManager.avatarListModel[index].address.isEmpty {
|
||||
if let addr = try? Factory.Instance.createAddress(addr: contactsManager.avatarListModel[index].address) {
|
||||
addParticipantsViewModel.selectParticipant(addr: addr)
|
||||
}
|
||||
} else if !contactsManager.avatarListModel[index].phoneNumbersWithLabel.isEmpty {
|
||||
if let address = core.interpretUrl(url: contactsManager.avatarListModel[index].phoneNumbersWithLabel.first?.phoneNumber ?? "", applyInternationalPrefix: LinphoneUtils.applyInternationalPrefix(core: core)) {
|
||||
addParticipantsViewModel.selectParticipant(addr: address)
|
||||
self.contactAvatarModel = contactsManager.avatarListModel[index]
|
||||
if let contactAvatarModelTmp = self.contactAvatarModel {
|
||||
if contactAvatarModelTmp.addresses.count == 1 && contactAvatarModelTmp.phoneNumbersWithLabel.isEmpty {
|
||||
if let firstAddress = contactAvatarModelTmp.addresses.first, let addr = try? Factory.Instance.createAddress(addr: firstAddress) {
|
||||
addParticipantsViewModel.selectParticipant(addr: addr)
|
||||
}
|
||||
} else if contactAvatarModelTmp.addresses.isEmpty && contactAvatarModelTmp.phoneNumbersWithLabel.count == 1 {
|
||||
if let address = core.interpretUrl(url: contactAvatarModelTmp.phoneNumbersWithLabel.first?.phoneNumber ?? "", applyInternationalPrefix: LinphoneUtils.applyInternationalPrefix(core: core)) {
|
||||
addParticipantsViewModel.selectParticipant(addr: address)
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
isShowSipAddressesPopup = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -255,6 +270,7 @@ struct AddParticipantsFragment: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
withAnimation {
|
||||
confirmAddParticipantsFunc(addParticipantsViewModel.participantsToAdd)
|
||||
|
|
@ -277,6 +293,100 @@ struct AddParticipantsFragment: View {
|
|||
|
||||
}
|
||||
.padding()
|
||||
|
||||
if isShowSipAddressesPopup && contactAvatarModel != nil {
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
Text("contact_dialog_pick_phone_number_or_sip_address_title")
|
||||
.default_text_style_800(styleSize: 16)
|
||||
.padding(.bottom, 2)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image("x")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
.frame(width: 25, height: 25)
|
||||
.padding(.all, 10)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
ForEach(0..<contactAvatarModel!.addresses.count, id: \.self) { index in
|
||||
HStack {
|
||||
HStack {
|
||||
VStack {
|
||||
Text(String(localized: "sip_address") + ":")
|
||||
.default_text_style_700(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
Text(contactAvatarModel!.addresses[index].dropFirst(4))
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(1)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.vertical, 15)
|
||||
.padding(.horizontal, 10)
|
||||
}
|
||||
.background(.white)
|
||||
.onTapGesture {
|
||||
do {
|
||||
let addr = try Factory.Instance.createAddress(addr: contactAvatarModel!.addresses[index])
|
||||
addParticipantsViewModel.selectParticipant(addr: addr)
|
||||
self.isShowSipAddressesPopup = false
|
||||
} catch {
|
||||
Log.error("[AddParticipantsFragment] unable to create address for a new outgoing call : \(contactAvatarModel!.addresses[index]) \(error) ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ForEach(0..<contactAvatarModel!.phoneNumbersWithLabel.count, id: \.self) { index in
|
||||
HStack {
|
||||
HStack {
|
||||
VStack {
|
||||
Text(String(localized: "phone_number") + ":")
|
||||
.default_text_style_700(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
Text(contactAvatarModel!.phoneNumbersWithLabel[index].phoneNumber)
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(1)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.vertical, 15)
|
||||
.padding(.horizontal, 10)
|
||||
}
|
||||
.background(.white)
|
||||
.onTapGesture {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
if let phoneAddr = core.interpretUrl(url: contactAvatarModel!.phoneNumbersWithLabel[index].phoneNumber, applyInternationalPrefix: LinphoneUtils.applyInternationalPrefix(core: core)) {
|
||||
addParticipantsViewModel.selectParticipant(addr: phoneAddr)
|
||||
self.isShowSipAddressesPopup = false
|
||||
} else {
|
||||
Log.error("[AddParticipantsFragment] unable to create address (interpret Url for phone number) for a new outgoing call : \(contactAvatarModel!.addresses[index])")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.vertical, 20)
|
||||
.background(.white)
|
||||
.cornerRadius(20)
|
||||
.frame(maxHeight: .infinity)
|
||||
.shadow(color: Color.orangeMain500, radius: 0, x: 0, y: 2)
|
||||
.frame(maxWidth: SharedMainViewModel.shared.maxWidth)
|
||||
.padding(.horizontal, 20)
|
||||
.background(.black.opacity(0.65))
|
||||
.zIndex(3)
|
||||
.onTapGesture {
|
||||
isShowSipAddressesPopup.toggle()
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("")
|
||||
.navigationBarHidden(true)
|
||||
|
|
@ -362,4 +472,14 @@ struct AddParticipantsFragment: View {
|
|||
.listRowSeparator(.hidden)
|
||||
}
|
||||
}
|
||||
|
||||
func phoneListsEqual(
|
||||
_ lhs: [(label: String, phoneNumber: String)],
|
||||
_ rhs: [(label: String, phoneNumber: String)]
|
||||
) -> Bool {
|
||||
lhs.count == rhs.count &&
|
||||
zip(lhs, rhs).allSatisfy { l, r in
|
||||
l.label == r.label && l.phoneNumber == r.phoneNumber
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue