diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 0e74a41c2589b278a7567a53fe86583d9c99296a..d00e4a93f2555ce90ef78898c62276b28830c780 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -637,6 +637,14 @@ 78D088DF6A23DD7BAE665C9A /* AudioRecorderProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = D12785F11EFEC4A76CC34917 /* AudioRecorderProtocols.swift */; }; 7A8FE56A8E5D02256D8BE936 /* EditPhotoPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4177485419FF2E8F7CF8FF98 /* EditPhotoPresenter.swift */; }; 82FCF48AA4A8C04CC8B0B5B6 /* FavoritesWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EC0DFB96051C50F0FC5B9CA /* FavoritesWireframe.swift */; }; + 850930A5202DC41300AC1C18 /* ExtendedStarHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855EF424202CCADB00541BE3 /* ExtendedStarHandler.swift */; }; + 855EF419202CB86500541BE3 /* ExtendedStar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855EF418202CB86500541BE3 /* ExtendedStar.swift */; }; + 855EF41B202CB9B900541BE3 /* ExtendedStar_Spec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855EF41A202CB9B900541BE3 /* ExtendedStar_Spec.swift */; }; + 855EF41E202CBE1900541BE3 /* ExtendedStar_Spec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855EF41A202CB9B900541BE3 /* ExtendedStar_Spec.swift */; }; + 855EF41F202CBE2400541BE3 /* ExtendedStar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855EF418202CB86500541BE3 /* ExtendedStar.swift */; }; + 855EF421202CC6F800541BE3 /* GetExtendedStarsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855EF420202CC6F800541BE3 /* GetExtendedStarsModel.swift */; }; + 855EF423202CC85300541BE3 /* MQTTServiceStars.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855EF422202CC85300541BE3 /* MQTTServiceStars.swift */; }; + 855EF425202CCADB00541BE3 /* ExtendedStarHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855EF424202CCADB00541BE3 /* ExtendedStarHandler.swift */; }; 858A72E5A4AE48CE24AFF649 /* MainInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70CEB31C47B0FEB0040FD0DA /* MainInteractor.swift */; }; 85F43C2BE9C631868C394BCD /* WebViewWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C469B351D6DA4CEBCE9C591 /* WebViewWireframe.swift */; }; 87A3D03524B9258B33726A57 /* HistoryInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D3E868EE32625048BCB13A8 /* HistoryInteractor.swift */; }; @@ -1473,6 +1481,11 @@ 8181D695D260804FB2F3102E /* ImagePreviewViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImagePreviewViewController.swift; sourceTree = ""; }; 83310EC1487B51C6F4FE9FB4 /* AudioRecorderInteractor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AudioRecorderInteractor.swift; sourceTree = ""; }; 83894D517BFF22637F2878B7 /* EditUsernameProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EditUsernameProtocols.swift; sourceTree = ""; }; + 855EF418202CB86500541BE3 /* ExtendedStar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtendedStar.swift; sourceTree = ""; }; + 855EF41A202CB9B900541BE3 /* ExtendedStar_Spec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtendedStar_Spec.swift; sourceTree = ""; }; + 855EF420202CC6F800541BE3 /* GetExtendedStarsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetExtendedStarsModel.swift; sourceTree = ""; }; + 855EF422202CC85300541BE3 /* MQTTServiceStars.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MQTTServiceStars.swift; sourceTree = ""; }; + 855EF424202CCADB00541BE3 /* ExtendedStarHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtendedStarHandler.swift; sourceTree = ""; }; 8606C1D61AA46EB77821B1B0 /* MyGroupAliasProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MyGroupAliasProtocols.swift; sourceTree = ""; }; 8B2389EFD3432F86296722BE /* QRCodeGeneratorProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = QRCodeGeneratorProtocols.swift; sourceTree = ""; }; 8B772E08B9E40EB48DD87082 /* EditUsernameViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EditUsernameViewController.swift; sourceTree = ""; }; @@ -2704,6 +2717,7 @@ 260552A51F9E1CD100D68DE6 /* SearchHandler.swift */, 263D66321FE8D95100A509F8 /* TypingHandler.swift */, 26FA420F201821B400E6F6EC /* StarHandler.swift */, + 855EF424202CCADB00541BE3 /* ExtendedStarHandler.swift */, ); name = HandleServices; sourceTree = ""; @@ -2808,6 +2822,7 @@ 3A8045CE1F60C8E200AED866 /* MQTTServiceFriend.swift */, 3A8045CF1F60C8E200AED866 /* MQTTServiceProfile.swift */, 3A8045D01F60C8E200AED866 /* MQTTServiceAuth.swift */, + 855EF422202CC85300541BE3 /* MQTTServiceStars.swift */, ); name = MQTT; path = Services/MQTT; @@ -2889,6 +2904,7 @@ 26035B421F9A73C700003850 /* Search_Spec.swift */, 26035B341F9A73C400003850 /* Service_Spec.swift */, 26035B4A1F9A73C900003850 /* Star_Spec.swift */, + 855EF41A202CB9B900541BE3 /* ExtendedStar_Spec.swift */, 26035B4C1F9A73C900003850 /* Tag_Spec.swift */, 26035B2E1F9A73C300003850 /* Test_Spec.swift */, 26035B391F9A73C500003850 /* Typing_Spec.swift */, @@ -2949,6 +2965,7 @@ 26035B511F9A73D500003850 /* Search.swift */, 26035B6A1F9A73D700003850 /* Service.swift */, 26035B661F9A73D700003850 /* Star.swift */, + 855EF418202CB86500541BE3 /* ExtendedStar.swift */, 26035B671F9A73D700003850 /* Tag.swift */, 26035B541F9A73D500003850 /* Test.swift */, 26035B6C1F9A73D800003850 /* Typing.swift */, @@ -3039,6 +3056,7 @@ 265AEA161FE9AFD400AC4806 /* MemberModel.swift */, 263D662C1FE8D03400A509F8 /* TypingModel.swift */, 269848C9200E9F1300590D6F /* StarModels.swift */, + 855EF420202CC6F800541BE3 /* GetExtendedStarsModel.swift */, ); name = Models; sourceTree = ""; @@ -5269,6 +5287,7 @@ }; 3ABCE8EC1EC9330D00A80B15 = { CreatedOnToolsVersion = 8.3.2; + DevelopmentTeam = 9GKQ5AMF2B; LastSwiftMigration = 0830; ProvisioningStyle = Automatic; SystemCapabilities = { @@ -5533,6 +5552,7 @@ 35B1ABAA1FA34AD400E65233 /* ok2.swift in Sources */, 263D66351FE8DA9700A509F8 /* Typing_Spec.swift in Sources */, 264FFA951FC5912E0028243D /* Table.swift in Sources */, + 855EF41F202CBE2400541BE3 /* ExtendedStar.swift in Sources */, 26FF00A51FCC2EC4002170B1 /* MQTTServiceAuth.swift in Sources */, 35B1AB9B1FA3498000E65233 /* Member.swift in Sources */, 35B1ABA81FA34AB600E65233 /* io.swift in Sources */, @@ -5679,6 +5699,7 @@ 268C62E32008DA0900433705 /* UIImageExtensions.swift in Sources */, 264FFA961FC5913A0028243D /* ProfileTable.swift in Sources */, 359EB25D1F9A1EA500147437 /* (null) in Sources */, + 855EF41E202CBE1900541BE3 /* ExtendedStar_Spec.swift in Sources */, 35B1AB951FA3491500E65233 /* Roster.swift in Sources */, 26770A551FFD2F91009AC870 /* StorageSubscriber.swift in Sources */, 35B1ABA71FA34A6B00E65233 /* error2_Spec.swift in Sources */, @@ -5687,6 +5708,7 @@ 35B1ABB51FA34C0C00E65233 /* Desc_Spec.swift in Sources */, 359EB2501F9A1DDC00147437 /* (null) in Sources */, 359EB25B1F9A1E9700147437 /* (null) in Sources */, + 850930A5202DC41300AC1C18 /* ExtendedStarHandler.swift in Sources */, 359EB27D1F9A2C9700147437 /* AuthModel.swift in Sources */, 359EB25E1F9A1EAD00147437 /* (null) in Sources */, ); @@ -5802,6 +5824,7 @@ E75D2CF62004ED84001E6718 /* MessageImageView.swift in Sources */, E7EDA5A21F8372EB00AE13F4 /* RosterExtension.swift in Sources */, 26A0B4291FA704B7009CD59A /* EditProfileWheelItemModel.swift in Sources */, + 855EF421202CC6F800541BE3 /* GetExtendedStarsModel.swift in Sources */, E7ABD2FF1FC2EDBC00E233F7 /* TagTable.swift in Sources */, 265AEA151FE9AFA700AC4806 /* MemberHandler.swift in Sources */, 26D268CE1FA7E3DB00F3BB23 /* CallsWheelItemModel.swift in Sources */, @@ -5811,6 +5834,7 @@ 26035B851F9A740A00003850 /* Feature.swift in Sources */, E75D2CFD2004ED84001E6718 /* MessageTableViewDelegate.swift in Sources */, 2661D12F1F373D1700F3E125 /* BoarderView.swift in Sources */, + 855EF425202CCADB00541BE3 /* ExtendedStarHandler.swift in Sources */, 3AC321781EEAC4C10068F3C8 /* AuthModel.swift in Sources */, 26D268C91FA7DD5C00F3BB23 /* MySelfWheelItemModel.swift in Sources */, 3A8218881EDF102D00337B05 /* Color.swift in Sources */, @@ -6142,6 +6166,7 @@ 267BE2941FDEA24000C47E18 /* SettingsGroupDS.swift in Sources */, 26035BA21F9A740A00003850 /* writer.swift in Sources */, F0839BACB1A52FCF846584D4 /* EditProfileWireframe.swift in Sources */, + 855EF419202CB86500541BE3 /* ExtendedStar.swift in Sources */, 262DAFE51F9AB6FF00EB9C01 /* Profile.swift in Sources */, 26035B821F9A740A00003850 /* Desc.swift in Sources */, 6D86A47B1F4D168A00BBD7A2 /* BaseButton.swift in Sources */, @@ -6254,6 +6279,7 @@ 8ED0F3CD1FBC5CF2004916AB /* GroupsListProtocols.swift in Sources */, E7229A4A1F8CAD72003AEE04 /* TutorialViewControllerLayout.swift in Sources */, E70402BD1FF6972B00182D81 /* BaseView.swift in Sources */, + 855EF41B202CB9B900541BE3 /* ExtendedStar_Spec.swift in Sources */, 4C5EEA13EBC6A8398F08DCD1 /* MainWireframe.swift in Sources */, 26035B8F1F9A740A00003850 /* Message.swift in Sources */, 8ECC067E1FC5BCC6002CF225 /* TransferManager.swift in Sources */, @@ -6408,6 +6434,7 @@ 990A25B2C84CE09B4CE64533 /* MyGroupAliasPresenter.swift in Sources */, D839883F9B7A8CD245A85701 /* MyGroupAliasInteractor.swift in Sources */, 8E96019F1FF303DF00E0C21D /* GroupAudiosListVC.swift in Sources */, + 855EF423202CC85300541BE3 /* MQTTServiceStars.swift in Sources */, 3362A56D731AC1411C02D037 /* MyGroupAliasWireframe.swift in Sources */, 8ED0F3D11FBC5CF2004916AB /* GroupsListViewController.swift in Sources */, BBF46945EB64E07C58817ACA /* EditGroupNameProtocols.swift in Sources */, @@ -6669,7 +6696,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 9GKQ5AMF2B; ENABLE_BITCODE = NO; INFOPLIST_FILE = "$(SRCROOT)/Nynja/Resources/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -6698,7 +6725,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 9GKQ5AMF2B; ENABLE_BITCODE = NO; INFOPLIST_FILE = "$(SRCROOT)/Nynja/Resources/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; diff --git a/Nynja/DB/Models/DBStar.swift b/Nynja/DB/Models/DBStar.swift index 52a75cfead67a221da3fd443cd5abfe29c75981d..2477c2e0ae4b12d440deed397ebfa8ca25fbc497 100644 --- a/Nynja/DB/Models/DBStar.swift +++ b/Nynja/DB/Models/DBStar.swift @@ -10,7 +10,8 @@ import Foundation import GRDB class DBStar: Record, DBModelProtocol { - var id: String? + var id: Int64? + var clientId: String? var rosterId: Int64? var message: DBStarMessage? var messageID: Int64? @@ -19,8 +20,9 @@ class DBStar: Record, DBModelProtocol { // MARK: - Mapping init?(star: Star) { + self.id = star.id + self.clientId = star.client_id ?? IdGenerator.generateUniqueId() self.rosterId = star.roster_id - self.id = star.id ?? IdGenerator.generateUniqueId() self.status = (star.status as? StringAtom)?.string if let msg = star.message { self.message = DBStarMessage(message: msg) @@ -34,17 +36,19 @@ class DBStar: Record, DBModelProtocol { } required init(row: Row) { + id = row[StarTable.Column.id.title] + clientId = row[StarTable.Column.clientId.title] rosterId = row[StarTable.Column.rosterId.title] status = row[StarTable.Column.status.title] - id = row[StarTable.Column.id.title] messageID = row[StarTable.Column.messageId.title] super.init() } override func encode(to container: inout PersistenceContainer) { + container[StarTable.Column.id.title] = id + container[StarTable.Column.clientId.title] = clientId container[StarTable.Column.rosterId.title] = rosterId container[StarTable.Column.status.title] = status - container[StarTable.Column.id.title] = id container[StarTable.Column.messageId.title] = messageID } diff --git a/Nynja/DB/Models/DBStarMessage.swift b/Nynja/DB/Models/DBStarMessage.swift index d450ee9a3a1f7aaa122a775517aa7d661a277cab..438383a2a07c43cfff4fefdf5ef396508da5fc73 100644 --- a/Nynja/DB/Models/DBStarMessage.swift +++ b/Nynja/DB/Models/DBStarMessage.swift @@ -86,6 +86,9 @@ class DBStarMessage: Record, DBModelProtocol { self.editMessage = row[StarMessageTable.Column.editMessage.title] self.repliedBy = row[StarMessageTable.Column.repliedBy.title] self.status = row[StarMessageTable.Column.status.title] + self.feedName = row[StarMessageTable.Column.feedName.title] + self.senderName = row[StarMessageTable.Column.senderName.title] + self.senderAvatar = row[StarMessageTable.Column.senderAvatar.title] super.init() } @@ -106,12 +109,56 @@ class DBStarMessage: Record, DBModelProtocol { container[StarMessageTable.Column.editMessage.title] = self.editMessage container[StarMessageTable.Column.repliedBy.title] = self.repliedBy container[StarMessageTable.Column.status.title] = self.status + container[StarMessageTable.Column.feedName.title] = self.feedName + container[StarMessageTable.Column.senderName.title] = self.senderName + container[StarMessageTable.Column.senderAvatar.title] = self.senderAvatar } override func didInsert(with rowID: Int64, for column: String?) { id = rowID } + // MARK: - Sender Info Setup + + func setup(contact: Contact) { + //self.feedName = contact.fullName + self.senderName = contact.nick ?? contact.fullName + self.senderAvatar = contact.avatar + } + + func setup(room: Room) { + self.feedName = room.name + if let sender = room.members?.first(where: { $0.phone_id == self.from }) { + setup(member: sender, room: room) + } + if let sender = room.admins?.first(where: { $0.phone_id == self.from }) { + setup(member: sender, room: room) + } + } + + private func setup(room: DBRoom) { + self.feedName = room.name + if let sender = room.members.first(where: { $0.phoneId == self.from }) { + let mem = Member(member: sender) + setup(member: mem, room: room) + } + if let sender = room.admins.first(where: { $0.phoneId == self.from }) { + let mem = Member(member: sender) + setup(member: mem, room: room) + } + } + + private func setup(member: Member, room: Room) { + self.senderName = member.alias ?? member.fullName + self.senderAvatar = room.data?.first?.payload + } + + private func setup(member: Member, room: DBRoom) { + self.senderName = member.alias ?? member.fullName + self.senderAvatar = room.files.first?.payload + } + + // MARK: - Query, Modification func saveAggregate(_ db: Database) throws { if let feed = self.feed { @@ -138,6 +185,7 @@ class DBStarMessage: Record, DBModelProtocol { } } + // MARK: - Fetching static func message(from db: Database, rowId: Int64) throws -> DBStarMessage? { @@ -226,9 +274,7 @@ class DBStarMessage: Record, DBModelProtocol { if let sender = try? DBContact.request(phoneId: from).fetchOne(db) { if let con = sender { let contact = Contact(contact: con) - //self.feedName = contact.fullName - self.senderName = contact.nick ?? contact.fullName - self.senderAvatar = contact.avatar + self.setup(contact: contact) } } } @@ -236,27 +282,11 @@ class DBStarMessage: Record, DBModelProtocol { self.feed = try DBMuc.fetchOne(db, key: feedId) if let f = feed as? DBMuc { if let room = try DBRoom.room(from: db, id: f.name) { - self.feedName = room.name - if let sender = room.members.filter({ (member) -> Bool in - member.phoneId == self.from - }).first { - let mem = Member(member: sender) - self.senderName = mem.alias ?? mem.fullName - self.senderAvatar = room.files.first?.payload - } - if let sender = room.admins.filter({ (member) -> Bool in - member.phoneId == self.from - }).first { - let mem = Member(member: sender) - self.senderName = mem.alias ?? mem.fullName - self.senderAvatar = room.files.first?.payload - } + setup(room: room) } } } } - - } func fetchId(_ db: Database) throws -> Int64? { diff --git a/Nynja/DB/Tables/DescTable.swift b/Nynja/DB/Tables/DescTable.swift index 2725ae2a8a4076eedcb825007e63ec2e23a42b23..061dbd24d4bc5ac79695660a0115fc70d9110d1c 100644 --- a/Nynja/DB/Tables/DescTable.swift +++ b/Nynja/DB/Tables/DescTable.swift @@ -20,9 +20,8 @@ class DescTable: Table { func create(in db: Database, name: String) throws { try db.create(table: name, body: { (t) in - t.column(Column.id, .integer).notNull().primaryKey(onConflict: nil, autoincrement: true) + t.primaryKey([Column.serverId.title, Column.targetType.title], onConflict: nil) t.column(Column.serverId, .text).notNull() - t.uniqueKey([Column.serverId.title, Column.targetType.title], onConflict: .replace) t.column(Column.mime, .text) t.column(Column.payload, .text) t.column(Column.size, .integer).notNull().defaults(to: 0) @@ -32,7 +31,6 @@ class DescTable: Table { t.column(Column.targetType, .integer) }) } - } extension DescTable { @@ -48,5 +46,4 @@ extension DescTable { case targetId case targetType } - } diff --git a/Nynja/DB/Tables/StarMessageTable.swift b/Nynja/DB/Tables/StarMessageTable.swift index c46f8703897571621495d90977d381e46e2b7424..bd157c427a763ea5705e459218354b7bad33cfa6 100644 --- a/Nynja/DB/Tables/StarMessageTable.swift +++ b/Nynja/DB/Tables/StarMessageTable.swift @@ -33,6 +33,9 @@ class StarMessageTable: Table { t.column(Column.editMessage, .integer) t.column(Column.repliedBy, .text) t.column(Column.status, .text) + t.column(Column.feedName, .text) + t.column(Column.senderName, .text) + t.column(Column.senderAvatar, .text) }) } @@ -57,6 +60,9 @@ extension StarMessageTable { case editMessage // link case repliedBy case status + case feedName + case senderName + case senderAvatar } } diff --git a/Nynja/DB/Tables/StarTable.swift b/Nynja/DB/Tables/StarTable.swift index 09bc755ac962d5bbcc3ec9c8cd8c3ea6583187ab..c3c91e92da13813b865fcfaf677ab56d1e12035a 100644 --- a/Nynja/DB/Tables/StarTable.swift +++ b/Nynja/DB/Tables/StarTable.swift @@ -16,7 +16,8 @@ class StarTable: Table { func create(in db: Database) throws { try db.create(table: StarTable.name, body: { (t) in - t.column(Column.id, .text).notNull().primaryKey() + t.column(Column.id, .integer) + t.column(Column.clientId, .text).notNull().primaryKey() t.column(Column.status, .text) t.column(Column.rosterId, .integer).references(RosterTable.name, onDelete: .cascade) t.column(Column.messageId, .integer).references(StarMessageTable.name, onDelete: .cascade) @@ -30,6 +31,7 @@ extension StarTable { enum Column: Int, Describable { case id + case clientId case status case rosterId case messageId diff --git a/Nynja/ExtendedStarHandler.swift b/Nynja/ExtendedStarHandler.swift new file mode 100644 index 0000000000000000000000000000000000000000..de8191b50b5369168417f77ca023695a6d1974a4 --- /dev/null +++ b/Nynja/ExtendedStarHandler.swift @@ -0,0 +1,45 @@ +// +// ExtendedStarHandler.swift +// Nynja +// +// Created by Anton Poltoratskyi on 08.02.2018. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import Foundation + +protocol ExtendedStarHandlerDelegate: class { + func didReceiveStars(_ stars: [Star]) +} + +final class ExtendedStarHandler: BaseHandler { + + static weak var delegate: ExtendedStarHandlerDelegate? + + static func executeHandle(data: BertList) { + let extendedStars = data.elements.flatMap { get_ExtendedStar().parse(bert: $0) as? ExtendedStar } + + let stars = extendedStars.flatMap { extendedStar -> Star? in + #if !SHARE_EXTENSION + guard let star = extendedStar.star, let dbStar = DBStar(star: star) else { return nil } + + if let feed = extendedStar.from { + switch feed { + case let feed as Contact: + dbStar.message?.setup(contact: feed) + case let feed as Room: + dbStar.message?.setup(room: feed) + default: + break + } + } + try? StorageService.sharedInstance.perform(action: .save, with: dbStar) + + return Star(star: dbStar) + #else + return extendedStar.star + #endif + } + delegate?.didReceiveStars(stars) + } +} diff --git a/Nynja/Extensions/Models/StarExtension.swift b/Nynja/Extensions/Models/StarExtension.swift index 7cd926185952643d81a1a70437f716070fa4bb2e..0547d131951ee8ab84bd141e89a3a9910b2293cd 100644 --- a/Nynja/Extensions/Models/StarExtension.swift +++ b/Nynja/Extensions/Models/StarExtension.swift @@ -83,6 +83,7 @@ extension Star: DialogCellModel { convenience init(star: DBStar) { self.init() self.id = star.id + self.client_id = star.clientId if let msg = star.message { self.message = Message(message: msg) } diff --git a/Nynja/GetExtendedStarsModel.swift b/Nynja/GetExtendedStarsModel.swift new file mode 100644 index 0000000000000000000000000000000000000000..eb84780049a61a212f1af48c951382a465e272a3 --- /dev/null +++ b/Nynja/GetExtendedStarsModel.swift @@ -0,0 +1,28 @@ +// +// GetExtendedStarsModel.swift +// Nynja +// +// Created by Anton Poltoratskyi on 08.02.2018. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import Foundation +import CocoaMQTT + +class GetExtendedStarsModel: BaseMQTTModel { + + override func getBert() -> [UInt8] { + let topic = BertAtom(fromString: "ExtendedStar") + + let model = BertTuple(fromElements: [topic, BertNil(), BertNil()]) + var result = [UInt8]() + do { + let bytes = try Bert.encode(object: model) + result = [UInt8](repeating: 0, count: bytes.length) + bytes.getBytes(&result, length: bytes.length) + return result + } catch { + return result + } + } +} diff --git a/Nynja/Library/Model/ExtendedStar.swift b/Nynja/Library/Model/ExtendedStar.swift new file mode 100644 index 0000000000000000000000000000000000000000..688970e64cba13612bf0239dcb9ca15fb7863f7d --- /dev/null +++ b/Nynja/Library/Model/ExtendedStar.swift @@ -0,0 +1,5 @@ + +class ExtendedStar { + var star: Star? + var from: AnyObject? +} diff --git a/Nynja/Library/Model/Star.swift b/Nynja/Library/Model/Star.swift index c89f12ecd7831feb8f0905521f5ef99be3ef5fe7..dcfc6f9dc6b6140b1850a39770fd0b19a0684dcf 100644 --- a/Nynja/Library/Model/Star.swift +++ b/Nynja/Library/Model/Star.swift @@ -1,8 +1,10 @@ class Star { - var id: String? + var id: Int64? + var client_id: String? var roster_id: Int64? var message: Message? var tags: [Tag]? var status: AnyObject? } + diff --git a/Nynja/Library/Source/Decoder.swift b/Nynja/Library/Source/Decoder.swift index d202c77d0e0de89794fea668885a7ee9ae0695a5..6347b38634a7ed5b9c156f26c83035ef23a90d11 100644 --- a/Nynja/Library/Source/Decoder.swift +++ b/Nynja/Library/Source/Decoder.swift @@ -253,13 +253,14 @@ func parseObject(name: String, body:[Model], tuple: BertTuple) -> AnyObject? a_Tag.status = body[3].parse(bert: tuple.elements[4]) as? AnyObject return a_Tag case "Star": - if body.count != 5 { return nil } + if body.count != 6 { return nil } let a_Star = Star() - a_Star.id = body[0].parse(bert: tuple.elements[1]) as? String - a_Star.roster_id = body[1].parse(bert: tuple.elements[2]) as? Int64 - a_Star.message = body[2].parse(bert: tuple.elements[3]) as? Message - a_Star.tags = body[3].parse(bert: tuple.elements[4]) as? [Tag] - a_Star.status = body[4].parse(bert: tuple.elements[5]) as? AnyObject + a_Star.id = body[0].parse(bert: tuple.elements[1]) as? Int64 + a_Star.client_id = body[1].parse(bert: tuple.elements[2]) as? String + a_Star.roster_id = body[2].parse(bert: tuple.elements[3]) as? Int64 + a_Star.message = body[3].parse(bert: tuple.elements[4]) as? Message + a_Star.tags = body[4].parse(bert: tuple.elements[5]) as? [Tag] + a_Star.status = body[5].parse(bert: tuple.elements[6]) as? AnyObject return a_Star case "History": if body.count != 6 { return nil } @@ -296,6 +297,12 @@ func parseObject(name: String, body:[Model], tuple: BertTuple) -> AnyObject? a_Contact.presence = body[13].parse(bert: tuple.elements[14]) as? StringAtom a_Contact.status = body[14].parse(bert: tuple.elements[15]) as? AnyObject return a_Contact + case "ExtendedStar": + if body.count != 2 { return nil } + let a_ExtendedStar = ExtendedStar() + a_ExtendedStar.star = body[0].parse(bert: tuple.elements[1]) as? Star + a_ExtendedStar.from = body[1].parse(bert: tuple.elements[2]) as? AnyObject + return a_ExtendedStar case "Auth": if body.count != 13 { return nil } let a_Auth = Auth() diff --git a/Nynja/Library/Spec/ExtendedStar_Spec.swift b/Nynja/Library/Spec/ExtendedStar_Spec.swift new file mode 100644 index 0000000000000000000000000000000000000000..6323c8cada0d260918821f4540900b3dd3b9fa88 --- /dev/null +++ b/Nynja/Library/Spec/ExtendedStar_Spec.swift @@ -0,0 +1,7 @@ + +func get_ExtendedStar() -> Model { + return Model(value:Tuple(name:"ExtendedStar",body:[ + get_Star(), + Model(value:Chain(types:[ + get_Contact(), + get_Room()]))]))} diff --git a/Nynja/Library/Spec/Star_Spec.swift b/Nynja/Library/Spec/Star_Spec.swift index 69b76ef26918ff3c2c931c83e763df439dfc5a6d..99b0ad9722b46ec69060c1e94958a5fdadf8fbd4 100644 --- a/Nynja/Library/Spec/Star_Spec.swift +++ b/Nynja/Library/Spec/Star_Spec.swift @@ -1,14 +1,17 @@ func get_Star() -> Model { - return Model(value:Tuple(name:"Star",body:[ - Model(value:Chain(types:[ - Model(value:List(constant:"")), - Model(value:Binary())])), - Model(value:Chain(types:[ - Model(value:List(constant:"")), - Model(value:Number())])), - get_Message(), - Model(value:List(constant:nil,model:get_Tag())), - Model(value:Chain(types:[ - Model(value:List(constant:"")), - Model(value:Atom(constant:"add")), - Model(value:Atom(constant:"remove"))]))]))} + return Model(value:Tuple(name:"Star",body:[ + 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:Number())])), + get_Message(), + Model(value:List(constant:nil,model:get_Tag())), + Model(value:Chain(types:[ + Model(value:List(constant:"")), + Model(value:Atom(constant:"add")), + Model(value:Atom(constant:"remove"))]))]))} diff --git a/Nynja/MigrationManager.swift b/Nynja/MigrationManager.swift index 9911ea4e7ccd8aa1cb98a4797a4ada047b4c48e1..85ac2e97c1fdf94aff298d5dfddc3dc2635b17d4 100644 --- a/Nynja/MigrationManager.swift +++ b/Nynja/MigrationManager.swift @@ -16,6 +16,8 @@ enum Migration: Describable { case createStarMessage case updateChatCheckpoint case addCreatedToContact + case addStarMessageId + case dropDescAutoincrementPrimaryKeyAndSetCompountKey } class MigrationManager { @@ -111,6 +113,31 @@ class MigrationManager { } } + migrator.registerMigration(Migration.addStarMessageId.title) { db in + let tableName = StarTable.name + let clientIdColumn = StarTable.Column.clientId.title + + guard try !db.hasColumns([clientIdColumn], tableName: tableName) else { return } + + let columnMapping = ColumnMapping([ + clientIdColumn: StarTable.Column.id.title + ]) + let stars = try DBStar.fetchAll(db, "SELECT * FROM \(tableName)", adapter: columnMapping) + try db.drop(table: tableName) + try StarTable().create(in: db) + try stars.forEach { try $0.saveAggregate(db) } + } + + migrator.registerMigration(Migration.dropDescAutoincrementPrimaryKeyAndSetCompountKey.title) { db in + let tableName = DescTable.name + let oldPrimaryKey = StarTable.Column.id.title + + guard try db.hasColumns([oldPrimaryKey], tableName: tableName) else { return } + + let descs = try DBDesc.fetchAll(db) + try db.drop(table: tableName) + try DescTable().create(in: db) + try descs.forEach { try $0.saveAggregate(db) } + } } - } diff --git a/Nynja/Modules/Favorites/Interactor/FavoritesInteractor.swift b/Nynja/Modules/Favorites/Interactor/FavoritesInteractor.swift index 1a63dddc68426ee5c3e7c55ff82c03d5440707ac..4f3ad977e19df56401091a576df363dea99518f1 100644 --- a/Nynja/Modules/Favorites/Interactor/FavoritesInteractor.swift +++ b/Nynja/Modules/Favorites/Interactor/FavoritesInteractor.swift @@ -6,23 +6,15 @@ // Copyright © 2017 TecSynt Solutions. All rights reserved. // -class FavoritesInteractor: FavoritesInteractorInputProtocol, StarHandlerDelegate { +class FavoritesInteractor: FavoritesInteractorInputProtocol, StarHandlerDelegate, ExtendedStarHandlerDelegate { weak var presenter: FavoritesInteractorOutputProtocol! func getStars() { StarHandler.delegate = self - if let id = (StorageService.sharedInstance.profile.rosters?.first as? Roster)?.id { - - let stars = try? StorageService.sharedInstance.fetchStars(rosterID: id).values.sorted(by: { (left, right) -> Bool in - let id1 = left.id?.split(separator: "_").last ?? "" - let id2 = right.id?.split(separator: "_").last ?? "" - return id1 > id2 - }) - if stars != nil { - self.presenter.getStarsSuccess(stars: stars!) - } - } + ExtendedStarHandler.delegate = self + + MQTTService.sharedInstance.getFavorites() } func getRoomOrContact(message: Message) -> AnyObject? { @@ -32,10 +24,34 @@ class FavoritesInteractor: FavoritesInteractorInputProtocol, StarHandlerDelegate return nil } + // MARK: - Local Storage + + private func fetchStars() { + guard let rosterId = StorageService.sharedInstance.rosterId else { return } + + let stars = try? StorageService.sharedInstance.fetchStars(rosterID: rosterId).values.sorted(by: { (left, right) -> Bool in + let id1 = left.client_id?.split(separator: "_").last ?? "" + let id2 = right.client_id?.split(separator: "_").last ?? "" + return id1 > id2 + }) + if stars != nil { + self.presenter.getStarsSuccess(stars: stars!) + } + } + + // MARK: - StarHandlerDelegate + func newStar(star: Star) { - self.getStars() + self.fetchStars() } + func removeStar(star: Star) { - self.getStars() + self.fetchStars() + } + + // MARK: - ExtendedStarHandlerDelegate + + func didReceiveStars(_ stars: [Star]) { + self.fetchStars() } } diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor.swift b/Nynja/Modules/Message/Interactor/MessageInteractor.swift index 10de5664f0cc0511b71df61f06ac073a43360a6f..1520e033dcd6407c3e1daaebbaefbf8ac3e8eb98 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor.swift @@ -717,7 +717,7 @@ class MessageInteractor: MessageInteractorInputProtocol, ContactHandlerDelegate, star.message = message star.status = StringAtom(string: "add") star.roster_id = roster.id - star.id = IdGenerator.generateUniqueId() + star.client_id = IdGenerator.generateUniqueId() if let dbStar = DBStar(star: star) { try? StorageService.sharedInstance.perform(action: .save, with: dbStar) } @@ -735,7 +735,7 @@ class MessageInteractor: MessageInteractorInputProtocol, ContactHandlerDelegate, } configuration.stars[localId] = nil MQTTService.sharedInstance.sendStar(star: star) - star.id = nil + star.client_id = nil self.presenter?.changeStarStatus(star: star, localId: localId) } } diff --git a/Nynja/Modules/Message/Presenter/MessagePresenter.swift b/Nynja/Modules/Message/Presenter/MessagePresenter.swift index d429b23cf12fc2179295a9e069d7942e6aa0c0c0..2c8cd992ead5e3ba5cce104caf0ee70eae19ba13 100644 --- a/Nynja/Modules/Message/Presenter/MessagePresenter.swift +++ b/Nynja/Modules/Message/Presenter/MessagePresenter.swift @@ -259,7 +259,7 @@ class MessagePresenter: MessagePresenterProtocol, MessageInteractorOutputProtoco model = self.attachProgress(model: model, progressModel: progres) } if let localId = message.msg_id { - model.starID = configuration.stars[localId]?.id + model.starID = configuration.stars[localId]?.client_id } cells.append(model) } @@ -325,7 +325,7 @@ class MessagePresenter: MessagePresenterProtocol, MessageInteractorOutputProtoco model = self.attachProgress(model: model, progressModel: progres) } if let localId = message.msg_id { - model.starID = configuration.stars[localId]?.id + model.starID = configuration.stars[localId]?.client_id } cells.append(model) } @@ -537,7 +537,7 @@ class MessagePresenter: MessagePresenterProtocol, MessageInteractorOutputProtoco } func changeStarStatus(star: Star, localId: String) { - view.updateStar(starID: star.id, messageId: localId) + view.updateStar(starID: star.client_id, messageId: localId) } func isSelfChat() -> Bool { diff --git a/Nynja/Modules/Profile/Interactor/ProfileInteractor.swift b/Nynja/Modules/Profile/Interactor/ProfileInteractor.swift index cd7cbfb16dcbd555568a822e6e321ce4c8a95c4a..438d36242fb46aca803a1f20a7a40e5d909df174 100644 --- a/Nynja/Modules/Profile/Interactor/ProfileInteractor.swift +++ b/Nynja/Modules/Profile/Interactor/ProfileInteractor.swift @@ -210,8 +210,8 @@ fileprivate extension ProfileInteractor { if let id = (StorageService.sharedInstance.profile.rosters?.first as? Roster)?.id { let stars = try? StorageService.sharedInstance.fetchStars(rosterID: id).values.sorted(by: { (left, right) -> Bool in - let id1 = left.id?.split(separator: "_").last ?? "" - let id2 = right.id?.split(separator: "_").last ?? "" + let id1 = left.client_id?.split(separator: "_").last ?? "" + let id2 = right.client_id?.split(separator: "_").last ?? "" return id1 > id2 }) if stars != nil { diff --git a/Nynja/Modules/Profile/View/TableView/Cells/StarCell/StarMessageCell.swift b/Nynja/Modules/Profile/View/TableView/Cells/StarCell/StarMessageCell.swift index 97055aaf0f0e7a5a3b60ddce7861ecbe7d24785e..6ccc16493eb89a3ad6dec86c7124d5c3fdc15c48 100644 --- a/Nynja/Modules/Profile/View/TableView/Cells/StarCell/StarMessageCell.swift +++ b/Nynja/Modules/Profile/View/TableView/Cells/StarCell/StarMessageCell.swift @@ -173,7 +173,7 @@ class StarMessageCell: UITableViewCell, ConfigurableCell { // timeLabel.text = DialogDateConverter().toString(createdDate) // } nameLabel.text = model.title - if let timestamp = (model as? Star)?.id?.split(separator: "_").last { + if let timestamp = (model as? Star)?.client_id?.split(separator: "_").last { if let timeS = Double(timestamp) { let date = Date(timeIntervalSince1970: timeS / 1000) let when = DialogDateConverter().toString(date) diff --git a/Nynja/Services/HandleServices/HandleService.swift b/Nynja/Services/HandleServices/HandleService.swift index 9251773eb7844263e1af7032c0e0b372f1f3e081..4712371a5c072b7aa60b1b5b02cd7b831cfbf8d2 100644 --- a/Nynja/Services/HandleServices/HandleService.swift +++ b/Nynja/Services/HandleServices/HandleService.swift @@ -11,6 +11,11 @@ import CocoaMQTT protocol BaseHandler { static func executeHandle(data: BertTuple) + static func executeHandle(data: BertList) +} +extension BaseHandler { + static func executeHandle(data: BertTuple) { } + static func executeHandle(data: BertList) { } } enum Handlers : String { @@ -25,6 +30,7 @@ enum Handlers : String { case member case typing case star + case extendedStar = "extendedstar" } class HandlerService { @@ -33,31 +39,26 @@ class HandlerService { let data = NSData(bytes: response.payload, length: response.payload.count) do { let result = try Bert.decode(data:data) - if let tuple = result as? BertTuple { - parseClass(tuple: tuple) - } - if let resultArray = result as? BertList { - if resultArray.elements.count > 0 { - if let tuple = resultArray.elements[0] as? BertTuple { - parseClass(tuple: tuple) - } - } + switch result { + case let result as BertTuple: + guard let handler = handler(of: result) else { return } + executeHandle(handler: handler, params: result) + + case let result as BertList where !result.elements.isEmpty: + guard let tuple = result.elements[0] as? BertTuple, let handler = handler(of: tuple) else { return } + executeHandle(handler: handler, params: result) + + default: + break } - } catch { - - } + } catch { } } - static func parseClass(tuple: BertTuple) { - if tuple.elements.count > 0 { - if let header = tuple.elements[0] as? BertAtom { - if let handle = Handlers(rawValue: header.value.lowercased()) { - executeHandle(handler: handle, params: tuple) - } else { - // assertionFailure("Handle Not Found") - } - } + static func handler(of tuple: BertTuple) -> Handlers? { + guard !tuple.elements.isEmpty, let header = tuple.elements[0] as? BertAtom else { + return nil } + return Handlers(rawValue: header.value.lowercased()) } static func executeHandle(handler: Handlers, params: BertTuple) { @@ -84,6 +85,37 @@ class HandlerService { TypingHandler.executeHandle(data: params) case .star: StarHandler.executeHandle(data: params) + case .extendedStar: + ExtendedStarHandler.executeHandle(data: params) + } + } + + static func executeHandle(handler: Handlers, params: BertList) { + switch handler { + case .io: + IoHandler.executeHandle(data:params) + case .profile: + ProfileHandler.executeHandle(data: params) + case .roster: + RosterHandler.executeHandle(data: params) + case .contact: + ContactHandler.executeHandle(data: params) + case .history: + HistoryHandler.executeHandle(data: params) + case .message: + MessageHandler.executeHandle(data: params) + case .search: + SearchHandler.executeHandle(data: params) + case .room: + RoomHandler.executeHandle(data: params) + case .member: + MemberHandler.executeHandle(data: params) + case .typing: + TypingHandler.executeHandle(data: params) + case .star: + StarHandler.executeHandle(data: params) + case .extendedStar: + ExtendedStarHandler.executeHandle(data: params) } } } diff --git a/Nynja/Services/MQTT/MQTTService.swift b/Nynja/Services/MQTT/MQTTService.swift index 4859e1a649b5214979aa3453dd7aa365ddb7a1ff..b53eefcc9a6759970271e91d8726104980a3618b 100644 --- a/Nynja/Services/MQTT/MQTTService.swift +++ b/Nynja/Services/MQTT/MQTTService.swift @@ -22,7 +22,7 @@ class MQTTService: NSObject, CocoaMQTTDelegate, ReachabilityServiceObserver { static let version = 2 - var currentHost = host.DemoTemp + var currentHost = host.Test let port: UInt16 = 1883 var push: String? diff --git a/Nynja/Services/MQTT/MQTTServiceStars.swift b/Nynja/Services/MQTT/MQTTServiceStars.swift new file mode 100644 index 0000000000000000000000000000000000000000..25671f4f584cb1a95600f97dccb471777b1288b1 --- /dev/null +++ b/Nynja/Services/MQTT/MQTTServiceStars.swift @@ -0,0 +1,19 @@ +// +// MQTTServiceStars.swift +// Nynja +// +// Created by Anton Poltoratskyi on 08.02.2018. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import Foundation + +extension MQTTService { + func getFavorites() { + guard StorageService.sharedInstance.getToken() != nil else { + return + } + let model = GetExtendedStarsModel() + publish(model: model) + } +} diff --git a/Nynja/Services/MQTT/StarExtension+BERT.swift b/Nynja/Services/MQTT/StarExtension+BERT.swift index 8a5fed1ad6a75a51ae96972cf868b46c9895cbb6..4be3b39961bc01a89507a1e04f81e8069d1fc400 100644 --- a/Nynja/Services/MQTT/StarExtension+BERT.swift +++ b/Nynja/Services/MQTT/StarExtension+BERT.swift @@ -12,14 +12,18 @@ extension Star { func getBert() -> BertObject { var result: BertObject = BertNil() let type = BertAtom(fromString: "Star") - let id = Bert.getBin(self.id) + var id: BertObject = BertNil() + if let idd = self.id { + id = BertNumber(fromInt64: idd) + } + let client_id = Bert.getBin(self.client_id) var rosterID: BertObject = BertNil() if let idd = roster_id { rosterID = BertNumber(fromInt64: idd) } let message = self.message?.getBert() ?? BertNil() let status = BertAtom(fromString:(self.status as? StringAtom)?.string ?? "") - result = BertTuple(fromElements: [type,id, rosterID, message, BertNil(),status]) + result = BertTuple(fromElements: [type, id, client_id,rosterID, message, BertNil(),status]) return result } } diff --git a/Nynja/StorageService+Star.swift b/Nynja/StorageService+Star.swift index 84f93b6b10cb12f4ef3a9de22ea5c25bc5729e1b..1ecab73912ec88e35581098b031cd4731e1917b6 100644 --- a/Nynja/StorageService+Star.swift +++ b/Nynja/StorageService+Star.swift @@ -23,4 +23,11 @@ extension StorageService { return result } + func fetchStarMessageId(of message: DBStarMessage) throws -> Int64? { + var starMessageId: Int64? + try read { (db) in + starMessageId = try message.fetchId(db) + } + return starMessageId + } }