diff --git a/Cartfile b/Cartfile index c0deb5b..d8bf5e6 100644 --- a/Cartfile +++ b/Cartfile @@ -19,5 +19,4 @@ github "RooyeKhat-Media/ALCameraViewController" "3.0.3" github "RooyeKhat-Media/INSPhotoGallery" "1.2.5-a" github "RooyeKhat-Media/Starscream" "3.0.4-a" github "RooyeKhat-Media/DBAttachmentPickerController" "1.1.4-a" -github "RooyeKhat-Media/swift-protobuf" "1.0.2-a" -github "RooyeKhat-Media/IGProtoBuffLibrary" "74-a" +github "RooyeKhat-Media/IGProtoBuffLibrary" "Build80" diff --git a/Cartfile.resolved b/Cartfile.resolved index d16f09f..e4b3190 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -5,10 +5,10 @@ github "ReactiveX/RxSwift" "4.1.2" github "RooyeKhat-Media/ALCameraViewController" "3.0.3" github "RooyeKhat-Media/DBAttachmentPickerController" "1.1.4-a" github "RooyeKhat-Media/Gifu" "v3.0.0-a" -github "RooyeKhat-Media/IGProtoBuffLibrary" "74-a" +github "RooyeKhat-Media/IGProtoBuffLibrary" "Build80" github "RooyeKhat-Media/INSPhotoGallery" "1.2.5-a" github "RooyeKhat-Media/Starscream" "3.0.4-a" -github "RooyeKhat-Media/swift-protobuf" "1.0.2-a" +github "RooyeKhat-Media/swift-protobuf" "1.0.3-iGap" github "RxSwiftCommunity/RxRealm" "0.7.5" github "SnapKit/SnapKit" "4.0.0" github "TakeScoop/SwiftyRSA" "0.5.0" @@ -18,5 +18,5 @@ github "evgenyneu/Cosmos" "15.0.0" github "facebook/pop" "1.0.10" github "jdg/MBProgressHUD" "1.1.0" github "krzyzanowskim/CryptoSwift" "0.7.2" -github "ninjaprox/NVActivityIndicatorView" "4.2.0" -github "realm/realm-cocoa" "v3.5.0" +github "ninjaprox/NVActivityIndicatorView" "4.2.1" +github "realm/realm-cocoa" "v3.6.0" diff --git a/iGap.xcodeproj/project.pbxproj b/iGap.xcodeproj/project.pbxproj index 39a75b3..d8ebba6 100644 --- a/iGap.xcodeproj/project.pbxproj +++ b/iGap.xcodeproj/project.pbxproj @@ -130,6 +130,7 @@ FA11E28A1DE8A8A900A2F87C /* IGAttachmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA11E2891DE8A8A900A2F87C /* IGAttachmentManager.swift */; }; FA11E28D1DE99BF400A2F87C /* IGFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA11E28C1DE99BF400A2F87C /* IGFactory.swift */; }; FA1C449C1DC716A20016C346 /* IGCountry.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1C449B1DC716A20016C346 /* IGCountry.swift */; }; + FA27F74020BD77ED00EC6A97 /* api.key in Sources */ = {isa = PBXBuildFile; fileRef = FA27F73F20BD77ED00EC6A97 /* api.key */; }; FA3306361F445A570096031A /* IRANSans.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FA3306351F445A570096031A /* IRANSans.ttf */; }; FA33063B1F445AE80096031A /* IRANSans_Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FA3306371F445AE80096031A /* IRANSans_Bold.ttf */; }; FA33063C1F445AE80096031A /* IRANSans_Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FA3306381F445AE80096031A /* IRANSans_Light.ttf */; }; @@ -216,6 +217,7 @@ FA8F22581DD89F7C005A90D1 /* IGAvatar.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA8F22571DD89F7C005A90D1 /* IGAvatar.swift */; }; FA8F8A682086027100AF03CB /* IGMapNearbyDistanceCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA8F8A672086027100AF03CB /* IGMapNearbyDistanceCell.swift */; }; FA8F8A69208602AB00AF03CB /* IGMapNearbyDistanceCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA8F8A66208600AB00AF03CB /* IGMapNearbyDistanceCell.xib */; }; + FA90B72A20B53EBC00043C89 /* MessageReceiveObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA90B72920B53EBC00043C89 /* MessageReceiveObserver.swift */; }; FA927E002028416300DF7145 /* VideoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA927DFF2028416300DF7145 /* VideoCell.swift */; }; FA927E02202841C900DF7145 /* VideoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA927E012028418600DF7145 /* VideoCell.xib */; }; FA927E0420284D7800DF7145 /* GifCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA927E0320284D7800DF7145 /* GifCell.swift */; }; @@ -448,6 +450,8 @@ FA11E2891DE8A8A900A2F87C /* IGAttachmentManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IGAttachmentManager.swift; sourceTree = ""; }; FA11E28C1DE99BF400A2F87C /* IGFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IGFactory.swift; sourceTree = ""; }; FA1C449B1DC716A20016C346 /* IGCountry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IGCountry.swift; sourceTree = ""; }; + FA27F73F20BD77ED00EC6A97 /* api.key */ = {isa = PBXFileReference; lastKnownFileType = text; path = api.key; sourceTree = ""; }; + FA27F74120BD780300EC6A97 /* secret.key */ = {isa = PBXFileReference; lastKnownFileType = text; path = secret.key; sourceTree = ""; }; FA3306351F445A570096031A /* IRANSans.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = IRANSans.ttf; sourceTree = ""; }; FA3306371F445AE80096031A /* IRANSans_Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = IRANSans_Bold.ttf; sourceTree = ""; }; FA3306381F445AE80096031A /* IRANSans_Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = IRANSans_Light.ttf; sourceTree = ""; }; @@ -537,6 +541,7 @@ FA8F22571DD89F7C005A90D1 /* IGAvatar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IGAvatar.swift; sourceTree = ""; }; FA8F8A66208600AB00AF03CB /* IGMapNearbyDistanceCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IGMapNearbyDistanceCell.xib; sourceTree = ""; }; FA8F8A672086027100AF03CB /* IGMapNearbyDistanceCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IGMapNearbyDistanceCell.swift; sourceTree = ""; }; + FA90B72920B53EBC00043C89 /* MessageReceiveObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageReceiveObserver.swift; sourceTree = ""; }; FA927DFF2028416300DF7145 /* VideoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoCell.swift; sourceTree = ""; }; FA927E012028418600DF7145 /* VideoCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VideoCell.xib; sourceTree = ""; }; FA927E0320284D7800DF7145 /* GifCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifCell.swift; sourceTree = ""; }; @@ -1124,6 +1129,14 @@ path = Map; sourceTree = ""; }; + FA90B72820B53E5F00043C89 /* Protocols */ = { + isa = PBXGroup; + children = ( + FA90B72920B53EBC00043C89 /* MessageReceiveObserver.swift */, + ); + path = Protocols; + sourceTree = ""; + }; FA930D961E5B178F00069EE1 /* ThirdParty Libraries */ = { isa = PBXGroup; children = ( @@ -1353,7 +1366,7 @@ FAF7960C1DAA39660030509B /* Model */, FAF795FF1DAA392F0030509B /* VIew */, FAF7960B1DAA39660030509B /* Controller */, - FAF796081DAA39460030509B /* Supporting FIles */, + FAF796081DAA39460030509B /* SupportingFiles */, ); path = iGap; sourceTree = ""; @@ -1374,20 +1387,23 @@ path = VIew; sourceTree = ""; }; - FAF796081DAA39460030509B /* Supporting FIles */ = { + FAF796081DAA39460030509B /* SupportingFiles */ = { isa = PBXGroup; children = ( FA752C321E1EC571008694C6 /* iGap.entitlements */, FAF796091DAA39460030509B /* Info.plist */, FA5097D21DEDA18000A44699 /* iGap-Bridging-Header.h */, FAF8BFE91E34AF00002AF525 /* GoogleService-Info.plist */, + FA27F74120BD780300EC6A97 /* secret.key */, + FA27F73F20BD77ED00EC6A97 /* api.key */, ); - path = "Supporting FIles"; + path = SupportingFiles; sourceTree = ""; }; FAF7960B1DAA39660030509B /* Controller */ = { isa = PBXGroup; children = ( + FA90B72820B53E5F00043C89 /* Protocols */, FAD530561E0BD6C300FE6C54 /* Custom Master Controllers */, FA087B2C1DC4A27200E139FA /* View Controllers */, ); @@ -1578,7 +1594,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "./Fabric.framework/run a8bb9474c4f59357347dbd3fd5707ca541e2a740 73c66be76fb6cd1becc07ca6b9a77d9dd134ff35089fe7aa02dbfa33ad57b654"; + shellScript = "apiKey=$(sed -n '1p' < ./iGap/SupportingFiles/api.key)\nsecretKey=$(sed -n '2p' < ./iGap/SupportingFiles/secret.key)\n\n/usr/libexec/PlistBuddy -c \"Set :Fabric:APIKey $apiKey\" ./iGap/SupportingFiles/Info.plist\n\n\"./Fabric.framework/run\" $apiKey $secretKey"; }; FADF684C1DB2607B00DC5038 /* [RS] Set Build Number */ = { isa = PBXShellScriptBuildPhase; @@ -1799,6 +1815,7 @@ FA8D056D20739C96007861E7 /* IGSettingAddContactViewController.swift in Sources */, FAD580941DDC5C4E00A242DE /* IGMessageCollectionViewCell.swift in Sources */, FA8204382025C97300A795D5 /* ImageCell.swift in Sources */, + FA27F74020BD77ED00EC6A97 /* api.key in Sources */, FA927E002028416300DF7145 /* VideoCell.swift in Sources */, FA0953561E1B97700043ED3F /* IGSettingChatTableViewController.swift in Sources */, FAD5808F1DDC5C1900A242DE /* IGMessageGeneralCollectionViewCell.swift in Sources */, @@ -1820,6 +1837,7 @@ FA03C1A020429D46008812E3 /* RTCClient.swift in Sources */, FA0CC80B1E5D7D4400556283 /* RegexParser.swift in Sources */, FA09538F1E1B97E20043ED3F /* SSRadioButtonController.swift in Sources */, + FA90B72A20B53EBC00043C89 /* MessageReceiveObserver.swift in Sources */, 9366D98C1E363C2500998BA3 /* IGSettingAboutWebViewViewController.swift in Sources */, FA0CC8071E5D7D4400556283 /* ActiveBuilder.swift in Sources */, FA42EF0E1E5C224F00CF8A32 /* CGSize.swift in Sources */, @@ -2025,7 +2043,7 @@ "$(PROJECT_DIR)/Carthage/Build/iOS", "$(PROJECT_DIR)", ); - INFOPLIST_FILE = "iGap/Supporting FIles/Info.plist"; + INFOPLIST_FILE = iGap/SupportingFiles/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; ONLY_ACTIVE_ARCH = NO; @@ -2033,7 +2051,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OBJC_BRIDGING_HEADER = "iGap/Supporting FIles/iGap-Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = "iGap/SupportingFiles/iGap-Bridging-Header.h"; SWIFT_VERSION = 3.0; }; name = Debug; @@ -2053,7 +2071,7 @@ "$(PROJECT_DIR)/Carthage/Build/iOS", "$(PROJECT_DIR)", ); - INFOPLIST_FILE = "iGap/Supporting FIles/Info.plist"; + INFOPLIST_FILE = iGap/SupportingFiles/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = "$(inherited)"; @@ -2061,7 +2079,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OBJC_BRIDGING_HEADER = "iGap/Supporting FIles/iGap-Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = "iGap/SupportingFiles/iGap-Bridging-Header.h"; SWIFT_VERSION = 3.0; }; name = Release; diff --git a/iGap/Controller/Custom Master Controllers/NavigationController/IGNavigationItem.swift b/iGap/Controller/Custom Master Controllers/NavigationController/IGNavigationItem.swift index fe04e40..3b8eb10 100644 --- a/iGap/Controller/Custom Master Controllers/NavigationController/IGNavigationItem.swift +++ b/iGap/Controller/Custom Master Controllers/NavigationController/IGNavigationItem.swift @@ -421,7 +421,7 @@ class IGNavigationItem: UINavigationItem { self.centerViewMainLabel!.font = UIFont.igFont(ofSize: 16.0, weight: .bold)//boldSystemFont(ofSize: 16) self.centerViewContainer!.addSubview(self.centerViewMainLabel!) self.centerViewMainLabel!.snp.makeConstraints { (make) in - make.top.equalTo(self.centerViewContainer!.snp.top).offset(0) + make.top.equalTo(self.centerViewContainer!.snp.top) make.leading.equalTo(self.centerViewContainer!.snp.leading).offset(5).priority(.required) make.width.lessThanOrEqualToSuperview().offset(-25) } @@ -432,10 +432,14 @@ class IGNavigationItem: UINavigationItem { self.centerViewSubLabel!.font = UIFont.igFont(ofSize: 12.0, weight: .regular)//boldSystemFont(ofSize: 12) self.centerViewContainer!.addSubview(self.centerViewSubLabel!) self.centerViewSubLabel!.snp.makeConstraints { (make) in - make.top.equalTo(self.centerViewMainLabel!.snp.bottom).offset(3) + make.top.equalTo(self.centerViewMainLabel!.snp.bottom).offset(-3) make.leading.equalTo(self.centerViewContainer!.snp.leading).offset(5) } + let verifiedFrame = CGRect(x: 20, y: 5, width: 25, height: 25) + let imgVerified = UIImageView(frame: verifiedFrame) + imgVerified.image = UIImage(named:"IG_Verify") + if room.mute == .mute { let muteFrame = CGRect(x: 20, y: 5, width: 25, height: 25) let imgMute = UIImageView(frame: muteFrame) @@ -449,6 +453,26 @@ class IGNavigationItem: UINavigationItem { make.top.equalTo(self.centerViewMainLabel!.snp.top).offset(3) make.right.equalTo(self.centerViewMainLabel!.snp.right).offset(20) } + + if isVerified(room: room) { + self.centerViewContainer!.addSubview(imgVerified) + imgVerified.snp.makeConstraints { (make) in + make.width.equalTo(20) + make.height.equalTo(20) + make.top.equalTo(self.centerViewMainLabel!.snp.top).offset(3) + make.right.equalTo(imgMute.snp.right).offset(25) + } + } + } else { + if isVerified(room: room) { + self.centerViewContainer!.addSubview(imgVerified) + imgVerified.snp.makeConstraints { (make) in + make.width.equalTo(20) + make.height.equalTo(20) + make.top.equalTo(self.centerViewMainLabel!.snp.top).offset(3) + make.right.equalTo(self.centerViewMainLabel!.snp.right).offset(25) + } + } } if let peer = room.chatRoom?.peer { @@ -462,6 +486,22 @@ class IGNavigationItem: UINavigationItem { } } + private func isVerified(room: IGRoom) -> Bool { + var verified = false + if room.type == .chat { + if let user = room.chatRoom?.peer { + if user.isVerified { + verified = true + } + } + } else if room.type == .channel { + if (room.channelRoom?.isVerified)! { + verified = true + } + } + return verified + } + private func setLastSeenLabelForUser(_ user: IGRegisteredUser , room : IGRoom) { if isCloud(room: room){ diff --git a/iGap/Controller/Protocols/MessageReceiveObserver.swift b/iGap/Controller/Protocols/MessageReceiveObserver.swift new file mode 100644 index 0000000..83a38f2 --- /dev/null +++ b/iGap/Controller/Protocols/MessageReceiveObserver.swift @@ -0,0 +1,15 @@ +/* + * This is the source code of iGap for iOS + * It is licensed under GNU AGPL v3.0 + * You should have received a copy of the license in this archive (see LICENSE). + * Copyright © 2017 , iGap - www.iGap.net + * iGap Messenger | Free, Fast and Secure instant messaging application + * The idea of the RooyeKhat Media Company - www.RooyeKhat.co + * All rights reserved. + */ + +import IGProtoBuff + +protocol MessageReceiveObserver { + func onMessageRecieve(messages: [IGPRoomMessage]) +} diff --git a/iGap/Controller/View Controllers/Channel and Group Info/IGChannelInfoTableViewController.swift b/iGap/Controller/View Controllers/Channel and Group Info/IGChannelInfoTableViewController.swift index 8a5c53a..5b32611 100644 --- a/iGap/Controller/View Controllers/Channel and Group Info/IGChannelInfoTableViewController.swift +++ b/iGap/Controller/View Controllers/Channel and Group Info/IGChannelInfoTableViewController.swift @@ -45,7 +45,8 @@ class IGChannelInfoTableViewController: UITableViewController , UIGestureRecogni @IBOutlet weak var allMemberCell: UITableViewCell! @IBOutlet weak var channelLinkCell: UITableViewCell! @IBOutlet weak var adminAndModeratorCell: UITableViewCell! - + @IBOutlet weak var imgVerified: UIImageView! + var selectedChannel : IGChannelRoom? private let disposeBag = DisposeBag() var room : IGRoom? @@ -696,6 +697,17 @@ class IGChannelInfoTableViewController: UITableViewController , UIGestureRecogni } func showChannelInfo(){ + + if (room?.isInvalidated)! { + return + } + + if (room?.channelRoom?.isVerified)! { + imgVerified.isHidden = false + } else { + imgVerified.isHidden = true + } + channelNameLabelTitle.text = room?.title channelNameLabel.text = room?.title ChannelDescriptionLabel.text = room?.channelRoom?.roomDescription diff --git a/iGap/Controller/View Controllers/Look And Find/IGLookAndFind.swift b/iGap/Controller/View Controllers/Look And Find/IGLookAndFind.swift index 6dc8f6e..f589988 100644 --- a/iGap/Controller/View Controllers/Look And Find/IGLookAndFind.swift +++ b/iGap/Controller/View Controllers/Look And Find/IGLookAndFind.swift @@ -128,7 +128,7 @@ class IGLookAndFind: UIViewController, UITableViewDataSource, UITableViewDelegat private func openUserProfile(searchResult: IGRealmClientSearchUsername){ let user = searchResult.user let room = searchResult.room - let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil) + let storyboard : UIStoryboard = UIStoryboard(name: "profile", bundle: nil) let destinationVC = storyboard.instantiateViewController(withIdentifier: "IGRegistredUserInfoTableViewController") as! IGRegistredUserInfoTableViewController destinationVC.user = user destinationVC.previousRoomId = 0 diff --git a/iGap/Controller/View Controllers/Setting/IGSettingPrivacy&SecurityTableViewController.swift b/iGap/Controller/View Controllers/Setting/IGSettingPrivacy&SecurityTableViewController.swift index bbb4cb7..b27e060 100644 --- a/iGap/Controller/View Controllers/Setting/IGSettingPrivacy&SecurityTableViewController.swift +++ b/iGap/Controller/View Controllers/Setting/IGSettingPrivacy&SecurityTableViewController.swift @@ -88,6 +88,11 @@ class IGSettingPrivacy_SecurityTableViewController: UITableViewController, UIGes } func showPrivacyInfo(){ + + if (userPrivacy?.isInvalidated)! { + return + } + if let avatarPrivacy = userPrivacy?.avatar { avatarUserPrivacy = avatarPrivacy switch avatarPrivacy{ diff --git a/iGap/Controller/View Controllers/Setting/IGSettingTableViewController.swift b/iGap/Controller/View Controllers/Setting/IGSettingTableViewController.swift index 2363e7a..5b570d5 100644 --- a/iGap/Controller/View Controllers/Setting/IGSettingTableViewController.swift +++ b/iGap/Controller/View Controllers/Setting/IGSettingTableViewController.swift @@ -209,9 +209,8 @@ class IGSettingTableViewController: UITableViewController , NVActivityIndicatorV } } - + self.scheduledTimerWithTimeInterval() } - scheduledTimerWithTimeInterval() } func scheduledTimerWithTimeInterval(){ // Scheduling timer to Call the function **Countdown** with the interval of 1 seconds diff --git a/iGap/Controller/View Controllers/Setting/iGAccountTableViewController.swift b/iGap/Controller/View Controllers/Setting/iGAccountTableViewController.swift index a38e986..172092f 100644 --- a/iGap/Controller/View Controllers/Setting/iGAccountTableViewController.swift +++ b/iGap/Controller/View Controllers/Setting/iGAccountTableViewController.swift @@ -80,20 +80,22 @@ class IGAccountTableViewController: UITableViewController , UINavigationControll } func updateUI() { - nicknameEntryLabel.text = currentUser.displayName - usernameEntryLabel.text = currentUser.username - emailEntryLabel.text = currentUser.email - phoneNumberEntryLabel.text = "\(currentUser.phone)" - bioEntryLabel.text = currentUser.bio - - if currentUser.selfRemove == -1 { - selfDestructionLabel.text = "" - } else if currentUser.selfRemove == 12 { - selfDestructionLabel.text = "1 year" - } else if currentUser.selfRemove == 1 { - selfDestructionLabel.text = "\(currentUser.selfRemove)" + " month" - } else { - selfDestructionLabel.text = "\(currentUser.selfRemove)" + " months" + DispatchQueue.main.async { + self.nicknameEntryLabel.text = self.currentUser.displayName + self.usernameEntryLabel.text = self.currentUser.username + self.emailEntryLabel.text = self.currentUser.email + self.phoneNumberEntryLabel.text = "\(self.currentUser.phone)" + self.bioEntryLabel.text = self.currentUser.bio + + if self.currentUser.selfRemove == -1 { + self.selfDestructionLabel.text = "" + } else if self.currentUser.selfRemove == 12 { + self.selfDestructionLabel.text = "1 year" + } else if self.currentUser.selfRemove == 1 { + self.selfDestructionLabel.text = "\(self.currentUser.selfRemove)" + " month" + } else { + self.selfDestructionLabel.text = "\(self.currentUser.selfRemove)" + " months" + } } } diff --git a/iGap/Controller/View Controllers/Splash and Register/IGRegistrationStepPhoneViewController.swift b/iGap/Controller/View Controllers/Splash and Register/IGRegistrationStepPhoneViewController.swift index 1d089e8..9a17fcf 100644 --- a/iGap/Controller/View Controllers/Splash and Register/IGRegistrationStepPhoneViewController.swift +++ b/iGap/Controller/View Controllers/Splash and Register/IGRegistrationStepPhoneViewController.swift @@ -162,12 +162,13 @@ class IGRegistrationStepPhoneViewController: UIViewController { let phone = phoneNumberField.text if phone != nil && phone != "" { phoneSpaceLess = phone?.replacingOccurrences(of: " ", with: "") + phoneSpaceLess = phoneSpaceLess?.replacingOccurrences(of: "_", with: "") } if phoneSpaceLess != nil && phoneSpaceLess != "" && Int64(phoneSpaceLess!) != nil{ if IGGlobal.matches(for: (selectedCountry?.codeRegex)!, in: phoneSpaceLess!) { let countryCode = String(Int((self.selectedCountry?.countryCode)!)) - let fullPhone = "+" + countryCode + " " + phone! + let fullPhone = "+" + countryCode + " " + (phone?.replacingOccurrences(of: "_", with: ""))! let alertVC = UIAlertController(title: "Is this correct",message: "Is this phone correct:\n"+fullPhone,preferredStyle: .alert) let yes = UIAlertAction(title: "Yes", style: .cancel, handler: { (action) in self.hud = MBProgressHUD.showAdded(to: self.view, animated: true) @@ -189,15 +190,8 @@ class IGRegistrationStepPhoneViewController: UIViewController { } } let alertVC = UIAlertController(title: "Invalid Phone", message: "Please enter a valid phone number", preferredStyle: .alert) - let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) in - - }) - - alertVC.addAction(ok) - self.present(alertVC, animated: true, completion: { - - }) - //self.performSegue(withIdentifier: "showRegistration", sender: self) + alertVC.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) + self.present(alertVC, animated: true, completion: nil) } } @@ -336,9 +330,9 @@ class IGRegistrationStepPhoneViewController: UIViewController { destination.delayBeforeSendingAgaing = self.registrationResponse?.resendDelay destination.username = self.registrationResponse?.username destination.verificationMethod = self.registrationResponse?.verificationMethod - destination.phone = phoneNumberField.text + destination.phone = phoneNumberField.text?.replacingOccurrences(of: "_", with: "") destination.selectedCountry = self.selectedCountry - let fullPhone = "+"+String(Int((self.selectedCountry?.countryCode)!))+" "+phoneNumberField.text! + let fullPhone = "+"+String(Int((self.selectedCountry?.countryCode)!))+" "+phoneNumberField.text!.replacingOccurrences(of: "_", with: "") destination.phoneNumber = fullPhone } } diff --git a/iGap/Controller/View Controllers/Tabbar Sub Controllers/IGRecentsTableViewController.swift b/iGap/Controller/View Controllers/Tabbar Sub Controllers/IGRecentsTableViewController.swift index c3c117b..e979cad 100644 --- a/iGap/Controller/View Controllers/Tabbar Sub Controllers/IGRecentsTableViewController.swift +++ b/iGap/Controller/View Controllers/Tabbar Sub Controllers/IGRecentsTableViewController.swift @@ -18,8 +18,10 @@ import IGProtoBuff import MGSwipeTableCell import MBProgressHUD -class IGRecentsTableViewController: UITableViewController { +class IGRecentsTableViewController: UITableViewController, MessageReceiveObserver { + static var messageReceiveDelegat: MessageReceiveObserver! + static var visibleChat: [Int64 : Bool] = [:] var alreadySavedContacts: Bool = false var selectedRoomForSegue : IGRoom? var cellIdentifer = IGChatRoomListTableViewCell.cellReuseIdentifier() @@ -179,6 +181,7 @@ class IGRecentsTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() + IGRecentsTableViewController.messageReceiveDelegat = self let sortProperties = [SortDescriptor(keyPath: "pinId", ascending: false), SortDescriptor(keyPath: "sortimgTimestamp", ascending: false)] self.rooms = try! Realm().objects(IGRoom.self).filter("isParticipant = 1").sorted(by: sortProperties) @@ -1190,6 +1193,95 @@ extension IGRecentsTableViewController { } }).send() } + + /***************** Send Rooms Status *****************/ + + func onMessageRecieve(messages: [IGPRoomMessage]) { + + let realm = try! Realm() + + for message in messages { + var roomId: Int64 = 0 + var roomType: IGRoom.IGType = .chat + var roomMessageStatus: IGPRoomMessageStatus = .delivered + + if message.igpAuthor.hasIgpUser { // chat + + let predicate = NSPredicate(format: "chatRoom.peer.id = %lld", message.igpAuthor.igpUser.igpUserID) + if let roomInfo = realm.objects(IGRoom.self).filter(predicate).first { + roomId = roomInfo.id + } + } else { // group or channel + + let predicate = NSPredicate(format: "id = %lld", message.igpAuthor.igpRoom.igpRoomID) + if let roomInfo = realm.objects(IGRoom.self).filter(predicate).first { + roomId = roomInfo.id + if roomInfo.groupRoom != nil { + roomType = .group + } else { + roomType = .channel + } + } + } + + let seenStatus = IGRecentsTableViewController.visibleChat[roomId] + + if seenStatus != nil && seenStatus! { + roomMessageStatus = .seen + } + + sendSeenForReceivedMessage(roomId: roomId, roomType: roomType, message: message, status: roomMessageStatus) + } + } + + private func sendSeenForReceivedMessage(roomId: Int64, roomType: IGRoom.IGType, message: IGPRoomMessage, status: IGPRoomMessageStatus) { + if message.igpAuthor.igpHash == IGAppManager.sharedManager.authorHash() || message.igpStatus == status || (message.igpStatus == .seen && status == .delivered) { + return + } + + var messageStatus: IGRoomMessageStatus = .seen + if status == .delivered { + messageStatus = .delivered + } + + switch roomType { + case .chat: + IGChatUpdateStatusRequest.Generator.generate(roomID: roomId, messageID: message.igpMessageID, status: messageStatus).success({ (responseProto) in + switch responseProto { + case let response as IGPChatUpdateStatusResponse: + IGChatUpdateStatusRequest.Handler.interpret(response: response) + default: + break + } + }).error({ (errorCode, waitTime) in + + }).send() + case .group: + IGGroupUpdateStatusRequest.Generator.generate(roomID: roomId, messageID: message.igpMessageID, status: messageStatus).success({ (responseProto) in + switch responseProto { + case let response as IGPGroupUpdateStatusResponse: + IGGroupUpdateStatusRequest.Handler.interpret(response: response) + default: + break + } + }).error({ (errorCode, waitTime) in + + }).send() + break + case .channel: + /* + if let message = self.messages?.last { + IGChannelGetMessagesStatsRequest.Generator.generate(messages: [message], room: self.room!).success({ (responseProto) in + + }).error({ (errorCode, waitTime) in + + }).send() + } + */ + break + } + } + } diff --git a/iGap/General/IGGlobal.swift b/iGap/General/IGGlobal.swift index 0b4463a..ea4cac5 100644 --- a/iGap/General/IGGlobal.swift +++ b/iGap/General/IGGlobal.swift @@ -44,6 +44,10 @@ class IGGlobal { return randomString } + public class func randomId() -> Int64 { + return Int64(arc4random()) + (Int64(arc4random()) << 32) + } + /* if device is iPad return "alert" style otherwise will be returned "actionSheet" style */ public class func detectAlertStyle() -> UIAlertControllerStyle{ if UIDevice.current.userInterfaceIdiom == .phone { @@ -84,7 +88,7 @@ extension UIColor { } //MARK: General Colors - class func organizationalColor() -> UIColor { + class func organizationalColor() -> UIColor { // iGap Color return UIColor(red:0/255.0, green:176.0/255.0, blue:191.0/255.0, alpha:1.0) } @@ -597,6 +601,14 @@ extension String { return ceil(boundingBox.width) } + + public func getExtension() -> String? { + let ext = (self as NSString).pathExtension + if ext.isEmpty { + return nil + } + return ext + } } extension Array where Element: Hashable { @@ -606,3 +618,11 @@ extension Array where Element: Hashable { return Array(thisSet.symmetricDifference(otherSet)) } } + +extension Array { + func chunks(_ chunkSize: Int) -> [[Element]] { + return stride(from: 0, to: self.count, by: chunkSize).map { + Array(self[$0.. Results!{ if lastId == 0 { - let predicate = NSPredicate(format: "roomId = %lld AND isDeleted == false", self.room!.id) + let predicate = NSPredicate(format: "roomId = %lld AND isDeleted == false AND id != %lld", self.room!.id, 0) allMessages = try! Realm().objects(IGRoomMessage.self).filter(predicate).sorted(by: sortProperties) let messageCount = allMessages.count @@ -410,7 +411,7 @@ class IGMessageViewController: UIViewController, DidSelectLocationDelegate , UIG } } - let predicate = NSPredicate(format: "roomId = %lld AND id >= %lld AND isDeleted == false", self.room!.id, lastId) + let predicate = NSPredicate(format: "roomId = %lld AND id >= %lld AND isDeleted == false AND id != %lld", self.room!.id, lastId, 0) let messages = try! Realm().objects(IGRoomMessage.self).filter(predicate).sorted(by: sortProperties) DispatchQueue.main.async { @@ -487,6 +488,7 @@ class IGMessageViewController: UIViewController, DidSelectLocationDelegate , UIG override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) + IGRecentsTableViewController.visibleChat[(room?.id)!] = true IGAppManager.sharedManager.currentMessagesNotificationToekn = self.notificationToken let navigationItem = self.navigationItem as! IGNavigationItem // _ = Observable.from(object: room!) @@ -536,10 +538,10 @@ class IGMessageViewController: UIViewController, DidSelectLocationDelegate , UIG override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) + IGRecentsTableViewController.visibleChat[(room?.id)!] = false IGAppManager.sharedManager.currentMessagesNotificationToekn = nil self.room!.saveDraft(inputTextView.text, replyToMessage: selectedMessageToReply) self.sendCancelTyping() - self.isInMessageViewController = false self.sendCancelRecoringVoice() if let room = self.room { IGFactory.shared.markAllMessagesAsRead(roomId: room.id) @@ -594,12 +596,12 @@ class IGMessageViewController: UIViewController, DidSelectLocationDelegate , UIG } private func sendSeenForMessage(_ message: IGRoomMessage) { - if message.status == .seen { + if message.authorHash == IGAppManager.sharedManager.authorHash() || message.status == .seen { return } switch self.room!.type { case .chat: - if isInMessageViewController { + if IGRecentsTableViewController.visibleChat[(room?.id)!]! { IGChatUpdateStatusRequest.Generator.generate(roomID: self.room!.id, messageID: message.id, status: .seen).success({ (responseProto) in switch responseProto { case let response as IGPChatUpdateStatusResponse: @@ -612,7 +614,7 @@ class IGMessageViewController: UIViewController, DidSelectLocationDelegate , UIG }).send() } case .group: - if isInMessageViewController { + if IGRecentsTableViewController.visibleChat[(room?.id)!]! { IGGroupUpdateStatusRequest.Generator.generate(roomID: self.room!.id, messageID: message.id, status: .seen).success({ (responseProto) in switch responseProto { case let response as IGPGroupUpdateStatusResponse: @@ -626,7 +628,7 @@ class IGMessageViewController: UIViewController, DidSelectLocationDelegate , UIG } break case .channel: - if isInMessageViewController { + if IGRecentsTableViewController.visibleChat[(room?.id)!]! { if let message = self.messages?.last { IGChannelGetMessagesStatsRequest.Generator.generate(messages: [message], room: self.room!).success({ (responseProto) in @@ -772,7 +774,139 @@ class IGMessageViewController: UIViewController, DidSelectLocationDelegate , UIG } + func groupPin(messageId: Int64 = 0){ + + var message = "Are you sure unpin this message?" + var title = "Unpin For All Users" + var titleMe = "Unpin Just For Me" + if messageId != 0 { + message = "Are you sure pin this message?" + title = "Pin" + } + + let alertC = UIAlertController(title: nil, message: message, preferredStyle: IGGlobal.detectAlertStyle()) + let unpin = UIAlertAction(title: title, style: .default, handler: { (action) in + IGGroupPinMessageRequest.Generator.generate(roomId: (self.room?.id)!, messageId: messageId).success({ (protoResponse) in + DispatchQueue.main.async { + if let groupPinMessage = protoResponse as? IGPGroupPinMessageResponse { + if groupPinMessage.hasIgpPinnedMessage { + self.txtPinnedMessage.text = IGRoomMessage.detectPinMessageProto(message: groupPinMessage.igpPinnedMessage) + self.pinnedMessageView.isHidden = false + } else { + self.pinnedMessageView.isHidden = true + } + IGGroupPinMessageRequest.Handler.interpret(response: groupPinMessage) + } + } + }).error({ (errorCode, waitTime) in + switch errorCode { + case .timeout: + DispatchQueue.main.async { + let alert = UIAlertController(title: "Timeout", message: "Please try again later for unpin message", preferredStyle: .alert) + let okAction = UIAlertAction(title: "OK", style: .default, handler: nil) + alert.addAction(okAction) + self.present(alert, animated: true, completion: nil) + } + default: + break + } + + }).send() + }) + + let unpinJustForMe = UIAlertAction(title: titleMe, style: .default, handler: { (action) in + self.pinnedMessageView.isHidden = true + IGFactory.shared.roomPinMessage(roomId: (self.room?.id)!) + }) + + let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + + alertC.addAction(unpin) + if messageId == 0 { + alertC.addAction(unpinJustForMe) + } + alertC.addAction(cancel) + self.present(alertC, animated: true, completion: nil) + } + func channelPin(messageId: Int64 = 0){ + + var message = "Are you sure unpin this message?" + var title = "Unpin" + var titleMe = "Unpin Just For Me" + if messageId != 0 { + message = "Are you sure pin this message?" + title = "Pin" + } + + let alertC = UIAlertController(title: nil, message: message, preferredStyle: IGGlobal.detectAlertStyle()) + let unpin = UIAlertAction(title: title, style: .default, handler: { (action) in + IGChannelPinMessageRequest.Generator.generate(roomId: (self.room?.id)!, messageId: messageId).success({ (protoResponse) in + DispatchQueue.main.async { + if let channelPinMessage = protoResponse as? IGPChannelPinMessageResponse { + if channelPinMessage.hasIgpPinnedMessage { + self.txtPinnedMessage.text = IGRoomMessage.detectPinMessageProto(message: channelPinMessage.igpPinnedMessage) + self.pinnedMessageView.isHidden = false + } else { + self.pinnedMessageView.isHidden = true + } + IGChannelPinMessageRequest.Handler.interpret(response: channelPinMessage) + } + } + }).error({ (errorCode, waitTime) in + switch errorCode { + case .timeout: + DispatchQueue.main.async { + let alert = UIAlertController(title: "Timeout", message: "Please try again later for unpin message", preferredStyle: .alert) + let okAction = UIAlertAction(title: "OK", style: .default, handler: nil) + alert.addAction(okAction) + self.present(alert, animated: true, completion: nil) + } + default: + break + } + + }).send() + }) + + let unpinJustForMe = UIAlertAction(title: titleMe, style: .default, handler: { (action) in + self.pinnedMessageView.isHidden = true + IGFactory.shared.roomPinMessage(roomId: (self.room?.id)!) + }) + + let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) + + alertC.addAction(unpin) + if messageId == 0 { + alertC.addAction(unpinJustForMe) + } + alertC.addAction(cancel) + self.present(alertC, animated: true, completion: nil) + } + + func groupPinGranted() -> Bool{ + if room?.type == .group && room?.groupRoom?.role != .member { + return true + } + return false + } + + func channelPinGranted() -> Bool{ + if room?.type == .channel && room?.channelRoom?.role != .member { + return true + } + return false + } + + @IBAction func didTapOnPinClose(_ sender: UIButton) { + if groupPinGranted() { + self.groupPin() + return + } else if channelPinGranted() { + self.channelPin() + return + } + } //MARK: IBActions @IBAction func didTapOnSendButton(_ sender: UIButton) { @@ -871,13 +1005,12 @@ class IGMessageViewController: UIViewController, DidSelectLocationDelegate , UIG message.type = .text } message.repliedTo = selectedMessageToReply - message.forwardedFrom = selectedMessageToForwardToThisRoom - message.roomId = self.room!.id let detachedMessage = message.detach() IGFactory.shared.saveNewlyWriitenMessageToDatabase(detachedMessage) + message.forwardedFrom = selectedMessageToForwardToThisRoom // Hint: if use this line before "saveNewlyWriitenMessageToDatabase" app will be crashed IGMessageSender.defaultSender.send(message: message, to: room!) self.inputBarSendButton.isHidden = true @@ -928,7 +1061,9 @@ class IGMessageViewController: UIViewController, DidSelectLocationDelegate , UIG let randomString = IGGlobal.randomString(length: 16) + "_" let fileNameOnDisk = randomString + selectedFile.fileName! attachment.fileNameOnDisk = fileNameOnDisk - self.saveAttachmentToLocalStorage(data: imgData!, fileNameOnDisk: fileNameOnDisk) + DispatchQueue.main.async { + self.saveAttachmentToLocalStorage(data: imgData!, fileNameOnDisk: fileNameOnDisk) + } attachment.height = Double((scaledImage?.size.height)!) attachment.width = Double((scaledImage?.size.width)!) @@ -1749,16 +1884,18 @@ extension IGMessageViewController: IGMessageCollectionViewDataSource { let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionFooter, withReuseIdentifier: IGMessageLogCollectionViewCell.cellReuseIdentifier(), for: indexPath) as! IGMessageLogCollectionViewCell - if let message = messages?[indexPath.section] { - if message.shouldFetchBefore { - header.setText("Loading ...") - } else { - - let dayTimePeriodFormatter = DateFormatter() - dayTimePeriodFormatter.dateFormat = "MMMM dd" - dayTimePeriodFormatter.calendar = Calendar.current - let dateString = dayTimePeriodFormatter.string(from: message.creationTime!) - header.setText(dateString) + if indexPath.section <= messages.count { + if let message = messages?[indexPath.section] { + if message.shouldFetchBefore { + header.setText("Loading ...") + } else { + + let dayTimePeriodFormatter = DateFormatter() + dayTimePeriodFormatter.dateFormat = "MMMM dd" + dayTimePeriodFormatter.calendar = Calendar.current + let dateString = dayTimePeriodFormatter.string(from: message.creationTime!) + header.setText(dateString) + } } } reusableview = header @@ -1800,7 +1937,7 @@ extension IGMessageViewController: UICollectionViewDelegateFlowLayout { if (messages!.count < 20 && lowerAllow) { // HINT: this number(20) should set lower than getMessageLimit(25) for work correct lowerAllow = false - let predicate = NSPredicate(format: "roomId = %lld AND isDeleted == false", self.room!.id) + let predicate = NSPredicate(format: "roomId = %lld AND isDeleted == false AND id != %lld", self.room!.id, 0) messages = try! Realm().objects(IGRoomMessage.self).filter(predicate).sorted(by: sortProperties) updateObserver() @@ -1837,7 +1974,7 @@ extension IGMessageViewController: UICollectionViewDelegateFlowLayout { let predicate = NSPredicate(format: "roomId = %lld", self.room!.id) if let message = try! Realm().objects(IGRoomMessage.self).filter(predicate).sorted(by: sortProperties).last { if isFirstHistory { - let predicate = NSPredicate(format: "roomId = %lld AND isDeleted == false", self.room!.id) + let predicate = NSPredicate(format: "roomId = %lld AND isDeleted == false AND id != %lld", self.room!.id, 0) messages = try! Realm().objects(IGRoomMessage.self).filter(predicate).sorted(by: sortProperties) updateObserver() DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { @@ -2004,6 +2141,15 @@ extension IGMessageViewController: GrowingTextViewDelegate { self.setCollectionViewInset() }) } + + func managePinnedMessage(){ + if room?.pinMessage != nil && room?.pinMessage?.id != room?.deletedPinMessageId { + txtPinnedMessage.text = IGRoomMessage.detectPinMessage(message: (room?.pinMessage)!) + pinnedMessageView.isHidden = false + } else { + pinnedMessageView.isHidden = true + } + } } //MARK: - AVAudioRecorderDelegate @@ -2044,11 +2190,31 @@ extension IGMessageViewController: AVAudioRecorderDelegate { //MARK: - IGMessageGeneralCollectionViewCellDelegate extension IGMessageViewController: IGMessageGeneralCollectionViewCellDelegate { func didTapAndHoldOnMessage(cellMessage: IGRoomMessage, cell: IGMessageGeneralCollectionViewCell) { - print(#function) let alertC = UIAlertController(title: nil, message: nil, preferredStyle: IGGlobal.detectAlertStyle()) let copy = UIAlertAction(title: "Copy", style: .default, handler: { (action) in self.copyMessage(cellMessage) }) + + var pinTitle = "Pin Message" + if self.room?.pinMessage != nil && self.room?.pinMessage?.id == cellMessage.id { + pinTitle = "Unpin Message" + } + + let pin = UIAlertAction(title: pinTitle, style: .default, handler: { (action) in + if self.groupPinGranted(){ + if self.room?.pinMessage != nil && self.room?.pinMessage?.id == cellMessage.id { + self.groupPin() + } else { + self.groupPin(messageId: cellMessage.id) + } + } else if self.channelPinGranted() { + if self.room?.pinMessage != nil && self.room?.pinMessage?.id == cellMessage.id { + self.channelPin() + } else { + self.channelPin(messageId: cellMessage.id) + } + } + }) let reply = UIAlertAction(title: "Reply", style: .default, handler: { (action) in self.replyMessage(cellMessage) }) @@ -2093,6 +2259,10 @@ extension IGMessageViewController: IGMessageGeneralCollectionViewCellDelegate { //Copy alertC.addAction(copy) + if groupPinGranted() || channelPinGranted() { + alertC.addAction(pin) + } + //Reply if !(room!.isReadOnly){ alertC.addAction(reply) diff --git a/iGap/Libraries/Chat Screen/View/IGMessageLogCollectionViewCell.swift b/iGap/Libraries/Chat Screen/View/IGMessageLogCollectionViewCell.swift index cc918f3..2374015 100644 --- a/iGap/Libraries/Chat Screen/View/IGMessageLogCollectionViewCell.swift +++ b/iGap/Libraries/Chat Screen/View/IGMessageLogCollectionViewCell.swift @@ -47,13 +47,12 @@ class IGMessageLogCollectionViewCell: IGMessageGeneralCollectionViewCell { override func setMessage(_ message: IGRoomMessage, isIncommingMessage: Bool, shouldShowAvatar: Bool, messageSizes: RoomMessageCalculatedSize, isPreviousMessageFromSameSender: Bool, isNextMessageFromSameSender: Bool) { - self.logLabel.textColor = UIColor.white - - self.logLabel.text = IGRoomMessageLog.textForLogMessage(message) - - //self.logLabel.text = IGRoomMessageLog. //bodyString - + if message.log?.type == .pinnedMessage { + self.logLabel.text = IGRoomMessage.detectPinMessage(message: message) + } else { + self.logLabel.text = IGRoomMessageLog.textForLogMessage(message) + } self.labelBackgrondView.layer.cornerRadius = 12.0 } diff --git a/iGap/Model/AppDelegate/AppDelegate.swift b/iGap/Model/AppDelegate/AppDelegate.swift index aa7f43b..85c3f18 100644 --- a/iGap/Model/AppDelegate/AppDelegate.swift +++ b/iGap/Model/AppDelegate/AppDelegate.swift @@ -31,7 +31,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // // _ = try! Realm() let config = Realm.Configuration( - schemaVersion: 12, + schemaVersion: 15, // Set the block which will be called automatically when opening a Realm with // a schema version lower than the one set above @@ -63,6 +63,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate { //version 0.3.1 build 454 } else if (oldSchemaVersion < 12) { //version 0.3.2 build 455 + } else if (oldSchemaVersion < 13) { + //version 0.4.6 build 461 + } else if (oldSchemaVersion < 14) { + //version 0.4.7 build 462 + } else if (oldSchemaVersion < 15) { + //version 0.4.8 build 463 } }) Realm.Configuration.defaultConfiguration = config diff --git a/iGap/Model/Factories/IGFactory.swift b/iGap/Model/Factories/IGFactory.swift index ba7434c..5e09a1a 100644 --- a/iGap/Model/Factories/IGFactory.swift +++ b/iGap/Model/Factories/IGFactory.swift @@ -331,6 +331,11 @@ class IGFactory: NSObject { //MARK: -------------------------------------------------------- //MARK: ▶︎▶︎ Messages func saveIgpMessagesToDatabase(_ igpMessages: [IGPRoomMessage], for roomId: Int64, updateLastMessage: Bool, isFromSharedMedia: Bool?, isFromSendMessage: Bool=false) { + + if IGRecentsTableViewController.messageReceiveDelegat != nil { + IGRecentsTableViewController.messageReceiveDelegat.onMessageRecieve(messages: igpMessages) + } + var userIDs = [Int64: String]() var roomIDs = Set() @@ -747,7 +752,6 @@ class IGFactory: NSObject { let task = IGFactoryTask() task.task = { IGDatabaseManager.shared.perfrmOnDatabaseThread { - print(" ======> setting needs to fetch before message") let predicate = NSPredicate(format: "id = %lld AND roomId = %lld", messageId, roomId) if let messageInDb = IGDatabaseManager.shared.realm.objects(IGRoomMessage.self).filter(predicate).first { try! IGDatabaseManager.shared.realm.write { @@ -2459,5 +2463,42 @@ class IGFactory: NSObject { self.performNextFactoryTaskIfPossible() } + + func roomPinMessage(roomId: Int64, messageId: Int64 = 0) { + let task = IGFactoryTask() + task.task = { + IGDatabaseManager.shared.perfrmOnDatabaseThread { + let roomPredicate = NSPredicate(format: "id = %lld", roomId) + if let roomInDb = try! Realm().objects(IGRoom.self).filter(roomPredicate).first { + + var pinMessage : IGRoomMessage? = nil + + if messageId != 0 { + let messagePredicate = NSPredicate(format: "id = %lld", messageId) + pinMessage = try! Realm().objects(IGRoomMessage.self).filter(messagePredicate).first + } + + try! IGDatabaseManager.shared.realm.write { + roomInDb.pinMessage = pinMessage + if messageId == 0 { + if pinMessage != nil { + roomInDb.deletedPinMessageId = (pinMessage?.id)! + } + } + } + } + IGFactory.shared.performInFactoryQueue { + task.success!() + } + } + } + task.success { + self.removeTaskFromQueueAndPerformNext(task) + }.error { + self.removeTaskFromQueueAndPerformNext(task) + }.addToQueue() + self.performNextFactoryTaskIfPossible() + + } } diff --git a/iGap/Model/Managers/IGContactManager.swift b/iGap/Model/Managers/IGContactManager.swift index fcd9c54..6e6ae3b 100644 --- a/iGap/Model/Managers/IGContactManager.swift +++ b/iGap/Model/Managers/IGContactManager.swift @@ -16,10 +16,20 @@ class IGContactManager: NSObject { static let sharedManager = IGContactManager() private var contactStore = CNContactStore() private var contacts = [IGContact]() + private var contactsStruct = [ContactsStruct]() + private var contactsStructChunk = [[ContactsStruct]]() + private var contactIndex = 0 + private var CONTACT_IMPORT_LIMIT = 100 private override init() { super.init() } + struct ContactsStruct { + var phoneNumber: String? + var firstName: String? + var lastName: String? + } + func savePhoneContactsToDatabase() { // self.contactStore.requestAccessForEntityType(CNEntityType.Contacts, completionHandler: { (access, accessError) -> Void in @@ -70,31 +80,49 @@ class IGContactManager: NSObject { for contact in results { for phone in contact.phoneNumbers { contacts.append(IGContact(phoneNumber: phone.value.stringValue, firstName: contact.givenName, lastName: contact.familyName)) + + var structContact = ContactsStruct() + structContact.phoneNumber = phone.value.stringValue + structContact.firstName = contact.givenName + structContact.lastName = contact.familyName + contactsStruct.append(structContact) } } IGFactory.shared.saveContactsToDatabase(contacts) } - - func sendContactsToServer() { - IGUserContactsImportRequest.Generator.generate(contacts: contacts).success { (protoResponse) in + contactIndex = 0 + contactsStructChunk = contactsStruct.chunks(CONTACT_IMPORT_LIMIT) + if contactsStructChunk.count == 0 { + return + } + sendContact(phoneContacts: contactsStructChunk[0]) + contactIndex += 1 + } + + func sendContact(phoneContacts : [ContactsStruct]){ + IGUserContactsImportRequest.Generator.generateStruct(contacts: phoneContacts).success { (protoResponse) in switch protoResponse { case let contactImportResponse as IGPUserContactsImportResponse: IGUserContactsImportRequest.Handler.interpret(response: contactImportResponse) + if self.contactIndex < self.contactsStructChunk.count { + self.sendContact(phoneContacts: self.contactsStructChunk[self.contactIndex]) + } + self.contactIndex += 1 + break default: break } self.getContactListFromServer() - }.error { (errorCode, waitTime) in - - }.send() + }.error { (errorCode, waitTime) in + + }.send() } - func getContactListFromServer() { IGUserContactsGetListRequest.Generator.generate().success { (protoResponse) in switch protoResponse { diff --git a/iGap/Model/Managers/Request Manager/IGRequestManager.swift b/iGap/Model/Managers/Request Manager/IGRequestManager.swift index 5b94f9d..2ec5ae7 100644 --- a/iGap/Model/Managers/Request Manager/IGRequestManager.swift +++ b/iGap/Model/Managers/Request Manager/IGRequestManager.swift @@ -199,6 +199,8 @@ let protoClassesLookupTable: [Int: (proto: ResponseMessage.Type, reponseHandler: IGGroupRevokLinkRequest.Handler.self as IGRequest.Handler.Type), 30325: (IGPGroupEditMessageResponse.self as ResponseMessage.Type, IGGroupEditMessageRequest.Handler.self as IGRequest.Handler.Type), + 30326: (IGPGroupPinMessageResponse.self as ResponseMessage.Type, + IGGroupPinMessageRequest.Handler.self as IGRequest.Handler.Type), //Channel: 304xx 30400: (IGPChannelCreateResponse.self as ResponseMessage.Type, @@ -247,6 +249,10 @@ let protoClassesLookupTable: [Int: (proto: ResponseMessage.Type, reponseHandler: IGChannelUpdateSignatureRequest.Handler.self as IGRequest.Handler.Type), 30425: (IGPChannelEditMessageResponse.self as ResponseMessage.Type, IGChannelEditMessageRequest.Handler.self as IGRequest.Handler.Type), + 30426: (IGPChannelUpdateReactionStatusResponse.self as ResponseMessage.Type, + IGChannelUpdateReactionStatusRequest.Handler.self as IGRequest.Handler.Type), + 30427: (IGPChannelPinMessageResponse.self as ResponseMessage.Type, + IGChannelPinMessageRequest.Handler.self as IGRequest.Handler.Type), //Info: 305xx 30500: (IGPInfoLocationResponse.self as ResponseMessage.Type, diff --git a/iGap/Model/Objects/IGChannelRoom.swift b/iGap/Model/Objects/IGChannelRoom.swift index dc5a043..87652ab 100644 --- a/iGap/Model/Objects/IGChannelRoom.swift +++ b/iGap/Model/Objects/IGChannelRoom.swift @@ -102,6 +102,7 @@ class IGChannelRoom: Object { @objc dynamic var privateExtra: IGChannelPrivateExtra? @objc dynamic var publicExtra: IGChannelPublicExtra? @objc dynamic var isSignature: Bool = false + @objc dynamic var isVerified: Bool = false //MARK: ignored properties var type: IGType { get { @@ -173,6 +174,8 @@ class IGChannelRoom: Object { if igpChannelRoom.hasIgpPublicExtra{ self.publicExtra = IGChannelPublicExtra(igpPublicExtra: igpChannelRoom.igpPublicExtra, id: id) } + + self.isVerified = igpChannelRoom.igpVerified } diff --git a/iGap/Model/Objects/IGFile.swift b/iGap/Model/Objects/IGFile.swift index 9b270a2..0c1235b 100644 --- a/iGap/Model/Objects/IGFile.swift +++ b/iGap/Model/Objects/IGFile.swift @@ -315,7 +315,11 @@ class IGFile: Object { if let fileNameOnDisk = self.fileNameOnDisk { return NSURL(fileURLWithPath: documents).appendingPathComponent(fileNameOnDisk) } else if let cacheId = self.cacheID, let name = self.name { - return NSURL(fileURLWithPath: documents).appendingPathComponent(cacheId + name) + var path = NSURL(fileURLWithPath: documents).appendingPathComponent(cacheId + name) + if name.getExtension() == "mp3" || name.getExtension() == "ogg" { + path = path?.deletingPathExtension().appendingPathExtension("m4a") + } + return path } return nil } diff --git a/iGap/Model/Objects/IGRegisteredUser.swift b/iGap/Model/Objects/IGRegisteredUser.swift index 8daec2c..b6abd84 100644 --- a/iGap/Model/Objects/IGRegisteredUser.swift +++ b/iGap/Model/Objects/IGRegisteredUser.swift @@ -46,7 +46,9 @@ class IGRegisteredUser: Object { @objc dynamic var isMutual: Bool = false //current user have this user in his/her contacts @objc dynamic var isInContacts: Bool = false @objc dynamic var isBlocked: Bool = false + @objc dynamic var isVerified: Bool = false @objc dynamic var lastSeenStatusRaw: IGLastSeenStatus.RawValue = IGLastSeenStatus.longTimeAgo.rawValue + //ignored properties var lastSeenStatus: IGLastSeenStatus { get { @@ -133,6 +135,8 @@ class IGRegisteredUser: Object { if igpUser.hasIgpAvatar{ self.avatar = IGAvatar(igpAvatar: igpUser.igpAvatar)//.detach() } + + self.isVerified = igpUser.igpVerified } //detach from current realm diff --git a/iGap/Model/Objects/IGRoom.swift b/iGap/Model/Objects/IGRoom.swift index 16ae738..752c50b 100644 --- a/iGap/Model/Objects/IGRoom.swift +++ b/iGap/Model/Objects/IGRoom.swift @@ -42,6 +42,8 @@ class IGRoom: Object { @objc dynamic var clearIdString: String? @objc dynamic var muteRoom: IGRoomMute.RawValue = IGRoomMute.unmute.rawValue @objc dynamic var pinId: Int64 = 0 + @objc dynamic var pinMessage: IGRoomMessage? + @objc dynamic var deletedPinMessageId:Int64 = 0 //ignored properties var currenctActionsByUsers = Dictionary() //actorId, action @@ -153,6 +155,8 @@ class IGRoom: Object { if igpRoom.hasIgpChannelRoomExtra { self.channelRoom = IGChannelRoom(igpChannelRoom: igpRoom.igpChannelRoomExtra, id: self.id) } + + self.pinMessage = IGRoomMessage(igpMessage: igpRoom.igpPinnedMessage, roomId: igpRoom.igpID) } diff --git a/iGap/Model/Objects/IGRoomMessage.swift b/iGap/Model/Objects/IGRoomMessage.swift index a11286f..d097b5f 100644 --- a/iGap/Model/Objects/IGRoomMessage.swift +++ b/iGap/Model/Objects/IGRoomMessage.swift @@ -47,6 +47,7 @@ class IGRoomMessage: Object { @objc dynamic var typeRaw: IGRoomMessageType.RawValue = IGRoomMessageType.unknown.rawValue @objc dynamic var statusRaw: IGRoomMessageStatus.RawValue = IGRoomMessageStatus.unknown.rawValue @objc dynamic var temporaryId: String? + @objc dynamic var randomId: Int64 = -1 var status: IGRoomMessageStatus { get { @@ -209,6 +210,8 @@ class IGRoomMessage: Object { if igpMessage.igpPreviousMessageID != 0 { self.previuosMessageUID = igpMessage.igpPreviousMessageID } + + self.randomId = igpMessage.igpRandomID } //used when sending a message @@ -224,6 +227,7 @@ class IGRoomMessage: Object { self.status = IGRoomMessageStatus.sending self.temporaryId = IGGlobal.randomString(length: 64) self.primaryKeyId = IGGlobal.randomString(length: 64) + self.randomId = IGGlobal.randomId() let predicate = NSPredicate(format: "id = %lld", IGAppManager.sharedManager.userID()!) let realm = try! Realm() if let userInDb = realm.objects(IGRegisteredUser.self).filter(predicate).first { @@ -242,6 +246,76 @@ class IGRoomMessage: Object { return "\(prefix)\(messageID)_\(roomID)" } + internal static func detectPinMessage(message: IGRoomMessage) -> String{ + + var messageType = message.type + if let reply = message.repliedTo { + messageType = reply.type + } + let pinText = "is pinned" + + if messageType == .text { + if let reply = message.repliedTo { + return "'\(reply.message!)' \(pinText)" + } + return "'\(message.message!)' \(pinText)" + } else if messageType == .image || messageType == .imageAndText { + return "'image' \(pinText)" + } else if messageType == .video || messageType == .videoAndText { + return "'video' \(pinText)" + } else if messageType == .gif || messageType == .gifAndText { + return "'gif' \(pinText)" + } else if messageType == .audio || messageType == .audioAndText { + return "'audio' \(pinText)" + } else if messageType == .file || messageType == .fileAndText { + return "'file' \(pinText)" + } else if messageType == .contact { + return "'contact' \(pinText)" + } else if messageType == .voice { + return "'voice' \(pinText)" + } else if messageType == .location { + return "'location' \(pinText)" + } + + return "'unknown' pinned message" + } + + internal static func detectPinMessageProto(message: IGPRoomMessage) -> String{ + + var messageType = message.igpMessageType + let pinText = "is pinned" + + if message.hasIgpReplyTo { + messageType = message.igpReplyTo.igpMessageType + } + + if messageType == .text { + if message.hasIgpReplyTo { + return "'\(message.igpReplyTo.igpMessage)' \(pinText)" + } + return "'\(message.igpMessage)' \(pinText)" + + } else if messageType == .image || messageType == .imageText { + return "'image' \(pinText)" + } else if messageType == .video || messageType == .videoText { + return "'video' \(pinText)" + } else if messageType == .gif || messageType == .gifText { + return "'gif' \(pinText)" + } else if messageType == .audio || messageType == .audioText { + return "'audio' \(pinText)" + } else if messageType == .file || messageType == .fileText { + return "'file' \(pinText)" + } else if messageType == .contact { + return "'contact' \(pinText)" + } else if messageType == .voice { + return "'voice' \(pinText)" + } else if messageType == .location { + return "'location' \(pinText)" + } + + return "'unknown' pinned message" + } + //detach from current realm func detach() -> IGRoomMessage { let detachedMessage = IGRoomMessage(value: self) diff --git a/iGap/Model/Objects/IGRoomMessageLog.swift b/iGap/Model/Objects/IGRoomMessageLog.swift index 2a6324c..6d65be6 100644 --- a/iGap/Model/Objects/IGRoomMessageLog.swift +++ b/iGap/Model/Objects/IGRoomMessageLog.swift @@ -28,6 +28,7 @@ class IGRoomMessageLog: Object { case missedVideoCall case missedScreenShare case missedSecretChat + case pinnedMessage } enum ExtraType: Int { @@ -136,6 +137,8 @@ class IGRoomMessageLog: Object { }else { bodyString = "Missed secret chat" } + case .pinnedMessage: + bodyString = IGRoomMessage.detectPinMessage(message: message) } if let target = message.log?.targetUser { @@ -189,6 +192,8 @@ class IGRoomMessageLog: Object { self.type = .missedSecretChat case .missedScreenShare: self.type = .missedScreenShare + case .pinnedMessage: + self.type = .pinnedMessage default: break } diff --git a/iGap/Model/Objects/Requests/IGRequestChannel.swift b/iGap/Model/Objects/Requests/IGRequestChannel.swift index 3cb38a3..75158f0 100644 --- a/iGap/Model/Objects/Requests/IGRequestChannel.swift +++ b/iGap/Model/Objects/Requests/IGRequestChannel.swift @@ -731,4 +731,53 @@ class IGChannelDeleteMessageRequest: IGRequest { } } +class IGChannelUpdateReactionStatusRequest : IGRequest { + class Generator : IGRequest.Generator{ + class func generate(roomId: Int64, reactionStatus: Bool) -> IGRequestWrapper { + var channelUpdateReactionStatus = IGPChannelUpdateReactionStatus() + channelUpdateReactionStatus.igpRoomID = roomId + channelUpdateReactionStatus.igpReactionStatus = reactionStatus + return IGRequestWrapper(message: channelUpdateReactionStatus, actionID: 426) + } + } + + class Handler : IGRequest.Handler{ + class func interpret(response: IGPChannelUpdateReactionStatusResponse) { + //response.igpRoomID + //response.igpReactionStatus + //IGFactory.shared.editMessage(response.igpMessageID, roomID: response.igpRoomID, message: response.igpMessage, messageType: IGRoomMessageType.unknown.fromIGP(response.igpMessageType), messageVersion: response.igpMessageVersion) + } + + override class func handlePush(responseProtoMessage: Message) { + if let channelUpdateReactionStatus = responseProtoMessage as? IGPChannelUpdateReactionStatusResponse { + self.interpret(response: channelUpdateReactionStatus) + } + } + } +} + +class IGChannelPinMessageRequest : IGRequest { + class Generator : IGRequest.Generator{ + class func generate(roomId: Int64, messageId: Int64 = 0) -> IGRequestWrapper { + var channelPinMessage = IGPChannelPinMessage() + channelPinMessage.igpRoomID = roomId + channelPinMessage.igpMessageID = messageId + return IGRequestWrapper(message: channelPinMessage, actionID: 427) + } + } + + class Handler : IGRequest.Handler{ + class func interpret(response: IGPChannelPinMessageResponse) { + IGFactory.shared.saveIgpMessagesToDatabase([response.igpPinnedMessage], for: response.igpRoomID, updateLastMessage: false , isFromSharedMedia: false) + IGFactory.shared.roomPinMessage(roomId: response.igpRoomID, messageId: response.igpPinnedMessage.igpMessageID) + } + + override class func handlePush(responseProtoMessage: Message) { + if let channelPinMessage = responseProtoMessage as? IGPChannelPinMessageResponse { + self.interpret(response: channelPinMessage) + } + } + } +} + diff --git a/iGap/Model/Objects/Requests/IGRequestGroup.swift b/iGap/Model/Objects/Requests/IGRequestGroup.swift index cb76a0c..2442968 100644 --- a/iGap/Model/Objects/Requests/IGRequestGroup.swift +++ b/iGap/Model/Objects/Requests/IGRequestGroup.swift @@ -797,3 +797,28 @@ class IGGroupEditMessageRequest : IGRequest { } } } + + +class IGGroupPinMessageRequest : IGRequest { + class Generator : IGRequest.Generator{ + class func generate(roomId: Int64, messageId: Int64 = 0) -> IGRequestWrapper { + var groupPinMessage = IGPGroupPinMessage() + groupPinMessage.igpRoomID = roomId + groupPinMessage.igpMessageID = messageId + return IGRequestWrapper(message: groupPinMessage, actionID: 326) + } + } + + class Handler : IGRequest.Handler{ + class func interpret(response: IGPGroupPinMessageResponse) { + IGFactory.shared.saveIgpMessagesToDatabase([response.igpPinnedMessage], for: response.igpRoomID, updateLastMessage: false , isFromSharedMedia: false) + IGFactory.shared.roomPinMessage(roomId: response.igpRoomID, messageId: response.igpPinnedMessage.igpMessageID) + } + + override class func handlePush(responseProtoMessage: Message) { + if let groupPinMessage = responseProtoMessage as? IGPGroupPinMessageResponse { + self.interpret(response: groupPinMessage) + } + } + } +} diff --git a/iGap/Model/Objects/Requests/IGRequestUser.swift b/iGap/Model/Objects/Requests/IGRequestUser.swift index cd2510c..aa6901b 100644 --- a/iGap/Model/Objects/Requests/IGRequestUser.swift +++ b/iGap/Model/Objects/Requests/IGRequestUser.swift @@ -241,6 +241,26 @@ class IGUserContactsImportRequest : IGRequest { contactsImportRequestMessage.igpForce = force return IGRequestWrapper(message: contactsImportRequestMessage, actionID: 106) } + + class func generateStruct(contacts: [IGContactManager.ContactsStruct], force: Bool = false) -> IGRequestWrapper { + var contactsImportRequestMessage = IGPUserContactsImport() + var igpContacts = Array() + for contact in contacts { + var igpContact = IGPUserContactsImport.IGPContact() + if let firstName = contact.firstName { + igpContact.igpFirstName = firstName + } + if let lastName = contact.lastName { + igpContact.igpLastName = lastName + } + igpContact.igpPhone = contact.phoneNumber! + igpContact.igpClientID = contact.phoneNumber! + igpContacts.append(igpContact) + } + contactsImportRequestMessage.igpContacts = igpContacts + contactsImportRequestMessage.igpForce = force + return IGRequestWrapper(message: contactsImportRequestMessage, actionID: 106) + } } class Handler : IGRequest.Handler{ diff --git a/iGap/Supporting FIles/GoogleService-Info.plist b/iGap/SupportingFiles/GoogleService-Info.plist similarity index 100% rename from iGap/Supporting FIles/GoogleService-Info.plist rename to iGap/SupportingFiles/GoogleService-Info.plist diff --git a/iGap/Supporting FIles/Info.plist b/iGap/SupportingFiles/Info.plist similarity index 94% rename from iGap/Supporting FIles/Info.plist rename to iGap/SupportingFiles/Info.plist index 66f833f..4234424 100644 --- a/iGap/Supporting FIles/Info.plist +++ b/iGap/SupportingFiles/Info.plist @@ -15,9 +15,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.4.4 + 0.4.8 CFBundleVersion - 459 + 463 Fabric APIKey @@ -52,6 +52,8 @@ This access is that perhaps you are sending your position to someone else or usi NSMicrophoneUsageDescription iGap needs to access your Microphone. It has access to record your voice, you want to record your voice and send it to another. + NSPhotoLibraryAddUsageDescription + $(PRODUCT_NAME) needs to access your gallery for save this photo NSPhotoLibraryUsageDescription iGap needs to access your Photo-Library. This is the option to choose a photo from your gallery and send it to someone else. diff --git a/iGap/Supporting FIles/iGap-Bridging-Header.h b/iGap/SupportingFiles/iGap-Bridging-Header.h similarity index 100% rename from iGap/Supporting FIles/iGap-Bridging-Header.h rename to iGap/SupportingFiles/iGap-Bridging-Header.h diff --git a/iGap/VIew/Assets.xcassets/Verified/Contents.json b/iGap/VIew/Assets.xcassets/Verified/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/iGap/VIew/Assets.xcassets/Verified/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Contents.json b/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Contents.json new file mode 100644 index 0000000..1ee5007 --- /dev/null +++ b/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Verify_20x20.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Verify_40x40.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Verify_60x60.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Verify_20x20.png b/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Verify_20x20.png new file mode 100644 index 0000000..cf0edb9 Binary files /dev/null and b/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Verify_20x20.png differ diff --git a/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Verify_40x40.png b/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Verify_40x40.png new file mode 100644 index 0000000..25df719 Binary files /dev/null and b/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Verify_40x40.png differ diff --git a/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Verify_60x60.png b/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Verify_60x60.png new file mode 100644 index 0000000..d48162c Binary files /dev/null and b/iGap/VIew/Assets.xcassets/Verified/IG_Verify.imageset/Verify_60x60.png differ diff --git a/iGap/VIew/Base.lproj/Main.storyboard b/iGap/VIew/Base.lproj/Main.storyboard index ec71103..b1dcc0e 100644 --- a/iGap/VIew/Base.lproj/Main.storyboard +++ b/iGap/VIew/Base.lproj/Main.storyboard @@ -481,7 +481,7 @@ - + @@ -637,7 +637,7 @@ - + @@ -810,11 +810,64 @@ + + + @@ -825,8 +878,10 @@ + + @@ -862,8 +917,10 @@ + + @@ -871,7 +928,7 @@ - + @@ -1410,9 +1467,8 @@ - - - + + diff --git a/iGap/VIew/IGSettingStoryboard.storyboard b/iGap/VIew/IGSettingStoryboard.storyboard index 096541f..4f91b51 100644 --- a/iGap/VIew/IGSettingStoryboard.storyboard +++ b/iGap/VIew/IGSettingStoryboard.storyboard @@ -1,19 +1,16 @@ - + - + - - HelveticaNeue - iGap-Fontico @@ -27,12 +24,12 @@ - + - + @@ -40,7 +37,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -4028,7 +3977,7 @@ Please wait 0:59 - + @@ -4319,7 +4268,7 @@ Please wait 0:59 - + @@ -4397,7 +4346,7 @@ Please wait 0:59 - + @@ -5278,7 +5227,7 @@ kay*****@gm**.com - + diff --git a/iGap/VIew/Register.storyboard b/iGap/VIew/Register.storyboard index 8d31522..f16e01c 100644 --- a/iGap/VIew/Register.storyboard +++ b/iGap/VIew/Register.storyboard @@ -74,7 +74,7 @@ - + diff --git a/iGap/VIew/ReusableViews/Chat List Cell/IGChatRoomListTableViewCell.swift b/iGap/VIew/ReusableViews/Chat List Cell/IGChatRoomListTableViewCell.swift index a8023e3..e550cdb 100644 --- a/iGap/VIew/ReusableViews/Chat List Cell/IGChatRoomListTableViewCell.swift +++ b/iGap/VIew/ReusableViews/Chat List Cell/IGChatRoomListTableViewCell.swift @@ -39,6 +39,7 @@ class IGChatRoomListTableViewCell: MGSwipeTableCell { @IBOutlet weak var roomTypeIndicatorImageView: UIImageView! @IBOutlet weak var roomTitleLabelLeftConstraint: NSLayoutConstraint! @IBOutlet weak var imgMute: UIImageView! + @IBOutlet weak var imgVerified: UIImageView! let currentLoggedInUserID = IGAppManager.sharedManager.userID() @@ -146,12 +147,29 @@ class IGChatRoomListTableViewCell: MGSwipeTableCell { case .chat: roomTypeIndicatorImageView.image = nil roomTitleLabelLeftConstraint.constant = 16 + + if let user = room.chatRoom?.peer { + if user.isVerified { + imgVerified.isHidden = false + } else { + imgVerified.isHidden = true + } + } + case .group: roomTypeIndicatorImageView.image = UIImage(named: "IG_Chat_List_Type_Group") roomTitleLabelLeftConstraint.constant = 36 + imgVerified.isHidden = true + case .channel: roomTypeIndicatorImageView.image = UIImage(named: "IG_Chat_List_Type_Channel") roomTitleLabelLeftConstraint.constant = 36 + + if (room.channelRoom?.isVerified)! { + imgVerified.isHidden = false + } else { + imgVerified.isHidden = true + } } if room.mute == IGRoom.IGRoomMute.mute { @@ -221,7 +239,6 @@ class IGChatRoomListTableViewCell: MGSwipeTableCell { deliveryStateImageView.isHidden = true unreadCountLabel.isHidden = false unreadCountLabel.text = "\(room.unreadCount)" - // self.sendDeliveredMessage() let labelFrame = unreadCountLabel.textRect(forBounds: CGRect(x: 0, y: 0, width: CGFloat.greatestFiniteMagnitude, height: 18.0) , limitedToNumberOfLines: 1) lastMessageStatusContainerViewWidthConstraint.constant = max(lastMessageStatusContainerViewWidthConstraintDefault, labelFrame.size.width + 8) } else { @@ -335,39 +352,4 @@ class IGChatRoomListTableViewCell: MGSwipeTableCell { self.lastMessageLabel.text = "" } } - func sendDeliveredMessage(){ - if let message = self.room?.lastMessage{ - switch self.room!.type { - case .chat: - IGChatUpdateStatusRequest.Generator.generate(roomID: self.room!.id, messageID: message.id, status: .delivered).success({ (responseProto) in - switch responseProto { - case let response as IGPChatUpdateStatusResponse: - IGChatUpdateStatusRequest.Handler.interpret(response: response) - default: - break - } - }).error({ (errorCode, waitTime) in - - }).send() - case .group: - IGGroupUpdateStatusRequest.Generator.generate(roomID: self.room!.id, messageID: message.id, status: .delivered).success({ (responseProto) in - switch responseProto { - case let response as IGPGroupUpdateStatusResponse: - IGGroupUpdateStatusRequest.Handler.interpret(response: response) - default: - break - } - }).error({ (errorCode, waitTime) in - - }).send() - break - case .channel: - IGChannelGetMessagesStatsRequest.Generator.generate(messages: [message], room: self.room!).success({ (responseProto) in - - }).error({ (errorCode, waitTime) in - - }).send() - } - } - } } diff --git a/iGap/VIew/ReusableViews/Chat List Cell/IGChatRoomListTableViewCell.xib b/iGap/VIew/ReusableViews/Chat List Cell/IGChatRoomListTableViewCell.xib index e346c6b..2118626 100644 --- a/iGap/VIew/ReusableViews/Chat List Cell/IGChatRoomListTableViewCell.xib +++ b/iGap/VIew/ReusableViews/Chat List Cell/IGChatRoomListTableViewCell.xib @@ -1,11 +1,11 @@ - + - + @@ -27,17 +27,8 @@ - + + + + + + + + + + - + @@ -120,6 +129,7 @@ + @@ -132,4 +142,7 @@ + + + diff --git a/iGap/VIew/ReusableViews/IGAvatarView.swift b/iGap/VIew/ReusableViews/IGAvatarView.swift index 08b7fce..7e530c1 100644 --- a/iGap/VIew/ReusableViews/IGAvatarView.swift +++ b/iGap/VIew/ReusableViews/IGAvatarView.swift @@ -93,6 +93,11 @@ class IGAvatarView: UIView { } func setRoom(_ room: IGRoom) { + + if room.isInvalidated { + return + } + self.avatarImageView!.image = nil self.initialLettersLabel!.text = room.initilas diff --git a/iGap/VIew/profile.storyboard b/iGap/VIew/profile.storyboard index 1743944..68485b1 100644 --- a/iGap/VIew/profile.storyboard +++ b/iGap/VIew/profile.storyboard @@ -1,20 +1,15 @@ - + - + - - - HelveticaNeue - - @@ -380,15 +375,24 @@ - @@ -1490,9 +1495,7 @@ - - - + @@ -1979,12 +1982,8 @@ - - - - - - + + @@ -2977,10 +2976,11 @@ + - +