mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
Add sip address selector for contact view
This commit is contained in:
parent
09ea819b55
commit
befad07719
6 changed files with 407 additions and 207 deletions
|
|
@ -159,6 +159,7 @@
|
|||
D7E6D0552AEBFCCE00A57AAF /* ContactsInnerFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E6D0542AEBFCCE00A57AAF /* ContactsInnerFragment.swift */; };
|
||||
D7EAACCF2AD6ED8000AA6A8A /* PermissionsFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7EAACCE2AD6ED8000AA6A8A /* PermissionsFragment.swift */; };
|
||||
D7F4D9CB2B5FD27200CDCD76 /* CallsListFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F4D9CA2B5FD27200CDCD76 /* CallsListFragment.swift */; };
|
||||
D7F5F6412C359F3B007FCF2F /* SipAddressesPopup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F5F6402C359F3B007FCF2F /* SipAddressesPopup.swift */; };
|
||||
D7FB55112AD447FD00A5AB15 /* RegisterFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7FB55102AD447FD00A5AB15 /* RegisterFragment.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
|
|
@ -337,6 +338,7 @@
|
|||
D7E6D0542AEBFCCE00A57AAF /* ContactsInnerFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsInnerFragment.swift; sourceTree = "<group>"; };
|
||||
D7EAACCE2AD6ED8000AA6A8A /* PermissionsFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermissionsFragment.swift; sourceTree = "<group>"; };
|
||||
D7F4D9CA2B5FD27200CDCD76 /* CallsListFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallsListFragment.swift; sourceTree = "<group>"; };
|
||||
D7F5F6402C359F3B007FCF2F /* SipAddressesPopup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SipAddressesPopup.swift; sourceTree = "<group>"; };
|
||||
D7FB55102AD447FD00A5AB15 /* RegisterFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterFragment.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
|
|
@ -711,6 +713,7 @@
|
|||
D7C365072AEFAB7F00FE6142 /* ContactListBottomSheet.swift */,
|
||||
D7C365092AF001C300FE6142 /* EditContactFragment.swift */,
|
||||
D7C48DF52AFCDF4700D938CB /* ContactInnerActionsFragment.swift */,
|
||||
D7F5F6402C359F3B007FCF2F /* SipAddressesPopup.swift */,
|
||||
);
|
||||
path = Fragments;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1125,6 +1128,7 @@
|
|||
662B69D92B25DE18007118BF /* TelecomManager.swift in Sources */,
|
||||
D72343342ACEFFC3009AA24E /* QRScanner.swift in Sources */,
|
||||
66C491FB2B24D32600CEA16D /* CoreExtension.swift in Sources */,
|
||||
D7F5F6412C359F3B007FCF2F /* SipAddressesPopup.swift in Sources */,
|
||||
D72A9A052B9750A1000DC093 /* UIList.swift in Sources */,
|
||||
D726E43D2B19E4FE0083C415 /* StartCallFragment.swift in Sources */,
|
||||
66E56BCC2BA9A1E0006CE56F /* MeetingsListItemModel.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -792,6 +792,23 @@
|
|||
},
|
||||
"Connexion à la réunion" : {
|
||||
|
||||
},
|
||||
"contact_dialog_pick_phone_number_or_sip_address_title" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Choose a number or a SIP address"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Choisissez un numéro ou adresse SIP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Contacts" : {
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ struct ContactFragment: View {
|
|||
|
||||
@Binding var isShowDeletePopup: Bool
|
||||
@Binding var isShowDismissPopup: Bool
|
||||
@Binding var isShowSipAddressesPopup: Bool
|
||||
|
||||
@State private var showingSheet = false
|
||||
@State private var showShareSheet = false
|
||||
|
|
@ -45,7 +46,8 @@ struct ContactFragment: View {
|
|||
isShowDeletePopup: $isShowDeletePopup,
|
||||
showingSheet: $showingSheet,
|
||||
showShareSheet: $showShareSheet,
|
||||
isShowDismissPopup: $isShowDismissPopup
|
||||
isShowDismissPopup: $isShowDismissPopup,
|
||||
isShowSipAddressesPopup: $isShowSipAddressesPopup
|
||||
)
|
||||
.sheet(isPresented: $showingSheet) {
|
||||
ContactListBottomSheet(contactViewModel: contactViewModel, showingSheet: $showingSheet)
|
||||
|
|
@ -65,7 +67,8 @@ struct ContactFragment: View {
|
|||
isShowDeletePopup: $isShowDeletePopup,
|
||||
showingSheet: $showingSheet,
|
||||
showShareSheet: $showShareSheet,
|
||||
isShowDismissPopup: $isShowDismissPopup
|
||||
isShowDismissPopup: $isShowDismissPopup,
|
||||
isShowSipAddressesPopup: $isShowSipAddressesPopup
|
||||
)
|
||||
.halfSheet(showSheet: $showingSheet) {
|
||||
ContactListBottomSheet(contactViewModel: contactViewModel, showingSheet: $showingSheet)
|
||||
|
|
@ -84,6 +87,7 @@ struct ContactFragment: View {
|
|||
contactViewModel: ContactViewModel(),
|
||||
editContactViewModel: EditContactViewModel(),
|
||||
isShowDeletePopup: .constant(false),
|
||||
isShowDismissPopup: .constant(false)
|
||||
isShowDismissPopup: .constant(false),
|
||||
isShowSipAddressesPopup: .constant(false)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,60 +34,48 @@ struct ContactInnerFragment: View {
|
|||
|
||||
@State private var orientation = UIDevice.current.orientation
|
||||
|
||||
@State private var presentingEditContact = false
|
||||
@State var cnContact: CNContact?
|
||||
@State private var presentingEditContact = false
|
||||
|
||||
@Binding var isShowDeletePopup: Bool
|
||||
@Binding var showingSheet: Bool
|
||||
@Binding var showShareSheet: Bool
|
||||
@Binding var isShowDismissPopup: Bool
|
||||
@Binding var isShowSipAddressesPopup: Bool
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
VStack(spacing: 1) {
|
||||
Rectangle()
|
||||
.foregroundColor(Color.orangeMain500)
|
||||
.edgesIgnoringSafeArea(.top)
|
||||
.frame(height: 0)
|
||||
|
||||
HStack {
|
||||
if !(orientation == .landscapeLeft || orientation == .landscapeRight
|
||||
|| UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) {
|
||||
Image("caret-left")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.orangeMain500)
|
||||
.frame(width: 25, height: 25, alignment: .leading)
|
||||
.padding(.all, 10)
|
||||
.padding(.top, 2)
|
||||
.padding(.leading, -10)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
contactViewModel.indexDisplayedFriend = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
ZStack {
|
||||
VStack(spacing: 1) {
|
||||
Rectangle()
|
||||
.foregroundColor(Color.orangeMain500)
|
||||
.edgesIgnoringSafeArea(.top)
|
||||
.frame(height: 0)
|
||||
|
||||
Spacer()
|
||||
if contactViewModel.indexDisplayedFriend != nil && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count
|
||||
&& !contactAvatarModel.nativeUri.isEmpty {
|
||||
Button(action: {
|
||||
editNativeContact()
|
||||
}, label: {
|
||||
Image("pencil-simple")
|
||||
HStack {
|
||||
if !(orientation == .landscapeLeft || orientation == .landscapeRight
|
||||
|| UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) {
|
||||
Image("caret-left")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.orangeMain500)
|
||||
.frame(width: 25, height: 25, alignment: .leading)
|
||||
.padding(.all, 10)
|
||||
.padding(.top, 2)
|
||||
})
|
||||
} else {
|
||||
NavigationLink(destination: EditContactFragment(
|
||||
editContactViewModel: editContactViewModel,
|
||||
contactViewModel: contactViewModel,
|
||||
isShowEditContactFragment: .constant(false),
|
||||
isShowDismissPopup: $isShowDismissPopup)) {
|
||||
.padding(.leading, -10)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
contactViewModel.indexDisplayedFriend = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
if contactViewModel.indexDisplayedFriend != nil && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count
|
||||
&& !contactAvatarModel.nativeUri.isEmpty {
|
||||
Button(action: {
|
||||
editNativeContact()
|
||||
}, label: {
|
||||
Image("pencil-simple")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
|
|
@ -95,175 +83,197 @@ struct ContactInnerFragment: View {
|
|||
.frame(width: 25, height: 25, alignment: .leading)
|
||||
.padding(.all, 10)
|
||||
.padding(.top, 2)
|
||||
}
|
||||
.simultaneousGesture(
|
||||
TapGesture().onEnded {
|
||||
editContactViewModel.selectedEditFriend = contactAvatarModel.friend
|
||||
editContactViewModel.resetValues()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: 50)
|
||||
.padding(.horizontal)
|
||||
.padding(.bottom, 4)
|
||||
.background(.white)
|
||||
|
||||
ScrollView {
|
||||
VStack(spacing: 0) {
|
||||
VStack(spacing: 0) {
|
||||
VStack(spacing: 0) {
|
||||
if contactViewModel.indexDisplayedFriend != nil && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count {
|
||||
Avatar(contactAvatarModel: contactAvatarModel, avatarSize: 100)
|
||||
} else if contactViewModel.indexDisplayedFriend != nil
|
||||
&& contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count
|
||||
&& contactAvatarModel != nil {
|
||||
Image("profil-picture-default")
|
||||
.resizable()
|
||||
.frame(width: 100, height: 100)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
if contactViewModel.indexDisplayedFriend != nil
|
||||
&& contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count {
|
||||
Text(contactAvatarModel.name)
|
||||
.foregroundStyle(Color.grayMain2c700)
|
||||
.multilineTextAlignment(.center)
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, 10)
|
||||
|
||||
Text(contactAvatarModel.lastPresenceInfo)
|
||||
.foregroundStyle(contactAvatarModel.lastPresenceInfo == "Online"
|
||||
? Color.greenSuccess500
|
||||
: Color.orangeWarning600)
|
||||
.multilineTextAlignment(.center)
|
||||
.default_text_style_300(styleSize: 12)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
|
||||
}
|
||||
.frame(minHeight: 150)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, 10)
|
||||
.background(Color.gray100)
|
||||
|
||||
HStack {
|
||||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
do {
|
||||
let address = try Factory.Instance.createAddress(addr: contactAvatarModel.address)
|
||||
telecomManager.doCallOrJoinConf(address: address)
|
||||
} catch {
|
||||
Log.error("[ContactInnerFragment] unable to create address for a new outgoing call : \(contactAvatarModel.address) \(error) ")
|
||||
}
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
Image("phone")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
.frame(width: 25, height: 25)
|
||||
}
|
||||
.padding(16)
|
||||
.background(Color.grayMain2c200)
|
||||
.cornerRadius(40)
|
||||
|
||||
Text("Appel")
|
||||
.default_text_style(styleSize: 14)
|
||||
}
|
||||
})
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
Image("chat-teardrop-text")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
//.foregroundStyle(Color.grayMain2c600)
|
||||
.foregroundStyle(Color.grayMain2c300)
|
||||
.frame(width: 25, height: 25)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(16)
|
||||
.background(Color.grayMain2c200)
|
||||
.cornerRadius(40)
|
||||
|
||||
Text("Message")
|
||||
.default_text_style(styleSize: 14)
|
||||
}
|
||||
})
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
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) ")
|
||||
}
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
Image("video-camera")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
.frame(width: 25, height: 25)
|
||||
}
|
||||
.padding(16)
|
||||
.background(Color.grayMain2c200)
|
||||
.cornerRadius(40)
|
||||
|
||||
Text("Video Call")
|
||||
.default_text_style(styleSize: 14)
|
||||
}
|
||||
})
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.top, 20)
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(Color.gray100)
|
||||
|
||||
ContactInnerActionsFragment(
|
||||
contactViewModel: contactViewModel,
|
||||
})
|
||||
} else {
|
||||
NavigationLink(destination: EditContactFragment(
|
||||
editContactViewModel: editContactViewModel,
|
||||
contactAvatarModel: contactAvatarModel, showingSheet: $showingSheet,
|
||||
showShareSheet: $showShareSheet,
|
||||
isShowDeletePopup: $isShowDeletePopup,
|
||||
isShowDismissPopup: $isShowDismissPopup,
|
||||
actionEditButton: editNativeContact
|
||||
)
|
||||
contactViewModel: contactViewModel,
|
||||
isShowEditContactFragment: .constant(false),
|
||||
isShowDismissPopup: $isShowDismissPopup)) {
|
||||
Image("pencil-simple")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.orangeMain500)
|
||||
.frame(width: 25, height: 25, alignment: .leading)
|
||||
.padding(.all, 10)
|
||||
.padding(.top, 2)
|
||||
}
|
||||
.simultaneousGesture(
|
||||
TapGesture().onEnded {
|
||||
editContactViewModel.selectedEditFriend = contactAvatarModel.friend
|
||||
editContactViewModel.resetValues()
|
||||
}
|
||||
)
|
||||
}
|
||||
.frame(maxWidth: sharedMainViewModel.maxWidth)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: 50)
|
||||
.padding(.horizontal)
|
||||
.padding(.bottom, 4)
|
||||
.background(.white)
|
||||
|
||||
ScrollView {
|
||||
VStack(spacing: 0) {
|
||||
VStack(spacing: 0) {
|
||||
VStack(spacing: 0) {
|
||||
if contactViewModel.indexDisplayedFriend != nil && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count {
|
||||
Avatar(contactAvatarModel: contactAvatarModel, avatarSize: 100)
|
||||
} else if contactViewModel.indexDisplayedFriend != nil
|
||||
&& contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count {
|
||||
Image("profil-picture-default")
|
||||
.resizable()
|
||||
.frame(width: 100, height: 100)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
if contactViewModel.indexDisplayedFriend != nil
|
||||
&& contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count {
|
||||
Text(contactAvatarModel.name)
|
||||
.foregroundStyle(Color.grayMain2c700)
|
||||
.multilineTextAlignment(.center)
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, 10)
|
||||
|
||||
Text(contactAvatarModel.lastPresenceInfo)
|
||||
.foregroundStyle(contactAvatarModel.lastPresenceInfo == "Online"
|
||||
? Color.greenSuccess500
|
||||
: Color.orangeWarning600)
|
||||
.multilineTextAlignment(.center)
|
||||
.default_text_style_300(styleSize: 12)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
|
||||
}
|
||||
.frame(minHeight: 150)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, 10)
|
||||
.background(Color.gray100)
|
||||
|
||||
HStack {
|
||||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
if contactAvatarModel.addresses.count <= 1 {
|
||||
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 {
|
||||
isShowSipAddressesPopup = true
|
||||
}
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
Image("phone")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
.frame(width: 25, height: 25)
|
||||
}
|
||||
.padding(16)
|
||||
.background(Color.grayMain2c200)
|
||||
.cornerRadius(40)
|
||||
|
||||
Text("Appel")
|
||||
.default_text_style(styleSize: 14)
|
||||
}
|
||||
})
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
Image("chat-teardrop-text")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
//.foregroundStyle(Color.grayMain2c600)
|
||||
.foregroundStyle(Color.grayMain2c300)
|
||||
.frame(width: 25, height: 25)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(16)
|
||||
.background(Color.grayMain2c200)
|
||||
.cornerRadius(40)
|
||||
|
||||
Text("Message")
|
||||
.default_text_style(styleSize: 14)
|
||||
}
|
||||
})
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
if contactAvatarModel.addresses.count <= 1 {
|
||||
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 {
|
||||
isShowSipAddressesPopup = true
|
||||
}
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
Image("video-camera")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
.frame(width: 25, height: 25)
|
||||
}
|
||||
.padding(16)
|
||||
.background(Color.grayMain2c200)
|
||||
.cornerRadius(40)
|
||||
|
||||
Text("Video Call")
|
||||
.default_text_style(styleSize: 14)
|
||||
}
|
||||
})
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.top, 20)
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(Color.gray100)
|
||||
|
||||
ContactInnerActionsFragment(
|
||||
contactViewModel: contactViewModel,
|
||||
editContactViewModel: editContactViewModel,
|
||||
contactAvatarModel: contactAvatarModel, showingSheet: $showingSheet,
|
||||
showShareSheet: $showShareSheet,
|
||||
isShowDeletePopup: $isShowDeletePopup,
|
||||
isShowDismissPopup: $isShowDismissPopup,
|
||||
actionEditButton: editNativeContact
|
||||
)
|
||||
}
|
||||
.frame(maxWidth: sharedMainViewModel.maxWidth)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
.background(Color.gray100)
|
||||
}
|
||||
.background(Color.gray100)
|
||||
}
|
||||
.background(.white)
|
||||
.navigationBarHidden(true)
|
||||
.onRotate { newOrientation in
|
||||
orientation = newOrientation
|
||||
}
|
||||
.fullScreenCover(isPresented: $presentingEditContact) {
|
||||
NavigationView {
|
||||
EditContactView(contact: $cnContact)
|
||||
.navigationBarTitle("Edit Contact")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.edgesIgnoringSafeArea(.vertical)
|
||||
.background(.white)
|
||||
.navigationBarHidden(true)
|
||||
.onRotate { newOrientation in
|
||||
orientation = newOrientation
|
||||
}
|
||||
.fullScreenCover(isPresented: $presentingEditContact) {
|
||||
NavigationView {
|
||||
EditContactView(contact: $cnContact)
|
||||
.navigationBarTitle("Edit Contact")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.edgesIgnoringSafeArea(.vertical)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -286,6 +296,69 @@ struct ContactInnerFragment: View {
|
|||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
var sipAddressesPopup: some View {
|
||||
GeometryReader { geometry in
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
Text("contact_dialog_pick_phone_number_or_sip_address_title")
|
||||
.default_text_style_800(styleSize: 16)
|
||||
.background(.red)
|
||||
.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("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 address = try Factory.Instance.createAddress(addr: contactAvatarModel.addresses[index])
|
||||
withAnimation {
|
||||
isShowSipAddressesPopup.toggle()
|
||||
telecomManager.doCallOrJoinConf(address: address)
|
||||
}
|
||||
} catch {
|
||||
Log.error("[ContactInnerActionsFragment] unable to create address for a new outgoing call : \(contactAvatarModel.addresses[index]) \(error) ")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.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.maxWidth)
|
||||
.position(x: geometry.size.width / 2, y: geometry.size.height / 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
|
|
@ -296,6 +369,7 @@ struct ContactInnerFragment: View {
|
|||
isShowDeletePopup: .constant(false),
|
||||
showingSheet: .constant(false),
|
||||
showShareSheet: .constant(false),
|
||||
isShowDismissPopup: .constant(false)
|
||||
isShowDismissPopup: .constant(false),
|
||||
isShowSipAddressesPopup: .constant(false)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
86
Linphone/UI/Main/Contacts/Fragments/SipAddressesPopup.swift
Normal file
86
Linphone/UI/Main/Contacts/Fragments/SipAddressesPopup.swift
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
//
|
||||
// SipAddressesPopup.swift
|
||||
// Linphone
|
||||
//
|
||||
// Created by Benoît Martins on 03/07/2024.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import linphonesw
|
||||
|
||||
struct SipAddressesPopup: View {
|
||||
|
||||
@ObservedObject private var telecomManager = TelecomManager.shared
|
||||
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
|
||||
|
||||
@ObservedObject var contactAvatarModel: ContactAvatarModel
|
||||
@ObservedObject var contactViewModel: ContactViewModel
|
||||
|
||||
@Binding var isShowSipAddressesPopup: Bool
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { geometry in
|
||||
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("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 address = try Factory.Instance.createAddress(addr: contactAvatarModel.addresses[index])
|
||||
withAnimation {
|
||||
isShowSipAddressesPopup.toggle()
|
||||
telecomManager.doCallOrJoinConf(address: address)
|
||||
}
|
||||
} catch {
|
||||
Log.error("[ContactInnerActionsFragment] unable to create address for a new outgoing call : \(contactAvatarModel.addresses[index]) \(error) ")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.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.maxWidth)
|
||||
.position(x: geometry.size.width / 2, y: geometry.size.height / 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
SipAddressesPopup(contactAvatarModel: ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false), contactViewModel: ContactViewModel(), isShowSipAddressesPopup: .constant(true))
|
||||
}
|
||||
|
|
@ -61,6 +61,7 @@ struct ContentView: View {
|
|||
@State var isShowStartCallFragment = false
|
||||
@State var isShowDismissPopup = false
|
||||
@State var isShowSendCancelMeetingNotificationPopup = false
|
||||
@State var isShowSipAddressesPopup = false
|
||||
|
||||
@State var fullscreenVideo = false
|
||||
|
||||
|
|
@ -741,7 +742,8 @@ struct ContentView: View {
|
|||
contactViewModel: contactViewModel,
|
||||
editContactViewModel: editContactViewModel,
|
||||
isShowDeletePopup: $isShowDeleteContactPopup,
|
||||
isShowDismissPopup: $isShowDismissPopup
|
||||
isShowDismissPopup: $isShowDismissPopup,
|
||||
isShowSipAddressesPopup: $isShowSipAddressesPopup
|
||||
)
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(Color.gray100)
|
||||
|
|
@ -979,6 +981,19 @@ struct ContentView: View {
|
|||
}
|
||||
}
|
||||
|
||||
if isShowSipAddressesPopup {
|
||||
SipAddressesPopup(
|
||||
contactAvatarModel: ContactsManager.shared.avatarListModel[contactViewModel.indexDisplayedFriend != nil ? contactViewModel.indexDisplayedFriend! : 0],
|
||||
contactViewModel: contactViewModel,
|
||||
isShowSipAddressesPopup: $isShowSipAddressesPopup
|
||||
)
|
||||
.background(.black.opacity(0.65))
|
||||
.zIndex(3)
|
||||
.onTapGesture {
|
||||
isShowSipAddressesPopup.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
if isShowScheduleMeetingFragment {
|
||||
ScheduleMeetingFragment(
|
||||
meetingViewModel: meetingViewModel,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue