Browse Source

update and fix bugs for release 5.0.43

alqindiirsyam 2 tháng trước cách đây
mục cha
commit
a401411342
23 tập tin đã thay đổi với 238 bổ sung162 xóa
  1. 4 4
      AppBuilder/AppBuilder.xcodeproj/project.pbxproj
  2. 1 6
      AppBuilder/AppBuilder/FourthTabViewController.swift
  3. 26 13
      AppBuilder/AppBuilder/SecondTabViewController.swift
  4. 5 5
      NexilisLite/NexilisLite/Source/APIS.swift
  5. 11 0
      NexilisLite/NexilisLite/Source/CoreMessage_TMessageBank.swift
  6. 1 0
      NexilisLite/NexilisLite/Source/CoreMessage_TMessageCode.swift
  7. 3 3
      NexilisLite/NexilisLite/Source/Database.swift
  8. 65 56
      NexilisLite/NexilisLite/Source/Extension.swift
  9. 38 5
      NexilisLite/NexilisLite/Source/Nexilis.swift
  10. 9 1
      NexilisLite/NexilisLite/Source/OutgoingThread.swift
  11. 13 5
      NexilisLite/NexilisLite/Source/Utils.swift
  12. 1 1
      NexilisLite/NexilisLite/Source/View/Chat/ArchivedChatView.swift
  13. 18 2
      NexilisLite/NexilisLite/Source/View/Chat/ChatGPTBotView.swift
  14. 1 1
      NexilisLite/NexilisLite/Source/View/Chat/ChatWALikeVC.swift
  15. 2 2
      NexilisLite/NexilisLite/Source/View/Chat/EditorGroup.swift
  16. 2 2
      NexilisLite/NexilisLite/Source/View/Chat/EditorPersonal.swift
  17. 3 1
      NexilisLite/NexilisLite/Source/View/Control/BackupRestoreView.swift
  18. 27 13
      NexilisLite/NexilisLite/Source/View/Control/ContactChatViewController.swift
  19. 1 34
      NexilisLite/NexilisLite/Source/View/Control/DocumentPicker.swift
  20. 1 1
      NexilisLite/NexilisLite/Source/View/Control/HistoryBroadcastViewController.swift
  21. 1 6
      NexilisLite/NexilisLite/Source/View/Control/SettingTableViewController.swift
  22. 4 0
      NexilisLite/NexilisLite/Source/View/Control/SignUpSignIn.swift
  23. 1 1
      StreamShield/StreamShield/Source/SecurityShield.swift

+ 4 - 4
AppBuilder/AppBuilder.xcodeproj/project.pbxproj

@@ -560,7 +560,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 5.0.42;
+				MARKETING_VERSION = 5.0.43;
 				PRODUCT_BUNDLE_IDENTIFIER = io.nexilis.appbuilder;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
@@ -596,7 +596,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 5.0.42;
+				MARKETING_VERSION = 5.0.43;
 				PRODUCT_BUNDLE_IDENTIFIER = io.nexilis.appbuilder;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
@@ -632,7 +632,7 @@
 					"@executable_path/../../Frameworks",
 				);
 				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
-				MARKETING_VERSION = 5.0.42;
+				MARKETING_VERSION = 5.0.43;
 				OTHER_CFLAGS = "-fstack-protector-strong";
 				PRODUCT_BUNDLE_IDENTIFIER = io.nexilis.appbuilder.AppBuilderShare;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -671,7 +671,7 @@
 					"@executable_path/../../Frameworks",
 				);
 				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
-				MARKETING_VERSION = 5.0.42;
+				MARKETING_VERSION = 5.0.43;
 				OTHER_CFLAGS = "-fstack-protector-strong";
 				PRODUCT_BUNDLE_IDENTIFIER = io.nexilis.appbuilder.AppBuilderShare;
 				PRODUCT_NAME = "$(TARGET_NAME)";

+ 1 - 6
AppBuilder/AppBuilder/FourthTabViewController.swift

@@ -368,6 +368,7 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                 Item.menus["Version"]?.insert(Item(icon: UIImage(systemName: "rectangle.portrait.and.arrow.right"), title: "Sign-Out".localized()), at: 0)
             }
         }
+        tableView.reloadData()
     }
     
     override public func viewWillAppear(_ animated: Bool) {
@@ -663,7 +664,6 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                     dataImage["name"] = imageName
                     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
                     self.makeMenu()
-                    self.tableView.reloadData()
                 }
                 navigationController?.show(controller, sender: nil)
             }
@@ -728,7 +728,6 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                 self.navigationController?.navigationBar.topItem?.title = "Settings".localized();
                 self.navigationController?.navigationBar.setNeedsLayout()
                 self.makeMenu()
-                self.tableView.reloadData()
             }))
             self.present(alert, animated: true, completion: nil)
         } else if item.title == "Chat Font Size".localized() {
@@ -766,7 +765,6 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                 self.navigationController?.navigationBar.topItem?.title = "Settings".localized();
                 self.navigationController?.navigationBar.setNeedsLayout()
                 self.makeMenu()
-                self.tableView.reloadData()
             }))
             self.present(alert, animated: true, completion: nil)
         } else if item.title == "Chat Wallpaper".localized() {
@@ -843,7 +841,6 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                                     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
                                     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                                     self.makeMenu()
-                                    self.tableView.reloadData()
                                     FirstTabViewController.forceRefresh = true
                                     ThirdTabViewController.forceRefresh = true
                                     FirstTabViewController.showModal = false
@@ -1069,7 +1066,6 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                             DispatchQueue.main.async {
                                 Nexilis.hideLoader {
                                     self.makeMenu()
-                                    self.tableView.reloadData()
                                     let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
                                     imageView.tintColor = .white
                                     let banner = FloatingNotificationBanner(title: "Successfully Sign-In Admin".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
@@ -1088,7 +1084,6 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                             DispatchQueue.main.async {
                                 Nexilis.hideLoader {
                                     self.makeMenu()
-                                    self.tableView.reloadData()
                                     let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
                                     imageView.tintColor = .white
                                     let banner = FloatingNotificationBanner(title: "Successfully Sign-In Internal Team".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)

+ 26 - 13
AppBuilder/AppBuilder/SecondTabViewController.swift

@@ -230,6 +230,7 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
         NotificationCenter.default.addObserver(self, selector: #selector(onReloadTab(notification:)), name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(onReloadTab(notification:)), name: NSNotification.Name(rawValue: "onTopic"), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(onDisconnected(notification:)), name: NSNotification.Name(rawValue: "disconnected_nexilis"), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(onDatabaseOpened(notification:)), name: NSNotification.Name(rawValue: "databaseOpened"), object: nil)
         
         imageViewSearch = UIImageView(image: UIImage(named: self.traitCollection.userInterfaceStyle == .dark ? "nx_search_bar_dark" : "nx_search_bar", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!)
         imageViewSearch.contentMode = .scaleToFill
@@ -774,19 +775,29 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
     private func reloadAllData() {
 //        print("reloadAllData")
         DispatchQueue.main.async { [weak self] in
-            if self?.timerReloadData == nil {
+            if self?.timerReloadData == nil && !self!.isGettingData {
                 self?.getData()
             } else {
                 self?.timerReloadData?.invalidate()
                 self?.timerReloadData = nil
-                self?.timerReloadData = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { [weak self] _ in
-                    self?.getData()
-                    self?.timerReloadData = nil
+                self?.timerReloadData = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { [weak self] _ in
+                    if !self!.isGettingData {
+                        self?.getData()
+                        self?.timerReloadData = nil
+                    }
                 }
             }
         }
     }
     
+    @objc func onDatabaseOpened(notification: NSNotification) {
+        DispatchQueue.main.async {
+            if self.loadingData {
+                self.reloadAllData()
+            }
+        }
+    }
+    
     @objc func onDisconnected(notification: NSNotification) {
         DispatchQueue.main.async {
             self.loadingData = true
@@ -897,7 +908,7 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
             let allChats = Chat.getData()
             self.archivedChats = Chat.getData(isArchived: true)
             var tempChats: [Chat] = []
-            var lowestPinned = 0
+            var lowestPinned: [String: Int] = [:]
 
             for singleChat in allChats {
                 guard !singleChat.groupId.isEmpty else {
@@ -918,8 +929,8 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
                         if let counterParent = Int(tempChats[parentChatIndex].counter), let counterSingle = Int(singleChat.counter) {
                             tempChats[parentChatIndex].counter = "\(counterParent + counterSingle)"
                         }
-                        if singleChat.pinned != 0 && (lowestPinned == 0 || lowestPinned > singleChat.pinned) {
-                            lowestPinned = singleChat.pinned
+                        if singleChat.pinned != 0 && (lowestPinned[singleChat.groupId] == 0 || lowestPinned[singleChat.groupId]! > singleChat.pinned) {
+                            lowestPinned[singleChat.groupId] = singleChat.pinned
                         }
                         if singleChat.pinned != 0 {
                             if !self.listMaxArchived.keys.contains(singleChat.groupId) {
@@ -933,12 +944,12 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
                         }
                         if tempChats[parentChatIndex].pinned > 0 {
                             if singleChat.pinned == 0 {
-                                singleChat.pinned = lowestPinned - 1
+                                singleChat.pinned = lowestPinned[singleChat.groupId]! - 1
                                 singleChat.isFolPinned = true
                             }
                             tempChats.forEach { chat in
-                                if chat.groupId == singleChat.groupId && (chat.pinned == 0 || (chat.isFolPinned && chat.pinned != lowestPinned - 1)) {
-                                    chat.pinned = lowestPinned - 1
+                                if chat.groupId == singleChat.groupId && (chat.pinned == 0 || (chat.isFolPinned && chat.pinned != lowestPinned[singleChat.groupId]! - 1)) {
+                                    chat.pinned = lowestPinned[singleChat.groupId]! - 1
                                     chat.isFolPinned = true
                                 }
                             }
@@ -950,9 +961,11 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
                         tempChats.insert(singleChat, at: min(indexParent + existingGroup.count, tempChats.count))
                     }
                 } else {
-                    lowestPinned = 0
+                    if lowestPinned[singleChat.groupId] == nil {
+                        lowestPinned[singleChat.groupId] = 0
+                    }
                     if singleChat.pinned != 0 {
-                        lowestPinned = singleChat.pinned
+                        lowestPinned[singleChat.groupId] = singleChat.pinned
                     }
                     self.chatGroupMaps[singleChat.groupId] = [singleChat]
                     let parentChat = Chat(profile: singleChat.profile, groupName: singleChat.groupName, counter: singleChat.counter, groupId: singleChat.groupId)
@@ -2073,7 +2086,7 @@ extension SecondTabViewController: UITableViewDelegate, UITableViewDataSource {
                     labelCounter.trailingAnchor.constraint(equalTo: viewCounter.trailingAnchor, constant: -2),
                 ])
                 labelCounter.font = UIFont.systemFont(ofSize: 11 + String.offset())
-                if Int(data.counter)! > 99 {
+                if Int(data.counter) ?? 0 > 99 {
                     labelCounter.text = "99+"
                 } else {
                     labelCounter.text = data.counter

+ 5 - 5
NexilisLite/NexilisLite/Source/APIS.swift

@@ -1199,7 +1199,7 @@ public class APIS: NSObject {
                 "pin": User.getMyPin() ?? "",
                 "message_id": id
             ]
-            Utils.postDataWithCookiesAndUserAgent(from: URL(string: Utils.getDomainOpr() + "ack_message")!, parameter: parameter, isFormData: true, isBackground: true) { data, response, error in
+            Utils.postDataWithCookiesAndUserAgent(from: URL(string: Utils.getDomainOpr() + "ack_message")!, parameter: parameter, isFormData: true) { data, response, error in
             }
         }
     }
@@ -1210,7 +1210,7 @@ public class APIS: NSObject {
                 "pin": User.getMyPin() ?? "",
                 "message_id": id
             ]
-            Utils.postDataWithCookiesAndUserAgent(from: URL(string: Utils.getDomainOpr() + "pull_notification")!, parameter: parameter, isFormData: true, isBackground: true) { data, response, error in
+            Utils.postDataWithCookiesAndUserAgent(from: URL(string: Utils.getDomainOpr() + "pull_notification")!, parameter: parameter, isFormData: true) { data, response, error in
                 if let data = data {
                     do {
                         if let dataString = String(data: data, encoding: .utf8) {
@@ -1770,10 +1770,10 @@ public class APIS: NSObject {
         viewController.present(alert, animated: true, completion: nil)
     }
     
-    static func showWarningFile() {
+    static func showWarningFile(type: Int) {
         alertControllerExpired = LibAlertController(
-            title: "⚠️ Suspicious File Detected".localized(),
-            message: "The file appears to have a mismatched name and extension, which may indicate a malicious file. Please verify the file’s source and format before uploading it.".localized(),
+            title: type == -1 ? "⚠️ Suspicious File Detected".localized() : "⚠️ Unrecognized File Type".localized(),
+            message: type == -1 ? "The file appears to have a mismatched name and extension, which may indicate a malicious file. Please verify the file’s source and format before uploading it.".localized() : "The selected item is not listed in the system dashboard.".localized(),
             preferredStyle: .alert
         )
         

+ 11 - 0
NexilisLite/NexilisLite/Source/CoreMessage_TMessageBank.swift

@@ -2715,4 +2715,15 @@ public class CoreMessage_TMessageBank {
         return tMessage
     }
     
+    public static func getWhitelistFileExt() -> TMessage {
+        let tMessage = NexilisLite.TMessage()
+        let me = User.getMyPin() ?? ""
+        tMessage.mPIN = me
+        tMessage.mCode = CoreMessage_TMessageCode.GET_WHITELIST
+        tMessage.mStatus = CoreMessage_TMessageUtil.getTID()
+        tMessage.mBodies[CoreMessage_TMessageKey.API] = Nexilis.sAPIKey
+        tMessage.mBodies[CoreMessage_TMessageKey.ANDROID_APP_NAME] = APIS.getAppNm()
+        return tMessage
+    }
+    
 }

+ 1 - 0
NexilisLite/NexilisLite/Source/CoreMessage_TMessageCode.swift

@@ -807,4 +807,5 @@ public class CoreMessage_TMessageCode {
     
     public static let GET_PUSH_PREFS = "GPR";
     public static let UPDATE_VERSION = "UPV";
+    public static let GET_WHITELIST = "GWL";
 }

+ 3 - 3
NexilisLite/NexilisLite/Source/Database.swift

@@ -85,7 +85,7 @@ public class Database {
                 }
                 fmdb.setKey(keyString)
             }
-            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
+            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "databaseOpened"), object: nil, userInfo: nil)
         })
     }
 
@@ -133,9 +133,9 @@ public class Database {
                     }
                 }
                 try database.executeUpdate(alterSQL, values: nil)
-                print("Added column \(columnName)")
+//                print("Added column \(columnName)")
             } else {
-                print("Column \(columnName) already exists")
+//                print("Column \(columnName) already exists")
             }
         } catch {
             print("Error checking or adding column: \(error.localizedDescription)")

+ 65 - 56
NexilisLite/NexilisLite/Source/Extension.swift

@@ -13,6 +13,7 @@ import ImageIO
 import MobileCoreServices
 import CommonCrypto
 import ZIPFoundation
+import PDFKit
 
 extension Date {
     
@@ -563,51 +564,55 @@ extension URL {
     }
     
     struct FileTypeSignature {
-        let magic: String
-        let extensions: [String]
-
-        static let knownSignatures: [FileTypeSignature] = [
-            FileTypeSignature(magic: "FFD8FF", extensions: ["jpg", "jpeg"]),
-            FileTypeSignature(magic: "89504E47", extensions: ["png"]),
-            FileTypeSignature(magic: "47494638", extensions: ["gif"]),
-            FileTypeSignature(magic: "25504446", extensions: ["pdf"]),
-            FileTypeSignature(magic: "504B0304", extensions: ["zip", "docx", "xlsx", "pptx", "jar", "odt", "ods", "odp", "apk", "ipa"]),
-            FileTypeSignature(magic: "D0CF11E0", extensions: ["doc", "xls", "ppt", "msg"]), // Legacy MS Office
-            FileTypeSignature(magic: "52617221", extensions: ["rar"]),
-            FileTypeSignature(magic: "1F8B08", extensions: ["gz"]),
-            FileTypeSignature(magic: "425A68", extensions: ["bz2"]),
-            FileTypeSignature(magic: "377ABCAF271C", extensions: ["7z"]),
-            FileTypeSignature(magic: "00000018", extensions: ["mp4"]),
-            FileTypeSignature(magic: "000001BA", extensions: ["mpg", "mpeg"]),
-            FileTypeSignature(magic: "000001B3", extensions: ["mpg"]),
-            FileTypeSignature(magic: "494433", extensions: ["mp3"]),
-            FileTypeSignature(magic: "4F676753", extensions: ["ogg"]),
-            FileTypeSignature(magic: "1A45DFA3", extensions: ["mkv", "webm"]),
-            FileTypeSignature(magic: "3026B2758E66CF11", extensions: ["wmv", "wma", "asf"]),
-            FileTypeSignature(magic: "57415645", extensions: ["wav"]),
-            FileTypeSignature(magic: "52494646", extensions: ["avi", "wav", "webp"]),
-            FileTypeSignature(magic: "3C3F786D6C", extensions: ["xml"]),
-            FileTypeSignature(magic: "68746D6C3E", extensions: ["html", "htm"]),
-            FileTypeSignature(magic: "7B5C727466", extensions: ["rtf"]),
-            FileTypeSignature(magic: "38425053", extensions: ["psd"]),
-            FileTypeSignature(magic: "49492A00", extensions: ["tif", "tiff"]),
-            FileTypeSignature(magic: "4D4D002A", extensions: ["tif", "tiff"]),
-            FileTypeSignature(magic: "00010000", extensions: ["ico"]),
-            FileTypeSignature(magic: "CAFEBABE", extensions: ["class"]),
-            FileTypeSignature(magic: "EFBBBF", extensions: ["txt"])
-        ]
+        let magic: [String]
+        let extensions: String
     }
 
     func detectFileType(from data: Data) -> FileTypeSignature? {
         let hexString = data.prefix(4).map { String(format: "%02X", $0) }.joined()
-        return FileTypeSignature.knownSignatures.first {
-            hexString.hasPrefix($0.magic)
+        let extUploadedFile = self.absoluteString.split(separator: ".").last ?? ""
+        let dataPrefs = Utils.getWhitelistFileExt()
+        guard !dataPrefs.isEmpty,
+              let jsonData = dataPrefs.data(using: .utf8) else {
+            return nil
         }
+        do {
+            if let jsonArray = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [[String: Any]] {
+                guard let _ = jsonArray.firstIndex(where: { $0["ext"] as? String ?? "" == extUploadedFile }) else {
+                    return nil
+                }
+                if let idxRealFile = jsonArray.firstIndex(where: {
+                    guard let magicArray = $0["magic"] as? [String] else { return false }
+                    return magicArray.contains(where: { magicItem in
+                        if magicItem.contains("~") {
+                            return magicItem.split(separator: "~").contains { $0 == hexString }
+                        } else {
+                            return magicItem == hexString
+                        }
+                    })
+                }) {
+                    let jsonRealFile = jsonArray[idxRealFile]
+                    return FileTypeSignature(magic: jsonRealFile["magic"] as? [String] ?? [], extensions: jsonRealFile["ext"] as? String ?? "")
+                }
+            }
+        } catch {
+            print("Error parsing JSON: \(error)")
+        }
+        
+        return nil
     }
     
     func isEncryptedPDF(data: Data) -> Bool {
-        if let content = String(data: data.prefix(2048), encoding: .ascii) {
-            return content.contains("/Encrypt")
+        guard let document = PDFDocument(data: data) else {
+            return false
+        }
+        
+        if document.isEncrypted {
+            if document.isLocked {
+                return true
+            } else {
+                return false
+            }
         }
         return false
     }
@@ -623,40 +628,44 @@ extension URL {
         let oleMagic = data.prefix(4).map { String(format: "%02X", $0) }.joined()
         return oleMagic == "D0CF11E0"
     }
-
-    func doesFileMatchExtension() -> Bool {
+    
+    func doesFileMatchExtension() -> (result: Int, realFileType: FileTypeSignature?) {
         guard let fileExtension = self.pathExtension.lowercased().split(separator: "?").first,
               let fileData = try? Data(contentsOf: self) else {
-            return false
+            return (-1, nil)
         }
 
         if let detected = detectFileType(from: fileData) {
-            return detected.extensions.contains(String(fileExtension))
+            if detected.extensions == String(fileExtension) {
+                return (1, detected)
+            } else {
+                return (-1, detected)
+            }
         }
 
-        return false
+        return (0, nil)
     }
 
-    func validateFile() -> (matchesExtension: Bool, isEncrypted: Bool) {
-        guard let fileExtension = self.pathExtension.lowercased().split(separator: "?").first,
-              let fileData = try? Data(contentsOf: self) else {
-            return (false, false)
+    func validateFile() -> Int {
+        guard let fileData = try? Data(contentsOf: self) else {
+            return -1
         }
 
         let matches = self.doesFileMatchExtension()
-        var isEncrypted = false
-
-        if matches {
-            if let type = detectFileType(from: fileData) {
-                if type.extensions.contains("pdf") {
-                    isEncrypted = isEncryptedPDF(data: fileData)
-                } else if type.extensions.contains(where: { ["pptx", "docx", "xlsx"].contains($0) }) {
-                    isEncrypted = isEncryptedOfficeFile(data: fileData)
-                }
+        
+        func isDoc(type: String) -> Bool {
+            return type == "ppt" || type == "doc" || type == "xls"
+        }
+
+        if (matches.result == -1 && matches.realFileType != nil) {
+            if isDoc(type: matches.realFileType!.extensions) && isEncryptedOfficeFile(data: fileData) {
+                return 1
+            } else if matches.realFileType!.extensions == "pdf" && isEncryptedPDF(data: fileData) {
+                return 1
             }
         }
 
-        return (matches, isEncrypted)
+        return matches.result
     }
     
 }

+ 38 - 5
NexilisLite/NexilisLite/Source/Nexilis.swift

@@ -19,7 +19,7 @@ import CryptoKit
 import WebKit
 
 public class Nexilis: NSObject {
-    public static var cpaasVersion = "5.0.42"
+    public static var cpaasVersion = "5.0.43"
     public static var sAPIKey = ""
     
     public static var ADDRESS = ""
@@ -287,6 +287,7 @@ public class Nexilis: NSObject {
                     getServiceBank()
                     getPullWorkingArea()
                     getPullGroupNoMember()
+                    getWhitelistFileExt()
                     delegate.onSuccess(userId: me)
                     forceShowFB()
                     if (Utils.getSetProfile() && !Utils.getFinishInitPrefsr()) || (!Utils.getForceAnonymous() && !Utils.getFinishInitPrefsr()) {
@@ -687,6 +688,16 @@ public class Nexilis: NSObject {
         return ""
     }
     
+    static func getWhitelistFileExt() {
+        if let response = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.getWhitelistFileExt(), timeout: 5000), response.isOk() {
+            let data = response.getBody(key: CoreMessage_TMessageKey.DATA, default_value: "[]")
+//            print("SUCCESS getWhitelistFileExt: \(data)")
+            Utils.setWhitelistFileExt(value: data)
+        } else {
+//            print("GAGAL getWhitelistFileExt")
+        }
+    }
+    
     private static func getPullWorkingArea() {
         while Nexilis.isProcessWriteSync {
             Thread.sleep(forTimeInterval: 0.5)
@@ -1625,15 +1636,23 @@ public class Nexilis: NSObject {
                             queryGetLastMessageId = "SELECT message_id FROM MESSAGE where l_pin = '\(chat_id.isEmpty ? pin : l_pin)' AND chat_id = '\(chat_id)' AND message_scope_id = '\(MessageScope.GROUP)' order by server_date desc LIMIT 1"
                         }
                         var messageId = ""
+                        var pinned = 0
+                        var archived = 0
                         if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: queryGetLastMessageId), cursorData.next() {
                             messageId = cursorData.string(forColumnIndex: 0) ?? ""
                             cursorData.close()
                         }
+                        if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select pinned, archived from MESSAGE_SUMMARY where l_pin = '\(pin)'"), cursor.next() {
+                            pinned = Int(cursor.int(forColumnIndex: 0))
+                            archived = Int(cursor.int(forColumnIndex: 1))
+                        }
                         if !messageId.isEmpty {
                             _ = try Database.shared.insertRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", cvalues: [
                                 "l_pin" : pin,
                                 "message_id" : messageId,
-                                "counter" : counter ?? 0
+                                "counter" : counter ?? 0,
+                                "pinned" : pinned,
+                                "archived" : archived
                             ], replace: true)
                         }
                     } catch {
@@ -1713,10 +1732,14 @@ public class Nexilis: NSObject {
         })
         let pin = "-999"
         var counter : Int? = nil
+        var pinned = 0
+        var archived = 0
         Database.shared.database?.inTransaction({ (fmdb, rollback) in
             do {
-                if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select counter from MESSAGE_SUMMARY where l_pin = '\(pin)'"), cursor.next() {
+                if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select counter, pinned, archived from MESSAGE_SUMMARY where l_pin = '\(pin)'"), cursor.next() {
                     counter = Int(cursor.int(forColumnIndex: 0))
+                    pinned = Int(cursor.int(forColumnIndex: 1))
+                    archived = Int(cursor.int(forColumnIndex: 2))
                     counter! += 1
                     cursor.close()
                     //print("select db message summary")
@@ -1735,7 +1758,9 @@ public class Nexilis: NSObject {
                 _ = try Database.shared.insertRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", cvalues: [
                     "l_pin" : pin,
                     "message_id" : message_id,
-                    "counter" : counter!
+                    "counter" : counter!,
+                    "pinned" : pinned,
+                    "archived" : archived
                 ], replace: true)
             } catch {
                 rollback.pointee = true
@@ -1796,12 +1821,20 @@ public class Nexilis: NSObject {
             }
         })
         let pin = lPin == me ? fPin : lPin
+        var pinned = 0
+        var archived = 0
         Database.shared.database?.inTransaction({ (fmdb, rollback) in
             do {
+                if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select pinned, archived from MESSAGE_SUMMARY where l_pin = '\(pin)'"), cursor.next() {
+                    pinned = Int(cursor.int(forColumnIndex: 0))
+                    archived = Int(cursor.int(forColumnIndex: 1))
+                }
                 _ = try Database.shared.insertRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", cvalues: [
                     "l_pin" : pin,
                     "message_id" : idCall,
-                    "counter" : 0
+                    "counter" : 0,
+                    "pinned" : pinned,
+                    "archived" : archived
                 ], replace: true)
             } catch {
                 rollback.pointee = true

+ 9 - 1
NexilisLite/NexilisLite/Source/OutgoingThread.swift

@@ -414,6 +414,8 @@ class OutgoingThread {
                         if !chat.isEmpty {
                             pin = chat
                         }
+                        var pinned = 0
+                        var archived = 0
                         var queryGetLastMessageId = "SELECT message_id FROM MESSAGE where (f_pin = '\(pin)' OR l_pin = '\(pin)') AND message_scope_id = '\(MessageScope.WHISPER)' order by server_date desc LIMIT 1"
                         if scope == "4" {
                             queryGetLastMessageId = "SELECT message_id FROM MESSAGE where l_pin = '\(chat.isEmpty ? pin : l_pin)' AND chat_id = '\(chat)' AND message_scope_id = '\(MessageScope.GROUP)' order by server_date desc LIMIT 1"
@@ -423,11 +425,17 @@ class OutgoingThread {
                             messageId = cursorData.string(forColumnIndex: 0) ?? ""
                             cursorData.close()
                         }
+                        if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select pinned, archived from MESSAGE_SUMMARY where l_pin = '\(pin)'"), cursor.next() {
+                            pinned = Int(cursor.int(forColumnIndex: 0))
+                            archived = Int(cursor.int(forColumnIndex: 1))
+                        }
                         if !messageId.isEmpty {
                             _ = try Database.shared.insertRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", cvalues: [
                                 "l_pin" : pin,
                                 "message_id" : messageId,
-                                "counter" : 0
+                                "counter" : 0,
+                                "pinned" : pinned,
+                                "archived" : archived
                             ], replace: true)
                         }
                         NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)

+ 13 - 5
NexilisLite/NexilisLite/Source/Utils.swift

@@ -392,6 +392,17 @@ public final class Utils {
         return ""
     }
     
+    public static func setWhitelistFileExt(value: String) {
+        SecureUserDefaults.shared.set(value, forKey: "pb_whitelist_file_ext")
+    }
+
+    public static func getWhitelistFileExt() -> String {
+        if let value: String = SecureUserDefaults.shared.value(forKey: "pb_whitelist_file_ext") {
+            return value
+        }
+        return ""
+    }
+    
 //    public static func getMD5(string: String) -> Data {
 //        let length = Int(CC_MD5_DIGEST_LENGTH)
 //        let messageData = string.data(using:.utf8)!
@@ -706,7 +717,7 @@ public final class Utils {
         task.resume()
     }
     
-    public static func postDataWithCookiesAndUserAgent(from url: URL, parameter: [String: Any] = [:], parameters: [[String: Any]] = [], isFormData: Bool = false, isBackground: Bool = false, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
+    public static func postDataWithCookiesAndUserAgent(from url: URL, parameter: [String: Any] = [:], parameters: [[String: Any]] = [], isFormData: Bool = false, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
         let apiKey: String = SecureUserDefaults.shared.value(forKey: "apiKey") ?? ""
         var defaultParameter: [String : Any] = [
             "app_id": APIS.getAppNm(),
@@ -740,10 +751,7 @@ public final class Utils {
         }
         request.httpBody = jsonData
         //print("DATA SEND MOBILE \(Utils.getUserAgent()) <> \(Utils.getCookiesMobile())")
-        var urlConfig = URLSessionConfiguration.default
-        if isBackground{
-            urlConfig = URLSessionConfiguration.background(withIdentifier: "nexilis.backgroundSession")
-        }
+        let urlConfig = URLSessionConfiguration.default
         urlConfig.timeoutIntervalForRequest = 30.0
         urlConfig.timeoutIntervalForResource = 60.0
         let sessionDelegate = SelfSignedURLSessionDelegate()

+ 1 - 1
NexilisLite/NexilisLite/Source/View/Chat/ArchivedChatView.swift

@@ -279,7 +279,7 @@ public class ArchivedChatView: UIViewController, UITableViewDataSource, UITableV
                 labelCounter.trailingAnchor.constraint(equalTo: viewCounter.trailingAnchor, constant: -2),
             ])
             labelCounter.font = UIFont.systemFont(ofSize: 11 + String.offset())
-            if Int(data.counter)! > 99 {
+            if Int(data.counter) ?? 0 > 99 {
                 labelCounter.text = "99+"
             } else {
                 labelCounter.text = data.counter

+ 18 - 2
NexilisLite/NexilisLite/Source/View/Chat/ChatGPTBotView.swift

@@ -219,12 +219,20 @@ public class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
             }
         })
         let pin = "-997"
+        var pinned = 0
+        var archived = 0
         Database.shared.database?.inTransaction({ (fmdb, rollback) in
             do {
+                if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select pinned, archived from MESSAGE_SUMMARY where l_pin = '\(pin)'"), cursor.next() {
+                    pinned = Int(cursor.int(forColumnIndex: 0))
+                    archived = Int(cursor.int(forColumnIndex: 1))
+                }
                 _ = try Database.shared.insertRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", cvalues: [
                     "l_pin" : pin,
                     "message_id" : message_id,
-                    "counter" : 0
+                    "counter" : 0,
+                    "pinned" : pinned,
+                    "archived" : archived
                 ], replace: true)
             } catch {
                 rollback.pointee = true
@@ -447,12 +455,20 @@ public class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
                                     }
                                 })
                                 let pin = "-997"
+                                var pinned = 0
+                                var archived = 0
                                 Database.shared.database?.inTransaction({ (fmdb, rollback) in
                                     do {
+                                        if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select pinned, archived from MESSAGE_SUMMARY where l_pin = '\(pin)'"), cursor.next() {
+                                            pinned = Int(cursor.int(forColumnIndex: 0))
+                                            archived = Int(cursor.int(forColumnIndex: 1))
+                                        }
                                         _ = try Database.shared.insertRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", cvalues: [
                                             "l_pin" : pin,
                                             "message_id" : message_id,
-                                            "counter" : 0
+                                            "counter" : 0,
+                                            "pinned" : pinned,
+                                            "archived" : archived
                                         ], replace: true)
                                     } catch {
                                         rollback.pointee = true

+ 1 - 1
NexilisLite/NexilisLite/Source/View/Chat/ChatWALikeVC.swift

@@ -765,7 +765,7 @@ public class ChatWALikeVC: UIViewController, UITableViewDataSource, UITableViewD
                 labelCounter.trailingAnchor.constraint(equalTo: viewCounter.trailingAnchor, constant: -2),
             ])
             labelCounter.font = UIFont.systemFont(ofSize: 11 + String.offset())
-            if Int(data.counter)! > 99 {
+            if Int(data.counter) ?? 0 > 99 {
                 labelCounter.text = "99+"
             } else {
                 labelCounter.text = data.counter

+ 2 - 2
NexilisLite/NexilisLite/Source/View/Chat/EditorGroup.swift

@@ -2488,10 +2488,10 @@ extension EditorGroup: UIDocumentPickerDelegate, DocumentPickerDelegate, QLPrevi
                 DispatchQueue.main.async {
                     Nexilis.hideLoader {
                         sender.navigation.dismiss(animated: true, completion: {
-                            if result.matchesExtension {
+                            if result == 1 {
                                 sendIt()
                             } else {
-                                APIS.showWarningFile()
+                                APIS.showWarningFile(type: result)
                             }
                         })
                     }

+ 2 - 2
NexilisLite/NexilisLite/Source/View/Chat/EditorPersonal.swift

@@ -3826,10 +3826,10 @@ extension EditorPersonal: UIDocumentPickerDelegate, DocumentPickerDelegate, QLPr
                 DispatchQueue.main.async {
                     Nexilis.hideLoader {
                         sender.navigation.dismiss(animated: true, completion: {
-                            if result.matchesExtension {
+                            if result == 1 {
                                 sendIt()
                             } else {
-                                APIS.showWarningFile()
+                                APIS.showWarningFile(type: result)
                             }
                         })
                     }

+ 3 - 1
NexilisLite/NexilisLite/Source/View/Control/BackupRestoreView.swift

@@ -504,7 +504,9 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                 _ = try Database.shared.insertRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", cvalues: [
                     "l_pin" : dataUcList[0],
                     "message_id" : dataUcList[1],
-                    "counter" : 0
+                    "counter" : 0,
+                    "pinned" : 0,
+                    "archived" : 0
                 ], replace: true)
                 recordSizeRestore += 1
             } catch {

+ 27 - 13
NexilisLite/NexilisLite/Source/View/Control/ContactChatViewController.swift

@@ -208,6 +208,7 @@ class ContactChatViewController: UITableViewController {
         NotificationCenter.default.addObserver(self, selector: #selector(onReload(notification:)), name: NSNotification.Name(rawValue: "onUpdatePersonInfo"), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(onReloadTab(notification:)), name: NSNotification.Name(rawValue: "onTopic"), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(onDisconnected(notification:)), name: NSNotification.Name(rawValue: "disconnected_nexilis"), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(onDatabaseOpened(notification:)), name: NSNotification.Name(rawValue: "databaseOpened"), object: nil)
         
         tableView.tableHeaderView = segment
         tableView.tableFooterView = UIView()
@@ -270,20 +271,31 @@ class ContactChatViewController: UITableViewController {
 //    }
     
     private func reloadAllData() {
+//        print("reloadAllData")
         DispatchQueue.main.async { [weak self] in
-            if self?.timerReloadData == nil {
+            if self?.timerReloadData == nil && !self!.isGettingData {
                 self?.getData()
             } else {
                 self?.timerReloadData?.invalidate()
                 self?.timerReloadData = nil
-                self?.timerReloadData = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { [weak self] _ in
-                    self?.getData()
-                    self?.timerReloadData = nil
+                self?.timerReloadData = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { [weak self] _ in
+                    if !self!.isGettingData {
+                        self?.getData()
+                        self?.timerReloadData = nil
+                    }
                 }
             }
         }
     }
     
+    @objc func onDatabaseOpened(notification: NSNotification) {
+        DispatchQueue.main.async {
+            if self.loadingData {
+                self.reloadAllData()
+            }
+        }
+    }
+    
     @objc func onDisconnected(notification: NSNotification) {
         DispatchQueue.main.async {
             self.loadingData = true
@@ -430,7 +442,7 @@ class ContactChatViewController: UITableViewController {
             let allChats = Chat.getData()
             self.archivedChats = Chat.getData(isArchived: true)
             var tempChats: [Chat] = []
-            var lowestPinned = 0
+            var lowestPinned: [String: Int] = [:]
 
             for singleChat in allChats {
                 guard !singleChat.groupId.isEmpty else {
@@ -451,8 +463,8 @@ class ContactChatViewController: UITableViewController {
                         if let counterParent = Int(tempChats[parentChatIndex].counter), let counterSingle = Int(singleChat.counter) {
                             tempChats[parentChatIndex].counter = "\(counterParent + counterSingle)"
                         }
-                        if singleChat.pinned != 0 && (lowestPinned == 0 || lowestPinned > singleChat.pinned) {
-                            lowestPinned = singleChat.pinned
+                        if singleChat.pinned != 0 && (lowestPinned[singleChat.groupId] == 0 || lowestPinned[singleChat.groupId]! > singleChat.pinned) {
+                            lowestPinned[singleChat.groupId] = singleChat.pinned
                         }
                         if singleChat.pinned != 0 {
                             if !self.listMaxArchived.keys.contains(singleChat.groupId) {
@@ -466,12 +478,12 @@ class ContactChatViewController: UITableViewController {
                         }
                         if tempChats[parentChatIndex].pinned > 0 {
                             if singleChat.pinned == 0 {
-                                singleChat.pinned = lowestPinned - 1
+                                singleChat.pinned = lowestPinned[singleChat.groupId]! - 1
                                 singleChat.isFolPinned = true
                             }
                             tempChats.forEach { chat in
-                                if chat.groupId == singleChat.groupId && (chat.pinned == 0 || (chat.isFolPinned && chat.pinned != lowestPinned - 1)) {
-                                    chat.pinned = lowestPinned - 1
+                                if chat.groupId == singleChat.groupId && (chat.pinned == 0 || (chat.isFolPinned && chat.pinned != lowestPinned[singleChat.groupId]! - 1)) {
+                                    chat.pinned = lowestPinned[singleChat.groupId]! - 1
                                     chat.isFolPinned = true
                                 }
                             }
@@ -483,9 +495,11 @@ class ContactChatViewController: UITableViewController {
                         tempChats.insert(singleChat, at: min(indexParent + existingGroup.count, tempChats.count))
                     }
                 } else {
-                    lowestPinned = 0
+                    if lowestPinned[singleChat.groupId] == nil {
+                        lowestPinned[singleChat.groupId] = 0
+                    }
                     if singleChat.pinned != 0 {
-                        lowestPinned = singleChat.pinned
+                        lowestPinned[singleChat.groupId] = singleChat.pinned
                     }
                     self.chatGroupMaps[singleChat.groupId] = [singleChat]
                     let parentChat = Chat(profile: singleChat.profile, groupName: singleChat.groupName, counter: singleChat.counter, groupId: singleChat.groupId)
@@ -1482,7 +1496,7 @@ extension ContactChatViewController {
                         labelCounter.trailingAnchor.constraint(equalTo: viewCounter.trailingAnchor, constant: -2),
                     ])
                     labelCounter.font = UIFont.systemFont(ofSize: 11 + String.offset())
-                    if Int(data.counter)! > 99 {
+                    if Int(data.counter) ?? 0 > 99 {
                         labelCounter.text = "99+"
                     } else {
                         labelCounter.text = data.counter

+ 1 - 34
NexilisLite/NexilisLite/Source/View/Control/DocumentPicker.swift

@@ -41,40 +41,7 @@ open class DocumentPicker: NSObject {
     }
     
     public func present() {
-        var supportedTypes: [UTType] = [
-            // General text and images
-            .image, .text, .plainText, .utf8PlainText, .utf16ExternalPlainText, .utf16PlainText,
-            .delimitedText, .commaSeparatedText, .tabSeparatedText, .utf8TabSeparatedText,
-            .rtf, .pdf, .webArchive,
-            // Images
-            .jpeg, .tiff, .gif, .png, .bmp, .ico, .rawImage, .svg, .livePhoto,
-            // Media
-            .movie, .video, .audio, .quickTimeMovie, .mpeg, .mpeg2Video, .mpeg2TransportStream,
-            .mp3, .mpeg4Movie, .mpeg4Audio, .avi, .aiff, .wav, .midi,
-            // Archives
-            .archive, .gzip, .bz2, .zip, .appleArchive,
-            // Documents
-            .spreadsheet, .epub, .presentation,
-            // Code and script types
-            .sourceCode, .cSource, .objectiveCSource, .swiftSource, .cPlusPlusSource,
-            .objectiveCPlusPlusSource, .script, .shellScript, .pythonScript, .rubyScript,
-            .perlScript, .json, .xml, .html,
-            // Custom UTTypes via extension
-            UTType(filenameExtension: "java")!,     // Java
-            UTType(filenameExtension: "ts")!,       // TypeScript
-            UTType(filenameExtension: "yaml")!,     // YAML
-            UTType(filenameExtension: "yml")!,      // YAML
-            UTType(filenameExtension: "sql")!,      // SQL
-            UTType(filenameExtension: "csv")!,      // CSV
-            UTType(filenameExtension: "ini")!,      // INI
-            UTType(filenameExtension: "log")!,      // Log
-            UTType(filenameExtension: "js")!,       // JavaScript
-            UTType(filenameExtension: "md")!        // Markdown
-        ]
-        if #available(iOS 18.0, *){
-            supportedTypes.append(.css)
-        }
-        self.pickerController = UIDocumentPickerViewController(forOpeningContentTypes: supportedTypes, asCopy: true)
+        self.pickerController = UIDocumentPickerViewController(forOpeningContentTypes: [.data], asCopy: true)
 //        self.pickerController?.allowsMultipleSelection = true
         self.pickerController!.delegate = self
         self.presentationController?.present(self.pickerController!, animated: true)

+ 1 - 1
NexilisLite/NexilisLite/Source/View/Control/HistoryBroadcastViewController.swift

@@ -236,7 +236,7 @@ class HistoryBroadcastViewController: UIViewController, UITableViewDelegate, UIT
                     labelCounter.trailingAnchor.constraint(equalTo: viewCounter.trailingAnchor, constant: -2),
                 ])
                 labelCounter.font = UIFont.systemFont(ofSize: 11)
-                if Int(data.counter)! > 99 {
+                if Int(data.counter) ?? 0 > 99 {
                     labelCounter.text = "99+"
                 } else {
                     labelCounter.text = data.counter

+ 1 - 6
NexilisLite/NexilisLite/Source/View/Control/SettingTableViewController.swift

@@ -332,6 +332,7 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                 Item.menus["Version"]?.insert(Item(icon: UIImage(systemName: "rectangle.portrait.and.arrow.right"), title: "Sign-Out".localized()), at: 0)
             }
         }
+        tableView.reloadData()
     }
     
     override public func viewWillAppear(_ animated: Bool) {
@@ -505,7 +506,6 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                     dataImage["name"] = imageName
                     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
                     self.makeMenu()
-                    self.tableView.reloadData()
                 }
                 navigationController?.show(controller, sender: nil)
             }
@@ -572,7 +572,6 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                 self.navigationController?.navigationBar.topItem?.title = "Settings".localized();
                 self.navigationController?.navigationBar.setNeedsLayout()
                 self.makeMenu()
-                self.tableView.reloadData()
             }))
             self.present(alert, animated: true, completion: nil)
         } else if item.title == "Chat Font Size".localized() {
@@ -610,7 +609,6 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                 self.navigationController?.navigationBar.topItem?.title = "Settings".localized();
                 self.navigationController?.navigationBar.setNeedsLayout()
                 self.makeMenu()
-                self.tableView.reloadData()
             }))
             self.present(alert, animated: true, completion: nil)
         } else if item.title == "Chat Wallpaper".localized() {
@@ -675,7 +673,6 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                                     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
                                     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                                     self.makeMenu()
-                                    self.tableView.reloadData()
                                     
                                     if !Utils.getForceAnonymous() {
                                         Nexilis.showForceSignIn()
@@ -901,7 +898,6 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                             DispatchQueue.main.async {
                                 Nexilis.hideLoader {
                                     self.makeMenu()
-                                    self.tableView.reloadData()
                                     let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
                                     imageView.tintColor = .white
                                     let banner = FloatingNotificationBanner(title: "Successfully Sign-In Admin".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
@@ -920,7 +916,6 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                             DispatchQueue.main.async {
                                 Nexilis.hideLoader {
                                     self.makeMenu()
-                                    self.tableView.reloadData()
                                     let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
                                     imageView.tintColor = .white
                                     let banner = FloatingNotificationBanner(title: "Successfully Sign-In Internal Team".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)

+ 4 - 0
NexilisLite/NexilisLite/Source/View/Control/SignUpSignIn.swift

@@ -364,6 +364,9 @@ public class SignUpSignIn: UIViewController {
                             Utils.setProfile(value: true)
                             // pos registration
                             _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
+                            DispatchQueue.global().asyncAfter(deadline: .now() + 2, execute: {
+                                Nexilis.getWhitelistFileExt()
+                            })
                             DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
                                 Nexilis.hideLoader(completion: {
                                     let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
@@ -409,6 +412,7 @@ public class SignUpSignIn: UIViewController {
                             }
                         })
                         Utils.setProfile(value: true)
+                        Nexilis.getWhitelistFileExt()
     //                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateFifthTab"), object: nil, userInfo: nil)
                         DispatchQueue.main.async {
                             Nexilis.hideLoader(completion: {

+ 1 - 1
StreamShield/StreamShield/Source/SecurityShield.swift

@@ -42,7 +42,7 @@ public class SecurityShield: NSObject {
                         Thread.sleep(forTimeInterval: 1)
                     }
                 }
-                pull()
+//                pull()
             } catch {
                 
             }