alqindiirsyam 2 年 前
コミット
c122f18583

+ 3 - 0
appbuilder-ios/NexilisLite/NexilisLite/Resource/id.lproj/Localizable.strings

@@ -309,3 +309,6 @@
 "WhiteBoard session is over" = "Sesi whiteBoard telah berakhir";
 "Screen Sharing session is over" = "Sesi screen sharing telah berakhir";
 "You are now sharing your screen" = "Anda sekarang sedang membagikan layar anda";
+"Start Whiteboard/Screen Sharing" = "Mulai Whiteboard/Screen Sharing";
+"92:Username is empty" = "92:Nama pengguna kosong";
+"91:Invalid name or you must add Username to your contact first" = "91:Nama tidak valid atau Anda harus menambahkan Nama Pengguna ke kontak Anda terlebih dahulu";

+ 172 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/APIS.swift

@@ -9,6 +9,7 @@ import Foundation
 import UIKit
 import FMDB
 import NotificationBannerSwift
+import Toast_Swift
 
 public class APIS: NSObject {
     public static func connect(apiKey: String, delegate: ConnectDelegate, showButton: Bool = true) {
@@ -119,6 +120,39 @@ public class APIS: NSObject {
         }
     }
     
+    public static func startChat(name: String) {
+        if name.isEmpty {
+            UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 2)
+            return
+        }
+        let user = User.getDataFromNameCanNil(name: name)
+        if user == nil {
+            UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 2)
+            return
+        }
+        let editorPersonalVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
+        editorPersonalVC.hidesBottomBarWhenPushed = true
+        editorPersonalVC.unique_l_pin = user!.pin
+        editorPersonalVC.fromNotification = true
+        let navigationController = UINavigationController(rootViewController: editorPersonalVC)
+        navigationController.modalPresentationStyle = .fullScreen
+        navigationController.navigationBar.tintColor = .white
+        navigationController.navigationBar.barTintColor = .mainColor
+        navigationController.navigationBar.isTranslucent = false
+        navigationController.navigationBar.overrideUserInterfaceStyle = .dark
+        navigationController.navigationBar.barStyle = .black
+        let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white]
+        UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
+        let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
+        navigationController.navigationBar.titleTextAttributes = textAttributes
+        navigationController.view.backgroundColor = .mainColor
+        if UIApplication.shared.visibleViewController?.navigationController != nil {
+            UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
+        } else {
+            UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
+        }
+    }
+    
     public static func openCall() {
         let isChangeProfile = Utils.getSetProfile()
         if !isChangeProfile {
@@ -182,6 +216,34 @@ public class APIS: NSObject {
         }
     }
     
+    public static func startAudioCall(name: String) {
+        if name.isEmpty {
+            UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 2)
+            return
+        }
+        let user = User.getDataFromNameCanNil(name: name)
+        if user == nil {
+            UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 2)
+            return
+        }
+        if !CheckConnection.isConnectedToNetwork() {
+            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+            imageView.tintColor = .white
+            let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+            banner.show()
+            return
+        }
+        let controller = QmeraAudioViewController()
+        controller.user = user
+        controller.isOutgoing = true
+        controller.modalPresentationStyle = .overFullScreen
+        if UIApplication.shared.visibleViewController?.navigationController != nil {
+            UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
+        } else {
+            UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
+        }
+    }
+    
     public static func openVideoCall() {
         let isChangeProfile = Utils.getSetProfile()
         if !isChangeProfile {
@@ -199,6 +261,42 @@ public class APIS: NSObject {
         }
     }
     
+    public static func startVideoCall(name: String) {
+        if name.isEmpty {
+            UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 2)
+            return
+        }
+        let user = User.getDataFromNameCanNil(name: name)
+        if user == nil {
+            UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 2)
+            return
+        }
+        if !CheckConnection.isConnectedToNetwork() {
+            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+            imageView.tintColor = .white
+            let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+            banner.show()
+            return
+        }
+        let videoVC = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "videoVCQmera") as! QmeraVideoViewController
+        var data: [String: String?] = [:]
+        data["f_pin"] = user!.pin
+        data["name"] = user!.fullName
+        data["picture"] = user!.thumb
+        data["isOfficial"] = user!.official
+        data["deviceId"] = user!.device_id
+        data["isOffline"] = user!.offline_mode
+        data["user_type"] = user!.userType
+        videoVC.dataPerson.append(data)
+        videoVC.isPresent = true
+        videoVC.modalPresentationStyle = .overFullScreen
+        if UIApplication.shared.visibleViewController?.navigationController != nil {
+            UIApplication.shared.visibleViewController?.navigationController?.present(videoVC, animated: true, completion: nil)
+        } else {
+            UIApplication.shared.visibleViewController?.present(videoVC, animated: true, completion: nil)
+        }
+    }
+    
     public static func openBroadcastForm() {
         let isChangeProfile = Utils.getSetProfile()
         if !isChangeProfile {
@@ -357,6 +455,34 @@ public class APIS: NSObject {
         }
     }
     
+    public static func startWhiteboard(name: String) {
+        if name.isEmpty {
+            UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 2)
+            return
+        }
+        let user = User.getDataFromNameCanNil(name: name)
+        if user == nil {
+            UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 2)
+            return
+        }
+        if !CheckConnection.isConnectedToNetwork() {
+            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+            imageView.tintColor = .white
+            let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+            banner.show()
+            return
+        }
+        let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "wbVC") as! WhiteboardViewController
+        controller.modalPresentationStyle = .overFullScreen
+        controller.fromContact = 0
+        controller.user = user
+        if UIApplication.shared.visibleViewController?.navigationController != nil {
+            UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
+        } else {
+            UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
+        }
+    }
+    
     public static func openScreenSharing() {
         let isChangeProfile = Utils.getSetProfile()
         if !isChangeProfile {
@@ -373,6 +499,52 @@ public class APIS: NSObject {
             UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
         }
     }
+    
+    public static func startScreenSharing(name: String) {
+        if name.isEmpty {
+            UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 2)
+            return
+        }
+        let user = User.getDataFromNameCanNil(name: name)
+        if user == nil {
+            UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 2)
+            return
+        }
+        if !CheckConnection.isConnectedToNetwork() {
+            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+            imageView.tintColor = .white
+            let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+            banner.show()
+            return
+        }
+        let controller = ScreenSharingViewController()
+        controller.modalPresentationStyle = .overFullScreen
+        controller.fromContact = 0
+        controller.user = user
+        if UIApplication.shared.visibleViewController?.navigationController != nil {
+            UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
+        } else {
+            UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
+        }
+    }
+    
+    public static func openWhiteboardAndScreenSharing() {
+        let isChangeProfile = Utils.getSetProfile()
+        if !isChangeProfile {
+            APIS.showChangeProfile()
+            return
+        }
+        let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID") as! ContactCallViewController
+        callContact.startSS = true
+        callContact.startWhiteBoard = true
+        let navigationController = UINavigationController(rootViewController: callContact)
+        navigationController.defaultStyle()
+        if UIApplication.shared.visibleViewController?.navigationController != nil {
+            UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
+        } else {
+            UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
+        }
+    }
 }
 
 extension UINavigationController {

+ 52 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/Model/User.swift

@@ -183,4 +183,56 @@ public class User: Model {
         return user
     }
     
+    public static func getDataFromNameCanNil(name: String?, fmdb: FMDatabase? = nil) -> User? {
+        guard let name = name else {
+            return nil
+        }
+        let listName = name.components(separatedBy: " ")
+        let firstName = listName[0]
+        var lastName = ""
+        print("firstName: \(firstName) <> lastName: \(lastName)")
+        if listName.count > 1 {
+            for i in 1..<listName.count {
+                if lastName.isEmpty {
+                    lastName = listName[i]
+                } else {
+                    lastName = lastName + " " + listName[i]
+                }
+            }
+        }
+        var user: User?
+        if fmdb != nil {
+            if let cursor = Database.shared.getRecords(fmdb: fmdb!, query: "select f_pin, first_name, last_name, image_id, user_type, privacy_flag, offline_mode, ex_block, device_id, official_account from BUDDY where LOWER(first_name) = '\(firstName.lowercased())' AND LOWER(last_name) = '\(lastName.lowercased())'"), cursor.next() {
+                user = User(pin: cursor.string(forColumnIndex: 0) ?? "",
+                            firstName: cursor.string(forColumnIndex: 1) ?? "",
+                            lastName: cursor.string(forColumnIndex: 2) ?? "",
+                            thumb: cursor.string(forColumnIndex: 3) ?? "",
+                            userType: cursor.string(forColumnIndex: 4) ?? "",
+                            privacy_flag: cursor.string(forColumnIndex: 5) ?? "",
+                            offline_mode: cursor.string(forColumnIndex: 6) ?? "",
+                            ex_block: cursor.string(forColumnIndex: 7) ?? "",
+                            official: cursor.string(forColumnIndex: 9) ?? "",
+                            device_id: cursor.string(forColumnIndex: 8) ?? "")
+                cursor.close()
+            }
+        } else {
+            Database.shared.database?.inTransaction({ fmdb, rollback in
+                if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select f_pin, first_name, last_name, image_id, user_type, privacy_flag, offline_mode, ex_block, device_id, official_account from BUDDY where LOWER(first_name) = '\(firstName.lowercased())' AND LOWER(last_name) = '\(lastName.lowercased())'"), cursor.next() {
+                    user = User(pin: cursor.string(forColumnIndex: 0) ?? "",
+                                firstName: cursor.string(forColumnIndex: 1) ?? "",
+                                lastName: cursor.string(forColumnIndex: 2) ?? "",
+                                thumb: cursor.string(forColumnIndex: 3) ?? "",
+                                userType: cursor.string(forColumnIndex: 4) ?? "",
+                                privacy_flag: cursor.string(forColumnIndex: 5) ?? "",
+                                offline_mode: cursor.string(forColumnIndex: 6) ?? "",
+                                ex_block: cursor.string(forColumnIndex: 7) ?? "",
+                                official: cursor.string(forColumnIndex: 9) ?? "",
+                                device_id: cursor.string(forColumnIndex: 8) ?? "")
+                    cursor.close()
+                }
+            })
+        }
+        return user
+    }
+    
 }

+ 5 - 4
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraVideoViewController.swift

@@ -21,6 +21,7 @@ class QmeraVideoViewController: UIViewController {
     var wbRoomId = ""
     var isInisiator = true
     var isSpeaker = true
+    var isPresent = false
     var listRemoteViewFix: [UIImageView] = [
         UIImageView(),
         UIImageView(),
@@ -510,7 +511,7 @@ class QmeraVideoViewController: UIViewController {
                 self.labelTimerVC.text = "Video call is over".localized()
                 self.endAllCall()
                 DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
-                    if self.isInisiator {
+                    if self.isInisiator && !self.isPresent {
                         self.navigationController?.popViewController(animated: true)
                     } else {
                         self.dismiss(animated: true, completion: nil)
@@ -1093,7 +1094,7 @@ class QmeraVideoViewController: UIViewController {
                     }
                     DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                         self.endAllCall()
-                        if self.isInisiator {
+                        if self.isInisiator && !self.isPresent {
                             self.navigationController?.popViewController(animated: true)
                         } else {
                             self.dismiss(animated: true, completion: nil)
@@ -1198,7 +1199,7 @@ class QmeraVideoViewController: UIViewController {
             if (self.dataPerson.count == 1) {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                     self.endAllCall()
-                    if self.isInisiator && onGoingCC.isEmpty {
+                    if self.isInisiator && onGoingCC.isEmpty && !self.isPresent {
                         self.navigationController?.popViewController(animated: true)
                     } else {
                         self.dismiss(animated: true, completion: nil)
@@ -1264,7 +1265,7 @@ class QmeraVideoViewController: UIViewController {
             if (self.dataPerson.count == 1) {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                     self.endAllCall()
-                    if self.isInisiator && onGoingCC.isEmpty {
+                    if self.isInisiator && onGoingCC.isEmpty && !self.isPresent {
                         self.navigationController?.popViewController(animated: true)
                     } else {
                         self.dismiss(animated: true, completion: nil)

+ 52 - 3
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Contact/ContactCallViewController.swift

@@ -54,7 +54,9 @@ class ContactCallViewController: UIViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
         title = "Start Call".localized()
-        if onlyAudioOrVideo == 1 {
+        if startWhiteBoard && startSS {
+            title = "Start Whiteboard/Screen Sharing".localized()
+        } else if onlyAudioOrVideo == 1 {
             title = "Start Audio Call".localized()
         } else if onlyAudioOrVideo == 2 {
             title = "Start Video Call".localized()
@@ -177,7 +179,9 @@ class ContactCallViewController: UIViewController {
 extension ContactCallViewController: UITableViewDelegate {
     
     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
-        if (isAddParticipantVideo) {
+        if startWhiteBoard && startSS {
+            return
+        } else if (isAddParticipantVideo) {
             self.dismiss(animated: true, completion: {
                 self.isDismiss?(self.dataPerson[indexPath.row] as [String: String?])
             })
@@ -262,7 +266,16 @@ extension ContactCallViewController: UITableViewDataSource {
             } else {
                 cell.namePerson.text = dataPerson[indexPath.row]["name"] as? String
             }
-            if onlyAudioOrVideo == 1 {
+            if startWhiteBoard && startSS {
+                cell.audioCallButton.tag = indexPath.row
+                cell.videoCallButton.tag = indexPath.row
+                
+                cell.audioCallButton.setImage(UIImage(named: "pb_screen_share", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withTintColor(.mainColor).resize(target: CGSize(width: 35, height: 35)), for: .normal)
+                cell.videoCallButton.setImage(UIImage(named: "pb_whiteboard", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withTintColor(.mainColor).resize(target: CGSize(width: 25, height: 25)), for: .normal)
+                
+                cell.audioCallButton.addTarget(self, action: #selector(SS(sender:)), for: .touchUpInside)
+                cell.videoCallButton.addTarget(self, action: #selector(WB(sender:)), for: .touchUpInside)
+            } else if onlyAudioOrVideo == 1 {
                 if cell.videoCallButton != nil && cell.videoCallButton.isDescendant(of: cell) {
                     cell.videoCallButton.removeFromSuperview()
                     cell.audioCallButton.removeConstraints(cell.audioCallButton.constraints)
@@ -319,6 +332,42 @@ extension ContactCallViewController: UITableViewDataSource {
         videoVC.modalPresentationStyle = .overFullScreen
         self.show(videoVC, sender: nil)
     }
+    
+    @objc func WB(sender: Any) {
+        let index = sender as! UIButton
+        if let pin = dataPerson[index.tag]["f_pin"] {
+            if !CheckConnection.isConnectedToNetwork() {
+                let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                imageView.tintColor = .white
+                let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                banner.show()
+                return
+            }
+            let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "wbVC") as! WhiteboardViewController
+            controller.modalPresentationStyle = .overFullScreen
+            controller.fromContact = 0
+            controller.user = User.getData(pin: pin)
+            present(controller, animated: true, completion: nil)
+        }
+    }
+    
+    @objc func SS(sender: Any) {
+        let index = sender as! UIButton
+        if let pin = dataPerson[index.tag]["f_pin"] {
+            if !CheckConnection.isConnectedToNetwork() {
+                let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                imageView.tintColor = .white
+                let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                banner.show()
+                return
+            }
+            let controller = ScreenSharingViewController()
+            controller.modalPresentationStyle = .overFullScreen
+            controller.fromContact = 0
+            controller.user = User.getData(pin: pin)
+            present(controller, animated: true, completion: nil)
+        }
+    }
 }
 
 class ContactCallCell: UITableViewCell {