forked from mirrors/linphone-iphone
Fixes
This commit is contained in:
parent
1ddf2602b9
commit
04dbce540c
24 changed files with 474 additions and 282 deletions
BIN
Linphone/Assets.xcassets/AppIcon.appiconset/1024.png
Normal file
BIN
Linphone/Assets.xcassets/AppIcon.appiconset/1024.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "1024.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
|
|||
|
|
@ -113,11 +113,14 @@ final class CoreContext: ObservableObject {
|
|||
NSLog("New configuration state is \(cbVal.status) = \(cbVal.message)\n")
|
||||
if cbVal.status == Config.ConfiguringState.Successful {
|
||||
ToastViewModel.shared.toastMessage = "Successful"
|
||||
ToastViewModel.shared.displayToast.toggle()
|
||||
} else {
|
||||
ToastViewModel.shared.toastMessage = "Failed"
|
||||
ToastViewModel.shared.displayToast.toggle()
|
||||
ToastViewModel.shared.displayToast = true
|
||||
}
|
||||
/*
|
||||
else {
|
||||
ToastViewModel.shared.toastMessage = "Failed"
|
||||
ToastViewModel.shared.displayToast = true
|
||||
}
|
||||
*/
|
||||
})
|
||||
|
||||
self.mCoreSuscriptions.insert(self.mCore.publisher?.onAccountRegistrationStateChanged?.postOnMainQueue { (cbVal: (core: Core, account: Account, state: RegistrationState, message: String)) in
|
||||
|
|
@ -135,7 +138,7 @@ final class CoreContext: ObservableObject {
|
|||
self.loggingInProgress = true
|
||||
} else {
|
||||
ToastViewModel.shared.toastMessage = "Registration failed"
|
||||
ToastViewModel.shared.displayToast.toggle()
|
||||
ToastViewModel.shared.displayToast = true
|
||||
self.loggingInProgress = false
|
||||
self.loggedIn = false
|
||||
}
|
||||
|
|
@ -168,7 +171,7 @@ final class CoreContext: ObservableObject {
|
|||
)
|
||||
|
||||
ToastViewModel.shared.toastMessage = "Success_copied_into_clipboard"
|
||||
ToastViewModel.shared.displayToast.toggle()
|
||||
ToastViewModel.shared.displayToast = true
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>UIUserInterfaceStyle</key>
|
||||
<string>Light</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Camera usage is required for video VOIP calls</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
|
|
|
|||
|
|
@ -38,8 +38,14 @@ struct LinphoneApp: App {
|
|||
if !sharedMainViewModel.welcomeViewDisplayed {
|
||||
WelcomeView()
|
||||
} else if coreContext.defaultAccount == nil || sharedMainViewModel.displayProfileMode {
|
||||
ZStack {
|
||||
AssistantView()
|
||||
|
||||
ToastView()
|
||||
.zIndex(3)
|
||||
}
|
||||
} else if coreContext.defaultAccount != nil
|
||||
&& coreContext.loggedIn
|
||||
&& contactViewModel != nil
|
||||
&& editContactViewModel != nil
|
||||
&& historyViewModel != nil
|
||||
|
|
|
|||
|
|
@ -120,10 +120,10 @@ class TelecomManager: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
func doCallWithCore(addr: Address) {
|
||||
func doCallWithCore(addr: Address, isVideo: Bool) {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
do {
|
||||
try self.startCallCallKit(core: core, addr: addr, isSas: false, isVideo: false, isConference: false)
|
||||
try self.startCallCallKit(core: core, addr: addr, isSas: false, isVideo: isVideo, isConference: false)
|
||||
} catch {
|
||||
Log.error("[TelecomManager] unable to create address for a new outgoing call : \(addr) \(error) ")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ struct LoginFragment: View {
|
|||
|
||||
TextField("username", text: $accountLoginViewModel.username)
|
||||
.default_text_style(styleSize: 15)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
.disabled(coreContext.loggedIn)
|
||||
.frame(height: 25)
|
||||
.padding(.horizontal, 20)
|
||||
|
|
@ -90,6 +92,8 @@ struct LoginFragment: View {
|
|||
} else {
|
||||
TextField("password", text: $accountLoginViewModel.passwd)
|
||||
.default_text_style(styleSize: 15)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
.frame(height: 25)
|
||||
.focused($isPasswordFocused)
|
||||
}
|
||||
|
|
@ -287,6 +291,8 @@ struct LoginFragment: View {
|
|||
.background(.black.opacity(0.65))
|
||||
}
|
||||
}
|
||||
.navigationTitle("")
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,8 +65,11 @@ struct RegisterFragment: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("")
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
.navigationTitle("")
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ struct ThirdPartySipAccountLoginFragment: View {
|
|||
|
||||
TextField("username", text: $accountLoginViewModel.username)
|
||||
.default_text_style(styleSize: 15)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
.disabled(coreContext.loggedIn)
|
||||
.frame(height: 25)
|
||||
.padding(.horizontal, 20)
|
||||
|
|
@ -108,6 +110,8 @@ struct ThirdPartySipAccountLoginFragment: View {
|
|||
} else {
|
||||
TextField("password", text: $accountLoginViewModel.passwd)
|
||||
.default_text_style(styleSize: 15)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
.frame(height: 25)
|
||||
.focused($isPasswordFocused)
|
||||
}
|
||||
|
|
@ -139,6 +143,8 @@ struct ThirdPartySipAccountLoginFragment: View {
|
|||
|
||||
TextField("sip.linphone.org", text: $accountLoginViewModel.domain)
|
||||
.default_text_style(styleSize: 15)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
.disabled(coreContext.loggedIn)
|
||||
.frame(height: 25)
|
||||
.padding(.horizontal, 20)
|
||||
|
|
@ -158,6 +164,8 @@ struct ThirdPartySipAccountLoginFragment: View {
|
|||
|
||||
TextField("Display Name", text: $accountLoginViewModel.displayName)
|
||||
.default_text_style(styleSize: 15)
|
||||
.disableAutocorrection(true)
|
||||
.autocapitalization(.none)
|
||||
.disabled(coreContext.loggedIn)
|
||||
.frame(height: 25)
|
||||
.padding(.horizontal, 20)
|
||||
|
|
@ -204,8 +212,6 @@ struct ThirdPartySipAccountLoginFragment: View {
|
|||
|
||||
Button(action: {
|
||||
self.accountLoginViewModel.login()
|
||||
accountLoginViewModel.domain = "sip.linphone.org"
|
||||
accountLoginViewModel.transportType = "TLS"
|
||||
}, label: {
|
||||
Text(coreContext.loggedIn ? "Log out" : "assistant_account_login")
|
||||
.default_text_style_white_600(styleSize: 20)
|
||||
|
|
|
|||
|
|
@ -171,8 +171,11 @@ struct ThirdPartySipAccountWarningFragment: View {
|
|||
.frame(minHeight: geometry.size.height)
|
||||
}
|
||||
}
|
||||
.navigationTitle("")
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
.navigationTitle("")
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,9 @@ class AccountLoginViewModel: ObservableObject {
|
|||
self.coreContext.defaultAccount = account
|
||||
}
|
||||
|
||||
self.domain = "sip.linphone.org"
|
||||
self.transportType = "TLS"
|
||||
|
||||
} catch { NSLog(error.localizedDescription) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -427,18 +427,29 @@ struct CallView: View {
|
|||
.presentationDetents([.fraction(0.3)])
|
||||
.frame(maxHeight: .infinity)
|
||||
}
|
||||
} else {
|
||||
innerView(geometry: geo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
// swiftlint:disable:next cyclomatic_complexity
|
||||
func innerView(geometry: GeometryProxy) -> some View {
|
||||
VStack {
|
||||
if !fullscreenVideo {
|
||||
if #available(iOS 16.0, *) {
|
||||
Rectangle()
|
||||
.foregroundColor(Color.orangeMain500)
|
||||
.edgesIgnoringSafeArea(.top)
|
||||
.frame(height: 0)
|
||||
} else if idiom != .pad && !(orientation == .landscapeLeft || orientation == .landscapeRight
|
||||
|| UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) {
|
||||
Rectangle()
|
||||
.foregroundColor(Color.orangeMain500)
|
||||
.edgesIgnoringSafeArea(.top)
|
||||
.frame(height: 1)
|
||||
}
|
||||
|
||||
HStack {
|
||||
if callViewModel.direction == .Outgoing {
|
||||
|
|
@ -465,13 +476,8 @@ struct CallView: View {
|
|||
|
||||
ZStack {
|
||||
Text(callViewModel.timeElapsed.convertDurationToString())
|
||||
.onAppear {
|
||||
callViewModel.timeElapsed = 0
|
||||
startDate = Date.now
|
||||
}
|
||||
.onReceive(callViewModel.timer) { firedDate in
|
||||
callViewModel.timeElapsed = Int(firedDate.timeIntervalSince(startDate))
|
||||
|
||||
}
|
||||
.foregroundStyle(.white)
|
||||
.if(callViewModel.isPaused || telecomManager.isPausedByRemote) { view in
|
||||
|
|
@ -646,6 +652,10 @@ struct CallView: View {
|
|||
callViewModel.timeElapsed = Int(firedDate.timeIntervalSince(startDate))
|
||||
|
||||
}
|
||||
.onDisappear {
|
||||
callViewModel.timeElapsed = 0
|
||||
startDate = Date.now
|
||||
}
|
||||
.padding(.top)
|
||||
.foregroundStyle(.white)
|
||||
|
||||
|
|
@ -695,6 +705,7 @@ struct CallView: View {
|
|||
|
||||
if !fullscreenVideo {
|
||||
if telecomManager.callStarted {
|
||||
if #available(iOS 16.0, *) {
|
||||
if telecomManager.callStarted && idiom != .pad && !(orientation == .landscapeLeft || orientation == .landscapeRight
|
||||
|| UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) {
|
||||
HStack(spacing: 12) {
|
||||
|
|
@ -726,7 +737,7 @@ struct CallView: View {
|
|||
Button {
|
||||
callViewModel.toggleVideo()
|
||||
} label: {
|
||||
Image("video-camera")
|
||||
Image(callViewModel.cameraDisplayed ? "video-camera" : "video-camera-slash")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white)
|
||||
|
|
@ -753,12 +764,116 @@ struct CallView: View {
|
|||
.cornerRadius(40)
|
||||
|
||||
Button {
|
||||
if AVAudioSession.sharedInstance().availableInputs != nil
|
||||
&& !AVAudioSession.sharedInstance().availableInputs!.filter({ $0.portType.rawValue.contains("Bluetooth") }).isEmpty {
|
||||
|
||||
hideButtonsSheet = true
|
||||
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) {
|
||||
audioRouteSheet = true
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().overrideOutputAudioPort(AVAudioSession.sharedInstance().currentRoute.outputs.filter({ $0.portType.rawValue == "Speaker" }).isEmpty ? .speaker : .none)
|
||||
} catch _ {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} label: {
|
||||
Image("speaker-high")
|
||||
Image(imageAudioRoute)
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(.white)
|
||||
.frame(width: 32, height: 32)
|
||||
.onAppear(perform: getAudioRouteImage)
|
||||
.onReceive(pub) { _ in
|
||||
self.getAudioRouteImage()
|
||||
}
|
||||
|
||||
}
|
||||
.frame(width: 60, height: 60)
|
||||
.background(Color.gray500)
|
||||
.cornerRadius(40)
|
||||
}
|
||||
.frame(height: geometry.size.height * 0.15)
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.top, -6)
|
||||
}
|
||||
} else {
|
||||
HStack(spacing: 12) {
|
||||
Button {
|
||||
callViewModel.terminateCall()
|
||||
} label: {
|
||||
Image("phone-disconnect")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(.white)
|
||||
.frame(width: 32, height: 32)
|
||||
|
||||
}
|
||||
.frame(width: 90, height: 60)
|
||||
.background(Color.redDanger500)
|
||||
.cornerRadius(40)
|
||||
|
||||
Spacer()
|
||||
|
||||
Button {
|
||||
callViewModel.toggleVideo()
|
||||
} label: {
|
||||
Image(callViewModel.cameraDisplayed ? "video-camera" : "video-camera-slash")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white)
|
||||
.frame(width: 32, height: 32)
|
||||
|
||||
}
|
||||
.frame(width: 60, height: 60)
|
||||
.background((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray600 : Color.gray500)
|
||||
.cornerRadius(40)
|
||||
.disabled(callViewModel.isPaused || telecomManager.isPausedByRemote)
|
||||
|
||||
Button {
|
||||
callViewModel.toggleMuteMicrophone()
|
||||
} label: {
|
||||
Image(callViewModel.micMutted ? "microphone-slash" : "microphone")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(callViewModel.micMutted ? .black : .white)
|
||||
.frame(width: 32, height: 32)
|
||||
|
||||
}
|
||||
.frame(width: 60, height: 60)
|
||||
.background(callViewModel.micMutted ? .white : Color.gray500)
|
||||
.cornerRadius(40)
|
||||
|
||||
Button {
|
||||
if AVAudioSession.sharedInstance().availableInputs != nil
|
||||
&& !AVAudioSession.sharedInstance().availableInputs!.filter({ $0.portType.rawValue.contains("Bluetooth") }).isEmpty {
|
||||
|
||||
hideButtonsSheet = true
|
||||
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) {
|
||||
audioRouteSheet = true
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().overrideOutputAudioPort(AVAudioSession.sharedInstance().currentRoute.outputs.filter({ $0.portType.rawValue == "Speaker" }).isEmpty ? .speaker : .none)
|
||||
} catch _ {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} label: {
|
||||
Image(imageAudioRoute)
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(.white)
|
||||
.frame(width: 32, height: 32)
|
||||
.onAppear(perform: getAudioRouteImage)
|
||||
.onReceive(pub) { _ in
|
||||
self.getAudioRouteImage()
|
||||
}
|
||||
|
||||
}
|
||||
.frame(width: 60, height: 60)
|
||||
|
|
|
|||
|
|
@ -41,8 +41,10 @@ struct ContactsView: View {
|
|||
}
|
||||
} label: {
|
||||
Image("user-plus")
|
||||
.renderingMode(.template)
|
||||
.foregroundStyle(.white)
|
||||
.padding()
|
||||
.background(.white)
|
||||
.background(Color.orangeMain500)
|
||||
.clipShape(Circle())
|
||||
.shadow(color: .black.opacity(0.2), radius: 4)
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ struct ContactInnerActionsFragment: View {
|
|||
.onTapGesture {
|
||||
withAnimation {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.addresses[index]
|
||||
addr: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.addresses[index], isVideo: false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -272,7 +272,9 @@ struct ContactInnerActionsFragment: View {
|
|||
Button {
|
||||
if contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil {
|
||||
contactViewModel.objectWillChange.send()
|
||||
contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.edit()
|
||||
contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.starred.toggle()
|
||||
contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.done()
|
||||
}
|
||||
} label: {
|
||||
HStack {
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ struct ContactInnerFragment: View {
|
|||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
telecomManager.doCallWithCore(addr: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.address!)
|
||||
telecomManager.doCallWithCore(addr: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.address!, isVideo: false)
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
|
|
@ -180,7 +180,8 @@ struct ContactInnerFragment: View {
|
|||
Image("chat-teardrop-text")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
//.foregroundStyle(Color.grayMain2c600)
|
||||
.foregroundStyle(Color.grayMain2c300)
|
||||
.frame(width: 25, height: 25)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
|
|
@ -200,7 +201,7 @@ struct ContactInnerFragment: View {
|
|||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
|
||||
telecomManager.doCallWithCore(addr: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.address!, isVideo: true)
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
|
|
@ -209,11 +210,6 @@ struct ContactInnerFragment: View {
|
|||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
.frame(width: 25, height: 25)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(16)
|
||||
.background(Color.grayMain2c200)
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@ struct ContactsListBottomSheet: View {
|
|||
Spacer()
|
||||
Button {
|
||||
if contactViewModel.selectedFriend != nil {
|
||||
contactViewModel.selectedFriend!.edit()
|
||||
contactViewModel.selectedFriend!.starred.toggle()
|
||||
contactViewModel.selectedFriend!.done()
|
||||
}
|
||||
|
||||
MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ struct ContentView: View {
|
|||
Menu {
|
||||
if index == 0 {
|
||||
Button {
|
||||
contactViewModel.indexDisplayedFriend = nil
|
||||
isMenuOpen = false
|
||||
magicSearch.allContact = true
|
||||
MagicSearchSingleton.shared.searchForContacts(
|
||||
|
|
@ -168,6 +169,7 @@ struct ContentView: View {
|
|||
}
|
||||
|
||||
Button {
|
||||
contactViewModel.indexDisplayedFriend = nil
|
||||
isMenuOpen = false
|
||||
magicSearch.allContact = false
|
||||
MagicSearchSingleton.shared.searchForContacts(
|
||||
|
|
@ -282,9 +284,8 @@ struct ContentView: View {
|
|||
text = newValue
|
||||
}
|
||||
))
|
||||
.default_text_style_white_700(styleSize: 15)
|
||||
.default_text_style_700(styleSize: 15)
|
||||
.padding(.all, 6)
|
||||
.accentColor(.white)
|
||||
.focused($focusedField)
|
||||
.onAppear {
|
||||
self.focusedField = true
|
||||
|
|
@ -671,10 +672,8 @@ struct ContentView: View {
|
|||
}
|
||||
}
|
||||
|
||||
// if sharedMainViewModel.displayToast {
|
||||
ToastView()
|
||||
.zIndex(3)
|
||||
// }
|
||||
}
|
||||
}
|
||||
.overlay {
|
||||
|
|
@ -698,12 +697,14 @@ struct ContentView: View {
|
|||
.onChange(of: scenePhase) { newPhase in
|
||||
if newPhase == .active {
|
||||
coreContext.onForeground()
|
||||
/*
|
||||
if !isShowStartCallFragment {
|
||||
contactsManager.fetchContacts()
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) {
|
||||
historyListViewModel.computeCallLogsList()
|
||||
}
|
||||
}
|
||||
*/
|
||||
print("Active")
|
||||
} else if newPhase == .inactive {
|
||||
print("Inactive")
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ struct DialerBottomSheet: View {
|
|||
if !startCallViewModel.searchField.isEmpty {
|
||||
do {
|
||||
let address = try Factory.Instance.createAddress(addr: String("sip:" + startCallViewModel.searchField + "@" + startCallViewModel.domain))
|
||||
telecomManager.doCallWithCore(addr: address)
|
||||
telecomManager.doCallWithCore(addr: address, isVideo: false)
|
||||
} catch {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,8 +194,12 @@ struct HistoryContactFragment: View {
|
|||
ScrollView {
|
||||
VStack(spacing: 0) {
|
||||
VStack(spacing: 0) {
|
||||
if #unavailable(iOS 16.0) {
|
||||
Rectangle()
|
||||
.foregroundColor(Color.gray100)
|
||||
.frame(height: 7)
|
||||
}
|
||||
VStack(spacing: 0) {
|
||||
|
||||
let fromAddressFriend = historyViewModel.displayedCall != nil ? contactsManager.getFriendWithAddress(address: historyViewModel.displayedCall!.fromAddress!) : nil
|
||||
let toAddressFriend = historyViewModel.displayedCall != nil ? contactsManager.getFriendWithAddress(address: historyViewModel.displayedCall!.toAddress!) : nil
|
||||
let addressFriend = historyViewModel.displayedCall != nil ? (historyViewModel.displayedCall!.dir == .Incoming ? fromAddressFriend : toAddressFriend) : nil
|
||||
|
|
@ -369,6 +373,7 @@ struct HistoryContactFragment: View {
|
|||
.frame(minHeight: 150)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, 10)
|
||||
.padding(.bottom, 2)
|
||||
.background(Color.gray100)
|
||||
|
||||
HStack {
|
||||
|
|
@ -377,11 +382,11 @@ struct HistoryContactFragment: View {
|
|||
Button(action: {
|
||||
if historyViewModel.displayedCall!.dir == .Outgoing && historyViewModel.displayedCall!.toAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyViewModel.displayedCall!.toAddress!
|
||||
addr: historyViewModel.displayedCall!.toAddress!, isVideo: false
|
||||
)
|
||||
} else if historyViewModel.displayedCall!.dir == .Incoming && historyViewModel.displayedCall!.fromAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyViewModel.displayedCall!.fromAddress!
|
||||
addr: historyViewModel.displayedCall!.fromAddress!, isVideo: false
|
||||
)
|
||||
}
|
||||
}, label: {
|
||||
|
|
@ -399,6 +404,7 @@ struct HistoryContactFragment: View {
|
|||
|
||||
Text("Appel")
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(minWidth: 80)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -412,7 +418,8 @@ struct HistoryContactFragment: View {
|
|||
Image("chat-teardrop-text")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
//.foregroundStyle(Color.grayMain2c600)
|
||||
.foregroundStyle(Color.grayMain2c300)
|
||||
.frame(width: 25, height: 25)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
|
|
@ -426,13 +433,22 @@ struct HistoryContactFragment: View {
|
|||
|
||||
Text("Message")
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(minWidth: 80)
|
||||
}
|
||||
})
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
|
||||
if historyViewModel.displayedCall!.dir == .Outgoing && historyViewModel.displayedCall!.toAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyViewModel.displayedCall!.toAddress!, isVideo: true
|
||||
)
|
||||
} else if historyViewModel.displayedCall!.dir == .Incoming && historyViewModel.displayedCall!.fromAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyViewModel.displayedCall!.fromAddress!, isVideo: true
|
||||
)
|
||||
}
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
|
|
@ -441,11 +457,6 @@ struct HistoryContactFragment: View {
|
|||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
.frame(width: 25, height: 25)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(16)
|
||||
.background(Color.grayMain2c200)
|
||||
|
|
@ -453,12 +464,14 @@ struct HistoryContactFragment: View {
|
|||
|
||||
Text("Video Call")
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(minWidth: 80)
|
||||
}
|
||||
})
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.top, 20)
|
||||
.padding(.bottom, 10)
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(Color.gray100)
|
||||
|
||||
|
|
@ -486,7 +499,8 @@ struct HistoryContactFragment: View {
|
|||
callStatus: callLogsFilter[index].status,
|
||||
callDir: callLogsFilter[index].dir
|
||||
).contains("rejected") ? 6 : 8)
|
||||
.padding(.top, 5)
|
||||
.padding(.top, 6)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
|
|
@ -517,6 +531,7 @@ struct HistoryContactFragment: View {
|
|||
}
|
||||
.padding(.vertical, 15)
|
||||
.padding(.horizontal, 20)
|
||||
.frame(maxHeight: 65)
|
||||
}
|
||||
}
|
||||
.background(.white)
|
||||
|
|
@ -526,6 +541,7 @@ struct HistoryContactFragment: View {
|
|||
.frame(maxWidth: sharedMainViewModel.maxWidth)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, 2)
|
||||
}
|
||||
.background(Color.gray100)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,11 +166,11 @@ struct HistoryListFragment: View {
|
|||
withAnimation {
|
||||
if historyListViewModel.callLogs[index].dir == .Outgoing && historyListViewModel.callLogs[index].toAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyListViewModel.callLogs[index].toAddress!
|
||||
addr: historyListViewModel.callLogs[index].toAddress!, isVideo: false
|
||||
)
|
||||
} else if historyListViewModel.callLogs[index].fromAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyListViewModel.callLogs[index].fromAddress!
|
||||
addr: historyListViewModel.callLogs[index].fromAddress!, isVideo: false
|
||||
)
|
||||
}
|
||||
historyViewModel.displayedCall = nil
|
||||
|
|
@ -213,6 +213,8 @@ struct HistoryListFragment: View {
|
|||
.padding(.all)
|
||||
)
|
||||
}
|
||||
.navigationTitle("")
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,9 @@ struct StartCallFragment: View {
|
|||
magicSearch.currentFilterSuggestions = newValue
|
||||
magicSearch.searchForSuggestions()
|
||||
}
|
||||
.simultaneousGesture(TapGesture().onEnded {
|
||||
showingDialer = false
|
||||
})
|
||||
|
||||
HStack {
|
||||
Button(action: {
|
||||
|
|
@ -105,10 +108,18 @@ struct StartCallFragment: View {
|
|||
|
||||
if startCallViewModel.searchField.isEmpty {
|
||||
Button(action: {
|
||||
if !showingDialer {
|
||||
isSearchFieldFocused = false
|
||||
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 0.2) {
|
||||
showingDialer.toggle()
|
||||
showingDialer = true
|
||||
}
|
||||
} else {
|
||||
showingDialer = false
|
||||
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 0.2) {
|
||||
isSearchFieldFocused = true
|
||||
}
|
||||
}
|
||||
}, label: {
|
||||
Image(!showingDialer ? "dialer" : "keyboard")
|
||||
|
|
@ -169,7 +180,7 @@ struct StartCallFragment: View {
|
|||
|
||||
withAnimation {
|
||||
isShowStartCallFragment.toggle()
|
||||
telecomManager.doCallWithCore(addr: addr)
|
||||
telecomManager.doCallWithCore(addr: addr, isVideo: false)
|
||||
}
|
||||
})
|
||||
.padding(.horizontal, 16)
|
||||
|
|
@ -208,6 +219,25 @@ struct StartCallFragment: View {
|
|||
var suggestionsList: some View {
|
||||
ForEach(0..<contactsManager.lastSearchSuggestions.count, id: \.self) { index in
|
||||
Button {
|
||||
showingDialer = false
|
||||
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 0.2) {
|
||||
magicSearch.searchForContacts(
|
||||
sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
}
|
||||
|
||||
startCallViewModel.searchField = ""
|
||||
magicSearch.currentFilterSuggestions = ""
|
||||
delayColorDismiss()
|
||||
|
||||
withAnimation {
|
||||
isShowStartCallFragment.toggle()
|
||||
if contactsManager.lastSearchSuggestions[index].address != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: contactsManager.lastSearchSuggestions[index].address!, isVideo: false
|
||||
)
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
HStack {
|
||||
if index < contactsManager.lastSearchSuggestions.count
|
||||
|
|
@ -237,27 +267,6 @@ struct StartCallFragment: View {
|
|||
.foregroundStyle(Color.orangeMain500)
|
||||
}
|
||||
}
|
||||
.onTapGesture {
|
||||
showingDialer = false
|
||||
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 0.2) {
|
||||
magicSearch.searchForContacts(
|
||||
sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
}
|
||||
|
||||
startCallViewModel.searchField = ""
|
||||
magicSearch.currentFilterSuggestions = ""
|
||||
delayColorDismiss()
|
||||
|
||||
withAnimation {
|
||||
isShowStartCallFragment.toggle()
|
||||
if contactsManager.lastSearchSuggestions[index].address != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: contactsManager.lastSearchSuggestions[index].address!
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
}
|
||||
.buttonStyle(.borderless)
|
||||
|
|
|
|||
|
|
@ -50,8 +50,10 @@ struct HistoryView: View {
|
|||
}
|
||||
} label: {
|
||||
Image("phone-plus")
|
||||
.renderingMode(.template)
|
||||
.foregroundStyle(.white)
|
||||
.padding()
|
||||
.background(.white)
|
||||
.background(Color.orangeMain500)
|
||||
.clipShape(Circle())
|
||||
.shadow(color: .black.opacity(0.2), radius: 4)
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@ struct WelcomeView: View {
|
|||
.frame(minHeight: geometry.size.height)
|
||||
}
|
||||
}
|
||||
.navigationTitle("")
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,15 +28,25 @@ class PermissionManager: ObservableObject {
|
|||
@Published var photoLibraryPermissionGranted = false
|
||||
@Published var cameraPermissionGranted = false
|
||||
@Published var contactsPermissionGranted = false
|
||||
@Published var microphonePermissionGranted = false
|
||||
|
||||
private init() {}
|
||||
|
||||
func getPermissions() {
|
||||
microphoneRequestPermission()
|
||||
photoLibraryRequestPermission()
|
||||
cameraRequestPermission()
|
||||
contactsRequestPermission()
|
||||
}
|
||||
|
||||
func microphoneRequestPermission() {
|
||||
AVAudioSession.sharedInstance().requestRecordPermission({ granted in
|
||||
DispatchQueue.main.async {
|
||||
self.microphonePermissionGranted = granted
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func photoLibraryRequestPermission() {
|
||||
PHPhotoLibrary.requestAuthorization(for: .readWrite, handler: {status in
|
||||
DispatchQueue.main.async {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue