Bladeren bron

update Whatsapp like and fix bugs for 5.0.36

alqindiirsyam 3 maanden geleden
bovenliggende
commit
55fd2c5739
31 gewijzigde bestanden met toevoegingen van 568 en 215 verwijderingen
  1. BIN
      .DS_Store
  2. 4 4
      AppBuilder/AppBuilder.xcodeproj/project.pbxproj
  3. 5 0
      AppBuilder/AppBuilder/ViewController.swift
  4. BIN
      ExampleCode/.DS_Store
  5. 21 0
      NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community.imageset/Contents.json
  6. BIN
      NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community.imageset/pb_community.png
  7. 21 0
      NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_shadow.imageset/Contents.json
  8. BIN
      NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_shadow.imageset/pb_community_shadow.png
  9. 21 0
      NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_social.imageset/Contents.json
  10. BIN
      NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_social.imageset/pb_community_social.png
  11. 21 0
      NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_social_new.imageset/Contents.json
  12. BIN
      NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_social_new.imageset/pb_community_social_new.png
  13. 47 47
      NexilisLite/NexilisLite/Resource/Palio.storyboard
  14. 109 25
      NexilisLite/NexilisLite/Source/APIS.swift
  15. 9 3
      NexilisLite/NexilisLite/Source/Extension.swift
  16. 3 1
      NexilisLite/NexilisLite/Source/InquiryThread.swift
  17. 25 0
      NexilisLite/NexilisLite/Source/Model/CommunityModel.swift
  18. 3 3
      NexilisLite/NexilisLite/Source/Nexilis.swift
  19. 6 4
      NexilisLite/NexilisLite/Source/OutgoingThread.swift
  20. 2 4
      NexilisLite/NexilisLite/Source/View/Call/CreateConferenceCallController.swift
  21. 26 35
      NexilisLite/NexilisLite/Source/View/Call/QmeraAudioViewController.swift
  22. 28 38
      NexilisLite/NexilisLite/Source/View/Call/QmeraVideoViewController.swift
  23. 157 0
      NexilisLite/NexilisLite/Source/View/Chat/CommunityList.swift
  24. 16 17
      NexilisLite/NexilisLite/Source/View/Chat/EditorGroup.swift
  25. 11 18
      NexilisLite/NexilisLite/Source/View/Chat/EditorPersonal.swift
  26. 1 2
      NexilisLite/NexilisLite/Source/View/Chat/EditorStarMessages.swift
  27. 8 1
      NexilisLite/NexilisLite/Source/View/Control/GroupDescViewController.swift
  28. 8 6
      NexilisLite/NexilisLite/Source/View/Control/GroupDetailViewController.swift
  29. 13 1
      NexilisLite/NexilisLite/Source/View/Control/GroupMemberViewController.swift
  30. 1 2
      NexilisLite/NexilisLite/Source/View/Streaming/CreateSeminarViewController.swift
  31. 2 4
      NexilisLite/NexilisLite/Source/View/Streaming/QmeraCreateStreamingViewController.swift

BIN
.DS_Store


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

@@ -560,7 +560,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 5.0.34;
+				MARKETING_VERSION = 5.0.35;
 				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.34;
+				MARKETING_VERSION = 5.0.35;
 				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.34;
+				MARKETING_VERSION = 5.0.35;
 				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.34;
+				MARKETING_VERSION = 5.0.35;
 				OTHER_CFLAGS = "-fstack-protector-strong";
 				PRODUCT_BUNDLE_IDENTIFIER = io.nexilis.appbuilder.AppBuilderShare;
 				PRODUCT_NAME = "$(TARGET_NAME)";

+ 5 - 0
AppBuilder/AppBuilder/ViewController.swift

@@ -36,6 +36,7 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
     var fourthTab : FourthTabViewController?
     var callTab : UINavigationController?
     var chatWATab : UINavigationController?
+    var communityTab : UINavigationController?
     let emptyTab = EmptyTabViewController()
     public static var isTab1 = true
     public static var isTab2 = false
@@ -96,6 +97,7 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
         fourthTab = storyboard?.instantiateViewController(withIdentifier: "fourthTabVC") as? FourthTabViewController
         callTab = UINavigationController(rootViewController: CallLogVC())
         chatWATab = UINavigationController(rootViewController: ChatWALikeVC())
+        communityTab = UINavigationController(rootViewController: CommunityList())
         
         self.delegate = self
         
@@ -105,6 +107,7 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
         fourthTab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_4_icon")!.withTintColor(.white) : UIImage(named: "tab_4_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_4_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
         callTab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_6_icon")!.withTintColor(.white) : UIImage(named: "tab_6_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_6_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
         chatWATab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_2_icon")!.withTintColor(.white) : UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
+        communityTab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_2_icon")!.withTintColor(.white) : UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
         var i = 0
         var j = 0
         while j < customTab.count {
@@ -124,6 +127,8 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
                     tabs.append(fourthTab!)
                 case "6":
                     tabs.append(callTab!)
+                case "16":
+                    tabs.append(communityTab!)
                 case "18":
                     tabs.append(chatWATab!)
                 default:

BIN
ExampleCode/.DS_Store


+ 21 - 0
NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "pb_community.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community.imageset/pb_community.png


+ 21 - 0
NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_shadow.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "pb_community_shadow.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_shadow.imageset/pb_community_shadow.png


+ 21 - 0
NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_social.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "pb_community_social.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_social.imageset/pb_community_social.png


+ 21 - 0
NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_social_new.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "pb_community_social_new.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
NexilisLite/NexilisLite/Resource/Assets.xcassets/pb_community_social_new.imageset/pb_community_social_new.png


+ 47 - 47
NexilisLite/NexilisLite/Resource/Palio.storyboard

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
         <capability name="Image references" minToolsVersion="12.0"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
@@ -19,7 +19,7 @@
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="QWa-3f-uCc">
-                                <rect key="frame" x="0.0" y="48" width="414" height="814"/>
+                                <rect key="frame" x="0.0" y="96" width="414" height="732"/>
                                 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <prototypes>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="cell" rowHeight="60" id="IAB-7H-Ah2" customClass="ContactCallCell" customModule="NexilisLite" customModuleProvider="target">
@@ -124,13 +124,13 @@
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ei8-yA-DhU">
-                                <rect key="frame" x="166" y="68" width="82" height="38.5"/>
+                                <rect key="frame" x="166" y="116" width="82" height="38.5"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="32"/>
                                 <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <nil key="highlightedColor"/>
                             </label>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Status" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uQZ-6c-vO9">
-                                <rect key="frame" x="182.5" y="126.5" width="49" height="20.5"/>
+                                <rect key="frame" x="182.5" y="174.5" width="49" height="20.5"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                 <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <nil key="highlightedColor"/>
@@ -145,7 +145,7 @@
                                 </constraints>
                             </imageView>
                             <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="aW7-4Q-0ED">
-                                <rect key="frame" x="87" y="742" width="240" height="60"/>
+                                <rect key="frame" x="87" y="708" width="240" height="60"/>
                                 <subviews>
                                     <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1Xe-lm-teG">
                                         <rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
@@ -1021,46 +1021,46 @@
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="amR-gf-O8n">
-                                <rect key="frame" x="40" y="58" width="334" height="2"/>
+                                <rect key="frame" x="40" y="106" width="334" height="2"/>
                                 <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="2" id="lQU-R4-eCU"/>
                                 </constraints>
                             </view>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Please enter your desired Username and Password" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nim-58-zjc">
-                                <rect key="frame" x="20" y="80" width="374" height="17"/>
+                                <rect key="frame" x="20" y="128" width="374" height="17"/>
                                 <color key="tintColor" systemColor="tintColor"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <color key="textColor" systemColor="systemGrayColor"/>
                                 <nil key="highlightedColor"/>
                             </label>
                             <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Username" textAlignment="natural" minimumFontSize="14" translatesAutoresizingMaskIntoConstraints="NO" id="XNI-ec-RQS">
-                                <rect key="frame" x="20" y="117" width="374" height="34"/>
+                                <rect key="frame" x="20" y="165" width="374" height="34"/>
                                 <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Hor-5y-mXt" customClass="PasswordTextField" customModule="NexilisLite" customModuleProvider="target">
-                                <rect key="frame" x="20" y="161" width="374" height="34"/>
+                                <rect key="frame" x="20" y="209" width="374" height="34"/>
                                 <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ytt-6A-LrS">
-                                <rect key="frame" x="358" y="168" width="26" height="22"/>
+                                <rect key="frame" x="358" y="216" width="26" height="22"/>
                                 <color key="tintColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                 <state key="normal" image="eye.fill" catalog="system"/>
                             </button>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Or do you have an account" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6YT-EA-rdk">
-                                <rect key="frame" x="20" y="215" width="374" height="17"/>
+                                <rect key="frame" x="20" y="263" width="374" height="17"/>
                                 <color key="tintColor" systemColor="tintColor"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <color key="textColor" systemColor="systemGrayColor"/>
                                 <nil key="highlightedColor"/>
                             </label>
                             <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="r6G-Iy-52F">
-                                <rect key="frame" x="176.5" y="240" width="61" height="25"/>
+                                <rect key="frame" x="176.5" y="288" width="61" height="25"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="25" id="iUn-3A-TRE"/>
                                 </constraints>
@@ -1118,39 +1118,39 @@
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kTB-1V-x5Q">
-                                <rect key="frame" x="40" y="226" width="334" height="2"/>
+                                <rect key="frame" x="40" y="274" width="334" height="2"/>
                                 <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="2" id="fjW-7f-3fX"/>
                                 </constraints>
                             </view>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="pb_cd_person" translatesAutoresizingMaskIntoConstraints="NO" id="QJj-ZS-JXF">
-                                <rect key="frame" x="87" y="88" width="240" height="128"/>
+                                <rect key="frame" x="87" y="136" width="240" height="128"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="128" id="EbJ-oL-HS6"/>
                                     <constraint firstAttribute="width" constant="240" id="xfn-bE-JX9"/>
                                 </constraints>
                             </imageView>
                             <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Nickname" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="1fG-j6-8fG">
-                                <rect key="frame" x="20" y="291.5" width="374" height="34"/>
+                                <rect key="frame" x="20" y="339.5" width="374" height="34"/>
                                 <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="8GQ-Mu-dYz" customClass="PasswordTextField" customModule="NexilisLite" customModuleProvider="target">
-                                <rect key="frame" x="20" y="335.5" width="374" height="34"/>
+                                <rect key="frame" x="20" y="383.5" width="374" height="34"/>
                                 <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="X96-Lm-m7m">
-                                <rect key="frame" x="357" y="341.5" width="26" height="22"/>
+                                <rect key="frame" x="357" y="389.5" width="26" height="22"/>
                                 <color key="tintColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                 <state key="normal" image="eye.fill" catalog="system"/>
                             </button>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Please enter your registered nickname or email address to Sign-In" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rgo-tO-vXt">
-                                <rect key="frame" x="40" y="248" width="334" height="33.5"/>
+                                <rect key="frame" x="40" y="296" width="334" height="33.5"/>
                                 <color key="tintColor" systemColor="tintColor"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <color key="textColor" systemColor="systemGrayColor"/>
@@ -1198,32 +1198,32 @@
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Change password to keep your account secure" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yqd-uF-xRd">
-                                <rect key="frame" x="40" y="88" width="334" height="17"/>
+                                <rect key="frame" x="40" y="136" width="334" height="17"/>
                                 <color key="tintColor" systemColor="tintColor"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <color key="textColor" systemColor="systemGrayColor"/>
                                 <nil key="highlightedColor"/>
                             </label>
                             <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Old password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="g7J-Td-biq" customClass="PasswordTextField" customModule="NexilisLite" customModuleProvider="target">
-                                <rect key="frame" x="20" y="125" width="374" height="34"/>
+                                <rect key="frame" x="20" y="173" width="374" height="34"/>
                                 <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="C5k-R9-1NU">
-                                <rect key="frame" x="357" y="131" width="26" height="22"/>
+                                <rect key="frame" x="357" y="179" width="26" height="22"/>
                                 <color key="tintColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                 <state key="normal" image="eye.fill" catalog="system"/>
                             </button>
                             <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="New password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="bDv-aU-6EW" customClass="PasswordTextField" customModule="NexilisLite" customModuleProvider="target">
-                                <rect key="frame" x="20" y="169" width="374" height="34"/>
+                                <rect key="frame" x="20" y="217" width="374" height="34"/>
                                 <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ZZQ-tO-BPg">
-                                <rect key="frame" x="357" y="175" width="26" height="22"/>
+                                <rect key="frame" x="357" y="223" width="26" height="22"/>
                                 <color key="tintColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                 <state key="normal" image="eye.fill" catalog="system"/>
@@ -1562,7 +1562,7 @@
                                 </constraints>
                             </view>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="nGr-Yc-eYs">
-                                <rect key="frame" x="284" y="58" width="120" height="160"/>
+                                <rect key="frame" x="284" y="106" width="120" height="160"/>
                                 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="160" id="2De-wS-ZKZ"/>
@@ -1589,13 +1589,13 @@
                                 <state key="normal" image="phone.down.fill" catalog="system"/>
                             </button>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Outgoing Video Call" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XYc-LN-m7Y">
-                                <rect key="frame" x="131" y="58" width="152" height="21"/>
+                                <rect key="frame" x="131" y="106" width="152" height="21"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                 <nil key="textColor"/>
                                 <nil key="highlightedColor"/>
                             </label>
                             <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="fl4-q1-mqH">
-                                <rect key="frame" x="284" y="218" width="120" height="578"/>
+                                <rect key="frame" x="284" y="266" width="120" height="530"/>
                                 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="120" id="sxa-uT-dTO"/>
@@ -1769,10 +1769,10 @@
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="XbX-90-NVU">
-                                <rect key="frame" x="0.0" y="48" width="414" height="814"/>
+                                <rect key="frame" x="0.0" y="96" width="414" height="732"/>
                             </imageView>
                             <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dtn-XY-Yjx">
-                                <rect key="frame" x="369" y="68" width="25" height="22"/>
+                                <rect key="frame" x="369" y="116" width="25" height="22"/>
                                 <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <state key="normal" image="arrow.triangle.2.circlepath.camera.fill" catalog="system"/>
                             </button>
@@ -1783,7 +1783,7 @@
                                 <nil key="highlightedColor"/>
                             </label>
                             <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VhD-Mu-Dj1">
-                                <rect key="frame" x="20" y="60" width="46" height="34"/>
+                                <rect key="frame" x="20" y="108" width="46" height="34"/>
                                 <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <state key="normal" title="Close"/>
                                 <connections>
@@ -1826,7 +1826,7 @@
                 <navigationController storyboardIdentifier="streamingNav" automaticallyAdjustsScrollViewInsets="NO" id="dEs-fL-JC4" sceneMemberID="viewController">
                     <toolbarItems/>
                     <navigationBar key="navigationBar" contentMode="scaleToFill" id="VMx-jK-5xn">
-                        <rect key="frame" x="0.0" y="48" width="414" height="44"/>
+                        <rect key="frame" x="0.0" y="96" width="414" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </navigationBar>
                     <nil name="viewControllers"/>
@@ -1844,7 +1844,7 @@
                 <navigationController storyboardIdentifier="settingNav" automaticallyAdjustsScrollViewInsets="NO" id="jUQ-Vs-n9A" sceneMemberID="viewController">
                     <toolbarItems/>
                     <navigationBar key="navigationBar" contentMode="scaleToFill" id="5pa-h0-hNP">
-                        <rect key="frame" x="0.0" y="48" width="414" height="44"/>
+                        <rect key="frame" x="0.0" y="96" width="414" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </navigationBar>
                     <nil name="viewControllers"/>
@@ -1862,7 +1862,7 @@
                 <navigationController storyboardIdentifier="contactChatNav" automaticallyAdjustsScrollViewInsets="NO" id="fN9-fa-00b" sceneMemberID="viewController">
                     <toolbarItems/>
                     <navigationBar key="navigationBar" contentMode="scaleToFill" id="cuo-kr-hfM">
-                        <rect key="frame" x="0.0" y="48" width="414" height="44"/>
+                        <rect key="frame" x="0.0" y="96" width="414" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </navigationBar>
                     <nil name="viewControllers"/>
@@ -1957,7 +1957,7 @@
                 <navigationController storyboardIdentifier="addFriendNav" automaticallyAdjustsScrollViewInsets="NO" id="7Wn-tA-a36" sceneMemberID="viewController">
                     <toolbarItems/>
                     <navigationBar key="navigationBar" contentMode="scaleToFill" id="BPo-Ji-MTR">
-                        <rect key="frame" x="0.0" y="48" width="414" height="44"/>
+                        <rect key="frame" x="0.0" y="96" width="414" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </navigationBar>
                     <nil name="viewControllers"/>
@@ -1991,7 +1991,7 @@
                 <navigationController storyboardIdentifier="createGroupNav" automaticallyAdjustsScrollViewInsets="NO" id="gGk-tB-HXd" sceneMemberID="viewController">
                     <toolbarItems/>
                     <navigationBar key="navigationBar" contentMode="scaleToFill" id="AVS-vC-GWW">
-                        <rect key="frame" x="0.0" y="48" width="414" height="44"/>
+                        <rect key="frame" x="0.0" y="96" width="414" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </navigationBar>
                     <nil name="viewControllers"/>
@@ -2483,7 +2483,7 @@
             <objects>
                 <navigationController storyboardIdentifier="broadcastNav" title="Broadcast Navigation Controller" modalPresentationStyle="fullScreen" id="NH6-7u-Fec" sceneMemberID="viewController">
                     <navigationBar key="navigationBar" contentMode="scaleToFill" id="56D-ii-ei5">
-                        <rect key="frame" x="0.0" y="48" width="414" height="44"/>
+                        <rect key="frame" x="0.0" y="96" width="414" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </navigationBar>
                     <connections>
@@ -3123,46 +3123,46 @@
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Q4b-oV-sHi">
-                                <rect key="frame" x="40" y="226" width="334" height="2"/>
+                                <rect key="frame" x="40" y="274" width="334" height="2"/>
                                 <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="2" id="0as-Zh-jRl"/>
                                 </constraints>
                             </view>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="pb_cd_person" translatesAutoresizingMaskIntoConstraints="NO" id="uMG-xq-HNf">
-                                <rect key="frame" x="87" y="88" width="240" height="128"/>
+                                <rect key="frame" x="87" y="136" width="240" height="128"/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="240" id="PBy-BT-r38"/>
                                     <constraint firstAttribute="height" constant="128" id="sJy-An-egS"/>
                                 </constraints>
                             </imageView>
                             <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Nickname" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="OGC-mO-8T0">
-                                <rect key="frame" x="20" y="291.5" width="374" height="34"/>
+                                <rect key="frame" x="20" y="339.5" width="374" height="34"/>
                                 <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="5jw-G4-iGy" customClass="PasswordTextField" customModule="NexilisLite" customModuleProvider="target">
-                                <rect key="frame" x="20" y="335.5" width="374" height="34"/>
+                                <rect key="frame" x="20" y="383.5" width="374" height="34"/>
                                 <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <textInputTraits key="textInputTraits"/>
                             </textField>
                             <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SAR-sw-Oq9">
-                                <rect key="frame" x="357" y="341.5" width="26" height="22"/>
+                                <rect key="frame" x="357" y="389.5" width="26" height="22"/>
                                 <color key="tintColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                 <state key="normal" image="eye.fill" catalog="system"/>
                             </button>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Please enter your registered nickname or email address to Sign-In" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kwq-ci-Qkk">
-                                <rect key="frame" x="40" y="248" width="334" height="33.5"/>
+                                <rect key="frame" x="40" y="296" width="334" height="33.5"/>
                                 <color key="tintColor" systemColor="tintColor"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <color key="textColor" systemColor="systemGrayColor"/>
                                 <nil key="highlightedColor"/>
                             </label>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="icL-yb-DMM">
-                                <rect key="frame" x="40" y="399.5" width="334" height="125.5"/>
+                                <rect key="frame" x="40" y="447.5" width="334" height="125.5"/>
                                 <string key="text">Disclaimer : Signing up with a nickname provides full privacy since %app_name% does not know your identity, which is usually linked to your email account or mobile number. However, if you use a nickname, we will not be able to reset your password if you lose or forget it, so please keep your password secure.</string>
                                 <fontDescription key="fontDescription" type="system" pointSize="15"/>
                                 <color key="textColor" systemColor="systemGrayColor"/>
@@ -3214,7 +3214,7 @@
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="w21-oX-k1B">
-                                <rect key="frame" x="0.0" y="92" width="414" height="770"/>
+                                <rect key="frame" x="0.0" y="140" width="414" height="688"/>
                                 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <prototypes>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="seminarListCell" rowHeight="60" id="fKY-DZ-Ct6" customClass="SeminarListCell" customModule="NexilisLite" customModuleProvider="target">
@@ -3341,7 +3341,7 @@
                 <navigationController storyboardIdentifier="seminarListNav" automaticallyAdjustsScrollViewInsets="NO" id="fLe-EJ-GeO" sceneMemberID="viewController">
                     <toolbarItems/>
                     <navigationBar key="navigationBar" contentMode="scaleToFill" id="ESA-C7-dc0">
-                        <rect key="frame" x="0.0" y="48" width="414" height="44"/>
+                        <rect key="frame" x="0.0" y="96" width="414" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </navigationBar>
                     <nil name="viewControllers"/>
@@ -3362,11 +3362,11 @@
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" indicatorStyle="black" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="PQ7-32-KB5">
-                                <rect key="frame" x="0.0" y="0.0" width="414" height="792"/>
+                                <rect key="frame" x="0.0" y="0.0" width="414" height="758"/>
                                 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                             </tableView>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="iIp-8A-V60">
-                                <rect key="frame" x="0.0" y="802" width="414" height="60"/>
+                                <rect key="frame" x="0.0" y="768" width="414" height="60"/>
                                 <subviews>
                                     <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="gDW-3i-WIf" customClass="CustomTextView" customModule="NexilisLite" customModuleProvider="target">
                                         <rect key="frame" x="20" y="0.0" width="374" height="40"/>

+ 109 - 25
NexilisLite/NexilisLite/Source/APIS.swift

@@ -469,6 +469,76 @@ public class APIS: NSObject {
         }
     }
     
+    public static func createCommunity() {
+        let isChangeProfile = Utils.getSetProfile()
+        if !isChangeProfile {
+            APIS.showChangeProfile()
+            return
+        }
+        let startedNewCommunity = UIViewController()
+        if let viewComm = startedNewCommunity.view {
+            viewComm.backgroundColor = .black.withAlphaComponent(0.1)
+            
+            let containerView = UIView()
+            viewComm.addSubview(containerView)
+            containerView.anchor(left: viewComm.leftAnchor, bottom: viewComm.bottomAnchor, right: viewComm.rightAnchor, minHeight: 40)
+            containerView.backgroundColor = .white
+            containerView.layer.cornerRadius = 15
+            containerView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
+            
+            let closeButton = UIButton(type: .close)
+            containerView.addSubview(closeButton)
+            closeButton.anchor(top: containerView.topAnchor, right: containerView.rightAnchor, paddingTop: 10, paddingRight: 10, width: 30, height: 30)
+            closeButton.layer.cornerRadius = 15
+            closeButton.clipsToBounds = true
+            closeButton.backgroundColor = .lightGray.withAlphaComponent(0.1)
+            let config = UIImage.SymbolConfiguration(pointSize: 18, weight: .semibold)
+            closeButton.setImage(UIImage(systemName: "xmark", withConfiguration: config), for: .normal)
+            closeButton.actionHandle(controlEvents: .touchUpInside,
+                                     ForAction:{() -> Void in
+                startedNewCommunity.dismiss(animated: true)
+            })
+            
+            let imageComm = UIImageView(image: UIImage(named: "pb_community_social", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!)
+            containerView.addSubview(imageComm)
+            imageComm.anchor(top: closeButton.bottomAnchor, paddingTop: -40, centerX: containerView.centerXAnchor, width: 380, height: 250)
+            
+            let titleComm = UILabel()
+            containerView.addSubview(titleComm)
+            titleComm.anchor(top: imageComm.bottomAnchor, left: containerView.leftAnchor, right: containerView.rightAnchor, paddingLeft: 20, paddingRight: 20)
+            titleComm.font = .boldSystemFont(ofSize: 30)
+            titleComm.textColor = .label
+            titleComm.numberOfLines = 0
+            titleComm.textAlignment = .center
+            titleComm.text = "Create a new community".localized()
+            
+            let descComm = UILabel()
+            containerView.addSubview(descComm)
+            descComm.anchor(top: titleComm.bottomAnchor, left: containerView.leftAnchor, right: containerView.rightAnchor, paddingTop: 8, paddingLeft: 20, paddingRight: 20)
+            descComm.font = .systemFont(ofSize: 16)
+            descComm.textColor = .label
+            descComm.numberOfLines = 0
+            descComm.textAlignment = .center
+            descComm.text = "Bring together a neighborhood, school or more. Create topic-based groups for members, and easily send them admin anouncements.".localized()
+            
+            let buttonComm = UIButton(type: .custom)
+            containerView.addSubview(buttonComm)
+            buttonComm.anchor(top: descComm.bottomAnchor, left: containerView.leftAnchor, bottom: containerView.bottomAnchor, right: containerView.rightAnchor, paddingTop: 20, paddingLeft: 20, paddingBottom: 20, paddingRight: 20, height: 45)
+            buttonComm.backgroundColor = .whatsappGreenColor
+            buttonComm.layer.cornerRadius = 15
+            buttonComm.clipsToBounds = true
+            buttonComm.setTitle("Get started".localized(), for: .normal)
+            buttonComm.setTitleColor(.white, for: .normal)
+            buttonComm.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
+        }
+        startedNewCommunity.modalPresentationStyle = .overCurrentContext
+        if UIApplication.shared.visibleViewController?.navigationController != nil {
+            UIApplication.shared.visibleViewController?.navigationController?.present(startedNewCommunity, animated: true, completion: nil)
+        } else {
+            UIApplication.shared.visibleViewController?.present(startedNewCommunity, animated: true, completion: nil)
+        }
+    }
+    
     public static func openCreateGroup() {
         let isChangeProfile = Utils.getSetProfile()
         if !isChangeProfile {
@@ -1363,7 +1433,6 @@ public class APIS: NSObject {
                                 navigationC.popViewController(animated: false)
                             }
                         }
-                        print("HUHU \(f_pin) \(l_pin) \(message_scope_id)")
                         showEditorOrCallFromAPN(pin, message_scope_id == "4" ? "1" : "0", "CL01")
                     }
                 }
@@ -1556,9 +1625,10 @@ public class APIS: NSObject {
             }
             if let vers = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.checkVersion()) {
                 let dataVersion = vers.getBody(key: CoreMessage_TMessageKey.DATA)
+                let type = vers.getBody(key: CoreMessage_TMessageKey.TYPE)
                 if dataVersion != "1" {
                     DispatchQueue.main.async {
-                        showExpiredVersion()
+                        showExpiredVersion(mandatory: type == "1")
                     }
                 }
             }
@@ -1617,14 +1687,16 @@ public class APIS: NSObject {
     }
     
     private static var alertControllerExpired: LibAlertController!
-    public static func showExpiredVersion() {
+    public static func showExpiredVersion(mandatory: Bool) {
         func showAl() {
             alertControllerExpired = LibAlertController(
                 title: "Update Available".localized(),
                 message: "A new version is now available. Please update to the latest version to enjoy new features and important improvements.".localized(),
                 preferredStyle: .alert
             )
-            alertControllerExpired.addAction(UIAlertAction(title: "Later".localized(), style: .cancel, handler: nil))
+            if !mandatory {
+                alertControllerExpired.addAction(UIAlertAction(title: "Later".localized(), style: .cancel, handler: nil))
+            }
             
             alertControllerExpired.addAction(UIAlertAction(title: "Update Now".localized(), style: .default, handler: { _ in
                 if APIS.appNm == "OneApp" {
@@ -1803,13 +1875,17 @@ public class APIS: NSObject {
                                            dataTemp[columnName] = value
                                            if let imageString = dataTemp[columnName] as? String, !imageString.isEmpty {
                                                do {
-                                                   let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
-                                                   let file = documentDir.appendingPathComponent(imageString)
-                                                   if FileManager().fileExists(atPath: file.path) {
-                                                       if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
-                                                           let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
-                                                           if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
-                                                               try? FileManager.default.copyItem(at: file, to: sharedFileURL)
+                                                   if FileEncryption.shared.isSecureExists(filename: imageString) {
+                                                       if var data = try FileEncryption.shared.readSecure(filename: imageString) {
+                                                           let dataDecrypt = FileEncryption.shared.decryptFileFromServer(data: data)
+                                                           if dataDecrypt != nil {
+                                                               data = dataDecrypt!
+                                                           }
+                                                           if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
+                                                               let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
+                                                               if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
+                                                                   try? data.write(to: sharedFileURL)
+                                                               }
                                                            }
                                                        }
                                                    }
@@ -1840,13 +1916,17 @@ public class APIS: NSObject {
                                             dataTemp[columnName] = value
                                             if let imageString = dataTemp[columnName] as? String, !imageString.isEmpty {
                                                 do {
-                                                    let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
-                                                    let file = documentDir.appendingPathComponent(imageString)
-                                                    if FileManager().fileExists(atPath: file.path) {
-                                                        if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
-                                                            let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
-                                                            if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
-                                                                try? FileManager.default.copyItem(at: file, to: sharedFileURL)
+                                                    if FileEncryption.shared.isSecureExists(filename: imageString) {
+                                                        if var data = try FileEncryption.shared.readSecure(filename: imageString) {
+                                                            let dataDecrypt = FileEncryption.shared.decryptFileFromServer(data: data)
+                                                            if dataDecrypt != nil {
+                                                                data = dataDecrypt!
+                                                            }
+                                                            if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
+                                                                let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
+                                                                if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
+                                                                    try? data.write(to: sharedFileURL)
+                                                                }
                                                             }
                                                         }
                                                     }
@@ -1877,13 +1957,17 @@ public class APIS: NSObject {
                                                     dataTempTopic[columnName] = "\(value)".isEmpty ? image_group : "\(value)"
                                                     if let imageString = dataTempTopic[columnName] as? String, !imageString.isEmpty {
                                                         do {
-                                                            let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
-                                                            let file = documentDir.appendingPathComponent(imageString)
-                                                            if FileManager().fileExists(atPath: file.path) {
-                                                                if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
-                                                                    let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
-                                                                    if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
-                                                                        try? FileManager.default.copyItem(at: file, to: sharedFileURL)
+                                                            if FileEncryption.shared.isSecureExists(filename: imageString) {
+                                                                if var data = try FileEncryption.shared.readSecure(filename: imageString) {
+                                                                    let dataDecrypt = FileEncryption.shared.decryptFileFromServer(data: data)
+                                                                    if dataDecrypt != nil {
+                                                                        data = dataDecrypt!
+                                                                    }
+                                                                    if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
+                                                                        let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
+                                                                        if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
+                                                                            try? data.write(to: sharedFileURL)
+                                                                        }
                                                                     }
                                                                 }
                                                             }

+ 9 - 3
NexilisLite/NexilisLite/Source/Extension.swift

@@ -573,7 +573,7 @@ extension UIColor {
     }
     
     public static var mentionColor: UIColor {
-        return UIApplication.shared.visibleViewController?.traitCollection.userInterfaceStyle == .dark ? renderColor(hex: "#f6fcae") : renderColor(hex: "#22C55E")
+        return UIApplication.shared.visibleViewController?.traitCollection.userInterfaceStyle == .dark ? renderColor(hex: "#f6fcae") : renderColor(hex: "#FFA500")
     }
     
     public static var blueBubbleColor: UIColor {
@@ -604,7 +604,7 @@ extension UIColor {
     }
     
     public static var whatsappGreenColor: UIColor {
-        return renderColor(hex: "#25D366")
+        return renderColor(hex: "#20A961")
     }
     
     public static var whatsappGreenTitleColor: UIColor {
@@ -871,7 +871,7 @@ extension String {
                         if fullRange.lowerBound == ((Int(listMentionInTextField[indexLM].ex_block ?? "0") ?? 0) - fullNameText.count){
                             text.addAttribute(.foregroundColor, value: UIColor.gray, range: NSRange(location: fullRange.lowerBound, length: 1))
                             text.addAttribute(.foregroundColor, value: UIColor.mentionColor, range: NSRange(location: range.lowerBound, length: fullNameText.count))
-                            text.addAttribute(.font, value: UIFont.systemFont(ofSize: 12 + String.offset(), weight: .medium), range: NSRange(location: fullRange.lowerBound, length: fullNameText.count))
+                            text.addAttribute(.font, value: UIFont.systemFont(ofSize: 12 + String.offset(), weight: .medium), range: NSRange(location: fullRange.lowerBound, length: fullNameText.count + 1))
                         }
                     }
                 }
@@ -1502,3 +1502,9 @@ extension NSAttributedString {
         try self.init(data: data, options: options, documentAttributes: nil)
     }
 }
+
+extension Collection {
+    subscript(safe index: Index) -> Element? {
+        return indices.contains(index) ? self[index] : nil
+    }
+}

+ 3 - 1
NexilisLite/NexilisLite/Source/InquiryThread.swift

@@ -102,7 +102,9 @@ class InquiryThread {
     func getQueue() -> TMessage {
         while queue.isEmpty || queue.count == 0 {
             //print("QUEUE INQUIRY.wait")
-            semaphore.wait()
+//            DispatchQueue.global(qos: .background).async {
+                self.semaphore.wait()
+//            }
         }
         return queue.remove(at: 0)
     }

+ 25 - 0
NexilisLite/NexilisLite/Source/Model/CommunityModel.swift

@@ -0,0 +1,25 @@
+//
+//  CommunityModel.swift
+//  Pods
+//
+//  Created by Qindi on 08/05/25.
+//
+
+public class CommunityModel: Model {
+    public var id: String
+    public var name: String
+    public var image: String
+    public var description: String
+    
+    public init(id: String, name: String, image: String) {
+        self.id = id
+        self.name = name
+        self.image = image
+        self.description = ""
+    }
+    
+    public static func == (lhs: CommunityModel, rhs: CommunityModel) -> Bool {
+        return lhs.id == rhs.id
+    }
+    
+}

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

@@ -18,7 +18,7 @@ import SDWebImage
 import CryptoKit
 
 public class Nexilis: NSObject {
-    public static var cpaasVersion = "5.0.34"
+    public static var cpaasVersion = "5.0.35"
     public static var sAPIKey = ""
     
     public static var ADDRESS = ""
@@ -128,7 +128,7 @@ public class Nexilis: NSObject {
     private static var ringbacktonePlayer: AVAudioPlayer?
     private static var busyPlayer: AVAudioPlayer?
     static var sharedAudioPlayer: AVAudioPlayer?
-    static var firstCall = true
+//    static var firstCall = true
     
     private func createDelegate() {
         //print("createDelegate...")
@@ -860,7 +860,7 @@ public class Nexilis: NSObject {
                 let url = response?.url,
                 let httpResponse = response as? HTTPURLResponse,
                 let fields = httpResponse.allHeaderFields as? [String: String] else {
-                print("MASUK SINI0 \(url)")
+//                print("MASUK SINI0 \(url)")
                 semaphore.signal()
                 return
             }

+ 6 - 4
NexilisLite/NexilisLite/Source/OutgoingThread.swift

@@ -102,7 +102,9 @@ class OutgoingThread {
     func getQueue() -> TMessage {
         while queue.isEmpty || queue.count == 0 {
             //print("QUEUE.wait")
-            semaphore.wait()
+//            DispatchQueue.global(qos: .background).async {
+                self.semaphore.wait()
+//            }
         }
         return queue.remove(at: 0)
     }
@@ -168,10 +170,10 @@ class OutgoingThread {
                         do {
                             do{
                                 let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
-                                let fileURL = documentsDirectory.appendingPathComponent(fileName)
-                                try FileEncryption.shared.writeSecure(filename: fileName, data: Data(contentsOf: fileURL))
+                                let fileURL = documentsDirectory.appendingPathComponent(CoreMessage_TMessageKey.THUMB_ID)
+                                try FileEncryption.shared.writeSecure(filename: CoreMessage_TMessageKey.THUMB_ID, data: Data(contentsOf: fileURL))
                                 try FileManager.default.removeItem(atPath: fileURL.path)
-                                if var data = try FileEncryption.shared.readSecure(filename: fileName) {
+                                if var data = try FileEncryption.shared.readSecure(filename: CoreMessage_TMessageKey.THUMB_ID) {
                                     let dataDecrypt = FileEncryption.shared.decryptFileFromServer(data: data)
                                     if dataDecrypt != nil {
                                         data = dataDecrypt!

+ 2 - 4
NexilisLite/NexilisLite/Source/View/Call/CreateConferenceCallController.swift

@@ -526,17 +526,15 @@ public class CreateConferenceCallController: UITableViewController {
         switch sections[indexPath.section] {
         case .users:
             if (editingStyle == .delete) {
-                tableView.beginUpdates()
                 users.remove(at: indexPath.row - 1)
                 tableView.deleteRows(at: [indexPath], with: .automatic)
-                tableView.endUpdates()
+                tableView.reloadData()
             }
         case .groups:
             if (editingStyle == .delete) {
-                tableView.beginUpdates()
                 groups.remove(at: indexPath.row - 1)
                 tableView.deleteRows(at: [indexPath], with: .automatic)
-                tableView.endUpdates()
+                tableView.reloadData()
             }
         default:
             return

+ 26 - 35
NexilisLite/NexilisLite/Source/View/Call/QmeraAudioViewController.swift

@@ -1071,47 +1071,38 @@ class QmeraAudioViewController: UIViewController {
                     }
                 }
             } else if state == Nexilis.STREAMING_SEMINAR_ENDED { // always call turnspeaker
-//                QmeraAudioViewController.isLoop = true
-//                DispatchQueue.global(qos: .userInitiated).async {
-//                    repeat {
-//                        Thread.sleep(forTimeInterval : 1)
-//                        if (QmeraAudioViewController.isLoop && !API.bAudioEngineIsRunning()) {
-//                            API.turnSpeakerPhone(bSPon: QmeraAudioViewController.bSpeakerPhone!)
-//                        }
-//                    } while (QmeraAudioViewController.isLoop)
-//                }
-//                DispatchQueue.main.async { [self] in
-//                    QmeraAudioViewController.bSpeakerPhone = true
-//                    self.tempSpeaker = true
-//                    didSpeaker(sender: nil)
-//                }
-                if #available(iOS 15.0, *), Nexilis.firstCall {
-                    DispatchQueue.main.async {
-                        self.speaker.isEnabled = false
-                    }
-                    QmeraAudioViewController.isLoop = true
-                    DispatchQueue.global(qos: .userInitiated).async {
-                        var countLoop = 0
-                        repeat {
-                            Thread.sleep(forTimeInterval : 0.5)
-                            if (QmeraAudioViewController.isLoop && !API.bAudioEngineIsRunning()) {
-                                API.restartAudioEngine()
-                                Nexilis.firstCall = false
-                                DispatchQueue.main.async {
+                DispatchQueue.main.async {
+                    self.speaker.isEnabled = false
+                }
+                QmeraAudioViewController.isLoop = true
+                DispatchQueue.global(qos: .userInitiated).async {
+                    var countLoop = 0
+                    repeat {
+                        Thread.sleep(forTimeInterval : 0.5)
+                        if (QmeraAudioViewController.isLoop && !API.bAudioEngineIsRunning()) {
+                            API.restartAudioEngine()
+                            DispatchQueue.main.async {
+                                if !self.speaker.isEnabled{
                                     self.speaker.isEnabled = true
+                                } else if QmeraAudioViewController.bSpeakerPhone {
+                                    do {
+                                        let audioSession = AVAudioSession.sharedInstance()
+                                        try audioSession.overrideOutputAudioPort(.speaker)
+                                    } catch {
+                                        
+                                    }
                                 }
-                                break
                             }
-                            countLoop = countLoop + 1
-                            if countLoop == 3 {
-                                Nexilis.firstCall = false
-                                DispatchQueue.main.async {
+                        }
+                        countLoop = countLoop + 1
+                        if countLoop == 3 {
+                            DispatchQueue.main.async {
+                                if !self.speaker.isEnabled{
                                     self.speaker.isEnabled = true
                                 }
-                                break
                             }
-                        } while (QmeraAudioViewController.isLoop)
-                    }
+                        }
+                    } while (QmeraAudioViewController.isLoop)
                 }
             } else if state == Nexilis.AUDIO_CALL_RINGING || (!ticketId.isEmpty && state == Nexilis.VIDEO_CALL_RINGING) {
                 if users.count == 1 && !autoAcceptAPN {

+ 28 - 38
NexilisLite/NexilisLite/Source/View/Call/QmeraVideoViewController.swift

@@ -1309,50 +1309,40 @@ class QmeraVideoViewController: UIViewController {
             }
         }
         else if state == Nexilis.STREAMING_SEMINAR_ENDED { // always call turnspeaker
-//            QmeraVideoViewController.isLoop = true
-//            DispatchQueue.global().asyncAfter(deadline: .now() + 0.5, execute: {
-//                API.adjustVolume(fValue: 10.0)
-//                self.setSpeaker()
-//                DispatchQueue.global(qos: .userInitiated).async {
-//                    repeat {
-//                        Thread.sleep(forTimeInterval : 1)
-//                        if (QmeraVideoViewController.isLoop && !API.bAudioEngineIsRunning()) {
-//                            API.turnSpeakerPhone(bSPon: QmeraVideoViewController.bSpeakerPhone!)
-//                        }
-//                    } while (QmeraVideoViewController.isLoop)
-//                }
-//            })
-            if #available(iOS 15.0, *), Nexilis.firstCall {
-                DispatchQueue.main.async {
-                    self.buttonSpeaker.isEnabled = false
-                }
-                QmeraVideoViewController.isLoop = true
-                DispatchQueue.global(qos: .userInitiated).async {
-                    var countLoop = 0
-                    repeat {
-                        Thread.sleep(forTimeInterval : 1)
-                        if (QmeraVideoViewController.isLoop && !API.bAudioEngineIsRunning()) {
-                            API.restartAudioEngine()
-                            Nexilis.firstCall = false
-                            self.setSpeaker()
-                            DispatchQueue.main.async {
+            DispatchQueue.main.async {
+                self.buttonSpeaker.isEnabled = false
+            }
+            QmeraVideoViewController.isLoop = true
+            DispatchQueue.global(qos: .userInitiated).async {
+                var countLoop = 0
+                repeat {
+                    Thread.sleep(forTimeInterval : 0.5)
+                    if (QmeraVideoViewController.isLoop && !API.bAudioEngineIsRunning()) {
+                        API.restartAudioEngine()
+                        DispatchQueue.main.async {
+                            if !self.buttonSpeaker.isEnabled{
+                                self.setSpeaker()
                                 self.buttonSpeaker.isEnabled = true
+                            } else if QmeraVideoViewController.bSpeakerPhone {
+                                do {
+                                    let audioSession = AVAudioSession.sharedInstance()
+                                    try audioSession.overrideOutputAudioPort(.speaker)
+                                } catch {
+                                    
+                                }
                             }
-                            break
                         }
-                        countLoop = countLoop + 1
-                        if countLoop == 5 {
-                            Nexilis.firstCall = false
-                            self.setSpeaker()
-                            DispatchQueue.main.async {
+                    }
+                    countLoop = countLoop + 1
+                    if countLoop == 3 {
+                        DispatchQueue.main.async {
+                            if !self.buttonSpeaker.isEnabled{
+                                self.setSpeaker()
                                 self.buttonSpeaker.isEnabled = true
                             }
-                            break
                         }
-                    } while (QmeraVideoViewController.isLoop)
-                }
-            } else {
-                self.setSpeaker()
+                    }
+                } while (QmeraVideoViewController.isLoop)
             }
         }
         else if (state == Nexilis.VIDEO_CALL_OFFHOOK) {

+ 157 - 0
NexilisLite/NexilisLite/Source/View/Chat/CommunityList.swift

@@ -0,0 +1,157 @@
+//
+//  CommunityTab.swift
+//  Pods
+//
+//  Created by Qindi on 07/05/25.
+//
+
+import Foundation
+import UIKit
+
+public class CommunityList: UIViewController, UITableViewDataSource, UITableViewDelegate {
+    private let tableView = UITableView(frame: .zero, style: .plain)
+    
+    private var communities: [CommunityModel] = []
+    private let containerCommEmpty = UIView()
+    
+    public override func viewDidLoad() {
+        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellCommunityList")
+        tableView.dataSource = self
+        tableView.delegate = self
+        tableView.tableFooterView = UIView()
+        tableView.sectionHeaderHeight = 0
+        tableView.sectionFooterHeight = 0
+        tableView.automaticallyAdjustsScrollIndicatorInsets = false
+        if #available(iOS 15.0, *) {
+            tableView.sectionHeaderTopPadding = 0
+        }
+        
+        setupTableView()
+        refresh()
+//        NotificationCenter.default.addObserver(self, selector: #selector(onRefreshCallLog(notification:)), name: NSNotification.Name(rawValue: "refreshCallLog"), object: nil)
+    }
+    
+    private func refresh() {
+//        getData()
+        
+        if communities.count > 0 {
+            if containerCommEmpty.isDescendant(of: view) {
+                containerCommEmpty.removeFromSuperview()
+            }
+        } else {
+            if !containerCommEmpty.isDescendant(of: view){
+                view.addSubview(containerCommEmpty)
+                containerCommEmpty.anchor(top: view.safeAreaLayoutGuide.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
+                
+                let iconComm = UIImageView(image: UIImage(named: "pb_community_social_new", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!)
+                containerCommEmpty.addSubview(iconComm)
+                iconComm.anchor(top: containerCommEmpty.topAnchor, paddingTop: -20, centerX: containerCommEmpty.centerXAnchor, width: 250, height: 250)
+                
+                let titleComm = UILabel()
+                containerCommEmpty.addSubview(titleComm)
+                titleComm.anchor(top: iconComm.bottomAnchor, left: view.leftAnchor, right: view.rightAnchor, paddingTop: -20, paddingLeft: 20, paddingRight: 20)
+                titleComm.font = .systemFont(ofSize: 20)
+                titleComm.textColor = .label
+                titleComm.numberOfLines = 0
+                titleComm.text = "Stay connected with a community".localized()
+                
+                let descComm = UILabel()
+                containerCommEmpty.addSubview(descComm)
+                descComm.anchor(top: titleComm.bottomAnchor, left: view.leftAnchor, right: view.rightAnchor, paddingTop: 8, paddingLeft: 20, paddingRight: 20)
+                descComm.font = .systemFont(ofSize: 16)
+                descComm.textColor = .gray
+                descComm.numberOfLines = 0
+                descComm.text = "Communities bring members together in topic-based groups. Any community you're added to will appear here.".localized()
+                
+                let buttonComm = UIButton(type: .custom)
+                containerCommEmpty.addSubview(buttonComm)
+                buttonComm.anchor(top: descComm.bottomAnchor, left: view.leftAnchor, right: view.rightAnchor, paddingTop: 20, paddingLeft: 20, paddingRight: 20, height: 45)
+                buttonComm.backgroundColor = .whatsappGreenColor
+                buttonComm.layer.cornerRadius = 15
+                buttonComm.clipsToBounds = true
+                buttonComm.setTitle("New Community".localized(), for: .normal)
+                buttonComm.setTitleColor(.white, for: .normal)
+                buttonComm.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
+                let config = UIImage.SymbolConfiguration(pointSize: 16, weight: .bold)
+                buttonComm.setImage(UIImage(systemName: "plus", withConfiguration: config), for: .normal)
+                buttonComm.imageView?.tintColor = .white
+                buttonComm.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 15)
+                buttonComm.addTarget(self, action: #selector(rightBarButtonTapped), for: .touchUpInside)
+            }
+        }
+        tableView.reloadData()
+    }
+    
+    private func setupTableView() {
+        view.addSubview(tableView)
+        tableView.translatesAutoresizingMaskIntoConstraints = false
+        
+        NSLayoutConstraint.activate([
+            tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
+            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
+            tableView.leftAnchor.constraint(equalTo: view.leftAnchor),
+            tableView.rightAnchor.constraint(equalTo: view.rightAnchor)
+        ])
+    }
+    
+    public override func viewWillAppear(_ animated: Bool) {
+        navigationItem.title = "Communities".localized()
+        navigationItem.hidesSearchBarWhenScrolling = true
+        tabBarController?.navigationController?.setNavigationBarHidden(true, animated: false)
+        navigationController?.navigationBar.prefersLargeTitles = true
+        navigationController?.navigationItem.largeTitleDisplayMode = .always
+        navigationController?.navigationBar.backgroundColor = .clear
+        navigationController?.navigationBar.tintColor = .black
+        navigationController?.navigationBar.overrideUserInterfaceStyle = .light
+        self.setNeedsStatusBarAppearanceUpdate()
+        let attributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: self.traitCollection.userInterfaceStyle == .dark ? .white : UIColor.black, NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 16)]
+        let largeAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: self.traitCollection.userInterfaceStyle == .dark ? .white : UIColor.black, NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 34)]
+        let appearance = UINavigationBarAppearance()
+        appearance.configureWithTransparentBackground()
+        appearance.backgroundColor = .clear
+        appearance.titleTextAttributes = attributes
+        appearance.largeTitleTextAttributes = largeAttributes
+        navigationController?.navigationBar.standardAppearance = appearance
+        navigationController?.navigationBar.scrollEdgeAppearance = appearance
+        let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.black, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
+        UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
+        
+//        let leftButton = UIButton(type: .system)
+//        let imageLeft = UIImage(systemName: "ellipsis", withConfiguration: UIImage.SymbolConfiguration(pointSize: 12, weight: .bold))
+//        leftButton.setImage(imageLeft, for: .normal)
+//        leftButton.tintColor = .black
+//        leftButton.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
+//        leftButton.layer.cornerRadius = 15
+//        leftButton.clipsToBounds = true
+//        leftButton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
+//        leftButton.addTarget(self, action: #selector(leftBarButtonTapped), for: .touchUpInside)
+//        let leftBarButtonItem = UIBarButtonItem(customView: leftButton)
+//        navigationItem.leftBarButtonItem = leftBarButtonItem
+        
+        let rightButton = UIButton(type: .system)
+        let imageRight = UIImage(systemName: "plus", withConfiguration: UIImage.SymbolConfiguration(pointSize: 12, weight: .bold))
+        rightButton.setImage(imageRight, for: .normal)
+        rightButton.tintColor = .white
+        rightButton.backgroundColor = .whatsappGreenColor
+        rightButton.layer.cornerRadius = 15
+        rightButton.clipsToBounds = true
+        rightButton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
+        rightButton.addTarget(self, action: #selector(rightBarButtonTapped), for: .touchUpInside)
+        let rightBarButtonItem = UIBarButtonItem(customView: rightButton)
+        navigationItem.rightBarButtonItem = rightBarButtonItem
+    }
+    
+    @objc func rightBarButtonTapped() {
+        APIS.createCommunity()
+    }
+    
+    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return communities.count
+    }
+    
+    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        let cell = tableView.dequeueReusableCell(withIdentifier: "cellCommunityList", for: indexPath)
+        return cell
+    }
+}
+

+ 16 - 17
NexilisLite/NexilisLite/Source/View/Chat/EditorGroup.swift

@@ -427,11 +427,11 @@ public class EditorGroup: UIViewController, CLLocationManagerDelegate {
             SecureUserDefaults.shared.set(dataGT, forKey: "inEditorGroup")
             
             if dataTopic["chat_id"]  as? String ?? "" == "" {
-                UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [dataGroup["group_id"]  as? String ?? ""])
-                sendTyping(l_pin: dataGroup["group_id"]  as? String ?? "")
+                UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [groupId])
+                sendTyping(l_pin: groupId)
             } else {
-                UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [dataTopic["chat_id"]  as? String ?? ""])
-                sendTyping(l_pin: dataTopic["chat_id"]  as? String ?? "")
+                UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [chatId])
+                sendTyping(l_pin: chatId)
             }
         } else {
             getOfficialGroup()
@@ -2444,18 +2444,8 @@ extension EditorGroup: UIDocumentPickerDelegate, DocumentPickerDelegate, QLPrevi
             self.previewItem = (document as! [URL])[0] as NSURL
             let previewController = QLPreviewController()
             let navController = CustomNavigationController(rootViewController: previewController)
-            navController.navigationBar.tintColor = .white
-            navController.navigationBar.barTintColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
-            navController.navigationBar.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
-            navController.navigationBar.isTranslucent = false
-            let attributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 16)]
-            let appearance = UINavigationBarAppearance()
-            appearance.configureWithDefaultBackground()
-            appearance.titleTextAttributes = attributes
-            appearance.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
-            navController.navigationBar.standardAppearance = appearance
-            navController.navigationBar.scrollEdgeAppearance = appearance
-            let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
+            navController.navigationBar.tintColor = .black
+            let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.black, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
             UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
             let leftBarButton = navigationQLPreviewDocument(title: "Cancel".localized(), style: .plain, target: self, action: #selector(cancelDocumentPreview))
             let rightBarButton = navigationQLPreviewDocument(title: "Send".localized(), style: .done, target: self, action: #selector(sendDocument))
@@ -2516,6 +2506,7 @@ extension EditorGroup: UITextViewDelegate, CustomTextViewPasteDelegate {
     
     public func textViewDidChangeSelection(_ textView: UITextView) {
         lastPositionCursorMention = textView.selectedRange.location
+        var isShowMention = false
 
         let fulltextForMention = textView.text.prefix(lastPositionCursorMention)
         
@@ -2528,10 +2519,15 @@ extension EditorGroup: UITextViewDelegate, CustomTextViewPasteDelegate {
                 if lastChar != "\n" && lastChar != " " {
                     if mentionText.starts(with: "@") || (mentionText.count >= 2 && (self.textFieldSend.textColor != UIColor.lightGray || heightTableEditMention != nil)) {
                         showMention(text: mentionText.starts(with: "@") ? String(mentionText.dropFirst()) : String(mentionText))
+                        isShowMention = true
                     }
                 }
             }
         }
+        
+        if !isShowMention {
+            hideMention()
+        }
 
         var nowTextFieldSend = self.textFieldSend
         if isEditingMessage {
@@ -4429,8 +4425,11 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource, AVAudioPlayer
                 }
             }
         }
-        let dataMessages = self.dataMessages.filter({ $0["chat_date"]  as? String ?? "" == dataDates[indexPath.section] })
         if copySession || forwardSession || deleteSession {
+            let dataMessages = self.dataMessages.filter({ $0["chat_date"]  as? String ?? "" == dataDates[indexPath.section] })
+            guard indexPath.row < dataMessages.count else {
+                return
+            }
             if copySession && dataMessages[indexPath.row]["f_pin"]  as? String ?? "" != "-999" {
                 return
             }

+ 11 - 18
NexilisLite/NexilisLite/Source/View/Chat/EditorPersonal.swift

@@ -549,12 +549,13 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
             }
         }
         
+        let pinPerson: String = (dataPerson["f_pin"] ?? "") ?? ""
         if onGoingCC {
             SecureUserDefaults.shared.set(self.fPinContacCenter, forKey: "inEditorPersonal")
         } else {
-            SecureUserDefaults.shared.set(dataPerson["f_pin"] ?? "", forKey: "inEditorPersonal")
+            SecureUserDefaults.shared.set(pinPerson, forKey: "inEditorPersonal")
         }
-        UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [dataPerson["f_pin"]!!])
+        UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [pinPerson])
         
         if isContactCenter || fromNotification {
             let imageButton = UIImageView(frame: CGRect(x: -16, y: 0, width: 20, height: 44))
@@ -3014,10 +3015,9 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                     let categoryCC = dataMessages[dataMessages.count - 2]["category_cc"] as! [CategoryCC]
                     self.nowSelectedCategoryCC = categoryCC[0].parent
                 }
-                self.tableChatView.beginUpdates()
-                tableChatView.deleteRows(at: [IndexPath(row: dataMessages.count - 1, section: 0)], with: .none)
                 dataMessages.remove(at: dataMessages.count - 1)
-                self.tableChatView.endUpdates()
+                tableChatView.deleteRows(at: [IndexPath(row: dataMessages.count - 1, section: 0)], with: .none)
+                tableChatView.reloadData()
             } else {
                 return
             }
@@ -3776,18 +3776,8 @@ extension EditorPersonal: UIDocumentPickerDelegate, DocumentPickerDelegate, QLPr
             self.previewItem = (document as! [URL])[0] as NSURL
             let previewController = QLPreviewController()
             let navController = CustomNavigationController(rootViewController: previewController)
-            navController.navigationBar.tintColor = .white
-            navController.navigationBar.barTintColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
-            navController.navigationBar.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
-            navController.navigationBar.isTranslucent = false
-            let attributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 16)]
-            let appearance = UINavigationBarAppearance()
-            appearance.configureWithDefaultBackground()
-            appearance.titleTextAttributes = attributes
-            appearance.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
-            navController.navigationBar.standardAppearance = appearance
-            navController.navigationBar.scrollEdgeAppearance = appearance
-            let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
+            navController.navigationBar.tintColor = .black
+            let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.black, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
             UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
             let leftBarButton = navigationQLPreviewDocument(title: "Cancel".localized(), style: .plain, target: self, action: #selector(cancelDocumentPreview))
             let rightBarButton = navigationQLPreviewDocument(title: "Send".localized(), style: .done, target: self, action: #selector(sendDocument))
@@ -5484,8 +5474,11 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
         if isContactCenter && indexPath.row == 0 && isRequestContactCenter {
             return
         }
-        let dataMessages = self.dataMessages.filter({ $0["chat_date"]  as? String ?? "" == dataDates[indexPath.section] })
         if copySession || forwardSession || deleteSession {
+            let dataMessages = self.dataMessages.filter({ $0["chat_date"]  as? String ?? "" == dataDates[indexPath.section] })
+            guard indexPath.row < dataMessages.count else {
+                return
+            }
             if (dataMessages[indexPath.row]["attachment_flag"]  as? String ?? "" != "0" || dataMessages[indexPath.row]["lock"] as? String == "1") && !forwardSession && !deleteSession {
                 return
             }

+ 1 - 2
NexilisLite/NexilisLite/Source/View/Chat/EditorStarMessages.swift

@@ -1348,14 +1348,13 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
             if idx != nil{
                 self.dataMessages[idx!]["is_stared"] = "0"
             }
-            self.tableChatView.beginUpdates()
             self.dataMessages.remove(at: idx!)
             self.tableChatView.deleteRows(at: [indexPath!], with: .fade)
             if self.dataMessages.filter({ $0["chat_date"] as! String == dataMessages[indexPath!.row]["chat_date"] as! String }).count == 0 {
                 self.dataDates.remove(at: indexPath!.section)
                 self.tableChatView.deleteSections(IndexSet(integer: indexPath!.section), with: .fade)
             }
-            self.tableChatView.endUpdates()
+            self.tableChatView.reloadData()
         })
         let forward = UIAction(title: "Forward".localized(), image: UIImage(systemName: "arrowshape.turn.up.right.fill"), handler: {(_) in
             let navigationController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactChatNav") as! UINavigationController

+ 8 - 1
NexilisLite/NexilisLite/Source/View/Control/GroupDescViewController.swift

@@ -7,7 +7,7 @@
 
 import UIKit
 
-class GroupDescViewController: UITableViewController {
+class GroupDescViewController: UITableViewController, UITextFieldDelegate {
 
     @IBOutlet weak var descText: UITextField!
     
@@ -29,6 +29,7 @@ class GroupDescViewController: UITableViewController {
         
         descText.addTarget(self, action: #selector(didChanged(sender:)), for: .editingChanged)
         descText.placeholder = "Description".localized()
+        descText.delegate = self
     }
     
     @objc func didChanged(sender: Any) {
@@ -38,6 +39,12 @@ class GroupDescViewController: UITableViewController {
             button.isEnabled = true
         }
     }
+    
+    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
+        guard let currentText = textField.text else { return true }
+        let newLength = currentText.count + string.count - range.length
+        return newLength <= 200
+    }
 
     @objc func save(sender: Any) {
         if let text = descText.text {

+ 8 - 6
NexilisLite/NexilisLite/Source/View/Control/GroupDetailViewController.swift

@@ -485,10 +485,9 @@ class GroupDetailViewController: UITableViewController, UITextFieldDelegate {
                                 data["topicId"] = topic.chatId
                                 NotificationCenter.default.post(name: NSNotification.Name(rawValue: "onTopic"), object: nil, userInfo: data)
                                 DispatchQueue.main.async {
-                                    tableView.beginUpdates()
-                                    tableView.deleteRows(at: [indexPath], with: .none)
                                     g.topics.remove(at: index)
-                                    tableView.endUpdates()
+                                    tableView.deleteRows(at: [indexPath], with: .none)
+                                    tableView.reloadData()
                                 }
                             }
                         }
@@ -612,10 +611,9 @@ class GroupDetailViewController: UITableViewController, UITextFieldDelegate {
                             self.exitGroup(pin: member.pin) { result in
                                 if result, let index = g.members.firstIndex(of: member) {
                                     DispatchQueue.main.async {
-                                        tableView.beginUpdates()
-                                        tableView.deleteRows(at: [indexPath], with: .none)
                                         g.members.remove(at: index)
-                                        tableView.endUpdates()
+                                        tableView.deleteRows(at: [indexPath], with: .automatic)
+                                        tableView.reloadData()
                                     }
                                 }
                             }
@@ -698,6 +696,10 @@ class GroupDetailViewController: UITableViewController, UITextFieldDelegate {
         }
     }
     
+    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
+        return true
+    }
+    
     private func didTapAdd(_ pin: String) {
         Nexilis.showLoader()
         addFriend(pin) { result in

+ 13 - 1
NexilisLite/NexilisLite/Source/View/Control/GroupMemberViewController.swift

@@ -50,7 +50,12 @@ class GroupMemberViewController: UITableViewController {
         searchController.searchBar.delegate = self
         searchController.obscuresBackgroundDuringPresentation = false
         searchController.searchBar.updateHeight(height: 36, radius: 18)
-        searchController.searchBar.searchTextField.attributedPlaceholder = NSAttributedString(string: "Search".localized(), attributes: [NSAttributedString.Key.foregroundColor: UIColor.gray, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)])
+        if let searchTextField = searchController.searchBar.value(forKey: "searchField") as? UITextField {
+            if let leftIconView = searchTextField.leftView as? UIImageView {
+                leftIconView.tintColor = UIColor.white.withAlphaComponent(0.5)
+            }
+        }
+        searchController.searchBar.searchTextField.attributedPlaceholder = NSAttributedString(string: "Search".localized(), attributes: [NSAttributedString.Key.foregroundColor: UIColor.white.withAlphaComponent(0.5), NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)])
         
         definesPresentationContext = true
         
@@ -65,6 +70,13 @@ class GroupMemberViewController: UITableViewController {
         }
     }
     
+    override func viewDidAppear(_ animated: Bool) {
+        if let searchTextField = searchController.searchBar.value(forKey: "searchField") as? UITextField {
+            searchTextField.textColor = .white
+            searchTextField.tintColor = .white
+        }
+    }
+    
     @objc func add(sender: Any) {
         Nexilis.showLoader()
         DispatchQueue.global().async {

+ 1 - 2
NexilisLite/NexilisLite/Source/View/Streaming/CreateSeminarViewController.swift

@@ -493,10 +493,9 @@ public class CreateSeminarViewController: UITableViewController {
         switch sections[indexPath.section] {
         case .participants:
             if (editingStyle == .delete) {
-                tableView.beginUpdates()
                 users.remove(at: indexPath.row - 1)
                 tableView.deleteRows(at: [indexPath], with: .automatic)
-                tableView.endUpdates()
+                tableView.reloadData()
             }
         default:
             return

+ 2 - 4
NexilisLite/NexilisLite/Source/View/Streaming/QmeraCreateStreamingViewController.swift

@@ -573,17 +573,15 @@ public class QmeraCreateStreamingViewController: UITableViewController {
         switch sections[indexPath.section] {
         case .users:
             if (editingStyle == .delete) {
-                tableView.beginUpdates()
                 users.remove(at: indexPath.row - 1)
                 tableView.deleteRows(at: [indexPath], with: .automatic)
-                tableView.endUpdates()
+                tableView.reloadData()
             }
         case .groups:
             if (editingStyle == .delete) {
-                tableView.beginUpdates()
                 groups.remove(at: indexPath.row - 1)
                 tableView.deleteRows(at: [indexPath], with: .automatic)
-                tableView.endUpdates()
+                tableView.reloadData()
             }
         default:
             return