From 89a16a5c0aa0bcc1be4cbd520b86c250acabf923 Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 11:01:48 +0300 Subject: [PATCH 01/16] [NY-1385] Update DBMessage extension. --- .../NynjaUIKit.xcodeproj/project.pbxproj | 52 +++---------------- Nynja.xcodeproj/project.pbxproj | 28 +++------- ...ension.swift => DBMessage+Extension.swift} | 33 ++++++++---- 3 files changed, 34 insertions(+), 79 deletions(-) rename Nynja/DB/Models/Extension/{DBMessage+TypeExtension.swift => DBMessage+Extension.swift} (69%) diff --git a/Frameworks/NynjaUIKit/NynjaUIKit.xcodeproj/project.pbxproj b/Frameworks/NynjaUIKit/NynjaUIKit.xcodeproj/project.pbxproj index e3b597217..d227aa966 100644 --- a/Frameworks/NynjaUIKit/NynjaUIKit.xcodeproj/project.pbxproj +++ b/Frameworks/NynjaUIKit/NynjaUIKit.xcodeproj/project.pbxproj @@ -328,7 +328,6 @@ 8514D4BD20EE27080002378A /* Frameworks */, 8514D4BE20EE27080002378A /* Headers */, 8514D4BF20EE27080002378A /* Resources */, - D7385F82B2053A99EACEB2FC /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -399,21 +398,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - D7385F82B2053A99EACEB2FC /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/../../Pods/Target Support Files/Pods-NynjaUIKit/Pods-NynjaUIKit-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -521,11 +505,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = NynjaUIKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.nynja.mobile.communicator.NynjaUIKit; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -606,11 +586,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = NynjaUIKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.nynja.mobile.communicator.NynjaUIKit; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -691,11 +667,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = NynjaUIKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.nynja.mobile.communicator.NynjaUIKit; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -776,11 +748,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = NynjaUIKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.nynja.mobile.communicator.NynjaUIKit; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -861,11 +829,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = NynjaUIKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.nynja.mobile.communicator.NynjaUIKit; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -946,11 +910,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = NynjaUIKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.nynja.mobile.communicator.NynjaUIKit; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 2c79f9b6a..094d3e2e4 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -230,7 +230,7 @@ 2651094020ADBB0200F1B38B /* NotificationSettingProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2651093E20ADB81100F1B38B /* NotificationSettingProtocol.swift */; }; 2652D6161FA82EFE005E62C7 /* EditProfileVCLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2652D6151FA82EFE005E62C7 /* EditProfileVCLayout.swift */; }; 2652D6181FA85B28005E62C7 /* ImageSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2652D6171FA85B28005E62C7 /* ImageSelector.swift */; }; - 26534B25210B4BE70003B9BC /* DBMessage+TypeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26534B24210B4BE70003B9BC /* DBMessage+TypeExtension.swift */; }; + 26534B25210B4BE70003B9BC /* DBMessage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26534B24210B4BE70003B9BC /* DBMessage+Extension.swift */; }; 26541F722007B93400AAEACF /* DBMessageAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26541F712007B93400AAEACF /* DBMessageAction.swift */; }; 26541F742007B9A200AAEACF /* MessageActionTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26541F732007B9A200AAEACF /* MessageActionTable.swift */; }; 2657BE51201233E300F21935 /* ImageFilledItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2657BE50201233E300F21935 /* ImageFilledItemModel.swift */; }; @@ -2388,7 +2388,7 @@ 2651093E20ADB81100F1B38B /* NotificationSettingProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingProtocol.swift; sourceTree = ""; }; 2652D6151FA82EFE005E62C7 /* EditProfileVCLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileVCLayout.swift; sourceTree = SOURCE_ROOT; }; 2652D6171FA85B28005E62C7 /* ImageSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageSelector.swift; sourceTree = ""; }; - 26534B24210B4BE70003B9BC /* DBMessage+TypeExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DBMessage+TypeExtension.swift"; sourceTree = ""; }; + 26534B24210B4BE70003B9BC /* DBMessage+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DBMessage+Extension.swift"; sourceTree = ""; }; 26541F712007B93400AAEACF /* DBMessageAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DBMessageAction.swift; sourceTree = ""; }; 26541F732007B9A200AAEACF /* MessageActionTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageActionTable.swift; sourceTree = ""; }; 2657BE50201233E300F21935 /* ImageFilledItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageFilledItemModel.swift; sourceTree = ""; }; @@ -4965,7 +4965,7 @@ 26534B23210B4BCA0003B9BC /* Extension */ = { isa = PBXGroup; children = ( - 26534B24210B4BE70003B9BC /* DBMessage+TypeExtension.swift */, + 26534B24210B4BE70003B9BC /* DBMessage+Extension.swift */, ); path = Extension; sourceTree = ""; @@ -12809,7 +12809,6 @@ 3578099F1F9765CF00C9680C /* Sources */, 357809A01F9765CF00C9680C /* Frameworks */, 357809A11F9765CF00C9680C /* Resources */, - 8E9C19F4C64BB9FB9EB70B9E /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -13110,7 +13109,7 @@ "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework", "${BUILT_PRODUCTS_DIR}/GRDBCipher/GRDBCipher.framework", "${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework", - "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", + "${BUILT_PRODUCTS_DIR}/GoogleToolboxForMac/GoogleToolboxForMac.framework", "${BUILT_PRODUCTS_DIR}/JTAppleCalendar/JTAppleCalendar.framework", "${BUILT_PRODUCTS_DIR}/MDFTextAccessibility/MDFTextAccessibility.framework", "${BUILT_PRODUCTS_DIR}/MaterialComponents/MaterialComponents.framework", @@ -13135,7 +13134,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GRDBCipher.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleToolboxForMac.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JTAppleCalendar.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MDFTextAccessibility.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MaterialComponents.framework", @@ -13202,21 +13201,6 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-NynjaUnitTests/Pods-NynjaUnitTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 8E9C19F4C64BB9FB9EB70B9E /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Nynja-Share/Pods-Nynja-Share-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; C00EEF59269812B03AB09233 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -15193,7 +15177,7 @@ 8520040720D4F436007C0036 /* StickerPreviewConfig.swift in Sources */, F1607B1D20B20F7800BDF60A /* GridView.swift in Sources */, F11786F320AC7A6E007A9A1B /* VideoPreviewView.swift in Sources */, - 26534B25210B4BE70003B9BC /* DBMessage+TypeExtension.swift in Sources */, + 26534B25210B4BE70003B9BC /* DBMessage+Extension.swift in Sources */, 2F7C7F7837BDE6F5767A3A8C /* GroupStorageViewController.swift in Sources */, 4B1D7E012029C4BE00703228 /* OptionsItemsFactory.swift in Sources */, C921738220BADAFC00519A2D /* TextInputValidationService.swift in Sources */, diff --git a/Nynja/DB/Models/Extension/DBMessage+TypeExtension.swift b/Nynja/DB/Models/Extension/DBMessage+Extension.swift similarity index 69% rename from Nynja/DB/Models/Extension/DBMessage+TypeExtension.swift rename to Nynja/DB/Models/Extension/DBMessage+Extension.swift index d003ddb0d..25d1b0226 100644 --- a/Nynja/DB/Models/Extension/DBMessage+TypeExtension.swift +++ b/Nynja/DB/Models/Extension/DBMessage+Extension.swift @@ -1,21 +1,13 @@ // -// DBMessage+TypeExtension.swift +// DBMessage+Extension.swift // Nynja // // Created by Andrey Reznik on 27.07.2018. // Copyright © 2018 TecSynt Solutions. All rights reserved. // - extension DBMessage { - var isInOwnChat: Bool { - let ownerId = StorageService.sharedInstance.phoneId - return from == ownerId && to == ownerId - } - - var isOwn: Bool { - return self.from == StorageService.sharedInstance.phoneId - } + // MARK: - Types var isForward: Bool { return type?.contains("forward") ?? false @@ -40,5 +32,24 @@ extension DBMessage { var isCursor: Bool { return type?.contains("cursor") ?? false } + + + // MARK: - Delivery Status + + var isDelivered: Bool { + return serverId != nil + } + + + // MARK: - Storage + // FIXME: must be removed from extension, because it shouldn't use implicit singleton dependency. + + var isInOwnChat: Bool { + let ownerId = StorageService.sharedInstance.phoneId + return from == ownerId && to == ownerId + } + + var isOwn: Bool { + return from == StorageService.sharedInstance.phoneId + } } - -- GitLab From 191464e8c4fd25047633d0703a6dc0c444185be1 Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 11:06:50 +0300 Subject: [PATCH 02/16] [NY-1385] Fixed HistoryHandler. --- Nynja/Services/HandleServices/HistoryHandler.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Nynja/Services/HandleServices/HistoryHandler.swift b/Nynja/Services/HandleServices/HistoryHandler.swift index 03ac100d1..b9b9fd5cd 100644 --- a/Nynja/Services/HandleServices/HistoryHandler.swift +++ b/Nynja/Services/HandleServices/HistoryHandler.swift @@ -74,7 +74,7 @@ final class HistoryHandler: BaseHandler { /// The first message is new, the last is old. private static func updateMessageHistory(_ messages: [Message]) { - var stackForSave = [Message]() + var stackForSave = [Message](reserveCapacity: messages.count) var stackForDelete = [Message]() var deletedActions = [DBMessageAction]() var systemClearMessage: Message? @@ -119,6 +119,9 @@ final class HistoryHandler: BaseHandler { ChatService.clearMessages(before: systemClearMessage) } + // Save new messages after old messages + stackForSave.reverse() + try? MessageDAO.saveMessages(stackForSave) ChatService.removeMessages(stackForDelete) try? MessageActionDAO.delete(deletedActions) -- GitLab From ec9218b2013adb23a3d27ff15949a0fc12edde13 Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 11:21:06 +0300 Subject: [PATCH 03/16] [NY-1385] Remove unneeded code from BaseChatCellModel. --- Nynja.xcodeproj/project.pbxproj | 4 +++ .../Message/View/MessageVC+CellDelegate.swift | 7 +++-- .../MessageCollectionViewDataSource.swift | 2 +- .../MessageCollectionViewDelegate.swift | 11 ++----- .../CollectionView/ScrollDirection.swift | 12 ++++++++ .../ChatCells/BaseChatCell/BaseChatCell.swift | 4 ++- .../Cells/Models/BaseChatCellModel.swift | 29 ++----------------- .../Cells/Models/RepliedMessageModel.swift | 2 +- 8 files changed, 30 insertions(+), 41 deletions(-) create mode 100644 Nynja/Modules/Message/View/Views/CollectionView/ScrollDirection.swift diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 094d3e2e4..60840dcf2 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -968,6 +968,7 @@ 85B0013421272694000C89FE /* MessageInteractor+History.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85B0013321272694000C89FE /* MessageInteractor+History.swift */; }; 85B750A120334A2B00AD6013 /* ForwardTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85B750A020334A2B00AD6013 /* ForwardTableViewCell.swift */; }; 85BA176120BEA7BD001EF8AC /* StickerPreviewContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BA176020BEA7BD001EF8AC /* StickerPreviewContainerView.swift */; }; + 85BDD2B821465EFA00695DE5 /* ScrollDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BDD2B721465EFA00695DE5 /* ScrollDirection.swift */; }; 85BEC0E12063F91C0098C99C /* TimeZoneCellModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BEC0E02063F91C0098C99C /* TimeZoneCellModel.swift */; }; 85C16C3520D2520E00EDB77E /* StickersDownloadingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C16C3420D2520E00EDB77E /* StickersDownloadingService.swift */; }; 85C16C3C20D261C000EDB77E /* MessageStickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C16C3B20D261C000EDB77E /* MessageStickerView.swift */; }; @@ -3030,6 +3031,7 @@ 85B0013321272694000C89FE /* MessageInteractor+History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageInteractor+History.swift"; sourceTree = ""; }; 85B750A020334A2B00AD6013 /* ForwardTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForwardTableViewCell.swift; sourceTree = ""; }; 85BA176020BEA7BD001EF8AC /* StickerPreviewContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerPreviewContainerView.swift; sourceTree = ""; }; + 85BDD2B721465EFA00695DE5 /* ScrollDirection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollDirection.swift; sourceTree = ""; }; 85BEC0E02063F91C0098C99C /* TimeZoneCellModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeZoneCellModel.swift; sourceTree = ""; }; 85C16C3420D2520E00EDB77E /* StickersDownloadingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StickersDownloadingService.swift; path = Services/StickersDownloadingService/StickersDownloadingService.swift; sourceTree = ""; }; 85C16C3B20D261C000EDB77E /* MessageStickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageStickerView.swift; sourceTree = ""; }; @@ -7740,6 +7742,7 @@ 8540A330211B34B4007F65AF /* MessageCollectionViewDataSource.swift */, 8540A332211B35A4007F65AF /* MessageCollectionViewDelegate.swift */, 85D77806211D9B980044E72F /* ScrollPosition.swift */, + 85BDD2B721465EFA00695DE5 /* ScrollDirection.swift */, 2625F29E212463E8007C42B5 /* ProgressIdentifier.swift */, ); path = CollectionView; @@ -14164,6 +14167,7 @@ 854751492093BDD300F8D5F8 /* CollectionViewScrollProxy.swift in Sources */, 850C301B204DA87A00DB26C2 /* PrivacyListPresenter.swift in Sources */, 267BE28E1FDE9FCC00C47E18 /* SettingsGroupWireFrame.swift in Sources */, + 85BDD2B821465EFA00695DE5 /* ScrollDirection.swift in Sources */, A4679BA620B2DD0F0021FE9C /* SubscribersSelectorWireFrame.swift in Sources */, 2648C41A2069B52100863614 /* ChangeNumberViewLayout.swift in Sources */, 8514D52420EE48A30002378A /* NynjaContextMenuItemsFactory+Messages.swift in Sources */, diff --git a/Nynja/Modules/Message/View/MessageVC+CellDelegate.swift b/Nynja/Modules/Message/View/MessageVC+CellDelegate.swift index bbad76598..71cf1415e 100644 --- a/Nynja/Modules/Message/View/MessageVC+CellDelegate.swift +++ b/Nynja/Modules/Message/View/MessageVC+CellDelegate.swift @@ -8,9 +8,12 @@ import Foundation -extension MessageVC: VoiceAudioInteractive, BaseChatCellDelegate, AudioManagerDelegate, ProximitySensorManagerDelegate { +extension MessageVC: VoiceAudioInteractive, AudioManagerDelegate, ProximitySensorManagerDelegate { } + +// MARK: - BaseChatCellDelegate + +extension MessageVC: BaseChatCellDelegate { - // MARK: - BaseChatCellDelegate func didCellTapped(_ cell: BaseChatCell) { guard let model = cell.model, let type = model.type else { return diff --git a/Nynja/Modules/Message/View/Views/CollectionView/MessageCollectionViewDataSource.swift b/Nynja/Modules/Message/View/Views/CollectionView/MessageCollectionViewDataSource.swift index e07023d47..2d6b1e91e 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/MessageCollectionViewDataSource.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/MessageCollectionViewDataSource.swift @@ -191,7 +191,7 @@ extension MessageCollectionViewDataSource: UICollectionViewDataSource { } } - if model.messageType == .system { + if case .system = model.messageType { if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "system", for: indexPath) as? SystemCell { cell.setup(message: model.text!) cell.accessibilityIdentifier = "system_cell_unread_\(indexPath.section)" diff --git a/Nynja/Modules/Message/View/Views/CollectionView/MessageCollectionViewDelegate.swift b/Nynja/Modules/Message/View/Views/CollectionView/MessageCollectionViewDelegate.swift index 422da5f56..1c2075eaa 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/MessageCollectionViewDelegate.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/MessageCollectionViewDelegate.swift @@ -8,13 +8,6 @@ import UIKit -enum ScrollDirection { - case top - case bottom -} - - - final class MessageCollectionViewDelegate: NSObject, UICollectionViewDelegateFlowLayout { unowned var view: MessageVC @@ -46,11 +39,11 @@ final class MessageCollectionViewDelegate: NSObject, UICollectionViewDelegateFlo private func heightForItem(at indexPath: IndexPath) -> CGFloat { let model = view.messageDS.cellModel(at: indexPath) - if model.messageType == .system { + if case .system = model.messageType { return 40 } - if let _ = model.type { + if model.type != nil { return height(for: model) } diff --git a/Nynja/Modules/Message/View/Views/CollectionView/ScrollDirection.swift b/Nynja/Modules/Message/View/Views/CollectionView/ScrollDirection.swift new file mode 100644 index 000000000..f077dc5c2 --- /dev/null +++ b/Nynja/Modules/Message/View/Views/CollectionView/ScrollDirection.swift @@ -0,0 +1,12 @@ +// +// ScrollDirection.swift +// Nynja +// +// Created by Anton Poltoratskyi on 10.09.2018. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +enum ScrollDirection { + case top + case bottom +} diff --git a/Nynja/Modules/Message/View/Views/TableView/Cells/ChatCells/BaseChatCell/BaseChatCell.swift b/Nynja/Modules/Message/View/Views/TableView/Cells/ChatCells/BaseChatCell/BaseChatCell.swift index 54b6ed8be..fbbe8e6c7 100644 --- a/Nynja/Modules/Message/View/Views/TableView/Cells/ChatCells/BaseChatCell/BaseChatCell.swift +++ b/Nynja/Modules/Message/View/Views/TableView/Cells/ChatCells/BaseChatCell/BaseChatCell.swift @@ -502,7 +502,9 @@ class BaseChatCell: UICollectionViewCell, MessageBaseImageViewDataSource, Messag } static func shouldShowSender(_ model: BaseChatCellModel) -> Bool { - guard model.messageType != .system else { return false } + if case .system = model.messageType { + return false + } switch model.infoType { case .date: diff --git a/Nynja/Modules/Message/View/Views/TableView/Cells/Models/BaseChatCellModel.swift b/Nynja/Modules/Message/View/Views/TableView/Cells/Models/BaseChatCellModel.swift index 542007821..31742b76b 100644 --- a/Nynja/Modules/Message/View/Views/TableView/Cells/Models/BaseChatCellModel.swift +++ b/Nynja/Modules/Message/View/Views/TableView/Cells/Models/BaseChatCellModel.swift @@ -28,38 +28,13 @@ enum PlayStatus { case stop } -enum MessageType: Hashable { +enum MessageType { case regular case forward indirect case reply(RepliedMessageModel, MessageType) indirect case convertion(ConvertionMessageModel, MessageType) case system - var hashValue: Int { - get { - return self.getHash() - } - } - - static func ==(lhs: MessageType, rhs: MessageType) -> Bool { - return lhs.hashValue == rhs.hashValue - } - - private func getHash() -> Int { - switch self { - case .regular: - return "regular".hashValue - case .reply(let model, _): - return ("reply" + model.id).hashValue - case .system: - return "system".hashValue - case .forward: - return "forward".hashValue - case .convertion: - return "convertion".hashValue - } - } - var ejectReply: MessageType? { switch self { case .reply: @@ -145,7 +120,7 @@ final class BaseChatCellModel { var serverID: Int64? - var id: String? + var id: MessageLocalId? var type: SendMessageType! var isOwner: Bool = true var timeStamp: Date? diff --git a/Nynja/Modules/Message/View/Views/TableView/Cells/Models/RepliedMessageModel.swift b/Nynja/Modules/Message/View/Views/TableView/Cells/Models/RepliedMessageModel.swift index 081e65bf8..3318c78f6 100644 --- a/Nynja/Modules/Message/View/Views/TableView/Cells/Models/RepliedMessageModel.swift +++ b/Nynja/Modules/Message/View/Views/TableView/Cells/Models/RepliedMessageModel.swift @@ -11,7 +11,7 @@ import Foundation final class RepliedMessageModel { /// local id of replied message - var id: String + var id: MessageLocalId var type: SendMessageType var author: String var text: String -- GitLab From c9bdafd080843ed642414628f0456053c154fa28 Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 12:08:19 +0300 Subject: [PATCH 04/16] [NY-1385] Update MessageDAO. Remove unused logic for fetching history gaps. --- Nynja/MessageDAO.swift | 10 ++- Nynja/MessageDAOProtocol.swift | 5 +- .../MessageInteractor+History.swift | 69 ++++++++----------- .../Interactor/MessageInteractor.swift | 27 ++++---- 4 files changed, 53 insertions(+), 58 deletions(-) diff --git a/Nynja/MessageDAO.swift b/Nynja/MessageDAO.swift index e96afa926..5ebfda37b 100644 --- a/Nynja/MessageDAO.swift +++ b/Nynja/MessageDAO.swift @@ -8,7 +8,7 @@ import GRDBCipher -class MessageDAO: MessageDAOProtocol { +final class MessageDAO: MessageDAOProtocol { // MARK: - Save static func saveMessages(_ messages: [Message]) throws { @@ -130,9 +130,13 @@ class MessageDAO: MessageDAOProtocol { // MARK: - Cursor - static func dropFirst(for fetchType: FetchType, closure: (DBMessage) -> Void) throws { + static func dropFirst(for fetchType: FetchType, + orderedBy order: TableOrder, + orderColumn: MessageTable.Column, + closure: (DBMessage) -> Void) throws { + dbManager.fetch { db in - let cursor = try DBMessage.fetchCursor(db, fetchType: fetchType, orderedBy: .desc, orderColumn: .serverId).dropFirst() + let cursor = try DBMessage.fetchCursor(db, fetchType: fetchType, orderedBy: order, orderColumn: orderColumn).dropFirst() while let message = try cursor.next() { closure(message) diff --git a/Nynja/MessageDAOProtocol.swift b/Nynja/MessageDAOProtocol.swift index b703ed2ad..784903d40 100644 --- a/Nynja/MessageDAOProtocol.swift +++ b/Nynja/MessageDAOProtocol.swift @@ -43,7 +43,10 @@ protocol MessageDAOProtocol: DAOProtocol { static func fetchMessages(_ type: FetchType, serverIds: Set) -> [Message] // MARK: - Cursor - static func dropFirst(for fetchType: FetchType, closure: (DBMessage) -> Void) throws + static func dropFirst(for fetchType: FetchType, + orderedBy order: TableOrder, + orderColumn: MessageTable.Column, + closure: (DBMessage) -> Void) throws // MARK: - Trusted diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor+History.swift b/Nynja/Modules/Message/Interactor/MessageInteractor+History.swift index 7ce3c9129..432c30863 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor+History.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor+History.swift @@ -10,12 +10,18 @@ import Foundation extension MessageInteractor { + enum HistoryCheckResult { + case valid + case updateRequired + case broken(MessageHistoryGaps) + } + struct MessageHistoryGaps { - typealias Range = CountableClosedRange + fileprivate typealias Range = CountableClosedRange private let ranges: [Range]? - init(ranges: [Range]) { + fileprivate init(ranges: [Range]) { self.ranges = ranges } @@ -32,57 +38,48 @@ extension MessageInteractor { } } - enum HistoryCheckResult { - case validSequence - case updateRequired - case gaps(MessageHistoryGaps) - } - func checkLocalHistory() -> HistoryCheckResult { guard chat.last_msg?.statusString != "update" else { return .updateRequired } guard let gaps = fetchAllHistoryGaps(), !gaps.isEmpty else { - return .validSequence + return .valid } - return .gaps(gaps) + return .broken(gaps) } private func fetchAllHistoryGaps() -> MessageHistoryGaps? { - guard let fetchType = fetchType else { return nil } - + guard let fetchType = fetchType, let lastMessage = chat.last_msg else { + return nil + } + return fetchAllHistoryGaps(in: fetchType, lastMessage: lastMessage) + } + + private func fetchAllHistoryGaps(in fetchType: FetchType, lastMessage: Message) -> MessageHistoryGaps { var gaps = [MessageHistoryGaps.Range]() + var previousMessage = DBMessage(message: lastMessage) - var endMessageId: MessageServerId? // Latest message id - var repliedMessageId: MessageServerId? // Oldest replied message id + let isValidChain: (DBMessage) -> Bool = { + previousMessage?.next == $0.serverId || previousMessage?.isTrusted == true + } + + // Latest message id + var endMessageId: MessageServerId? - let appendGapIfExists = { (message: DBMessage) in + let appendGapIfExists: (DBMessage) -> Void = { message in if let end = endMessageId, let start = message.serverId, start <= end { gaps.append(start...end) } endMessageId = nil } - var previousMessage = chat.last_msg.flatMap { DBMessage(message: $0) } - - let isValidChain = { (message: DBMessage) -> Bool in - return previousMessage?.next == message.serverId || previousMessage?.isTrusted == true - } - // Iterate over all messages that isn't filtered by status. // Ignore first message, because it's equal to chat's last message. - try? MessageDAO.dropFirst(for: fetchType) { message in - guard let id = message.serverId else { return } + try? MessageDAO.dropFirst(for: fetchType, orderedBy: .desc, orderColumn: .serverId) { message in + guard message.isDelivered else { return } defer { previousMessage = message } - - if id == repliedMessageId { - repliedMessageId = nil - - } else if message.isReply, let link = message.link { - repliedMessageId = repliedMessageId.flatMap { min($0, link) } ?? link - } - + if isValidChain(message) { appendGapIfExists(message) @@ -93,15 +90,7 @@ extension MessageInteractor { } previousMessage.map { appendGapIfExists($0) } - /* - if let repliedMessageId = repliedMessageId, - let start = gaps.last?.lowerBound, - let end = gaps.first?.upperBound, - !(start...end).contains(repliedMessageId) { - - gaps.append(repliedMessageId...start) - }*/ - + return MessageHistoryGaps(ranges: gaps) } } diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor.swift b/Nynja/Modules/Message/Interactor/MessageInteractor.swift index 97927d23d..34c8e5257 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor.swift @@ -337,10 +337,10 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H private func fetchData() { fetchChatModel() switch checkLocalHistory() { - case .updateRequired, .validSequence: + case .updateRequired, .valid: fetchMessages() - case let .gaps(gaps): + case let .broken(gaps): processingQueue.async { [weak self] in self?.fetchFromStorage() } @@ -905,30 +905,29 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H } // MARK: - HistoryHandlerDelegate - var isNew = false + private var isNew = false private var isHistoryUpdating: Bool = false func getHistorySuccess() { guard !isHistoryUpdating else { isHistoryUpdating = false - isNew = false + processingQueue.async { + self.isNew = false + } fetchData() return } - if isNew { - processingQueue.async { [weak self] in - guard let `self` = self else { return } + processingQueue.async { [weak self] in + guard let `self` = self else { return } + + if self.isNew { self.fetchNewFromStorage() - self.autoTranslateReceiptMessagesIfNeeded() - } - } else { - isNew = true - processingQueue.async { [weak self] in - guard let `self` = self else { return } + } else { + self.isNew = true self.fetchFromStorage() - self.autoTranslateReceiptMessagesIfNeeded() } + self.autoTranslateReceiptMessagesIfNeeded() } } -- GitLab From 64cf5ec6e57910a5a05c5345ec1264a372f84baa Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 12:25:28 +0300 Subject: [PATCH 05/16] [NY-1385] Update server model version up to 9. --- Nynja/Extensions/Bundle+Keys.swift | 2 -- Nynja/Resources/DevConfig.xcconfig | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Nynja/Extensions/Bundle+Keys.swift b/Nynja/Extensions/Bundle+Keys.swift index dcc1a320a..293ec8e66 100644 --- a/Nynja/Extensions/Bundle+Keys.swift +++ b/Nynja/Extensions/Bundle+Keys.swift @@ -33,7 +33,6 @@ extension Bundle { return object(forInfoDictionaryKey: "ServerURL") as! String } - var appGroupName: String { return object(forInfoDictionaryKey: "AppGroup") as! String } @@ -41,7 +40,6 @@ extension Bundle { var serverPort: UInt16 { let serverPort = object(forInfoDictionaryKey: "ServerPort") as! String return UInt16(serverPort)! - } var modelsVersion: Int { diff --git a/Nynja/Resources/DevConfig.xcconfig b/Nynja/Resources/DevConfig.xcconfig index be91b0379..fccdcaf03 100644 --- a/Nynja/Resources/DevConfig.xcconfig +++ b/Nynja/Resources/DevConfig.xcconfig @@ -14,6 +14,6 @@ AppName = NYNJADev ServerPort = 1883 Config = dev AppGroup = group.com.nynja.mobile.communicator.dev -ModelsVersion = 8 +ModelsVersion = 9 ConfServerAddress = 35.198.118.190 ConfServerPort = 80 -- GitLab From 13c46fdabac0bf0121d698ef69ecb05abbbbdc74 Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 12:40:29 +0300 Subject: [PATCH 06/16] [NY-1385] Updated Message_Spec --- Nynja/ServerModel/Spec/Message_Spec.swift | 29 +++++++---------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/Nynja/ServerModel/Spec/Message_Spec.swift b/Nynja/ServerModel/Spec/Message_Spec.swift index 59a1eea24..b8d1286b8 100644 --- a/Nynja/ServerModel/Spec/Message_Spec.swift +++ b/Nynja/ServerModel/Spec/Message_Spec.swift @@ -4,7 +4,6 @@ func get_Message() -> Model { Model(value:List(constant:"")), Model(value:Number())])), Model(value:Chain(types:[ - Model(value:Atom()), Model(value:Atom(constant:"chain")), Model(value:Atom(constant:"cur"))])), Model(value:Chain(types:[ @@ -27,36 +26,26 @@ func get_Message() -> Model { Model(value:Binary())])), Model(value:Chain(types:[ Model(value:List(constant:"")), - Model(value:Number()), - Model(value:Binary())])), - Model(value:Chain(types:[ - Model(value:List(constant:"")), - Model(value:List(constant:nil,model:get_Desc()))])), + Model(value:Number())])), + Model(value:List(constant:nil,model:get_Desc())), Model(value:Chain(types:[ Model(value:List(constant:"")), Model(value:List(constant:nil, model:Model(value:Chain(types:[ - Model(value:Atom()), Model(value:Atom(constant:"sys")), Model(value:Atom(constant:"reply")), Model(value:Atom(constant:"forward")), - Model(value:Atom(constant:"sched")), Model(value:Atom(constant:"read")), Model(value:Atom(constant:"edited")), Model(value:Atom(constant:"cursor"))]))))])), Model(value:Chain(types:[ Model(value:List(constant:"")), - Model(value:Number())])), - Model(value:Chain(types:[ - Model(value:List(constant:"")), - Model(value:List(constant:nil, model:Model(value:Chain(types:[ - Model(value:Binary()), - Model(value:Number())]))))])), - Model(value:Chain(types:[ - Model(value:List(constant:"")), - Model(value:List(constant:nil, model:Model(value:Number())))])), - Model(value:Chain(types:[ - Model(value:List(constant:"")), - Model(value:List(constant:nil, model:Model(value:Number())))])), + Model(value:Number()), + get_Message()])), + Model(value:List(constant:nil, model:Model(value:Chain(types:[ + Model(value:Binary()), + Model(value:Number())])))), + Model(value:List(constant:nil, model:Model(value:Number()))), + Model(value:List(constant:nil, model:Model(value:Number()))), Model(value:Chain(types:[ Model(value:List(constant:"")), Model(value:Atom(constant:"async")), -- GitLab From 4169110fc4c0046cf435143e7602e5fb15efd006 Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 12:41:19 +0300 Subject: [PATCH 07/16] [NY-1385] Refactored MessageExtension+BERT. Don't need to always allocate BertNil() object. --- Nynja/MQTTModels/MessageExtension+BERT.swift | 29 ++++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/Nynja/MQTTModels/MessageExtension+BERT.swift b/Nynja/MQTTModels/MessageExtension+BERT.swift index 970f0ec64..b9871405e 100644 --- a/Nynja/MQTTModels/MessageExtension+BERT.swift +++ b/Nynja/MQTTModels/MessageExtension+BERT.swift @@ -41,18 +41,23 @@ extension Message { _seenBy = BertList(fromElements: obj) } - var _feed: BertObject = BertNil() + let _feed: BertObject if let p2p = self.feed_id as? p2p { _feed = p2p.getBert() - } - if let muc = self.feed_id as? muc { + } else if let muc = self.feed_id as? muc { _feed = muc.getBert() + } else { + _feed = BertNil() } - var _created: BertObject = BertNil() + + let _created: BertObject if let c = self.created as? Int64 { _created = BertNumber(fromInt64: c) + } else { + _created = BertNil() } - var attachments: BertObject = BertNil() + + let attachments: BertObject if let descs = self.files, descs.count > 0 { var att = [BertObject]() for i in descs { @@ -60,25 +65,31 @@ extension Message { att.append(desc) } attachments = BertList(fromElements: att) + } else { + attachments = BertNil() } - var types: BertObject = BertNil() + let types: BertObject if !self.types.isEmpty { let arr = self.types.map { BertAtom(fromString: $0) } types = BertList(fromElements: arr) + } else { + types = BertNil() } let link = Bert.getBin(self.link) - var status: BertObject = BertNil() + let status: BertObject if let string = self.status as? String { status = BertAtom(fromString: string) } else if let atom = self.status as? StringAtom, let string = atom.string { status = BertAtom(fromString: string) + } else { + status = BertNil() } - var mentioned: BertObject - if let objects = (self.mentioned as? [Int64])?.compactMap({ Bert.getBin($0) as? BertNumber }) { + let mentioned: BertObject + if let objects = (self.mentioned as? [Int64])?.compactMap({ Bert.getBin($0) as? BertNumber }), !objects.isEmpty { mentioned = BertList(fromElements: objects) } else { mentioned = BertNil() -- GitLab From 48109834c2cecf2673374ced7701d1f2dde4e080 Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 13:09:36 +0300 Subject: [PATCH 08/16] [NY-1385] Update 'link' field for Message model. Update Decoder. --- Nynja/ChatService/ChatService.swift | 7 +++---- Nynja/DB/Models/DBJobMessage.swift | 4 ++-- Nynja/DB/Models/DBMessage.swift | 4 ++-- Nynja/DB/Models/DBStarMessage.swift | 2 +- Nynja/Extensions/Models/Message/Message+DB.swift | 12 ++++++------ Nynja/Library/MessageFactory/MessageFactory.swift | 2 +- Nynja/MQTTModels/MessageExtension+BERT.swift | 11 +++++++++-- Nynja/MessageDAO.swift | 5 ++--- .../Message/Interactor/MessageInteractor+Fetch.swift | 2 +- .../MessageInteractor+StorageSubscriber.swift | 2 +- .../Message/Interactor/MessageInteractor.swift | 6 +++--- .../Modules/Message/Presenter/MessagePresenter.swift | 4 ++-- .../Interactor/ScheduleMessageInteractor.swift | 2 +- Nynja/ServerModel/Model/Message.swift | 4 ++-- Nynja/ServerModel/Source/Decoder.swift | 4 ++-- Nynja/Services/HandleServices/HistoryHandler.swift | 2 +- Nynja/Services/HandleServices/MessageHandler.swift | 2 +- .../MessageSendingService.swift | 2 +- .../Extensions/Models/Message/Message+Factory.swift | 4 ++-- .../Extensions/Models/Message/MessageExtension.swift | 5 +++++ 20 files changed, 48 insertions(+), 38 deletions(-) diff --git a/Nynja/ChatService/ChatService.swift b/Nynja/ChatService/ChatService.swift index 4e9442626..479980e02 100644 --- a/Nynja/ChatService/ChatService.swift +++ b/Nynja/ChatService/ChatService.swift @@ -150,9 +150,8 @@ final class ChatService { } static func removeMessage(_ message: Message, shouldUpdateChat: Bool = true) { - guard MessageDAO.removeMessage(using: message), - let id = message.link else { - return + guard MessageDAO.removeMessage(using: message), let id = message.linkedId else { + return } if let action = MessageActionDAO.fetchMessageAction(by: id) { @@ -185,7 +184,7 @@ final class ChatService { } ChatService.updateLastMessage(lastMessage, chat: chat, shouldChangeUnread: false) { (lastMessageId) -> Bool in - return message.link == lastMessageId + return message.linkedId == lastMessageId } } diff --git a/Nynja/DB/Models/DBJobMessage.swift b/Nynja/DB/Models/DBJobMessage.swift index 558373a7c..3cc8ac67e 100644 --- a/Nynja/DB/Models/DBJobMessage.swift +++ b/Nynja/DB/Models/DBJobMessage.swift @@ -43,9 +43,9 @@ class DBJobMessage: Record, DBModelProtocol { self.localId = message.msg_id self.from = message.from self.to = message.to - self.created = message.created as? Int64 + self.created = message.created self.type = message.types.joinedByCommaIfNotEmpty() - self.editMessage = message.link + self.editMessage = message.linkedId self.status = message.statusString self.files = (message.files ?? []).compactMap { DBDesc(desc: $0, targetId: nil, targetType: .schedule) } diff --git a/Nynja/DB/Models/DBMessage.swift b/Nynja/DB/Models/DBMessage.swift index 7301113c6..346423896 100644 --- a/Nynja/DB/Models/DBMessage.swift +++ b/Nynja/DB/Models/DBMessage.swift @@ -43,9 +43,9 @@ final class DBMessage: Record, DBModelProtocol { self.localId = message.msg_id self.from = message.from self.to = message.to - self.created = message.created as? Int64 + self.created = message.created self.type = message.types.joinedByCommaIfNotEmpty() - self.link = message.link + self.link = message.linkedId self.status = message.statusString self.isTrusted = message.isTrusted diff --git a/Nynja/DB/Models/DBStarMessage.swift b/Nynja/DB/Models/DBStarMessage.swift index c3143042d..ca3078056 100644 --- a/Nynja/DB/Models/DBStarMessage.swift +++ b/Nynja/DB/Models/DBStarMessage.swift @@ -65,7 +65,7 @@ final class DBStarMessage: Record, DBModelProtocol { self.to = message.to self.created = message.created as? Int64 self.type = message.types.joinedByCommaIfNotEmpty() - self.editMessage = message.link + self.editMessage = message.linkedId self.status = message.statusString self.files = (message.files ?? []).compactMap { DBDesc(desc: $0, targetId: nil, targetType: .star) } diff --git a/Nynja/Extensions/Models/Message/Message+DB.swift b/Nynja/Extensions/Models/Message/Message+DB.swift index 891a54a70..c5250a72c 100644 --- a/Nynja/Extensions/Models/Message/Message+DB.swift +++ b/Nynja/Extensions/Models/Message/Message+DB.swift @@ -20,9 +20,9 @@ extension Message { self.msg_id = message.localId self.from = message.from self.to = message.to - self.created = message.created as AnyObject? + self.created = message.created self.types = Set(message.type?.components(separatedBy: Constants.commaSeparator) ?? []) - self.link = message.link + self.linkedId = message.link self.repliedby = message.repliedBy?.splitIntegerIdentifiers() self.mentioned = message.mentioned?.splitIntegerIdentifiers() @@ -51,9 +51,9 @@ extension Message { self.msg_id = message.localId self.from = message.from self.to = message.to - self.created = message.created as AnyObject? + self.created = message.created self.types = Set(message.type?.components(separatedBy: Constants.commaSeparator) ?? []) - self.link = message.editMessage + self.linkedId = message.editMessage self.repliedby = message.repliedBy?.splitIntegerIdentifiers() self.mentioned = message.mentioned?.splitIntegerIdentifiers() @@ -86,9 +86,9 @@ extension Message { self.msg_id = message.localId self.from = message.from self.to = message.to - self.created = message.created as AnyObject? + self.created = message.created self.types = Set(message.type?.components(separatedBy: Constants.commaSeparator) ?? []) - self.link = message.editMessage + self.linkedId = message.editMessage self.repliedby = message.repliedBy?.splitIntegerIdentifiers() self.mentioned = message.mentioned?.splitIntegerIdentifiers() diff --git a/Nynja/Library/MessageFactory/MessageFactory.swift b/Nynja/Library/MessageFactory/MessageFactory.swift index ef4b71c75..4adb32a2f 100644 --- a/Nynja/Library/MessageFactory/MessageFactory.swift +++ b/Nynja/Library/MessageFactory/MessageFactory.swift @@ -322,7 +322,7 @@ final class MessageFactory: MessageFactoryProtocol, InitializeInjectable { private extension MessageFactory { func makeMessage(descs: [Desc], mentioned: [Int64]? = nil, phoneId: String?, contact: Contact?, room: Room?) -> Message { let message = Message(phoneId: phoneId, contact: contact, room: room) - message.created = Date.currentTimestamp as AnyObject + message.created = Date.currentTimestamp message.files = descs message.status = nil message.mentioned = mentioned as [AnyObject]? diff --git a/Nynja/MQTTModels/MessageExtension+BERT.swift b/Nynja/MQTTModels/MessageExtension+BERT.swift index b9871405e..3aa85dc72 100644 --- a/Nynja/MQTTModels/MessageExtension+BERT.swift +++ b/Nynja/MQTTModels/MessageExtension+BERT.swift @@ -51,7 +51,7 @@ extension Message { } let _created: BertObject - if let c = self.created as? Int64 { + if let c = self.created { _created = BertNumber(fromInt64: c) } else { _created = BertNil() @@ -77,7 +77,14 @@ extension Message { types = BertNil() } - let link = Bert.getBin(self.link) + let link: BertObject + if let linkedId = self.linkedId { + link = Bert.getBin(linkedId) + } else if let linkedMessage = self.link as? Message { + link = linkedMessage.getBert() + } else { + link = BertNil() + } let status: BertObject if let string = self.status as? String { diff --git a/Nynja/MessageDAO.swift b/Nynja/MessageDAO.swift index 5ebfda37b..10990bf5d 100644 --- a/Nynja/MessageDAO.swift +++ b/Nynja/MessageDAO.swift @@ -198,9 +198,8 @@ final class MessageDAO: MessageDAOProtocol { // MARK: - Remove static func removeMessage(using message: Message) -> Bool { - guard let id = message.link, - let deletedMessage = fetchMessage(serverId: id) else { - return false + guard let id = message.linkedId, let deletedMessage = fetchMessage(serverId: id) else { + return false } let shouldMarkMessageAsDelete = self.shouldMarkMessageAsDelete(message) diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift b/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift index 8b0bcbfda..4d4921f6f 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift @@ -159,7 +159,7 @@ extension MessageInteractor { } private func fetchRepliedModels(_ type: FetchType) -> ChatConfiguration.RepliedModels { - let serverIds = configuration.messages.compactMap { $0.isReply ? $0.link : nil } + let serverIds = configuration.messages.compactMap { $0.isReply ? $0.linkedId : nil } let repliedMessages = MessageDAO.fetchMessages(type, serverIds: Set(serverIds)) var repliedModels = ChatConfiguration.RepliedModels() diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift b/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift index c2790c3cf..02cce20a3 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift @@ -259,7 +259,7 @@ extension MessageInteractor { func createMessageConfiguration(_ message: Message) -> MessageConfiguration { var repliedModel: RepliedMessageModel? if message.isReply { - if let serverId = message.link, let repliedMessage = messageBy(serverId: serverId), let sender = sender(for: repliedMessage) { + if let serverId = message.linkedId, let repliedMessage = messageBy(serverId: serverId), let sender = sender(for: repliedMessage) { let mentions = payloadParser.parse(repliedMessage) repliedModel = RepliedMessageModel(message: repliedMessage, author: sender.nick ?? sender.fullname, mentions: mentions) configuration.repliedModels[serverId] = repliedModel diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor.swift b/Nynja/Modules/Message/Interactor/MessageInteractor.swift index 34c8e5257..9d39dbf7d 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor.swift @@ -629,7 +629,7 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H if let url = message.mainUrl { configuration.progressModels.removeValue(forKey: url) } - if let serverId = message.link { + if let serverId = message.linkedId { configuration.repliedModels.removeValue(forKey: serverId) } presenter?.removeMessage(id) @@ -713,7 +713,7 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H } let message = Message(message: msg) - message.created = Date.currentTimestamp as AnyObject + message.created = Date.currentTimestamp let starLocalId = IdBuilder(format: .starClientId) .addValueForComponent(messageServerId, .key) @@ -861,7 +861,7 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H } func processForwardMessageTap(serverId: MessageServerId) { - guard let link = MessageDAO.fetchMessage(serverId: serverId)?.link, + guard let link = MessageDAO.fetchMessage(serverId: serverId)?.linkedId, let linkedMessage = MessageDAO.fetchMessage(serverId: link), let localId = linkedMessage.msg_id else { return diff --git a/Nynja/Modules/Message/Presenter/MessagePresenter.swift b/Nynja/Modules/Message/Presenter/MessagePresenter.swift index 19581446b..331bface1 100644 --- a/Nynja/Modules/Message/Presenter/MessagePresenter.swift +++ b/Nynja/Modules/Message/Presenter/MessagePresenter.swift @@ -583,7 +583,7 @@ class MessagePresenter: BasePresenter, MessagePresenterProtocol, MessageInteract } var repliedModel: RepliedMessageModel? - if message.isReply, let serverId = message.link { + if message.isReply, let serverId = message.linkedId { repliedModel = configuration.repliedModels[serverId] } @@ -652,7 +652,7 @@ class MessagePresenter: BasePresenter, MessagePresenterProtocol, MessageInteract } var repliedModel: RepliedMessageModel? - if message.isReply, let serverId = message.link { + if message.isReply, let serverId = message.linkedId { repliedModel = configuration.repliedModels[serverId] } diff --git a/Nynja/Modules/ScheduleMessage/Interactor/ScheduleMessageInteractor.swift b/Nynja/Modules/ScheduleMessage/Interactor/ScheduleMessageInteractor.swift index 4b682e480..969c88e3d 100644 --- a/Nynja/Modules/ScheduleMessage/Interactor/ScheduleMessageInteractor.swift +++ b/Nynja/Modules/ScheduleMessage/Interactor/ScheduleMessageInteractor.swift @@ -58,7 +58,7 @@ class ScheduleMessageInteractor: BaseInteractor, ScheduleMessageInteractorInputP guard let phoneId = StorageService.sharedInstance.phoneId, let info = self.info, let (features, timestamp) = prepareDateTimeInfo(with: timeZone, date: date) else { return } let message = info.message - message.created = timestamp as AnyObject + message.created = timestamp let messages = info.targets.messages(from: message, phoneId: phoneId) sentMessagesLocalIds = messages.compactMap { $0.msg_id } diff --git a/Nynja/ServerModel/Model/Message.swift b/Nynja/ServerModel/Model/Message.swift index c6d66da65..fdda11f7c 100644 --- a/Nynja/ServerModel/Model/Message.swift +++ b/Nynja/ServerModel/Model/Message.swift @@ -8,10 +8,10 @@ class Message { var msg_id: String? var from: String? var to: String? - var created: AnyObject? + var created: Int64? var files: [Desc]? var type: [AnyObject]? - var link: Int64? + var link: AnyObject? var seenby: [AnyObject]? var repliedby: [AnyObject]? var mentioned: [AnyObject]? diff --git a/Nynja/ServerModel/Source/Decoder.swift b/Nynja/ServerModel/Source/Decoder.swift index 58d381134..bf56d8420 100644 --- a/Nynja/ServerModel/Source/Decoder.swift +++ b/Nynja/ServerModel/Source/Decoder.swift @@ -233,10 +233,10 @@ func parseObject(name: String, body:[Model], tuple: BertTuple) -> AnyObject? a_Message.msg_id = body[5].parse(bert: tuple.elements[6]) as? String a_Message.from = body[6].parse(bert: tuple.elements[7]) as? String a_Message.to = body[7].parse(bert: tuple.elements[8]) as? String - a_Message.created = body[8].parse(bert: tuple.elements[9]) as? AnyObject + a_Message.created = body[8].parse(bert: tuple.elements[9]) as? Int64 a_Message.files = body[9].parse(bert: tuple.elements[10]) as? [Desc] a_Message.type = body[10].parse(bert: tuple.elements[11]) as? [AnyObject] - a_Message.link = body[11].parse(bert: tuple.elements[12]) as? Int64 + a_Message.link = body[11].parse(bert: tuple.elements[12]) as? AnyObject a_Message.seenby = body[12].parse(bert: tuple.elements[13]) as? [AnyObject] a_Message.repliedby = body[13].parse(bert: tuple.elements[14]) as? [AnyObject] a_Message.mentioned = body[14].parse(bert: tuple.elements[15]) as? [AnyObject] diff --git a/Nynja/Services/HandleServices/HistoryHandler.swift b/Nynja/Services/HandleServices/HistoryHandler.swift index b9b9fd5cd..f28645bf4 100644 --- a/Nynja/Services/HandleServices/HistoryHandler.swift +++ b/Nynja/Services/HandleServices/HistoryHandler.swift @@ -85,7 +85,7 @@ final class HistoryHandler: BaseHandler { message.isTrusted = true if message.isStatusDelete { - if let id = message.link, let action = MessageActionDAO.fetchMessageAction(by: id) { + if let id = message.linkedId, let action = MessageActionDAO.fetchMessageAction(by: id) { deletedActions.append(action) } if !isHistoryCleared { diff --git a/Nynja/Services/HandleServices/MessageHandler.swift b/Nynja/Services/HandleServices/MessageHandler.swift index 2b20d6385..a4d4415a4 100644 --- a/Nynja/Services/HandleServices/MessageHandler.swift +++ b/Nynja/Services/HandleServices/MessageHandler.swift @@ -70,7 +70,7 @@ final class MessageHandler: BaseHandler { private static func editMessage(_ message: Message) { try? saveIntoDatabase(message: message) - guard let link = message.link else { + guard let link = message.linkedId else { return } diff --git a/Nynja/Services/MessageSendingService/MessageSendingService.swift b/Nynja/Services/MessageSendingService/MessageSendingService.swift index 3856ab129..cc4e311f2 100644 --- a/Nynja/Services/MessageSendingService/MessageSendingService.swift +++ b/Nynja/Services/MessageSendingService/MessageSendingService.swift @@ -50,7 +50,7 @@ final class MessageSendingService: MessageSendingServiceProtocol, InitializeInje } func sendReplayedMessage(_ repliedMessage: Message, message: Message) { - message.link = repliedMessage.id + message.linkedId = repliedMessage.id message.types = ["reply"] sendMessage(message) diff --git a/Shared/Library/Extensions/Models/Message/Message+Factory.swift b/Shared/Library/Extensions/Models/Message/Message+Factory.swift index 0513e042a..197a44394 100644 --- a/Shared/Library/Extensions/Models/Message/Message+Factory.swift +++ b/Shared/Library/Extensions/Models/Message/Message+Factory.swift @@ -39,7 +39,7 @@ extension Message { message.types = ["forward"] - message.link = link + message.linkedId = link message.status = nil message.files = message.files?.filter({ $0.mime != "translate" @@ -67,7 +67,7 @@ extension Message { func cloned() -> Message { let msg = Message(message: self) - msg.created = Date.currentTimestamp as AnyObject + msg.created = Date.currentTimestamp let builder = IdBuilder(format: .defaultId) diff --git a/Shared/Library/Extensions/Models/Message/MessageExtension.swift b/Shared/Library/Extensions/Models/Message/MessageExtension.swift index 10dfdcae5..a3394fa2c 100644 --- a/Shared/Library/Extensions/Models/Message/MessageExtension.swift +++ b/Shared/Library/Extensions/Models/Message/MessageExtension.swift @@ -99,6 +99,11 @@ extension Message { type = newValue.compactMap { StringAtom(string: $0) } } } + + var linkedId: MessageServerId? { + get { return link as? MessageServerId } + set { link = newValue as AnyObject? } + } } // MARK: - Feed -- GitLab From a5b3b9d20349c6fcc1639d6dc7af7c642c05604e Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 13:14:34 +0300 Subject: [PATCH 09/16] [NY-1385] Move MessageFactoryProtocol to separate file, because it's too big. --- Nynja.xcodeproj/project.pbxproj | 4 ++ .../MessageFactory/MessageFactory.swift | 54 ++--------------- .../MessageFactoryProtocol.swift | 59 +++++++++++++++++++ 3 files changed, 68 insertions(+), 49 deletions(-) create mode 100644 Nynja/Library/MessageFactory/MessageFactoryProtocol.swift diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 60840dcf2..c52661255 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -969,6 +969,7 @@ 85B750A120334A2B00AD6013 /* ForwardTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85B750A020334A2B00AD6013 /* ForwardTableViewCell.swift */; }; 85BA176120BEA7BD001EF8AC /* StickerPreviewContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BA176020BEA7BD001EF8AC /* StickerPreviewContainerView.swift */; }; 85BDD2B821465EFA00695DE5 /* ScrollDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BDD2B721465EFA00695DE5 /* ScrollDirection.swift */; }; + 85BDD2BA21467A9500695DE5 /* MessageFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BDD2B921467A9500695DE5 /* MessageFactoryProtocol.swift */; }; 85BEC0E12063F91C0098C99C /* TimeZoneCellModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BEC0E02063F91C0098C99C /* TimeZoneCellModel.swift */; }; 85C16C3520D2520E00EDB77E /* StickersDownloadingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C16C3420D2520E00EDB77E /* StickersDownloadingService.swift */; }; 85C16C3C20D261C000EDB77E /* MessageStickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C16C3B20D261C000EDB77E /* MessageStickerView.swift */; }; @@ -3032,6 +3033,7 @@ 85B750A020334A2B00AD6013 /* ForwardTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForwardTableViewCell.swift; sourceTree = ""; }; 85BA176020BEA7BD001EF8AC /* StickerPreviewContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerPreviewContainerView.swift; sourceTree = ""; }; 85BDD2B721465EFA00695DE5 /* ScrollDirection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollDirection.swift; sourceTree = ""; }; + 85BDD2B921467A9500695DE5 /* MessageFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageFactoryProtocol.swift; sourceTree = ""; }; 85BEC0E02063F91C0098C99C /* TimeZoneCellModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeZoneCellModel.swift; sourceTree = ""; }; 85C16C3420D2520E00EDB77E /* StickersDownloadingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StickersDownloadingService.swift; path = Services/StickersDownloadingService/StickersDownloadingService.swift; sourceTree = ""; }; 85C16C3B20D261C000EDB77E /* MessageStickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageStickerView.swift; sourceTree = ""; }; @@ -12036,6 +12038,7 @@ F11786CF20A9867C007A9A1B /* MessageFactory */ = { isa = PBXGroup; children = ( + 85BDD2B921467A9500695DE5 /* MessageFactoryProtocol.swift */, F11786D020A98685007A9A1B /* MessageFactory.swift */, 264C808520DBF397003532FA /* DBFeatureFactory.swift */, ); @@ -14031,6 +14034,7 @@ 32868DD51F31CADF0028B260 /* ChatsListProtocols.swift in Sources */, A49CC1D220E4A9C000879D41 /* InputBar+DisplayMode.swift in Sources */, A42D51B3206A361400EEB952 /* Room.swift in Sources */, + 85BDD2BA21467A9500695DE5 /* MessageFactoryProtocol.swift in Sources */, 4B06D31E2028A6D6003B275B /* MySelfItemsFactory.swift in Sources */, 26588E6720A20E49000D3E1A /* Customizable.swift in Sources */, 8541BD6B206CE3A40093EF1E /* ChatPlaceholderWheelItemModel.swift in Sources */, diff --git a/Nynja/Library/MessageFactory/MessageFactory.swift b/Nynja/Library/MessageFactory/MessageFactory.swift index 4adb32a2f..bbf75a976 100644 --- a/Nynja/Library/MessageFactory/MessageFactory.swift +++ b/Nynja/Library/MessageFactory/MessageFactory.swift @@ -9,57 +9,10 @@ import AVFoundation import CoreLocation -protocol MessageFactoryProtocol: class { - func makeTextMessage(inputText: InputTextMessage, contact: Contact?, room: Room?) -> Message - - func makeTextMessageEdited(message: Message, newInputText: InputTextMessage) -> Message - func makeTextMessageEdited(message: Message, action: DBMessageEditAction) -> Message - - func makeMediaMessage(media: Media, contact: Contact?, room: Room?) -> Message - func makeImageMessage(imageURL: URL, contact: Contact?, room: Room?) -> Message - func makeVideoMessage(videoURL: URL, contact: Contact?, room: Room?) -> Message - - func makeLocationMessage(coordinate: CLLocationCoordinate2D, contact: Contact?, room: Room?) -> Message - func makeLocationMessage(coordinate: String, contact: Contact?, room: Room?) -> Message - - func makePlaceMessage(place: Place, contact: Contact?, room: Room?) -> Message - func makeAudioMessage(withUrl url: URL, language: String?, contact: Contact?, room: Room?) -> Message - func makeContactMessage(sendingContact: Contact, contact: Contact?, room: Room?) -> Message - - func makeFileMessage(withUrl url: URL, contact: Contact?, room: Room?) -> Message - func makeStickerMessage(sticker: Sticker, contact: Contact?, room: Room?) -> Message - - func makeTranslatedMessage(message: Message, text: String, translatedText: String, lang: String) -> Message - func makeUntranslatedMessage(message: Message, translationId: String) -> Message - func autotranslationDesc(text: String, translatedText: String, lang: String) -> Desc - - func makeTranscribedMessage(message: Message, text: String, lang: String) -> Message - func makeUntranscribedMessage(message: Message, transcriptionId: String, translationId: String?) -> Message - - func makePaymentMessage(inputText: String, contact: Contact) -> Message - - func makeCallMessage(members: [String], room: Room?) -> Message - - func makeMessageForDelete(message: Message, seenBy: [AnyObject]) -> Message -} - -extension MessageFactoryProtocol { - func makeAudioMessage(withUrl url: URL, language: String? = nil, contact: Contact?, room: Room?) -> Message { - return makeAudioMessage(withUrl: url, - language: language, - contact: contact, - room: room) - } - - func makeUntranscribedMessage(message: Message, transcriptionId: String, translationId: String? = nil) -> Message { - return makeUntranscribedMessage(message: message, - transcriptionId: transcriptionId, - translationId: translationId) - } -} - final class MessageFactory: MessageFactoryProtocol, InitializeInjectable { + // MARK: - Dependencies + private let storageService: StorageService private let payloadBuilder: MessagePayloadBuilderInput @@ -68,6 +21,9 @@ final class MessageFactory: MessageFactoryProtocol, InitializeInjectable { let payloadBuilder: MessagePayloadBuilderInput } + + // MARK: - Init + init(dependencies: Dependencies) { storageService = dependencies.storageService payloadBuilder = dependencies.payloadBuilder diff --git a/Nynja/Library/MessageFactory/MessageFactoryProtocol.swift b/Nynja/Library/MessageFactory/MessageFactoryProtocol.swift new file mode 100644 index 000000000..5fde105e4 --- /dev/null +++ b/Nynja/Library/MessageFactory/MessageFactoryProtocol.swift @@ -0,0 +1,59 @@ +// +// MessageFactoryProtocol.swift +// Nynja +// +// Created by Anton Poltoratskyi on 10.09.2018. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import Foundation +import CoreLocation + +protocol MessageFactoryProtocol: class { + func makeTextMessage(inputText: InputTextMessage, contact: Contact?, room: Room?) -> Message + + func makeTextMessageEdited(message: Message, newInputText: InputTextMessage) -> Message + func makeTextMessageEdited(message: Message, action: DBMessageEditAction) -> Message + + func makeMediaMessage(media: Media, contact: Contact?, room: Room?) -> Message + func makeImageMessage(imageURL: URL, contact: Contact?, room: Room?) -> Message + func makeVideoMessage(videoURL: URL, contact: Contact?, room: Room?) -> Message + + func makeLocationMessage(coordinate: CLLocationCoordinate2D, contact: Contact?, room: Room?) -> Message + func makeLocationMessage(coordinate: String, contact: Contact?, room: Room?) -> Message + + func makePlaceMessage(place: Place, contact: Contact?, room: Room?) -> Message + func makeAudioMessage(withUrl url: URL, language: String?, contact: Contact?, room: Room?) -> Message + func makeContactMessage(sendingContact: Contact, contact: Contact?, room: Room?) -> Message + + func makeFileMessage(withUrl url: URL, contact: Contact?, room: Room?) -> Message + func makeStickerMessage(sticker: Sticker, contact: Contact?, room: Room?) -> Message + + func makeTranslatedMessage(message: Message, text: String, translatedText: String, lang: String) -> Message + func makeUntranslatedMessage(message: Message, translationId: String) -> Message + func autotranslationDesc(text: String, translatedText: String, lang: String) -> Desc + + func makeTranscribedMessage(message: Message, text: String, lang: String) -> Message + func makeUntranscribedMessage(message: Message, transcriptionId: String, translationId: String?) -> Message + + func makePaymentMessage(inputText: String, contact: Contact) -> Message + + func makeCallMessage(members: [String], room: Room?) -> Message + + func makeMessageForDelete(message: Message, seenBy: [AnyObject]) -> Message +} + +extension MessageFactoryProtocol { + func makeAudioMessage(withUrl url: URL, language: String? = nil, contact: Contact?, room: Room?) -> Message { + return makeAudioMessage(withUrl: url, + language: language, + contact: contact, + room: room) + } + + func makeUntranscribedMessage(message: Message, transcriptionId: String, translationId: String? = nil) -> Message { + return makeUntranscribedMessage(message: message, + transcriptionId: transcriptionId, + translationId: translationId) + } +} -- GitLab From e95212c4b0e5b3241b8cf278996bebe0235b31e3 Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 13:20:12 +0300 Subject: [PATCH 10/16] [NY-1385] Rename 'editMessage' field in DBJobMessage and DBStarMessage to 'link' field. --- Nynja/DB/Models/DBJobMessage.swift | 10 +++++----- Nynja/DB/Models/DBStarMessage.swift | 10 +++++----- Nynja/Extensions/Models/Message/Message+DB.swift | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Nynja/DB/Models/DBJobMessage.swift b/Nynja/DB/Models/DBJobMessage.swift index 3cc8ac67e..6787e6ceb 100644 --- a/Nynja/DB/Models/DBJobMessage.swift +++ b/Nynja/DB/Models/DBJobMessage.swift @@ -9,7 +9,7 @@ import Foundation import GRDBCipher -class DBJobMessage: Record, DBModelProtocol { +final class DBJobMessage: Record, DBModelProtocol { var id: Int64? var container: String? @@ -23,7 +23,7 @@ class DBJobMessage: Record, DBModelProtocol { var to: String? var created: Int64? var type: String? - var editMessage: Int64? + var link: Int64? var repliedBy: String? var mentioned: String? var status: String? @@ -45,7 +45,7 @@ class DBJobMessage: Record, DBModelProtocol { self.to = message.to self.created = message.created self.type = message.types.joinedByCommaIfNotEmpty() - self.editMessage = message.linkedId + self.link = message.linkedId self.status = message.statusString self.files = (message.files ?? []).compactMap { DBDesc(desc: $0, targetId: nil, targetType: .schedule) } @@ -79,7 +79,7 @@ class DBJobMessage: Record, DBModelProtocol { self.to = row[JobMessageTable.Column.to.title] self.created = row[JobMessageTable.Column.created.title] self.type = row[JobMessageTable.Column.type.title] - self.editMessage = row[JobMessageTable.Column.editMessage.title] + self.link = row[JobMessageTable.Column.editMessage.title] self.repliedBy = row[JobMessageTable.Column.repliedBy.title] self.mentioned = row[JobMessageTable.Column.mentioned.title] self.status = row[JobMessageTable.Column.status.title] @@ -100,7 +100,7 @@ class DBJobMessage: Record, DBModelProtocol { container[JobMessageTable.Column.to.title] = self.to container[JobMessageTable.Column.created.title] = self.created container[JobMessageTable.Column.type.title] = self.type - container[JobMessageTable.Column.editMessage.title] = self.editMessage + container[JobMessageTable.Column.editMessage.title] = self.link container[JobMessageTable.Column.repliedBy.title] = self.repliedBy container[JobMessageTable.Column.mentioned.title] = self.mentioned container[JobMessageTable.Column.status.title] = self.status diff --git a/Nynja/DB/Models/DBStarMessage.swift b/Nynja/DB/Models/DBStarMessage.swift index ca3078056..2d29114ad 100644 --- a/Nynja/DB/Models/DBStarMessage.swift +++ b/Nynja/DB/Models/DBStarMessage.swift @@ -23,7 +23,7 @@ final class DBStarMessage: Record, DBModelProtocol { var to: String? var created: Int64? var type: String? - var editMessage: Int64? + var link: Int64? var repliedBy: String? var mentioned: String? var status: String? @@ -63,9 +63,9 @@ final class DBStarMessage: Record, DBModelProtocol { self.localId = message.msg_id self.from = message.from self.to = message.to - self.created = message.created as? Int64 + self.created = message.created self.type = message.types.joinedByCommaIfNotEmpty() - self.editMessage = message.linkedId + self.link = message.linkedId self.status = message.statusString self.files = (message.files ?? []).compactMap { DBDesc(desc: $0, targetId: nil, targetType: .star) } @@ -101,7 +101,7 @@ final class DBStarMessage: Record, DBModelProtocol { self.to = row[StarMessageTable.Column.to.title] self.created = row[StarMessageTable.Column.created.title] self.type = row[StarMessageTable.Column.type.title] - self.editMessage = row[StarMessageTable.Column.editMessage.title] + self.link = row[StarMessageTable.Column.editMessage.title] self.repliedBy = row[StarMessageTable.Column.repliedBy.title] self.mentioned = row[StarMessageTable.Column.mentioned.title] self.status = row[StarMessageTable.Column.status.title] @@ -122,7 +122,7 @@ final class DBStarMessage: Record, DBModelProtocol { container[StarMessageTable.Column.to.title] = self.to container[StarMessageTable.Column.created.title] = self.created container[StarMessageTable.Column.type.title] = self.type - container[StarMessageTable.Column.editMessage.title] = self.editMessage + container[StarMessageTable.Column.editMessage.title] = self.link container[StarMessageTable.Column.repliedBy.title] = self.repliedBy container[StarMessageTable.Column.mentioned.title] = self.mentioned container[StarMessageTable.Column.status.title] = self.status diff --git a/Nynja/Extensions/Models/Message/Message+DB.swift b/Nynja/Extensions/Models/Message/Message+DB.swift index c5250a72c..8de627d30 100644 --- a/Nynja/Extensions/Models/Message/Message+DB.swift +++ b/Nynja/Extensions/Models/Message/Message+DB.swift @@ -53,7 +53,7 @@ extension Message { self.to = message.to self.created = message.created self.types = Set(message.type?.components(separatedBy: Constants.commaSeparator) ?? []) - self.linkedId = message.editMessage + self.linkedId = message.link self.repliedby = message.repliedBy?.splitIntegerIdentifiers() self.mentioned = message.mentioned?.splitIntegerIdentifiers() @@ -88,7 +88,7 @@ extension Message { self.to = message.to self.created = message.created self.types = Set(message.type?.components(separatedBy: Constants.commaSeparator) ?? []) - self.linkedId = message.editMessage + self.linkedId = message.link self.repliedby = message.repliedBy?.splitIntegerIdentifiers() self.mentioned = message.mentioned?.splitIntegerIdentifiers() -- GitLab From b9d4f31c06a5c00247119374b57d5a1144ea2dbc Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 13:25:34 +0300 Subject: [PATCH 11/16] [NY-1385] Remove unneeded cast to Int64 for 'Message.created' field. --- Nynja/ConversationsProvider.swift | 4 ++-- Nynja/Extensions/Models/StarExtension.swift | 2 +- Nynja/Modules/Message/Interactor/MessageInteractor.swift | 4 ++-- .../Views/TableView/Cells/Models/RepliedMessageModel.swift | 2 +- Nynja/Modules/Replies/Presenter/RepliesPresenter.swift | 2 +- .../Library/Extensions/Models/Message/MessageExtension.swift | 5 ++--- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Nynja/ConversationsProvider.swift b/Nynja/ConversationsProvider.swift index b5acc08a0..c7b497524 100644 --- a/Nynja/ConversationsProvider.swift +++ b/Nynja/ConversationsProvider.swift @@ -64,8 +64,8 @@ class ConversationsProvider: ConversationsProviding { // MARK: - Comparator func comparator(lhs: ChatModel, rhs: ChatModel) -> Bool { - let created1 = lhs.last_msg?.created as? Int64 ?? 0 - let created2 = rhs.last_msg?.created as? Int64 ?? 0 + let created1 = lhs.last_msg?.created ?? 0 + let created2 = rhs.last_msg?.created ?? 0 return created1 > created2 } diff --git a/Nynja/Extensions/Models/StarExtension.swift b/Nynja/Extensions/Models/StarExtension.swift index a0f63c181..95cbaf53a 100644 --- a/Nynja/Extensions/Models/StarExtension.swift +++ b/Nynja/Extensions/Models/StarExtension.swift @@ -101,7 +101,7 @@ extension Star { } var timestamp: Int64 { - guard let timestamp = message?.created as? Int64 else { + guard let timestamp = message?.created else { return 0 } return timestamp diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor.swift b/Nynja/Modules/Message/Interactor/MessageInteractor.swift index 9d39dbf7d..80f76fb2c 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor.swift @@ -533,7 +533,7 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H } private func compare(_ left: Message?, with right: Message?) -> Bool { - return Date(timestamp: (left?.created as? Int64) ?? 0) > Date(timestamp: (right?.created as? Int64) ?? 0) + return Date(timestamp: left?.created ?? 0) > Date(timestamp: right?.created ?? 0) } private func flatMap(desc: Desc?) -> LocationType? { @@ -561,7 +561,7 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H urls[mainURL] = message } return urls.values - .sorted { Date(timestamp: ($0.created as? Int64) ?? 0) < Date(timestamp: ($1.created as? Int64) ?? 0) } + .sorted { Date(timestamp: $0.created ?? 0) < Date(timestamp: $1.created ?? 0) } .compactMap { guard let mainFile = $0.mainFile, let thumbnailFile = $0.thumb, let mainURL = mainFile.url, let thumbnailURL = thumbnailFile.url else { diff --git a/Nynja/Modules/Message/View/Views/TableView/Cells/Models/RepliedMessageModel.swift b/Nynja/Modules/Message/View/Views/TableView/Cells/Models/RepliedMessageModel.swift index 3318c78f6..77bfcee3b 100644 --- a/Nynja/Modules/Message/View/Views/TableView/Cells/Models/RepliedMessageModel.swift +++ b/Nynja/Modules/Message/View/Views/TableView/Cells/Models/RepliedMessageModel.swift @@ -42,7 +42,7 @@ final class RepliedMessageModel { self.text = fileName } - self.date = Date(timestamp: (message.created as? Int64) ?? 0) + self.date = Date(timestamp: message.created ?? 0) self.mentions = mentions } diff --git a/Nynja/Modules/Replies/Presenter/RepliesPresenter.swift b/Nynja/Modules/Replies/Presenter/RepliesPresenter.swift index 5d04e312b..a15b38b4b 100644 --- a/Nynja/Modules/Replies/Presenter/RepliesPresenter.swift +++ b/Nynja/Modules/Replies/Presenter/RepliesPresenter.swift @@ -88,7 +88,7 @@ class RepliesPresenter: BasePresenter, RepliesPresenterProtocol, RepliesInteract model.isOwner = message.from == StorageService.sharedInstance.phoneId model.replied = message.repliedby?.count ?? 0 - model.timeStamp = Date(timestamp: (message.created as? Int64) ?? 0) + model.timeStamp = Date(timestamp: message.created ?? 0) let size = attach.size ?? 0 model.currentSize = size diff --git a/Shared/Library/Extensions/Models/Message/MessageExtension.swift b/Shared/Library/Extensions/Models/Message/MessageExtension.swift index a3394fa2c..1b623b2f1 100644 --- a/Shared/Library/Extensions/Models/Message/MessageExtension.swift +++ b/Shared/Library/Extensions/Models/Message/MessageExtension.swift @@ -70,15 +70,14 @@ extension Message { } var createdInt: Int64 { - return (created as? Int64) ?? 0 + return created ?? 0 } var createdDate: Date? { - if let timestamp = created as? Int64 { + if let timestamp = created { let formattedTimestamp = Double(timestamp) / 1000 return Date(timeIntervalSince1970: formattedTimestamp) } - return nil } -- GitLab From 01797c14feb22a70017602969771866d144bce7d Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 13:52:31 +0300 Subject: [PATCH 12/16] [NY-1385] Fixed recursive constraints in Message_Spec. --- Nynja/ServerModel/Spec/Message_Spec.swift | 62 ++++++++++++++++++- .../Models/Message/MessageExtension.swift | 7 ++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/Nynja/ServerModel/Spec/Message_Spec.swift b/Nynja/ServerModel/Spec/Message_Spec.swift index b8d1286b8..3d1ac4148 100644 --- a/Nynja/ServerModel/Spec/Message_Spec.swift +++ b/Nynja/ServerModel/Spec/Message_Spec.swift @@ -40,7 +40,7 @@ func get_Message() -> Model { Model(value:Chain(types:[ Model(value:List(constant:"")), Model(value:Number()), - get_Message()])), + getNotRecursiveMessage()])), Model(value:List(constant:nil, model:Model(value:Chain(types:[ Model(value:Binary()), Model(value:Number())])))), @@ -52,4 +52,62 @@ func get_Message() -> Model { Model(value:Atom(constant:"delete")), Model(value:Atom(constant:"clear")), Model(value:Atom(constant:"update")), - Model(value:Atom(constant:"edit"))]))]))} + Model(value:Atom(constant:"edit"))]))])) +} + +// FIXME: need to think about recursive relations. +private func getNotRecursiveMessage() -> Model { + return Model(value:Tuple(name:"Message",body:[ + Model(value:Chain(types:[ + Model(value:List(constant:"")), + Model(value:Number())])), + Model(value:Chain(types:[ + Model(value:Atom(constant:"chain")), + Model(value:Atom(constant:"cur"))])), + Model(value:Chain(types:[ + get_muc(), + get_p2p()])), + Model(value:Chain(types:[ + Model(value:List(constant:"")), + Model(value:Number())])), + Model(value:Chain(types:[ + Model(value:List(constant:"")), + Model(value:Number())])), + Model(value:Chain(types:[ + Model(value:List(constant:"")), + Model(value:Binary())])), + Model(value:Chain(types:[ + Model(value:List(constant:"")), + Model(value:Binary())])), + Model(value:Chain(types:[ + Model(value:List(constant:"")), + Model(value:Binary())])), + Model(value:Chain(types:[ + Model(value:List(constant:"")), + Model(value:Number())])), + Model(value:List(constant:nil,model:get_Desc())), + Model(value:Chain(types:[ + Model(value:List(constant:"")), + Model(value:List(constant:nil, model:Model(value:Chain(types:[ + Model(value:Atom(constant:"sys")), + Model(value:Atom(constant:"reply")), + Model(value:Atom(constant:"forward")), + Model(value:Atom(constant:"read")), + Model(value:Atom(constant:"edited")), + Model(value:Atom(constant:"cursor"))]))))])), + Model(value:Chain(types:[ + Model(value:List(constant:"")), + Model(value:Number())])), + Model(value:List(constant:nil, model:Model(value:Chain(types:[ + Model(value:Binary()), + Model(value:Number())])))), + Model(value:List(constant:nil, model:Model(value:Number()))), + Model(value:List(constant:nil, model:Model(value:Number()))), + Model(value:Chain(types:[ + Model(value:List(constant:"")), + Model(value:Atom(constant:"async")), + Model(value:Atom(constant:"delete")), + Model(value:Atom(constant:"clear")), + Model(value:Atom(constant:"update")), + Model(value:Atom(constant:"edit"))]))])) +} diff --git a/Shared/Library/Extensions/Models/Message/MessageExtension.swift b/Shared/Library/Extensions/Models/Message/MessageExtension.swift index 1b623b2f1..4ae167c32 100644 --- a/Shared/Library/Extensions/Models/Message/MessageExtension.swift +++ b/Shared/Library/Extensions/Models/Message/MessageExtension.swift @@ -100,7 +100,12 @@ extension Message { } var linkedId: MessageServerId? { - get { return link as? MessageServerId } + get { + if let link = link as? MessageServerId { + return link + } + return (link as? Message)?.id + } set { link = newValue as AnyObject? } } } -- GitLab From 5ec432ae430ed976c7eb99b51aa7c03701dac9ae Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 15:37:11 +0300 Subject: [PATCH 13/16] [NY-1385] Update BERT encoding logic for Message model - don't encode full Message model into link field. --- Nynja/MQTTModels/MessageExtension+BERT.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/Nynja/MQTTModels/MessageExtension+BERT.swift b/Nynja/MQTTModels/MessageExtension+BERT.swift index 3aa85dc72..b8fe8b296 100644 --- a/Nynja/MQTTModels/MessageExtension+BERT.swift +++ b/Nynja/MQTTModels/MessageExtension+BERT.swift @@ -80,8 +80,6 @@ extension Message { let link: BertObject if let linkedId = self.linkedId { link = Bert.getBin(linkedId) - } else if let linkedMessage = self.link as? Message { - link = linkedMessage.getBert() } else { link = BertNil() } -- GitLab From c6a13e1820bc4ddeaa89d1b44ca553e085032219 Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 18:24:53 +0300 Subject: [PATCH 14/16] [NY-1385] Save and fetch replied messages --- .../Message/Interactor/MessageInteractor+Fetch.swift | 7 +++++-- .../MessageInteractor+StorageSubscriber.swift | 11 ++++++++--- .../Message/Interactor/MessageInteractor.swift | 8 +++----- .../Modules/Message/Presenter/MessagePresenter.swift | 2 ++ .../Modules/Message/Protocols/MessageProtocols.swift | 2 +- Nynja/Services/HandleServices/HistoryHandler.swift | 3 +++ .../Extensions/Models/Message/MessageExtension.swift | 7 +++++++ 7 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift b/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift index 4d4921f6f..d0369dd81 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift @@ -164,9 +164,12 @@ extension MessageInteractor { var repliedModels = ChatConfiguration.RepliedModels() repliedMessages.forEach { message in - if let serverId = message.id, let sender = sender(for: message) { + if let serverId = message.id { + let sender = self.sender(for: message) let mentions = payloadParser.parse(message) - repliedModels[serverId] = RepliedMessageModel(message: message, author: sender.nick ?? sender.fullname, mentions: mentions) + repliedModels[serverId] = RepliedMessageModel(message: message, + author: sender.nick ?? sender.fullname, + mentions: mentions) } } diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift b/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift index 02cce20a3..c69dede2e 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift @@ -258,10 +258,15 @@ extension MessageInteractor { func createMessageConfiguration(_ message: Message) -> MessageConfiguration { var repliedModel: RepliedMessageModel? - if message.isReply { - if let serverId = message.linkedId, let repliedMessage = messageBy(serverId: serverId), let sender = sender(for: repliedMessage) { + if message.isReply, let serverId = message.linkedId { + let repliedMessage = messageBy(serverId: serverId) ?? MessageDAO.fetchMessage(serverId: serverId) + + if let repliedMessage = repliedMessage { + let sender = self.sender(for: repliedMessage) let mentions = payloadParser.parse(repliedMessage) - repliedModel = RepliedMessageModel(message: repliedMessage, author: sender.nick ?? sender.fullname, mentions: mentions) + repliedModel = RepliedMessageModel(message: repliedMessage, + author: sender.nick ?? sender.fullname, + mentions: mentions) configuration.repliedModels[serverId] = repliedModel } } diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor.swift b/Nynja/Modules/Message/Interactor/MessageInteractor.swift index 9c900bf58..a80750827 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor.swift @@ -377,9 +377,10 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H // MARK: - Sender - func sender(for message: Message) -> MessageSender? { + func sender(for message: Message) -> MessageSender { let isOwner = message.from == myContact?.phone_id - if let _ = (message.feed_id as? muc), let from = message.from, let member = member(for: from) { + + if message.feed_id is muc, let from = message.from, let member = member(for: from) { return messageSender(from: member) } else if let contact = self.contact { if isOwner, let myContact = myContact { @@ -626,9 +627,6 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H if let url = message.mainUrl { configuration.progressModels.removeValue(forKey: url) } - if let serverId = message.linkedId { - configuration.repliedModels.removeValue(forKey: serverId) - } presenter?.removeMessage(id) } } diff --git a/Nynja/Modules/Message/Presenter/MessagePresenter.swift b/Nynja/Modules/Message/Presenter/MessagePresenter.swift index 0765143ac..2e80d93bc 100644 --- a/Nynja/Modules/Message/Presenter/MessagePresenter.swift +++ b/Nynja/Modules/Message/Presenter/MessagePresenter.swift @@ -647,10 +647,12 @@ class MessagePresenter: BasePresenter, MessagePresenterProtocol, MessageInteract if let systemMessage = message.systemMessage(for: interactor.chat) { cells.append(systemModel(message: systemMessage, mod: message)) + } else if let localId = message.msg_id, var model = self.getCellModel(message: message, repliedModel: repliedModel, readerID: configuration.reader, + links: configuration.links[localId], mentions: configuration.mentions[localId], translation: configuration.translations[localId], transcription: configuration.transcriptions[localId], diff --git a/Nynja/Modules/Message/Protocols/MessageProtocols.swift b/Nynja/Modules/Message/Protocols/MessageProtocols.swift index 104ea6625..5bf2900b9 100644 --- a/Nynja/Modules/Message/Protocols/MessageProtocols.swift +++ b/Nynja/Modules/Message/Protocols/MessageProtocols.swift @@ -238,7 +238,7 @@ protocol MessageInteractorInputProtocol: BaseInteractorProtocol, MentionFetchInp func member(for phoneId: String) -> Member? - func sender(for message: Message) -> MessageSender? + func sender(for message: Message) -> MessageSender func askForInternetStatus() diff --git a/Nynja/Services/HandleServices/HistoryHandler.swift b/Nynja/Services/HandleServices/HistoryHandler.swift index f28645bf4..07850011d 100644 --- a/Nynja/Services/HandleServices/HistoryHandler.swift +++ b/Nynja/Services/HandleServices/HistoryHandler.swift @@ -104,6 +104,9 @@ final class HistoryHandler: BaseHandler { } else if !isHistoryCleared { stackForSave.append(message) + if let repliedMessage = message.repliedMessage { + stackForSave.append(repliedMessage) + } } case .skip: // Ignore received message if we have local 'edit' action for it. diff --git a/Shared/Library/Extensions/Models/Message/MessageExtension.swift b/Shared/Library/Extensions/Models/Message/MessageExtension.swift index 4ae167c32..1374dbe88 100644 --- a/Shared/Library/Extensions/Models/Message/MessageExtension.swift +++ b/Shared/Library/Extensions/Models/Message/MessageExtension.swift @@ -108,6 +108,13 @@ extension Message { } set { link = newValue as AnyObject? } } + + var repliedMessage: Message? { + guard isReply, let repliedMessage = link as? Message else { + return nil + } + return repliedMessage + } } // MARK: - Feed -- GitLab From 949f648eb6b83e4c3c4d07352f693d0f822b667b Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 19:56:15 +0300 Subject: [PATCH 15/16] [NY-1385] Added 'isVisible' and 'localStatus' columns. --- Nynja/DB/Models/DBMessage.swift | 10 ++++++++ Nynja/DB/Tables/MessageTable.swift | 4 ++++ .../Models/Message/Message+DB.swift | 2 ++ Nynja/MigrationManager.swift | 23 +++++++++++++++++++ Nynja/ServerModel/Model/Message.swift | 9 ++++++++ .../Models/Message/MessageExtension.swift | 6 +++++ 6 files changed, 54 insertions(+) diff --git a/Nynja/DB/Models/DBMessage.swift b/Nynja/DB/Models/DBMessage.swift index 346423896..70f9b33b7 100644 --- a/Nynja/DB/Models/DBMessage.swift +++ b/Nynja/DB/Models/DBMessage.swift @@ -28,7 +28,9 @@ final class DBMessage: Record, DBModelProtocol { var repliedBy: String? var mentioned: String? var status: String? + var localStatus: String? var isTrusted: Bool? + var isVisible: Bool? var files: [DBDesc] = [] @@ -47,7 +49,9 @@ final class DBMessage: Record, DBModelProtocol { self.type = message.types.joinedByCommaIfNotEmpty() self.link = message.linkedId self.status = message.statusString + self.localStatus = message.localStatus self.isTrusted = message.isTrusted + self.isVisible = message.isVisible self.files = (message.files ?? []).compactMap { DBDesc(desc: $0, targetId: nil, targetType: .message) } @@ -87,7 +91,9 @@ final class DBMessage: Record, DBModelProtocol { self.repliedBy = row[MessageTable.Column.repliedBy.title] self.mentioned = row[MessageTable.Column.mentioned.title] self.status = row[MessageTable.Column.status.title] + self.localStatus = row[MessageTable.Column.localStatus.title] self.isTrusted = row[MessageTable.Column.trusted.title] + self.isVisible = row[MessageTable.Column.visible.title] super.init() } @@ -109,9 +115,13 @@ final class DBMessage: Record, DBModelProtocol { container[MessageTable.Column.repliedBy.title] = self.repliedBy container[MessageTable.Column.mentioned.title] = self.mentioned container[MessageTable.Column.status.title] = self.status + container[MessageTable.Column.localStatus.title] = self.localStatus if let isTrusted = isTrusted { container[MessageTable.Column.trusted.title] = isTrusted } + if let isVisible = isVisible { + container[MessageTable.Column.visible.title] = isVisible + } } override func didInsert(with rowID: Int64, for column: String?) { diff --git a/Nynja/DB/Tables/MessageTable.swift b/Nynja/DB/Tables/MessageTable.swift index c65e1fd62..32ba1ad43 100644 --- a/Nynja/DB/Tables/MessageTable.swift +++ b/Nynja/DB/Tables/MessageTable.swift @@ -32,7 +32,9 @@ final class MessageTable: Table { t.column(Column.repliedBy, .text) t.column(Column.mentioned, .text) t.column(Column.status, .text) + t.column(Column.localStatus, .text) t.column(Column.trusted, .boolean) + t.column(Column.visible, .boolean) } } } @@ -57,6 +59,8 @@ extension MessageTable { case repliedBy case mentioned case status + case localStatus case trusted + case visible } } diff --git a/Nynja/Extensions/Models/Message/Message+DB.swift b/Nynja/Extensions/Models/Message/Message+DB.swift index 8de627d30..183f73fc0 100644 --- a/Nynja/Extensions/Models/Message/Message+DB.swift +++ b/Nynja/Extensions/Models/Message/Message+DB.swift @@ -28,6 +28,7 @@ extension Message { self.mentioned = message.mentioned?.splitIntegerIdentifiers() self.status = StringAtom(string: message.status) + self.localStatus = message.localStatus self.files = message.files.map { Desc(desc: $0) } @@ -39,6 +40,7 @@ extension Message { } self.isTrusted = message.isTrusted + self.isVisible = message.isVisible } convenience init(message: DBStarMessage) { diff --git a/Nynja/MigrationManager.swift b/Nynja/MigrationManager.swift index 643ebe939..856bf9d51 100644 --- a/Nynja/MigrationManager.swift +++ b/Nynja/MigrationManager.swift @@ -24,6 +24,8 @@ enum Migration: Int, Describable { case primaryKeyMessageAction case addTrustedColumnForMessage case createStarActionTable + case addLocalStatusColumnForMessage + case addVisibleColumnForMessage static var allTitles: [String] = { var i = 0 @@ -254,6 +256,26 @@ final class MigrationManager { migrator.registerMigration(.createStarActionTable) { db in try StarActionTable.createIfNotExists(in: db) } + + migrator.registerMigration(.addLocalStatusColumnForMessage) { db in + let column = MessageTable.Column.localStatus.title + guard try !MessageTable.hasColumns([column], in: db) else { + return + } + try MessageTable.alter(in: db) { t in + t.add(column: column, .text) + } + } + + migrator.registerMigration(.addVisibleColumnForMessage) { db in + let column = MessageTable.Column.visible.title + guard try !MessageTable.hasColumns([column], in: db) else { + return + } + try MessageTable.alter(in: db) { t in + t.add(column: column, .boolean) + } + } } private func replaceFeatureKey(_ key: String, newKey: Room.FeatureKey, db: Database) throws { @@ -271,6 +293,7 @@ final class MigrationManager { // MARK: - DatabaseMigrator private extension DatabaseMigrator { + mutating func registerMigration(_ migration: Migration, migrate: @escaping (Database) throws -> Void) { registerMigration(migration.title, migrate: migrate) } diff --git a/Nynja/ServerModel/Model/Message.swift b/Nynja/ServerModel/Model/Message.swift index fdda11f7c..156fa575f 100644 --- a/Nynja/ServerModel/Model/Message.swift +++ b/Nynja/ServerModel/Model/Message.swift @@ -17,13 +17,22 @@ class Message { var mentioned: [AnyObject]? var status: AnyObject? + + // MARK: - Local Fields + var feedName: String? var senderName: String? var senderAvatar: String? + var localStatus: String? + /// Property is needed in order to handle gaps in message history. /// Property 'isTrusted = true' when sequence of [message BEFORE (serverId = 1), self message (serverId = 2)] /// form a valid history chain inside a p2p of muc, /// so we could ignore some of history gaps based on 'prev' and 'next' fields. var isTrusted: Bool? + + /// Property is needed in order to hide replied message from visible history that will be displayed, + /// until replied message will be received with other chat history. + var isVisible: Bool? } diff --git a/Shared/Library/Extensions/Models/Message/MessageExtension.swift b/Shared/Library/Extensions/Models/Message/MessageExtension.swift index 1374dbe88..0342830c1 100644 --- a/Shared/Library/Extensions/Models/Message/MessageExtension.swift +++ b/Shared/Library/Extensions/Models/Message/MessageExtension.swift @@ -49,12 +49,14 @@ extension Message { self.repliedby = message.repliedby self.mentioned = message.mentioned self.status = StringAtom(any: message.status) + self.localStatus = message.localStatus self.feedName = message.feedName self.senderName = message.senderName self.senderAvatar = message.senderAvatar self.isTrusted = message.isTrusted + self.isVisible = message.isVisible } var isDelivered: Bool { @@ -182,6 +184,10 @@ extension Message { extension Message { + enum LocalStatus: String { + case replied = "replied" + } + var isStatusClear: Bool { return statusString == "clear" } -- GitLab From c8ba79191a9904068145bf655709790f4d424b6e Mon Sep 17 00:00:00 2001 From: Anton Poltoratskyi Date: Mon, 10 Sep 2018 20:18:33 +0300 Subject: [PATCH 16/16] Update migration --- Nynja/MigrationManager.swift | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Nynja/MigrationManager.swift b/Nynja/MigrationManager.swift index 856bf9d51..c26a35d74 100644 --- a/Nynja/MigrationManager.swift +++ b/Nynja/MigrationManager.swift @@ -244,12 +244,7 @@ final class MigrationManager { try MessageTable.alter(in: db) { t in t.add(column: column, .boolean) } - - let sql = """ - UPDATE \(MessageTable.name) - SET \(column) = ? - """ - + let sql = "UPDATE \(MessageTable.name) SET \(column) = ?" try db.execute(sql, arguments: [true]) } @@ -275,6 +270,10 @@ final class MigrationManager { try MessageTable.alter(in: db) { t in t.add(column: column, .boolean) } + + // Make all replied messages 'visible', that was currently loaded in database. + let sql = "UPDATE \(MessageTable.name) SET \(column) = ?" + try db.execute(sql, arguments: [true]) } } -- GitLab