From 76d7de31a31997c33c3f83ff1525d62a3529a7ef Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Thu, 18 Oct 2018 13:10:54 +0300 Subject: [PATCH 01/59] Added skeleton for call history controller --- Nynja.xcodeproj/project.pbxproj | 60 +++++++++++++++++++ .../CallHistory/CallHistoryProtocols.swift | 55 +++++++++++++++++ .../Interactor/CallHistoryInteractor.swift | 14 +++++ .../Presenter/CallHistoryPresenter.swift | 21 +++++++ .../View/CallHistoryViewController.swift | 40 +++++++++++++ .../WireFrame/CallHistoryWireFrame.swift | 43 +++++++++++++ 6 files changed, 233 insertions(+) create mode 100644 Nynja/Modules/CallHistory/CallHistoryProtocols.swift create mode 100644 Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift create mode 100644 Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift create mode 100644 Nynja/Modules/CallHistory/View/CallHistoryViewController.swift create mode 100644 Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index c86e8d39c..46601e977 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -1194,6 +1194,11 @@ 9BD8E41120F39AE3001384EC /* CallInProgressPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BD8E41020F39AE3001384EC /* CallInProgressPresenter.swift */; }; 9BD8E41320F3A2E2001384EC /* CallInProgressInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BD8E41220F3A2E2001384EC /* CallInProgressInteractor.swift */; }; 9BFFE61B2178DD00004FE2CA /* BannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE61A2178DCFF004FE2CA /* BannerView.swift */; }; + 9BFFE60D21778ABF004FE2CA /* CallHistoryInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE60C21778ABF004FE2CA /* CallHistoryInteractor.swift */; }; + 9BFFE60F21778ACD004FE2CA /* CallHistoryPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE60E21778ACD004FE2CA /* CallHistoryPresenter.swift */; }; + 9BFFE61121778AD7004FE2CA /* CallHistoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE61021778AD6004FE2CA /* CallHistoryViewController.swift */; }; + 9BFFE61321778AE2004FE2CA /* CallHistoryWireFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE61221778AE2004FE2CA /* CallHistoryWireFrame.swift */; }; + 9BFFE6152177935C004FE2CA /* CallHistoryProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE6142177935C004FE2CA /* CallHistoryProtocols.swift */; }; 9E9DD4C7F700872D7CCEE227 /* ProfileInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFF6A30BDE89BF7887B67DA0 /* ProfileInteractor.swift */; }; A1AD6864F4F49D9FC8997D59 /* SelectCountryPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5522F1F73FC8C564BF0254BF /* SelectCountryPresenter.swift */; }; A402A1CC20DE694A005BFA20 /* PartialCheckableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A402A1CB20DE694A005BFA20 /* PartialCheckableButton.swift */; }; @@ -3404,6 +3409,11 @@ 9BD8E41020F39AE3001384EC /* CallInProgressPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallInProgressPresenter.swift; sourceTree = ""; }; 9BD8E41220F3A2E2001384EC /* CallInProgressInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallInProgressInteractor.swift; sourceTree = ""; }; 9BFFE61A2178DCFF004FE2CA /* BannerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BannerView.swift; sourceTree = ""; }; + 9BFFE60C21778ABF004FE2CA /* CallHistoryInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryInteractor.swift; sourceTree = ""; }; + 9BFFE60E21778ACD004FE2CA /* CallHistoryPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryPresenter.swift; sourceTree = ""; }; + 9BFFE61021778AD6004FE2CA /* CallHistoryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryViewController.swift; sourceTree = ""; }; + 9BFFE61221778AE2004FE2CA /* CallHistoryWireFrame.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryWireFrame.swift; sourceTree = ""; }; + 9BFFE6142177935C004FE2CA /* CallHistoryProtocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryProtocols.swift; sourceTree = ""; }; 9C4192D925259B75441492A9 /* FavoritesPresenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = FavoritesPresenter.swift; sourceTree = ""; }; 9DE44A136617140435B23343 /* GroupStorageWireframe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = GroupStorageWireframe.swift; sourceTree = ""; }; 9E82188EE0AC1D1C05470692 /* Pods-NynjaUnitTests.channels.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NynjaUnitTests.channels.xcconfig"; path = "Pods/Target Support Files/Pods-NynjaUnitTests/Pods-NynjaUnitTests.channels.xcconfig"; sourceTree = ""; }; @@ -6367,6 +6377,7 @@ 2E2DD2D281B2F74B4B39DF24 /* EditProfile */, C4AE70AB74CA331DD03D830B /* AddContactViaPhone */, F370781E99F6E0BC86F82844 /* History */, + 9BFFE5FE21777453004FE2CA /* CallHistory */, 9B96709221514CA30058E98F /* LeaveVoiceMessage */, C0F3DD8B2859372188498348 /* Call */, 32868DD31F31CAC10028B260 /* ChatsList */, @@ -9510,6 +9521,50 @@ path = WireFrame; sourceTree = ""; }; + 9BFFE5FE21777453004FE2CA /* CallHistory */ = { + isa = PBXGroup; + children = ( + 9BFFE6142177935C004FE2CA /* CallHistoryProtocols.swift */, + 9BFFE60221778281004FE2CA /* View */, + 9BFFE60121778277004FE2CA /* Presenter */, + 9BFFE6002177826B004FE2CA /* Interactor */, + 9BFFE5FF21778261004FE2CA /* WireFrame */, + ); + path = CallHistory; + sourceTree = ""; + }; + 9BFFE5FF21778261004FE2CA /* WireFrame */ = { + isa = PBXGroup; + children = ( + 9BFFE61221778AE2004FE2CA /* CallHistoryWireFrame.swift */, + ); + path = WireFrame; + sourceTree = ""; + }; + 9BFFE6002177826B004FE2CA /* Interactor */ = { + isa = PBXGroup; + children = ( + 9BFFE60C21778ABF004FE2CA /* CallHistoryInteractor.swift */, + ); + path = Interactor; + sourceTree = ""; + }; + 9BFFE60121778277004FE2CA /* Presenter */ = { + isa = PBXGroup; + children = ( + 9BFFE60E21778ACD004FE2CA /* CallHistoryPresenter.swift */, + ); + path = Presenter; + sourceTree = ""; + }; + 9BFFE60221778281004FE2CA /* View */ = { + isa = PBXGroup; + children = ( + 9BFFE61021778AD6004FE2CA /* CallHistoryViewController.swift */, + ); + path = View; + sourceTree = ""; + }; 9CB68C9C1271BC0D3657FDC0 /* Presenter */ = { isa = PBXGroup; children = ( @@ -14904,6 +14959,7 @@ 00102F3C202C8B6600A877A9 /* NynjaSegmentedControl.swift in Sources */, E76D132F1FA35D2900B07F0E /* ProfilePlaceholderCellLayout.swift in Sources */, 8E47DBEB200EB05900E612B0 /* MapViewControllerLayout.swift in Sources */, + 9BFFE61121778AD7004FE2CA /* CallHistoryViewController.swift in Sources */, 260225DF20F390C6004FC238 /* ConvertionInfoView.swift in Sources */, FEA655CF2167777E00B44029 /* SeedVerificationWalletViewController.swift in Sources */, A42CE5AF20692EDB000889CC /* TypeSpec.swift in Sources */, @@ -15112,6 +15168,7 @@ FEA655F02167777E00B44029 /* TransferHistoryTableModel.swift in Sources */, A42D51BA206A361400EEB952 /* io.swift in Sources */, 4B6D20E82164D4AB003ADB29 /* ProgressDisplayable.swift in Sources */, + 9BFFE60D21778ABF004FE2CA /* CallHistoryInteractor.swift in Sources */, 3A1EB9A51F3A848A00658E93 /* HistoryHandler.swift in Sources */, 850FC5F42032F4CE00832D87 /* ForwardTargets.swift in Sources */, 85788C422044237B003600C9 /* BuildNumberViewController.swift in Sources */, @@ -15551,6 +15608,7 @@ A42D52D8206A53AB00EEB952 /* task_Spec.swift in Sources */, 859B863920486068003272B2 /* CarouselPickerViewControllerLayout.swift in Sources */, A43B25BF20AB1E9600FF8107 /* LengthInputValidator.swift in Sources */, + 9BFFE61321778AE2004FE2CA /* CallHistoryWireFrame.swift in Sources */, 85D669E520BD956000FBD803 /* UIButtonExtensions.swift in Sources */, E74EC9ED1FC2DA6E007268E6 /* RoomTable.swift in Sources */, A42D52C8206A53AB00EEB952 /* Auth_Spec.swift in Sources */, @@ -15847,6 +15905,7 @@ 853E594F20D6AED2007799B9 /* Desc+Messages.swift in Sources */, A460324F2105C9A1009783DA /* InputsCachePolicy.swift in Sources */, 855AC534208E441500DC2335 /* StickersInputProtocols.swift in Sources */, + 9BFFE60F21778ACD004FE2CA /* CallHistoryPresenter.swift in Sources */, 266F04CB2015050400B97A83 /* DBStarMessage.swift in Sources */, 1D31D13E6E53E71F8279C55C /* HistoryProtocols.swift in Sources */, A4CE80C020C9318700400713 /* EmptyStateTableViewDS.swift in Sources */, @@ -16050,6 +16109,7 @@ 26D621F42069778400595E13 /* ChatWheelItemView.swift in Sources */, E7E06C661F792AEF00BFC8FA /* LoginWheelContainerDelegate.swift in Sources */, FB16E79D20EFCF15009FA203 /* CryptoMoney.swift in Sources */, + 9BFFE6152177935C004FE2CA /* CallHistoryProtocols.swift in Sources */, 9B96709E215151D20058E98F /* LeaveVoiceMessageWireFrame.swift in Sources */, 4B8996F2204EF5E900DCB183 /* ChatCheckpointDAO.swift in Sources */, 265F5D2E209B8C1C008ACCC8 /* MessageEditActionDAO.swift in Sources */, diff --git a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift new file mode 100644 index 000000000..96c30bf0c --- /dev/null +++ b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift @@ -0,0 +1,55 @@ +// +// CallHistoryProtocols.swift +// Nynja +// +// Created by Bozhko Terziev on 19.09.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +protocol CallHistoryWireFrameProtocol: class { + + /** + * Add here your methods for communication PRESENTER -> WIREFRAME + */ + + func closeController() +} + +protocol CallHistoryViewProtocol: class { + + /** + * Add here your methods for communication PRESENTER -> VIEW + */ + + var presenter: CallHistoryPresenterProtocol! { get set } +} + +protocol CallHistoryPresenterProtocol: class { + + /** + * Add here your methods for communication VIEW -> PRESENTER + */ + + var view: CallHistoryViewProtocol! { get set } + var interactor: CallHistoryInteractorInputProtocol! { get set } + var wireFrame: CallHistoryWireFrameProtocol! { get set } + func closeController() +} + +protocol CallHistoryInteractorOutputProtocol: class { + + /** + * Add here your methods for communication INTERACTOR -> PRESENTER + */ +} + +protocol CallHistoryInteractorInputProtocol: class { + + /** + * Add here your methods for communication PRESENTER -> INTERACTOR + */ + + var presenter: CallHistoryInteractorOutputProtocol! { get set } +} diff --git a/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift new file mode 100644 index 000000000..42f9abcdf --- /dev/null +++ b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift @@ -0,0 +1,14 @@ +// +// CallHistoryInteractor.swift +// Nynja +// +// Created by Bozhko Terziev on 18.09.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +class CallHistoryInteractor: CallHistoryInteractorInputProtocol { + + weak var presenter: CallHistoryInteractorOutputProtocol! +} diff --git a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift new file mode 100644 index 000000000..68ea36523 --- /dev/null +++ b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift @@ -0,0 +1,21 @@ +// +// CallHistoryPresenter.swift +// Nynja +// +// Created by Bozhko Terziev on 18.09.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +class CallHistoryPresenter: CallHistoryPresenterProtocol, CallHistoryInteractorOutputProtocol { + + weak var view: CallHistoryViewProtocol! + var interactor: CallHistoryInteractorInputProtocol! + var wireFrame: CallHistoryWireFrameProtocol! + var contact: Contact? + + func closeController() { + wireFrame.closeController() + } +} diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift new file mode 100644 index 000000000..8fc30d4a6 --- /dev/null +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -0,0 +1,40 @@ +// +// CallHistoryViewController.swift +// Nynja +// +// Created by Bozhko Terziev on 18.09.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +private let askLeaveMessageKey = "AskLeaveMessage" + +class CallHistoryViewController: BaseVC, CallHistoryViewProtocol { + + var presenter: CallHistoryPresenterProtocol! + + private let offset: Float = 10.0 + + public init() { + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private enum ConstraintConstants { + + } + + override func initialize() { + super.initialize() + + setupInitialVisibility() + } + + private func setupInitialVisibility() { + + } +} diff --git a/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift b/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift new file mode 100644 index 000000000..5b627a049 --- /dev/null +++ b/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift @@ -0,0 +1,43 @@ +// +// CallHistoryWireFrame.swift +// Nynja +// +// Created by Bozhko Terziev on 18.09.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +class CallHistoryWireFrame: CallHistoryWireFrameProtocol { + + weak var navigation : UINavigationController? + weak var mainWF: MainWireFrame? + weak var view: CallHistoryViewProtocol! + + func presentCallHistory(navigation: UINavigationController, main: MainWireFrame?) { + + let view = CallHistoryViewController() + let presenter = CallHistoryPresenter() + let interactor = CallHistoryInteractor() + + self.navigation = navigation + self.view = view + self.mainWF = main + + // Connecting + view.presenter = presenter + presenter.view = view + presenter.wireFrame = self + presenter.interactor = interactor + interactor.presenter = presenter + + // pop to root of the navigation stack in case we have call in progress + LogService.log(topic: .callSystem) { return "present leave voice screen" } + navigation.popToRootViewController(animated: false) + navigation.pushViewController(view as UIViewController, animated: false) + } + + func closeController() { + self.navigation?.popViewController(animated: false) + } +} -- GitLab From 12fb1e480fc7a8cb1f8cb5380126726d8cf80640 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Tue, 23 Oct 2018 16:06:09 +0300 Subject: [PATCH 02/59] partial work on call history is done (layout navigation and table view) --- Nynja.xcodeproj/project.pbxproj | 8 +++ Nynja/Generated/LocalizableConstants.swift | 2 + .../CallHistory/CallHistoryProtocols.swift | 2 +- .../Presenter/CallHistoryPresenter.swift | 5 ++ .../View/CallHistoryViewController.swift | 56 ++++++++++++++++--- .../WireFrame/CallHistoryWireFrame.swift | 8 +-- .../Main/WireFrame/MainWireframe.swift | 4 +- Nynja/Resources/en.lproj/Localizable.strings | 3 + 8 files changed, 74 insertions(+), 14 deletions(-) diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 46601e977..86e1232ed 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -9426,6 +9426,13 @@ path = View; sourceTree = ""; }; + 9B2399F9217F0D4F00769770 /* TableView */ = { + isa = PBXGroup; + children = ( + ); + path = TableView; + sourceTree = ""; + }; 9B96709221514CA30058E98F /* LeaveVoiceMessage */ = { isa = PBXGroup; children = ( @@ -9560,6 +9567,7 @@ 9BFFE60221778281004FE2CA /* View */ = { isa = PBXGroup; children = ( + 9B2399F9217F0D4F00769770 /* TableView */, 9BFFE61021778AD6004FE2CA /* CallHistoryViewController.swift */, ); path = View; diff --git a/Nynja/Generated/LocalizableConstants.swift b/Nynja/Generated/LocalizableConstants.swift index 361ff5bfb..1e5f2a9e1 100644 --- a/Nynja/Generated/LocalizableConstants.swift +++ b/Nynja/Generated/LocalizableConstants.swift @@ -130,6 +130,8 @@ internal extension String { static var callDisconnected: String { return localizable.tr("Localizable", "call_disconnected") } /// Connection dropped static var callFailed: String { return localizable.tr("Localizable", "call_failed") } + /// call history + static var callHistoryTitle: String { return localizable.tr("Localizable", "call_history_title") } /// Incoming Voice Call... static var callIncoming: String { return localizable.tr("Localizable", "call_incoming") } /// Audio Conference diff --git a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift index 96c30bf0c..985d4556c 100644 --- a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift +++ b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift @@ -26,7 +26,7 @@ protocol CallHistoryViewProtocol: class { var presenter: CallHistoryPresenterProtocol! { get set } } -protocol CallHistoryPresenterProtocol: class { +protocol CallHistoryPresenterProtocol: NavigationProtocol { /** * Add here your methods for communication VIEW -> PRESENTER diff --git a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift index 68ea36523..aa712c9ed 100644 --- a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift +++ b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift @@ -18,4 +18,9 @@ class CallHistoryPresenter: CallHistoryPresenterProtocol, CallHistoryInteractorO func closeController() { wireFrame.closeController() } + + // MARK: NavigationProtocol + func back() { + closeController() + } } diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index 8fc30d4a6..499c5df05 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -14,7 +14,31 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol { var presenter: CallHistoryPresenterProtocol! - private let offset: Float = 10.0 + private struct Constraints { + + static let offset: CGFloat = 10.0 + static let rowHeight: CGFloat = 10.0 + static let separatorHeight: CGFloat = 1.0 + + enum tableView { + static let topInset = 16.0 + } + } + + private lazy var tableView: UITableView = { + let tblView = UITableView.default + + tblView.clipsToBounds = true + tblView.keyboardDismissMode = .interactive + + self.view.addSubview(tblView) + tblView.snp.makeConstraints { (make) in + make.top.equalTo(navigationView.snp.bottom) + make.left.right.bottom.equalToSuperview() + } + + return tblView + }() public init() { super.init(nibName: nil, bundle: nil) @@ -24,17 +48,35 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol { fatalError("init(coder:) has not been implemented") } - private enum ConstraintConstants { - - } - override func initialize() { super.initialize() - setupInitialVisibility() + setupUI() + } + + private func setupTableView() { + tableView.register(viewModel: ChatListMessageCellModel.self) + tableView.rowHeight = ChatListMessageCellModel.Cell.Constraints.height } - private func setupInitialVisibility() { + private func setupUI() { + + navigationView.isSeparatorVisible = true + tableView.isHidden = false + + let title:String = String.localizable.callHistoryTitle.uppercased() + let backBtnImage:UIImage? = UIImage.nynja.icBackNavigation.image + let navHandler:NavigationProtocol? = presenter + + navigationView.configure(config: NavigationView.Config( + isVisibleSeparator: navigationView.isSeparatorVisible ?? false, + isVisibleBackButton: (nil != backBtnImage), + title: title, + navigationHandler: navHandler, + backButtonImage: backBtnImage) + ) + screenTitle = title + setupTableView() } } diff --git a/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift b/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift index 5b627a049..7e58324b5 100644 --- a/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift +++ b/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift @@ -31,13 +31,11 @@ class CallHistoryWireFrame: CallHistoryWireFrameProtocol { presenter.interactor = interactor interactor.presenter = presenter - // pop to root of the navigation stack in case we have call in progress - LogService.log(topic: .callSystem) { return "present leave voice screen" } - navigation.popToRootViewController(animated: false) - navigation.pushViewController(view as UIViewController, animated: false) + LogService.log(topic: .callSystem) { return "present call history screen" } + navigation.pushViewController(view as UIViewController, animated: true) } func closeController() { - self.navigation?.popViewController(animated: false) + self.navigation?.popViewController(animated: true) } } diff --git a/Nynja/Modules/Main/WireFrame/MainWireframe.swift b/Nynja/Modules/Main/WireFrame/MainWireframe.swift index cbb1e674e..68d23ece9 100644 --- a/Nynja/Modules/Main/WireFrame/MainWireframe.swift +++ b/Nynja/Modules/Main/WireFrame/MainWireframe.swift @@ -474,7 +474,9 @@ class MainWireFrame: MainWireFrameProtocol, NynjaCommunicatorServiceDelegate { func showAddParticipantsToCreateConferenceCall() { - AddParticipantsWireFrame().presentAddParticipants(navigation: contentNavigation!, main: self, selectedContacts: [], delegate: self.external, mode: .createConferenceCall, members: [], room: nil) + CallHistoryWireFrame().presentCallHistory(navigation: contentNavigation!, main: self) + +// AddParticipantsWireFrame().presentAddParticipants(navigation: contentNavigation!, main: self, selectedContacts: [], delegate: self.external, mode: .createConferenceCall, members: [], room: nil) } func presentLeaveVoiceMessageViewForContact(contact:Contact) { diff --git a/Nynja/Resources/en.lproj/Localizable.strings b/Nynja/Resources/en.lproj/Localizable.strings index 081cc02f6..e8a9f14bc 100644 --- a/Nynja/Resources/en.lproj/Localizable.strings +++ b/Nynja/Resources/en.lproj/Localizable.strings @@ -986,3 +986,6 @@ "BY DATE" = "BY DATE"; "BY FOLDER" = "BY FOLDER"; "ALL" = "ALL"; + +//MARK: Call History +"call_history_title" = "call history"; -- GitLab From e704fa52f19b1356347611716af58c67bda49168 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Tue, 30 Oct 2018 11:13:31 +0200 Subject: [PATCH 03/59] Bottom view buttons are added --- Nynja.xcodeproj/project.pbxproj | 16 ++ Nynja/Generated/ColorsConstants.swift | 1 - Nynja/Generated/LocalizableConstants.swift | 8 + .../View/CallHistoryViewController.swift | 248 +++++++++++++++++- .../View/TableView/CallHistoryCellModel.swift | 13 + .../TableView/CallHistoryDataSource.swift | 13 + .../View/TableView/CallHistoryDelegate.swift | 13 + .../TableView/CallHistoryTableViewCell.swift | 24 ++ Nynja/Resources/en.lproj/Localizable.strings | 4 + 9 files changed, 331 insertions(+), 9 deletions(-) create mode 100644 Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift create mode 100644 Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift create mode 100644 Nynja/Modules/CallHistory/View/TableView/CallHistoryDelegate.swift create mode 100644 Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 86e1232ed..cb69454bb 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -1179,6 +1179,10 @@ 99B9D27D2F0EFE051E6581ED /* CreateGroupProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE9DC6ADA0E71241C49A328 /* CreateGroupProtocols.swift */; }; 9B0C32F12153CF1600094ECF /* HintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B0C32F02153CF1600094ECF /* HintView.swift */; }; 9B2C6693216F82AB00116486 /* NynjaJoinByLinkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B2C6692216F82AB00116486 /* NynjaJoinByLinkService.swift */; }; + 9B517995218333B2006E1A4B /* CallHistoryCellModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B517994218333B2006E1A4B /* CallHistoryCellModel.swift */; }; + 9B517997218333E1006E1A4B /* CallHistoryTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B517996218333E1006E1A4B /* CallHistoryTableViewCell.swift */; }; + 9B51799A21834B95006E1A4B /* CallHistoryDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */; }; + 9B51799C21834BA7006E1A4B /* CallHistoryDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */; }; 9B81AD92215A5EEA00993A8C /* ActiveSpeakerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B81AD91215A5EEA00993A8C /* ActiveSpeakerView.swift */; }; 9B96705F214BE3FE0058E98F /* MultiPageCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B96705E214BE3FE0058E98F /* MultiPageCollectionView.swift */; }; 9B967098215151760058E98F /* LeaveVoiceMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B967097215151760058E98F /* LeaveVoiceMessageViewController.swift */; }; @@ -3393,6 +3397,10 @@ 997E1A59FCAB5602A049C6E7 /* EditUsernamePresenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EditUsernamePresenter.swift; sourceTree = ""; }; 9B0C32F02153CF1600094ECF /* HintView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HintView.swift; sourceTree = ""; }; 9B2C6692216F82AB00116486 /* NynjaJoinByLinkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NynjaJoinByLinkService.swift; sourceTree = ""; }; + 9B517994218333B2006E1A4B /* CallHistoryCellModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryCellModel.swift; sourceTree = ""; }; + 9B517996218333E1006E1A4B /* CallHistoryTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryTableViewCell.swift; sourceTree = ""; }; + 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDelegate.swift; sourceTree = ""; }; + 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDataSource.swift; sourceTree = ""; }; 9B810991D7143259040DCA31 /* LanguageSettingsViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LanguageSettingsViewController.swift; sourceTree = ""; }; 9B81AD91215A5EEA00993A8C /* ActiveSpeakerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSpeakerView.swift; sourceTree = ""; }; 9B96705E214BE3FE0058E98F /* MultiPageCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiPageCollectionView.swift; sourceTree = ""; }; @@ -9429,6 +9437,10 @@ 9B2399F9217F0D4F00769770 /* TableView */ = { isa = PBXGroup; children = ( + 9B517994218333B2006E1A4B /* CallHistoryCellModel.swift */, + 9B517996218333E1006E1A4B /* CallHistoryTableViewCell.swift */, + 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */, + 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */, ); path = TableView; sourceTree = ""; @@ -16063,6 +16075,7 @@ 26CD3FDD2104D1DD00597E62 /* AudioConvertOperation.swift in Sources */, 8509FC7D2158DCFB00734D93 /* Feature+Construct.swift in Sources */, 26771CC1212ECE08006112B5 /* ConvertMessageTable.swift in Sources */, + 9B51799A21834B95006E1A4B /* CallHistoryDelegate.swift in Sources */, 8514F17C20EA219F00883513 /* ContextMenuConfiguration.swift in Sources */, FBCE840D20E525A6003B7558 /* HTTPResponseResult.swift in Sources */, A43B259F20AB1DFA00FF8107 /* PickerCell.swift in Sources */, @@ -16071,6 +16084,7 @@ F119E67920D27EA50043A532 /* VideoPreviewCVCell.swift in Sources */, 8502DB542061030100613C8C /* WheelPositionPickerViewController.swift in Sources */, 4B752B612163A5C900E852B9 /* DescExtension.swift in Sources */, + 9B517997218333E1006E1A4B /* CallHistoryTableViewCell.swift in Sources */, A45F116120B422AF00F45004 /* Message+System.swift in Sources */, 4B06D30C2028A25D003B275B /* HomeItemsFactory.swift in Sources */, 266AE8C3203496B60096A12C /* AsyncOperation.swift in Sources */, @@ -16078,6 +16092,7 @@ F119E67220D24BE40043A532 /* MultiplePreviewInteractor.swift in Sources */, 8503B525205046A6006F0593 /* NotificationSettingsPresenter.swift in Sources */, 85458CFD212D7B8C00BA8814 /* Desc+Construct.swift in Sources */, + 9B51799C21834BA7006E1A4B /* CallHistoryDataSource.swift in Sources */, 85433F2C204D5AA500B373A7 /* NynjaCloseButton.swift in Sources */, 8524C4D6217772C8003BF374 /* Member+Construct.swift in Sources */, A44B4D5A20CE9BDF00CA700A /* SwitchCell.swift in Sources */, @@ -16102,6 +16117,7 @@ A432CF1620B4347D00993AFB /* FloatingPlaceholderProvider.swift in Sources */, E7302A931FC83477002892F8 /* Desc+DescMime.swift in Sources */, 8509FC7B2158CCA800734D93 /* MessageInteractor+Reply.swift in Sources */, + 9B517995218333B2006E1A4B /* CallHistoryCellModel.swift in Sources */, A42D51CB206A361400EEB952 /* Job.swift in Sources */, E7F68D271FA22C45009C98D1 /* EditProfileVCStrings.swift in Sources */, 8ECC06801FC5C80C002CF225 /* MessagesProcessingManager.swift in Sources */, diff --git a/Nynja/Generated/ColorsConstants.swift b/Nynja/Generated/ColorsConstants.swift index 713effb5a..d175e25b9 100644 --- a/Nynja/Generated/ColorsConstants.swift +++ b/Nynja/Generated/ColorsConstants.swift @@ -105,4 +105,3 @@ internal extension SGColor { static let white = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0) } } - diff --git a/Nynja/Generated/LocalizableConstants.swift b/Nynja/Generated/LocalizableConstants.swift index 1e5f2a9e1..9ce3960fd 100644 --- a/Nynja/Generated/LocalizableConstants.swift +++ b/Nynja/Generated/LocalizableConstants.swift @@ -130,6 +130,14 @@ internal extension String { static var callDisconnected: String { return localizable.tr("Localizable", "call_disconnected") } /// Connection dropped static var callFailed: String { return localizable.tr("Localizable", "call_failed") } + /// All + static var callHistoryButtonAllTitle: String { return localizable.tr("Localizable", "call_history_button_all_title") } + /// Incoming + static var callHistoryButtonIncomingTitle: String { return localizable.tr("Localizable", "call_history_button_incoming_title") } + /// Missed + static var callHistoryButtonMissedTitle: String { return localizable.tr("Localizable", "call_history_button_missed_title") } + /// Outgoing + static var callHistoryButtonOutgoingTitle: String { return localizable.tr("Localizable", "call_history_button_outgoing_title") } /// call history static var callHistoryTitle: String { return localizable.tr("Localizable", "call_history_title") } /// Incoming Voice Call... diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index 499c5df05..55059d2f3 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -10,9 +10,11 @@ import UIKit private let askLeaveMessageKey = "AskLeaveMessage" -class CallHistoryViewController: BaseVC, CallHistoryViewProtocol { +class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDelegate { var presenter: CallHistoryPresenterProtocol! + let buttonFontSize: CGFloat = CGFloat(17.0.adjustedByWidth) + var contentWidth: CGFloat = Constraints.button.buttonOffset private struct Constraints { @@ -23,6 +25,42 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol { enum tableView { static let topInset = 16.0 } + + enum scrollView { + static let height: CGFloat = 68.0 + static let bottomInset: CGFloat = 14.0 + static let rightInset: CGFloat = 14.0 + } + + enum button { + static let height: CGFloat = 44.0 + static let buttonOffset: CGFloat = 10.0 + } + } + + private func deselectAllButtons() { + buttonAll.isSelected = false + buttonOutgoing.isSelected = false + buttonIncoming.isSelected = false + buttonMissed.isSelected = false + } + + private func updateScrollViewContentSize() { + self.scrollView.contentSize = CGSize(width: contentWidth, + height: CGFloat(Constraints.scrollView.height.adjustedByWidth)) + } + + private func buttonWidthBy(text:String) -> CGFloat { + + var width:CGFloat = 0.0 + + if let font = UIFont.makeFont(with: FontFamily.NotoSans.medium.name, height:buttonFontSize) { + let fontAttributes = [NSAttributedStringKey.font: font] + let size = (text as NSString).size(withAttributes: fontAttributes) + width = size.width + 4*Constraints.button.buttonOffset + } + + return width } private lazy var tableView: UITableView = { @@ -30,15 +68,180 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol { tblView.clipsToBounds = true tblView.keyboardDismissMode = .interactive + tblView.backgroundColor = .clear self.view.addSubview(tblView) tblView.snp.makeConstraints { (make) in make.top.equalTo(navigationView.snp.bottom) - make.left.right.bottom.equalToSuperview() + make.left.right.equalToSuperview() + make.bottom.equalTo(scrollView.snp.top).offset(-2*Constraints.offset) } return tblView }() + + private lazy var scrollView: UIScrollView = { + let scroll = UIScrollView() + scroll.backgroundColor = .clear + scroll.delegate = self + scroll.contentSize = CGSize(width: UIScreen.main.bounds.size.width - CGFloat(Constraints.scrollView.rightInset.adjustedByWidth + Constraints.scrollView.height.adjustedByWidth), + height: CGFloat(Constraints.scrollView.height.adjustedByWidth)) + scroll.isPagingEnabled = false + scroll.showsVerticalScrollIndicator = false + scroll.showsHorizontalScrollIndicator = false + + self.view.addSubview(scroll) + + scroll.snp.makeConstraints({ (make) in + make.left.equalToSuperview() + make.height.equalTo(Constraints.scrollView.height.adjustedByWidth) + make.right.equalToSuperview().offset(-Constraints.scrollView.rightInset.adjustedByWidth - Constraints.scrollView.height.adjustedByWidth) + adjustVerticalInset(.bottom, make: make, offset: -Constraints.scrollView.bottomInset) + }) + + return scroll + }() + + private lazy var buttonAll: UIButton = { + let butotnText = String.localizable.callHistoryButtonAllTitle.uppercased() + let width = buttonWidthBy(text: butotnText) + let height = CGFloat(Constraints.button.height.adjustedByWidth) + + let button = UIButton() + button.titleLabel?.font = UIFont.makeFont(with: FontFamily.NotoSans.medium.name, height:buttonFontSize) + button.setTitle(butotnText, for: .normal) + button.setTitleColor(UIColor.nynja.mainRed, for: .normal) + button.setTitleColor(UIColor.nynja.white, for: .selected) + button.setTitleColor(UIColor.nynja.white, for: .highlighted) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.clear), for: .normal) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.mainRed), for: .selected) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.mainRed), for: .highlighted) + + button.addTarget(self, action: #selector(allTapped(_:)), for: .touchUpInside) + button.backgroundColor = .clear + button.layer.cornerRadius = height/2 + button.layer.borderWidth = 1.0 + button.layer.borderColor = UIColor.nynja.mainRed.cgColor + button.clipsToBounds = true + self.scrollView.addSubview(button) + contentWidth += (CGFloat(width) + Constraints.button.buttonOffset) + updateScrollViewContentSize() + button.snp.makeConstraints({ (make) in + make.width.equalTo(width) + make.height.equalTo(height) + + make.centerY.equalToSuperview() + make.left.equalToSuperview().offset(Constraints.button.buttonOffset) + + }) + + return button + }() + + private lazy var buttonOutgoing: UIButton = { + let butotnText = String.localizable.callHistoryButtonOutgoingTitle.uppercased() + let width = buttonWidthBy(text: butotnText) + let height = CGFloat(Constraints.button.height.adjustedByWidth) + + let button = UIButton() + button.titleLabel?.font = UIFont.makeFont(with: FontFamily.NotoSans.medium.name, height:buttonFontSize) + button.setTitle(butotnText, for: .normal) + button.setTitleColor(UIColor.nynja.mainRed, for: .normal) + button.setTitleColor(UIColor.nynja.white, for: .selected) + button.setTitleColor(UIColor.nynja.white, for: .highlighted) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.clear), for: .normal) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.mainRed), for: .selected) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.mainRed), for: .highlighted) + + button.addTarget(self, action: #selector(outgoingTapped(_:)), for: .touchUpInside) + button.backgroundColor = .clear + button.layer.cornerRadius = height/2 + button.layer.borderWidth = 1.0 + button.layer.borderColor = UIColor.nynja.mainRed.cgColor + button.clipsToBounds = true + self.scrollView.addSubview(button) + contentWidth += (CGFloat(width) + Constraints.button.buttonOffset) + updateScrollViewContentSize() + button.snp.makeConstraints({ (make) in + make.width.equalTo(width) + make.height.equalTo(height) + + make.centerY.equalToSuperview() + make.left.equalTo(buttonAll.snp.right).offset(Constraints.button.buttonOffset) + }) + + return button + }() + + private lazy var buttonIncoming: UIButton = { + let butotnText = String.localizable.callHistoryButtonIncomingTitle.uppercased() + let width = buttonWidthBy(text: butotnText) + let height = CGFloat(Constraints.button.height.adjustedByWidth) + + let button = UIButton() + button.titleLabel?.font = UIFont.makeFont(with: FontFamily.NotoSans.medium.name, height:buttonFontSize) + button.setTitle(butotnText, for: .normal) + button.setTitleColor(UIColor.nynja.mainRed, for: .normal) + button.setTitleColor(UIColor.nynja.white, for: .selected) + button.setTitleColor(UIColor.nynja.white, for: .highlighted) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.clear), for: .normal) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.mainRed), for: .selected) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.mainRed), for: .highlighted) + + button.addTarget(self, action: #selector(incomingTapped(_:)), for: .touchUpInside) + button.backgroundColor = .clear + button.layer.cornerRadius = height/2 + button.layer.borderWidth = 1.0 + button.layer.borderColor = UIColor.nynja.mainRed.cgColor + button.clipsToBounds = true + self.scrollView.addSubview(button) + contentWidth += (CGFloat(width) + Constraints.button.buttonOffset) + updateScrollViewContentSize() + button.snp.makeConstraints({ (make) in + make.width.equalTo(width) + make.height.equalTo(height) + + make.centerY.equalToSuperview() + make.left.equalTo(buttonOutgoing.snp.right).offset(Constraints.button.buttonOffset) + }) + + return button + }() + + private lazy var buttonMissed: UIButton = { + let butotnText = String.localizable.callHistoryButtonMissedTitle.uppercased() + let width = buttonWidthBy(text: butotnText) + let height = CGFloat(Constraints.button.height.adjustedByWidth) + + let button = UIButton() + button.titleLabel?.font = UIFont.makeFont(with: FontFamily.NotoSans.medium.name, height:buttonFontSize) + button.setTitle(butotnText, for: .normal) + button.setTitleColor(UIColor.nynja.mainRed, for: .normal) + button.setTitleColor(UIColor.nynja.white, for: .selected) + button.setTitleColor(UIColor.nynja.white, for: .highlighted) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.clear), for: .normal) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.mainRed), for: .selected) + button.setBackgroundImage(UIImage.imageWithColor(color: UIColor.nynja.mainRed), for: .highlighted) + + button.addTarget(self, action: #selector(missedTapped(_:)), for: .touchUpInside) + button.backgroundColor = .clear + button.layer.cornerRadius = height/2 + button.layer.borderWidth = 1.0 + button.layer.borderColor = UIColor.nynja.mainRed.cgColor + button.clipsToBounds = true + self.scrollView.addSubview(button) + contentWidth += (CGFloat(width) + Constraints.button.buttonOffset) + updateScrollViewContentSize() + button.snp.makeConstraints({ (make) in + make.width.equalTo(width) + make.height.equalTo(height) + + make.centerY.equalToSuperview() + make.left.equalTo(buttonIncoming.snp.right).offset(Constraints.button.buttonOffset) + }) + + return button + }() public init() { super.init(nibName: nil, bundle: nil) @@ -54,15 +257,16 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol { setupUI() } - private func setupTableView() { - tableView.register(viewModel: ChatListMessageCellModel.self) - tableView.rowHeight = ChatListMessageCellModel.Cell.Constraints.height - } - private func setupUI() { navigationView.isSeparatorVisible = true tableView.isHidden = false + scrollView.isHidden = false + buttonMissed.isHidden = false + + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) { + self.buttonAll.isHidden = false + } let title:String = String.localizable.callHistoryTitle.uppercased() let backBtnImage:UIImage? = UIImage.nynja.icBackNavigation.image @@ -77,6 +281,34 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol { ) screenTitle = title - setupTableView() + allTapped(buttonAll) + } + + // MARK UIScrollView Delegates + func scrollViewDidScroll(_ scrollView: UIScrollView) { + } + + func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { + } + + // MARK: - Actions + @objc private func allTapped(_ button: UIButton) { + deselectAllButtons() + button.isSelected = !button.isSelected + } + + @objc private func outgoingTapped(_ button: UIButton) { + deselectAllButtons() + button.isSelected = !button.isSelected + } + + @objc private func incomingTapped(_ button: UIButton) { + deselectAllButtons() + button.isSelected = !button.isSelected + } + + @objc private func missedTapped(_ button: UIButton) { + deselectAllButtons() + button.isSelected = !button.isSelected } } diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift new file mode 100644 index 000000000..0e0e2078d --- /dev/null +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift @@ -0,0 +1,13 @@ +// +// CallHistoryCellModel.swift +// Nynja +// +// Created by Bozhko Terziev on 26.10.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +class CallHistoryCellModel: NSObject { + +} diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift new file mode 100644 index 000000000..c53d0e857 --- /dev/null +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift @@ -0,0 +1,13 @@ +// +// CallHistoryDataSource.swift +// Nynja +// +// Created by Bozhko Terziev on 26.10.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +class CallHistoryDataSource: NSObject { + +} diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDelegate.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDelegate.swift new file mode 100644 index 000000000..72bade060 --- /dev/null +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDelegate.swift @@ -0,0 +1,13 @@ +// +// CallHistoryDelegate.swift +// Nynja +// +// Created by Bozhko Terziev on 26.10.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +class CallHistoryDelegate: NSObject { + +} diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift new file mode 100644 index 000000000..586878d89 --- /dev/null +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift @@ -0,0 +1,24 @@ +// +// CallHistoryTableViewCell.swift +// Nynja +// +// Created by Bozhko Terziev on 26.10.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +class CallHistoryTableViewCell: UITableViewCell { + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/Nynja/Resources/en.lproj/Localizable.strings b/Nynja/Resources/en.lproj/Localizable.strings index e8a9f14bc..e1193654a 100644 --- a/Nynja/Resources/en.lproj/Localizable.strings +++ b/Nynja/Resources/en.lproj/Localizable.strings @@ -989,3 +989,7 @@ //MARK: Call History "call_history_title" = "call history"; +"call_history_button_all_title" = "All"; +"call_history_button_outgoing_title" = "Outgoing"; +"call_history_button_incoming_title" = "Incoming"; +"call_history_button_missed_title" = "Missed"; -- GitLab From 7cde540ac60ab0be8b15801013374464d680f8db Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Thu, 8 Nov 2018 19:10:12 +0200 Subject: [PATCH 04/59] UI layout is done for call history --- Nynja.xcodeproj/project.pbxproj | 8 +- Nynja/Generated/AssetsConstants.swift | 22 ++ Nynja/Generated/ColorsConstants.swift | 1 + Nynja/Generated/LocalizableConstants.swift | 2 + Nynja/HomeItemsFactory.swift | 10 +- .../View/CallHistoryViewController.swift | 83 ++++++- .../View/TableView/CallHistoryCellModel.swift | 1 + .../TableView/CallHistoryDataController.swift | 25 +++ .../TableView/CallHistoryDataSource.swift | 40 +++- .../View/TableView/CallHistoryDelegate.swift | 14 ++ .../TableView/CallHistoryTableViewCell.swift | 210 +++++++++++++++++- Nynja/Modules/Main/MainProtocols.swift | 2 + .../Main/Presenter/MainPresenter.swift | 4 + .../Main/View/MainNavigationItem.swift | 1 + .../MainViewController+NavigateProtocol.swift | 6 + .../Modules/Main/View/NavigateProtocol.swift | 1 + .../Main/WireFrame/MainWireframe.swift | 5 +- .../Assets.xcassets/callHistory/Contents.json | 6 + .../ic_canceled_video.imageset/Contents.json | 21 ++ .../Icons_Message_ic_canceled_video_call.pdf | Bin 0 -> 4110 bytes .../ic_canceled_voice.imageset/Contents.json | 21 ++ ...Message_ic_\321\201anceled_voice_call.pdf" | Bin 0 -> 4931 bytes .../ic_incoming_video.imageset/Contents.json | 21 ++ .../Icons_Message_ic_incoming_video_call.pdf | Bin 0 -> 4058 bytes .../ic_incoming_voice.imageset/Contents.json | 21 ++ .../Icons_Message_ic_incoming_voice_call.pdf | Bin 0 -> 4874 bytes .../ic_missed_video.imageset/Contents.json | 21 ++ .../Icons_Message_ic_missed_video_call.pdf | Bin 0 -> 4106 bytes .../ic_missed_voice.imageset/Contents.json | 21 ++ .../Icons_Message_ic_missed_voice_call.pdf | Bin 0 -> 4929 bytes .../ic_no_answer_video.imageset/Contents.json | 21 ++ .../Icons_Message_ic_no_answer_video_call.pdf | Bin 0 -> 4038 bytes .../ic_no_answer_voice.imageset/Contents.json | 21 ++ .../Icons_Message_ic_no_answer_voice_call.pdf | Bin 0 -> 4854 bytes .../ic_outgoing_video.imageset/Contents.json | 21 ++ .../Icons_Message_ic_outgoing_video_call.pdf | Bin 0 -> 4093 bytes .../ic_outgoing_voice.imageset/Contents.json | 21 ++ .../Icons_Message_ic_outgoing_voice_call.pdf | Bin 0 -> 4926 bytes Nynja/Resources/en.lproj/Localizable.strings | 1 + 39 files changed, 636 insertions(+), 16 deletions(-) create mode 100644 Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_video.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_video.imageset/Icons_Message_ic_canceled_video_call.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_voice.imageset/Contents.json create mode 100644 "Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_voice.imageset/Icons_Message_ic_\321\201anceled_voice_call.pdf" create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_video.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_video.imageset/Icons_Message_ic_incoming_video_call.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_voice.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_voice.imageset/Icons_Message_ic_incoming_voice_call.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_missed_video.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_missed_video.imageset/Icons_Message_ic_missed_video_call.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_missed_voice.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_missed_voice.imageset/Icons_Message_ic_missed_voice_call.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_video.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_video.imageset/Icons_Message_ic_no_answer_video_call.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_voice.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_voice.imageset/Icons_Message_ic_no_answer_voice_call.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_video.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_video.imageset/Icons_Message_ic_outgoing_video_call.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_voice.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_voice.imageset/Icons_Message_ic_outgoing_voice_call.pdf diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index cb69454bb..c7406d29b 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -1183,6 +1183,7 @@ 9B517997218333E1006E1A4B /* CallHistoryTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B517996218333E1006E1A4B /* CallHistoryTableViewCell.swift */; }; 9B51799A21834B95006E1A4B /* CallHistoryDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */; }; 9B51799C21834BA7006E1A4B /* CallHistoryDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */; }; + 9B804AB9219326A1000606EC /* CallHistoryDataController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804AB8219326A1000606EC /* CallHistoryDataController.swift */; }; 9B81AD92215A5EEA00993A8C /* ActiveSpeakerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B81AD91215A5EEA00993A8C /* ActiveSpeakerView.swift */; }; 9B96705F214BE3FE0058E98F /* MultiPageCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B96705E214BE3FE0058E98F /* MultiPageCollectionView.swift */; }; 9B967098215151760058E98F /* LeaveVoiceMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B967097215151760058E98F /* LeaveVoiceMessageViewController.swift */; }; @@ -1197,12 +1198,12 @@ 9BD8E40720F3576F001384EC /* CallInProgressWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BD8E40620F3576F001384EC /* CallInProgressWireframe.swift */; }; 9BD8E41120F39AE3001384EC /* CallInProgressPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BD8E41020F39AE3001384EC /* CallInProgressPresenter.swift */; }; 9BD8E41320F3A2E2001384EC /* CallInProgressInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BD8E41220F3A2E2001384EC /* CallInProgressInteractor.swift */; }; - 9BFFE61B2178DD00004FE2CA /* BannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE61A2178DCFF004FE2CA /* BannerView.swift */; }; 9BFFE60D21778ABF004FE2CA /* CallHistoryInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE60C21778ABF004FE2CA /* CallHistoryInteractor.swift */; }; 9BFFE60F21778ACD004FE2CA /* CallHistoryPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE60E21778ACD004FE2CA /* CallHistoryPresenter.swift */; }; 9BFFE61121778AD7004FE2CA /* CallHistoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE61021778AD6004FE2CA /* CallHistoryViewController.swift */; }; 9BFFE61321778AE2004FE2CA /* CallHistoryWireFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE61221778AE2004FE2CA /* CallHistoryWireFrame.swift */; }; 9BFFE6152177935C004FE2CA /* CallHistoryProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE6142177935C004FE2CA /* CallHistoryProtocols.swift */; }; + 9BFFE61B2178DD00004FE2CA /* BannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BFFE61A2178DCFF004FE2CA /* BannerView.swift */; }; 9E9DD4C7F700872D7CCEE227 /* ProfileInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFF6A30BDE89BF7887B67DA0 /* ProfileInteractor.swift */; }; A1AD6864F4F49D9FC8997D59 /* SelectCountryPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5522F1F73FC8C564BF0254BF /* SelectCountryPresenter.swift */; }; A402A1CC20DE694A005BFA20 /* PartialCheckableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A402A1CB20DE694A005BFA20 /* PartialCheckableButton.swift */; }; @@ -3401,6 +3402,7 @@ 9B517996218333E1006E1A4B /* CallHistoryTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryTableViewCell.swift; sourceTree = ""; }; 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDelegate.swift; sourceTree = ""; }; 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDataSource.swift; sourceTree = ""; }; + 9B804AB8219326A1000606EC /* CallHistoryDataController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDataController.swift; sourceTree = ""; }; 9B810991D7143259040DCA31 /* LanguageSettingsViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LanguageSettingsViewController.swift; sourceTree = ""; }; 9B81AD91215A5EEA00993A8C /* ActiveSpeakerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSpeakerView.swift; sourceTree = ""; }; 9B96705E214BE3FE0058E98F /* MultiPageCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiPageCollectionView.swift; sourceTree = ""; }; @@ -3416,12 +3418,12 @@ 9BD8E40620F3576F001384EC /* CallInProgressWireframe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallInProgressWireframe.swift; sourceTree = ""; }; 9BD8E41020F39AE3001384EC /* CallInProgressPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallInProgressPresenter.swift; sourceTree = ""; }; 9BD8E41220F3A2E2001384EC /* CallInProgressInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallInProgressInteractor.swift; sourceTree = ""; }; - 9BFFE61A2178DCFF004FE2CA /* BannerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BannerView.swift; sourceTree = ""; }; 9BFFE60C21778ABF004FE2CA /* CallHistoryInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryInteractor.swift; sourceTree = ""; }; 9BFFE60E21778ACD004FE2CA /* CallHistoryPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryPresenter.swift; sourceTree = ""; }; 9BFFE61021778AD6004FE2CA /* CallHistoryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryViewController.swift; sourceTree = ""; }; 9BFFE61221778AE2004FE2CA /* CallHistoryWireFrame.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryWireFrame.swift; sourceTree = ""; }; 9BFFE6142177935C004FE2CA /* CallHistoryProtocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryProtocols.swift; sourceTree = ""; }; + 9BFFE61A2178DCFF004FE2CA /* BannerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BannerView.swift; sourceTree = ""; }; 9C4192D925259B75441492A9 /* FavoritesPresenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = FavoritesPresenter.swift; sourceTree = ""; }; 9DE44A136617140435B23343 /* GroupStorageWireframe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = GroupStorageWireframe.swift; sourceTree = ""; }; 9E82188EE0AC1D1C05470692 /* Pods-NynjaUnitTests.channels.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NynjaUnitTests.channels.xcconfig"; path = "Pods/Target Support Files/Pods-NynjaUnitTests/Pods-NynjaUnitTests.channels.xcconfig"; sourceTree = ""; }; @@ -9441,6 +9443,7 @@ 9B517996218333E1006E1A4B /* CallHistoryTableViewCell.swift */, 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */, 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */, + 9B804AB8219326A1000606EC /* CallHistoryDataController.swift */, ); path = TableView; sourceTree = ""; @@ -15465,6 +15468,7 @@ 4B8996E4204EEC5A00DCB183 /* MessageDAOProtocol.swift in Sources */, E76491961F7A529D001E741C /* WheelContainer.swift in Sources */, 2648C4122069B52100863614 /* ChangeNumberStep3ViewController.swift in Sources */, + 9B804AB9219326A1000606EC /* CallHistoryDataController.swift in Sources */, 8E9601931FF295DF00E0C21D /* ItemsSelector.swift in Sources */, A42D51C9206A361400EEB952 /* writer.swift in Sources */, 2648C3E62069B49000863614 /* UITextField+Extension.swift in Sources */, diff --git a/Nynja/Generated/AssetsConstants.swift b/Nynja/Generated/AssetsConstants.swift index 78d609564..6b4c33a25 100644 --- a/Nynja/Generated/AssetsConstants.swift +++ b/Nynja/Generated/AssetsConstants.swift @@ -658,6 +658,28 @@ internal extension Image { static var btnTakePhotoHighlighted: ImageAsset { return ImageAsset(name: "btn_take_photo_highlighted") } /// "btn_wheel_done" static var btnWheelDone: ImageAsset { return ImageAsset(name: "btn_wheel_done") } + enum CallHistory { + /// "ic_canceled_video" + static var icCanceledVideo: ImageAsset { return ImageAsset(name: "ic_canceled_video") } + /// "ic_canceled_voice" + static var icCanceledVoice: ImageAsset { return ImageAsset(name: "ic_canceled_voice") } + /// "ic_incoming_video" + static var icIncomingVideo: ImageAsset { return ImageAsset(name: "ic_incoming_video") } + /// "ic_incoming_voice" + static var icIncomingVoice: ImageAsset { return ImageAsset(name: "ic_incoming_voice") } + /// "ic_missed_video" + static var icMissedVideo: ImageAsset { return ImageAsset(name: "ic_missed_video") } + /// "ic_missed_voice" + static var icMissedVoice: ImageAsset { return ImageAsset(name: "ic_missed_voice") } + /// "ic_no_answer_video" + static var icNoAnswerVideo: ImageAsset { return ImageAsset(name: "ic_no_answer_video") } + /// "ic_no_answer_voice" + static var icNoAnswerVoice: ImageAsset { return ImageAsset(name: "ic_no_answer_voice") } + /// "ic_outgoing_video" + static var icOutgoingVideo: ImageAsset { return ImageAsset(name: "ic_outgoing_video") } + /// "ic_outgoing_voice" + static var icOutgoingVoice: ImageAsset { return ImageAsset(name: "ic_outgoing_voice") } + } /// "callKitImage" static var callKitImage: ImageAsset { return ImageAsset(name: "callKitImage") } /// "camera" diff --git a/Nynja/Generated/ColorsConstants.swift b/Nynja/Generated/ColorsConstants.swift index d175e25b9..713effb5a 100644 --- a/Nynja/Generated/ColorsConstants.swift +++ b/Nynja/Generated/ColorsConstants.swift @@ -105,3 +105,4 @@ internal extension SGColor { static let white = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0) } } + diff --git a/Nynja/Generated/LocalizableConstants.swift b/Nynja/Generated/LocalizableConstants.swift index 9ce3960fd..9f7272a45 100644 --- a/Nynja/Generated/LocalizableConstants.swift +++ b/Nynja/Generated/LocalizableConstants.swift @@ -1338,6 +1338,8 @@ internal extension String { static var wheelItemByUsername: String { return localizable.tr("Localizable", "wheel_item_byUsername") } /// Call static var wheelItemCall: String { return localizable.tr("Localizable", "wheel_item_call") } + /// Call History + static var wheelItemCallHistory: String { return localizable.tr("Localizable", "wheel_item_callHistory") } /// Calls static var wheelItemCalls: String { return localizable.tr("Localizable", "wheel_item_calls") } /// Camera diff --git a/Nynja/HomeItemsFactory.swift b/Nynja/HomeItemsFactory.swift index c4c64d1b6..039ada8fd 100644 --- a/Nynja/HomeItemsFactory.swift +++ b/Nynja/HomeItemsFactory.swift @@ -30,7 +30,7 @@ class HomeItemsFactory: WCBaseItemsFactory { navigateDelegate?.helpFeedBack(indexPath: indexPath) }) - call.subitems = [videoCall, voiceCall] + call.subitems = [callHistory, videoCall, voiceCall] return [call, edit, myQR, help] } @@ -45,10 +45,16 @@ class HomeItemsFactory: WCBaseItemsFactory { var videoCall: ImageFilledItemModel { return ImageFilledItemModel(nameImage: "ic_video", navItem: .videoCall, isSelectable: false, action: { [weak navigateDelegate] (item, indexPath) in navigateDelegate?.unavailableFunctionality() -// navigateDelegate?.conferenceVideoCall(indexPath: indexPath) }) } + var callHistory: ImageFilledItemModel { + return ImageFilledItemModel(nameImage: "ic_history", navItem: .callHistory, isSelectable: false, action: { [weak navigateDelegate] (item, indexPath) in + navigateDelegate?.callHistory(indexPath: indexPath) + }) + } + + // MARK: - Edit Profile var photo: ImageFilledItemModel { diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index 55059d2f3..80a5fd1d0 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -8,13 +8,23 @@ import UIKit -private let askLeaveMessageKey = "AskLeaveMessage" +enum CallHistoryMode { + case all + case outgoing + case incoming + case missed +} -class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDelegate { +class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDelegate, CallHistoryDataSourceDelegate, UITableViewDelegate { var presenter: CallHistoryPresenterProtocol! let buttonFontSize: CGFloat = CGFloat(17.0.adjustedByWidth) var contentWidth: CGFloat = Constraints.button.buttonOffset + var callHistoryMode: CallHistoryMode = .all + + var dataController: CallHistoryDataController? + var tableViewDataSource: CallHistoryDataSource? + var tableViewDelegate: CallHistoryDelegate? private struct Constraints { @@ -24,6 +34,7 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe enum tableView { static let topInset = 16.0 + static let rowHeight = 64.0 } enum scrollView { @@ -38,7 +49,27 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe } } - private func deselectAllButtons() { + private func cleanUpBeforeReloading() { + tableViewDataSource = nil + tableViewDelegate = nil + } + + private func reloadTableView() { + self.dataController?.buildDataSourceWith(mode: self.callHistoryMode, completionHandler: { (dataSource) -> Void in + cleanUpBeforeReloading() + tableViewDataSource = CallHistoryDataSource(tableView:tableView, dataSource: dataSource) + tableViewDataSource?.delegate = self + self.tableView.reloadData() + }) + } + + override func viewDidLoad() { + super.viewDidLoad() + self.dataController = CallHistoryDataController() + reloadTableView() + } + + private func deselectAllButtons() { buttonAll.isSelected = false buttonOutgoing.isSelected = false buttonIncoming.isSelected = false @@ -69,6 +100,12 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe tblView.clipsToBounds = true tblView.keyboardDismissMode = .interactive tblView.backgroundColor = .clear + tblView.rowHeight = CGFloat(Constraints.tableView.rowHeight) + tblView.estimatedRowHeight = CGFloat(Constraints.tableView.rowHeight) + tblView.register(CallHistoryTableViewCell.self, forCellReuseIdentifier: CallHistoryTableViewCell.cellId) + tblView.separatorColor = UIColor.nynja.backgroundGray + tblView.separatorStyle = .singleLine + tblView.delegate = self self.view.addSubview(tblView) tblView.snp.makeConstraints { (make) in @@ -284,31 +321,71 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe allTapped(buttonAll) } + private func callBackFor(indexPath: IndexPath) { + + } + // MARK UIScrollView Delegates + func scrollViewDidScroll(_ scrollView: UIScrollView) { } func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { } + // MARK Cal History Data Source Delegates + + func showMenuWith(callHistoryCell: CallHistoryTableViewCell) { + var arrActions = [UIAlertAction]() + + let cancelAction = UIAlertAction(title: String.localizable.cancel, style: .cancel) + let deleteAction = UIAlertAction(title: String.localizable.delete, style: .default) { [weak self] _ in + + } + + arrActions.append(deleteAction) + arrActions.append(cancelAction) + + AlertManager.sharedInstance.showActionSheet(title: nil, message: nil, actions: arrActions) + } + + func showInfoWith(callHistoryCell: CallHistoryTableViewCell) { + } + // MARK: - Actions + @objc private func allTapped(_ button: UIButton) { deselectAllButtons() button.isSelected = !button.isSelected + callHistoryMode = .all + reloadTableView() } @objc private func outgoingTapped(_ button: UIButton) { deselectAllButtons() button.isSelected = !button.isSelected + callHistoryMode = .outgoing + reloadTableView() } @objc private func incomingTapped(_ button: UIButton) { deselectAllButtons() button.isSelected = !button.isSelected + callHistoryMode = .incoming + reloadTableView() } @objc private func missedTapped(_ button: UIButton) { deselectAllButtons() button.isSelected = !button.isSelected + callHistoryMode = .missed + reloadTableView() + } + + // MARK: UITableView Delegates + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath, animated: false) + callBackFor(indexPath: indexPath) } } diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift index 0e0e2078d..321d58b3e 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift @@ -10,4 +10,5 @@ import UIKit class CallHistoryCellModel: NSObject { + } diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift new file mode 100644 index 000000000..5731954eb --- /dev/null +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift @@ -0,0 +1,25 @@ +// +// CallHistoryDataController.swift +// Nynja +// +// Created by Bozhko Terziev on 7.11.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +typealias CompletionHandler = (_ dataSource:Array) -> Void + +class CallHistoryDataController: NSObject { + + func buildDataSourceWith(mode: CallHistoryMode, completionHandler: CompletionHandler) { + + let dataSource = NSMutableArray() + + dataSource.add(CallHistoryCellModel()) + dataSource.add(CallHistoryCellModel()) + dataSource.add(CallHistoryCellModel()) + + completionHandler((dataSource as? [CallHistoryCellModel])!) + } +} diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift index c53d0e857..537c0639e 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift @@ -8,6 +8,44 @@ import UIKit -class CallHistoryDataSource: NSObject { +protocol CallHistoryDataSourceDelegate: class { + + func showMenuWith( callHistoryCell: CallHistoryTableViewCell) -> Void + func showInfoWith( callHistoryCell: CallHistoryTableViewCell) -> Void +} + +class CallHistoryDataSource: NSObject, CallHistoryTableViewCellDelegate { + + let dataSource: Array + weak var delegate:CallHistoryDataSourceDelegate? + + init(tableView: UITableView, dataSource: Array) { + self.dataSource = dataSource + super.init() + tableView.dataSource = self + } + + // MARK: - Call History Cell Delegate + + func showMenuWith(callHistoryCell: CallHistoryTableViewCell) { + delegate?.showMenuWith(callHistoryCell: callHistoryCell) + } + + func showInfoWith(callHistoryCell: CallHistoryTableViewCell) { + delegate?.showInfoWith(callHistoryCell: callHistoryCell) + } +} +extension CallHistoryDataSource: UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 50 //self.dataSource.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: CallHistoryTableViewCell.cellId, for: indexPath) as! CallHistoryTableViewCell + + cell.updateCell() + cell.delegate = self + return cell + } } diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDelegate.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDelegate.swift index 72bade060..9bc4520f4 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDelegate.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDelegate.swift @@ -9,5 +9,19 @@ import UIKit class CallHistoryDelegate: NSObject { + let dataSource: Array + + init(tableView: UITableView, dataSource: Array) { + self.dataSource = dataSource + super.init() + tableView.delegate = self + } +} +extension CallHistoryDelegate: UITableViewDelegate { + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath, animated: false) + } } + diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift index 586878d89..7dd8335c0 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift @@ -8,17 +8,215 @@ import UIKit +protocol CallHistoryTableViewCellDelegate: class { + + func showMenuWith( callHistoryCell: CallHistoryTableViewCell) -> Void + func showInfoWith( callHistoryCell: CallHistoryTableViewCell) -> Void +} + class CallHistoryTableViewCell: UITableViewCell { + + var model:CallHistoryCellModel? + weak var delegate:CallHistoryTableViewCellDelegate? + private var longPressRecognizer: UILongPressGestureRecognizer? + + static var cellId = "CallHistoryTableViewCell" + + private lazy var avatarImageView: UIImageView = { + let av = UIImageView() + av.contentMode = .scaleToFill + av.layer.cornerRadius = CGFloat(Constraints.avatar.height/2) + av.backgroundColor = UIColor.nynja.lightGray + + self.contentView.addSubview(av) + av.snp.makeConstraints { (make) in + make.left.equalToSuperview().offset(Constraints.avatar.leftOffset) + make.centerY.equalToSuperview() + make.height.width.equalTo(Constraints.avatar.height) + } + + return av + }() + + private lazy var callTypeImageView: UIImageView = { + let av = UIImageView() + av.contentMode = .scaleToFill + av.backgroundColor = .clear + av.image = UIImage.nynja.CallHistory.icCanceledVideo.image + + self.contentView.addSubview(av) + av.snp.makeConstraints { (make) in + make.left.equalTo(avatarImageView.snp.right).offset(Constraints.callTypeImageView.leftOffset) + make.bottom.equalToSuperview().offset(-Constraints.callTypeImageView.bottomOffset) + make.height.width.equalTo(Constraints.callTypeImageView.height) + } + + return av + }() + + private lazy var infoButton: UIButton = { + let button = UIButton(type: .infoLight) + button.tintColor = UIColor.nynja.lightGray + button.addTarget(self, action: #selector(onInfoTap(sender:)), for: .touchUpInside) + button.setImage(nil, for: .normal) + button.contentMode = .center + + self.contentView.addSubview(button) + button.snp.makeConstraints { (make) in + make.right.equalToSuperview().offset(-Constraints.infoButton.rightOffset) + make.height.width.equalTo(Constraints.infoButton.height) + make.centerY.equalTo(callTypeImageView.snp.centerY) + } - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code + return button + }() + + private lazy var callTypeLabel: UILabel = { + let label = UILabel() + label.textAlignment = .left + label.font = UIFont.makeFont(with: FontFamily.NotoSans.regular.name, height: 20.0) + label.textColor = UIColor.nynja.lightGray + label.backgroundColor = UIColor.nynja.clear + label.text = "Incomming call" + + self.contentView.addSubview(label) + label.snp.makeConstraints { (make) in + make.left.equalTo(callTypeImageView.snp.right).offset(Constraints.callTypelabel.leftOffset) + make.right.equalTo(infoButton.snp.left).offset(-Constraints.callTypelabel.rightOffset) + make.centerY.equalTo(callTypeImageView.snp.centerY) + } + + return label + }() + + private lazy var nameLabel: UILabel = { + let label = UILabel() + label.textAlignment = .left + label.font = UIFont.makeFont(with: FontFamily.NotoSans.regular.name, height: 22.0) + label.textColor = UIColor.nynja.white + label.backgroundColor = UIColor.nynja.clear + label.text = "Astronomy or Astrology" + + self.contentView.addSubview(label) + label.snp.makeConstraints { (make) in + make.left.equalTo(avatarImageView.snp.right).offset(Constraints.labelName.leftOffset) + make.top.equalTo(Constraints.labelName.topOffset) + } + + return label + }() + + private lazy var timeLabel: UILabel = { + let label = UILabel() + label.textAlignment = .right + label.font = UIFont.makeFont(with: FontFamily.NotoSans.regular.name, height: 16.0) + label.textColor = UIColor.nynja.lightGray + label.backgroundColor = UIColor.nynja.clear + label.text = "10:55 PM" + + self.contentView.addSubview(label) + label.snp.makeConstraints { (make) in + make.right.equalToSuperview().offset(-Constraints.labelTime.rightOffset) + make.centerY.equalTo(nameLabel.snp.centerY) + make.left.equalTo(nameLabel.snp.right).offset(Constraints.labelTime.horInset) + } + + return label + }() + + // MARK: - Init + + override init(style: UITableViewCellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + baseSetup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + baseSetup() + } + + private func baseSetup() { + self.backgroundColor = UIColor.nynja.clear + self.selectionStyle = .none + + longPressRecognizer = UILongPressGestureRecognizer.init(target: self, action: #selector(longPressed(_:))) + + if let lp = longPressRecognizer{ + lp.minimumPressDuration = 0.5 + lp.delegate = self + self.contentView.addGestureRecognizer(lp) + } } + + // MARK: - Public - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) + func updateCell() { - // Configure the view for the selected state + avatarImageView.isHidden = false + timeLabel.isHidden = false + nameLabel.isHidden = false + + callTypeImageView.isHidden = false + callTypeLabel.isHidden = false + infoButton.isHidden = false } + + // MARK: - Actions + + @objc func onInfoTap(sender: UIButton) { + delegate?.showInfoWith(callHistoryCell: self) + } + + // MARL: - Long Press Delegates + + override func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { + return !(touch.view is UIButton) + } + + @objc private func longPressed(_ recognizer: UILongPressGestureRecognizer) { + guard recognizer.state == .began else { + return + } + + delegate?.showMenuWith(callHistoryCell: self) + } +} +extension CallHistoryTableViewCell { + + struct Constraints { + + struct avatar { + static let leftOffset = 16.0 + static let height = 44.0 + } + + struct labelName { + static let leftOffset = 16.0 + static let topOffset = 11.0 + } + + struct labelTime { + static let rightOffset = 16.0 + static let horInset = 5.0 + } + + struct callTypeImageView { + static let leftOffset = 16.0 + static let bottomOffset = 11.0 + static let height = 18.0 + } + + struct callTypelabel { + static let leftOffset = 8.0 + static let rightOffset = 8.0 + } + + struct infoButton { + static let rightOffset = 16.0 + static let height = 18.0 + } + } } + diff --git a/Nynja/Modules/Main/MainProtocols.swift b/Nynja/Modules/Main/MainProtocols.swift index 98d9743d6..ec91bb1c0 100644 --- a/Nynja/Modules/Main/MainProtocols.swift +++ b/Nynja/Modules/Main/MainProtocols.swift @@ -46,6 +46,7 @@ protocol MainWireFrameProtocol: class { func showAddParticipantsToCreateCallWith(room:Room) func showAddParticipantsToCreateConferenceCall() + func showCallHistory() func showPayment(profile: Profile, to contact: Contact) func showScheduleMessage(with mode: ScheduledMessageMode, delegate: ScheduleMessageDelegate?) @@ -190,6 +191,7 @@ protocol MainPresenterProtocol: class { func conferenceVoiceCall() func conferenceVideoCall() + func callHistory() // Group func showAddParticipants() diff --git a/Nynja/Modules/Main/Presenter/MainPresenter.swift b/Nynja/Modules/Main/Presenter/MainPresenter.swift index 5292588ec..a8e2ae48f 100644 --- a/Nynja/Modules/Main/Presenter/MainPresenter.swift +++ b/Nynja/Modules/Main/Presenter/MainPresenter.swift @@ -193,6 +193,10 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu func conferenceVideoCall() { } + + func callHistory() { + wireFrame.showCallHistory() + } func showThemePicker() { self.wireFrame.showThemePicker() diff --git a/Nynja/Modules/Main/View/MainNavigationItem.swift b/Nynja/Modules/Main/View/MainNavigationItem.swift index 7fd4c3064..3afe4b57a 100644 --- a/Nynja/Modules/Main/View/MainNavigationItem.swift +++ b/Nynja/Modules/Main/View/MainNavigationItem.swift @@ -35,6 +35,7 @@ enum MainNavigationItem: String { case voiceCall = "wheel_item_voiceCall" case voiceGroupCall = "wheel_item_voiceGroupCall" case videoCall = "wheel_item_videoCall" + case callHistory = "wheel_item_callHistory" case videoGroupCall = "wheel_item_videoGroupCall" case contact = "wheel_item_contact" case event = "wheel_item_event" diff --git a/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift b/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift index 23e4a8d39..688f62dbd 100644 --- a/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift +++ b/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift @@ -214,6 +214,12 @@ extension MainViewController: NavigateProtocol { closeWheel(indexPath: indexPath) } + func callHistory(indexPath: IndexPath?) { + presenter.callHistory() + closeWheel(indexPath: indexPath) + } + + // MARK: - Contact Actions func showListContacts(indexPath: IndexPath?) { presenter.showMyContacts() diff --git a/Nynja/Modules/Main/View/NavigateProtocol.swift b/Nynja/Modules/Main/View/NavigateProtocol.swift index 8b2368203..973f78851 100644 --- a/Nynja/Modules/Main/View/NavigateProtocol.swift +++ b/Nynja/Modules/Main/View/NavigateProtocol.swift @@ -70,6 +70,7 @@ protocol SecondLevelNavigateProtocol: class { func conferenceVoiceCall(indexPath: IndexPath?) func conferenceVideoCall(indexPath: IndexPath?) + func callHistory(indexPath: IndexPath?) // MARK: - Contact Actions diff --git a/Nynja/Modules/Main/WireFrame/MainWireframe.swift b/Nynja/Modules/Main/WireFrame/MainWireframe.swift index 68d23ece9..0e8e1d299 100644 --- a/Nynja/Modules/Main/WireFrame/MainWireframe.swift +++ b/Nynja/Modules/Main/WireFrame/MainWireframe.swift @@ -473,10 +473,11 @@ class MainWireFrame: MainWireFrameProtocol, NynjaCommunicatorServiceDelegate { } func showAddParticipantsToCreateConferenceCall() { + AddParticipantsWireFrame().presentAddParticipants(navigation: contentNavigation!, main: self, selectedContacts: [], delegate: self.external, mode: .createConferenceCall, members: [], room: nil) + } + func showCallHistory() { CallHistoryWireFrame().presentCallHistory(navigation: contentNavigation!, main: self) - -// AddParticipantsWireFrame().presentAddParticipants(navigation: contentNavigation!, main: self, selectedContacts: [], delegate: self.external, mode: .createConferenceCall, members: [], room: nil) } func presentLeaveVoiceMessageViewForContact(contact:Contact) { diff --git a/Nynja/Resources/Assets.xcassets/callHistory/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callHistory/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_video.imageset/Contents.json new file mode 100644 index 000000000..156d8b331 --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_video.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Icons_Message_ic_canceled_video_call.pdf", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_video.imageset/Icons_Message_ic_canceled_video_call.pdf b/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_video.imageset/Icons_Message_ic_canceled_video_call.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e4c7c89e484ac4f4fae9019f869f9c8aab022391 GIT binary patch literal 4110 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 literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_voice.imageset/Contents.json new file mode 100644 index 000000000..acc23756f --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_voice.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Icons_Message_ic_сanceled_voice_call.pdf", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_voice.imageset/Icons_Message_ic_\321\201anceled_voice_call.pdf" "b/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_voice.imageset/Icons_Message_ic_\321\201anceled_voice_call.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..a0747a18fe60db9131b710b239943af4f8b61936 GIT binary patch literal 4931 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 GH2(oLhls@h literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_video.imageset/Contents.json new file mode 100644 index 000000000..dbc1fe921 --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_video.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Icons_Message_ic_incoming_video_call.pdf", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_video.imageset/Icons_Message_ic_incoming_video_call.pdf b/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_video.imageset/Icons_Message_ic_incoming_video_call.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b17a6fc4c329982887937537b1e8acbd14c6eb56 GIT binary patch literal 4058 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 literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_voice.imageset/Contents.json new file mode 100644 index 000000000..e450ee5b7 --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_voice.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Icons_Message_ic_incoming_voice_call.pdf", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_voice.imageset/Icons_Message_ic_incoming_voice_call.pdf b/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_voice.imageset/Icons_Message_ic_incoming_voice_call.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6f84db8a6b74abe04ed12f73de385f408e94056c GIT binary patch literal 4874 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 literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_video.imageset/Contents.json new file mode 100644 index 000000000..c4458f7c1 --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_video.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Icons_Message_ic_missed_video_call.pdf", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_video.imageset/Icons_Message_ic_missed_video_call.pdf b/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_video.imageset/Icons_Message_ic_missed_video_call.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f9816664b634238fc88494f85257eb7842b840e5 GIT binary patch literal 4106 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 literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_voice.imageset/Contents.json new file mode 100644 index 000000000..57ad928fa --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_voice.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Icons_Message_ic_missed_voice_call.pdf", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_voice.imageset/Icons_Message_ic_missed_voice_call.pdf b/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_voice.imageset/Icons_Message_ic_missed_voice_call.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1ae42c443bc71619e78973633e511994aaa1d81d GIT binary patch literal 4929 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 literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_video.imageset/Contents.json new file mode 100644 index 000000000..6ff0c0f2e --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_video.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Icons_Message_ic_no_answer_video_call.pdf", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_video.imageset/Icons_Message_ic_no_answer_video_call.pdf b/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_video.imageset/Icons_Message_ic_no_answer_video_call.pdf new file mode 100644 index 0000000000000000000000000000000000000000..28af7c1d517b145e4ec980228bc1588874ab6af3 GIT binary patch literal 4038 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 UQfvJ9Ly$;>7>JKg39StJ4+Y*>HUIzs literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_video.imageset/Contents.json new file mode 100644 index 000000000..38b545a97 --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_video.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Icons_Message_ic_outgoing_video_call.pdf", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_video.imageset/Icons_Message_ic_outgoing_video_call.pdf b/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_video.imageset/Icons_Message_ic_outgoing_video_call.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3f9199449e04a33fdc10eca41292a67d7537f207 GIT binary patch literal 4093 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 literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_voice.imageset/Contents.json new file mode 100644 index 000000000..9bd484450 --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_voice.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Icons_Message_ic_outgoing_voice_call.pdf", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_voice.imageset/Icons_Message_ic_outgoing_voice_call.pdf b/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_voice.imageset/Icons_Message_ic_outgoing_voice_call.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fe0a06c02c260d38d887fecaebe8827fb31a9a9e GIT binary patch literal 4926 zcmai&2T)U6*M@0Q0#c+2B19xqDG3P>=^aF+DZM2SAXKFnks?K!bSY8VLi8{bs&1XL3&7z0S(Y*=yc;_6F&ws0o8b!~vid{3d>>VC(6p zmR0~1CUbF9&RXv zGr)&9EJe|UN0LT$*Aq}iYQz9aOdOVLZiH@lDvXUfdkSEE$Mo*K#-|#C z^rR0V221$YMkTnUb=|{^+HmCSsFu1y(mtim&uCM?i8eCVC^NvNY9BaU4nE{{8XVev zXl@YO4%a|9?ZUcBk9Nu%;ilFjA3)tTPgoco(%+~@7x{GDAPnxyBx~S?CZt$MXYL(JHibOgG=WUcANs1qXoY_GAjPY zEf-zrF?%h!QZ^;{pbyijnPgyM>OJOk&Ov8eE>XvLze|;h9?K`Jgp(GKGp&{xYvmQX zs?RDr)uU^A#n8YY^5a1lhdz&I^`h(>&U(MJ1kM1nOl{sl!<1JJqebNCo1OU}=h#dq z?z=flO6vpuWJ^M~3Jm5xgI^UjC3M9EVDN9A>0?Eu$D_!p*F#*4$wF0pp6s^UqIhvX(ZC`Oe9h+8mZVUx=#jd1M6B-uRZ^Rj zkVQ6Z>-ol3i?e6lg1$w%|M)fjrUI#lYEQGiBAQz-(2UntQdx4bEITxK&Gp|}sw4ub zWB3+qi4SGS)1y_Pc6dc zOiZ`BQY8UEP@#i6W2wBAPBwcIi}@Luk4&`BHb&VGDCqA{G-Z{XVHmrlTNjWio42q))NX1sV6 zjeg|+3U|9>Q2^T)v)-T?y&)IWbm*xl%HkJ5PeL66?iTWvp=<^=bJZrWQ_`~w+ly_; ze#P!LO_9WImA_k(zLhjf;y?%=Oi|JN5oSzx zwOzokq%w9Wg0__WaVYYYkJgSze<7xm2-l?O-i`r$JF?SIjbNR?&pG!%0=6MibnFNb z*LqIo<@-~>b9JwEM|`F7eOz(tfsWju=X~vP{_@pv;`4onb?PD{M;G_Z)@1}IB6eP` z%FflCOpkk)`X7f!_%bT$hqFgd@wDn|XL)nZ3r#{>=AfAmx4!3!9Ltu`t*jh;n#rtM zUCF^tqAfcs@B@?Q!Tlltl#9(TJ0jejy4b08onFCUn8fMm={@8Rhr8u_2L%+>LD>EL zbVIp#0LA}uJ3W-UtEZba${i^2m!RzG;z1a92c9~l-l_Bb%6B^c+c9?$1w6G>Wp^-8@>haCa!CD=5sBR^kOBkpU!auLEG$pRKR{|4Q4XkNX;M}lJHPoFO@TD zObh}BHn*CH)g!pARhg(Cgdj(#HtBU*n{`!G@#8U$RBL6ht%;1|Hsi_BxtfttyS0Fk zIwGB;5VCh3M#MqTTqCB{rDn5pj9o3eBU%0AgGX4|^z=fF)~cOV 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 literal 0 HcmV?d00001 diff --git a/Nynja/Resources/en.lproj/Localizable.strings b/Nynja/Resources/en.lproj/Localizable.strings index e1193654a..2b5c91758 100644 --- a/Nynja/Resources/en.lproj/Localizable.strings +++ b/Nynja/Resources/en.lproj/Localizable.strings @@ -548,6 +548,7 @@ "wheel_item_voiceCall"="Voice Call"; "wheel_item_voiceGroupCall"="Voice Group"; "wheel_item_videoCall"="Video Call"; +"wheel_item_callHistory"="Call History"; "wheel_item_videoGroupCall"="Video Group"; "wheel_item_contact"="Contact"; "wheel_item_event"="Event"; -- GitLab From bf4a02fcbd62fefd856f4a4929edb511c32c7e06 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Fri, 9 Nov 2018 16:43:17 +0200 Subject: [PATCH 05/59] Polishing call history UI --- Nynja.xcodeproj/project.pbxproj | 4 + Nynja/Generated/AssetsConstants.swift | 2 + Nynja/Generated/LocalizableConstants.swift | 2 + .../View/CallHistoryViewController.swift | 21 +++++- .../TableView/CallHistoryDataController.swift | 8 +- .../TableView/CallHistoryDataSource.swift | 2 +- .../View/TableView/EmptyCallHistoryView.swift | 69 ++++++++++++++++++ .../Contents.json | 12 +++ .../ic_search_empty.pdf | Bin 0 -> 5010 bytes .../ic_canceled_video.imageset/Contents.json | 11 +-- Nynja/Resources/en.lproj/Localizable.strings | 2 + 11 files changed, 117 insertions(+), 16 deletions(-) create mode 100644 Nynja/Modules/CallHistory/View/TableView/EmptyCallHistoryView.swift create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_call_history_empty.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callHistory/ic_call_history_empty.imageset/ic_search_empty.pdf diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index c7406d29b..f30d31653 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -1184,6 +1184,7 @@ 9B51799A21834B95006E1A4B /* CallHistoryDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */; }; 9B51799C21834BA7006E1A4B /* CallHistoryDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */; }; 9B804AB9219326A1000606EC /* CallHistoryDataController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804AB8219326A1000606EC /* CallHistoryDataController.swift */; }; + 9B804ABB2195A93E000606EC /* EmptyCallHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804ABA2195A93E000606EC /* EmptyCallHistoryView.swift */; }; 9B81AD92215A5EEA00993A8C /* ActiveSpeakerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B81AD91215A5EEA00993A8C /* ActiveSpeakerView.swift */; }; 9B96705F214BE3FE0058E98F /* MultiPageCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B96705E214BE3FE0058E98F /* MultiPageCollectionView.swift */; }; 9B967098215151760058E98F /* LeaveVoiceMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B967097215151760058E98F /* LeaveVoiceMessageViewController.swift */; }; @@ -3403,6 +3404,7 @@ 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDelegate.swift; sourceTree = ""; }; 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDataSource.swift; sourceTree = ""; }; 9B804AB8219326A1000606EC /* CallHistoryDataController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDataController.swift; sourceTree = ""; }; + 9B804ABA2195A93E000606EC /* EmptyCallHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyCallHistoryView.swift; sourceTree = ""; }; 9B810991D7143259040DCA31 /* LanguageSettingsViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LanguageSettingsViewController.swift; sourceTree = ""; }; 9B81AD91215A5EEA00993A8C /* ActiveSpeakerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSpeakerView.swift; sourceTree = ""; }; 9B96705E214BE3FE0058E98F /* MultiPageCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiPageCollectionView.swift; sourceTree = ""; }; @@ -9444,6 +9446,7 @@ 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */, 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */, 9B804AB8219326A1000606EC /* CallHistoryDataController.swift */, + 9B804ABA2195A93E000606EC /* EmptyCallHistoryView.swift */, ); path = TableView; sourceTree = ""; @@ -15403,6 +15406,7 @@ E785EF2A1FB9D99400F0C689 /* PinView.swift in Sources */, A42D51D0206A361400EEB952 /* Star.swift in Sources */, 85C16C3E20D2794500EDB77E /* BubbleImageSizeCalculatable.swift in Sources */, + 9B804ABB2195A93E000606EC /* EmptyCallHistoryView.swift in Sources */, A43B25D620AB1EE400FF8107 /* NewChannelPresenter.swift in Sources */, E7598F691FA1D8B90082FBE7 /* ProfileScheduledMesssageCellLayout.swift in Sources */, E7C1D3681F683A7D007D4E1E /* MainNavigationItem.swift in Sources */, diff --git a/Nynja/Generated/AssetsConstants.swift b/Nynja/Generated/AssetsConstants.swift index 6b4c33a25..7e5d35b69 100644 --- a/Nynja/Generated/AssetsConstants.swift +++ b/Nynja/Generated/AssetsConstants.swift @@ -659,6 +659,8 @@ internal extension Image { /// "btn_wheel_done" static var btnWheelDone: ImageAsset { return ImageAsset(name: "btn_wheel_done") } enum CallHistory { + /// "ic_call_history_empty" + static var icCallHistoryEmpty: ImageAsset { return ImageAsset(name: "ic_call_history_empty") } /// "ic_canceled_video" static var icCanceledVideo: ImageAsset { return ImageAsset(name: "ic_canceled_video") } /// "ic_canceled_voice" diff --git a/Nynja/Generated/LocalizableConstants.swift b/Nynja/Generated/LocalizableConstants.swift index 9f7272a45..c72e01f51 100644 --- a/Nynja/Generated/LocalizableConstants.swift +++ b/Nynja/Generated/LocalizableConstants.swift @@ -138,6 +138,8 @@ internal extension String { static var callHistoryButtonMissedTitle: String { return localizable.tr("Localizable", "call_history_button_missed_title") } /// Outgoing static var callHistoryButtonOutgoingTitle: String { return localizable.tr("Localizable", "call_history_button_outgoing_title") } + /// Call history is empty + static var callHistoryEmptyTitle: String { return localizable.tr("Localizable", "call_history_empty_title") } /// call history static var callHistoryTitle: String { return localizable.tr("Localizable", "call_history_title") } /// Incoming Voice Call... diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index 80a5fd1d0..b811b15d9 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -58,7 +58,10 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe self.dataController?.buildDataSourceWith(mode: self.callHistoryMode, completionHandler: { (dataSource) -> Void in cleanUpBeforeReloading() tableViewDataSource = CallHistoryDataSource(tableView:tableView, dataSource: dataSource) - tableViewDataSource?.delegate = self + tableViewDataSource?.delegate = self + + self.emptyHistoryView.should(shown: dataSource.isEmpty) + self.tableView.isHidden = dataSource.isEmpty self.tableView.reloadData() }) } @@ -94,6 +97,22 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe return width } + private lazy var emptyHistoryView: EmptyCallHistoryView = { + let ehv = EmptyCallHistoryView() + + ehv.isHidden = false + ehv.backgroundColor = .clear + self.view.addSubview(ehv) + + ehv.snp.makeConstraints { (make) in + make.top.equalTo(navigationView.snp.bottom) + make.left.right.equalToSuperview() + make.bottom.equalTo(scrollView.snp.top).offset(-2*Constraints.offset) + } + + return ehv + }() + private lazy var tableView: UITableView = { let tblView = UITableView.default diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift index 5731954eb..12a777358 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift @@ -15,10 +15,10 @@ class CallHistoryDataController: NSObject { func buildDataSourceWith(mode: CallHistoryMode, completionHandler: CompletionHandler) { let dataSource = NSMutableArray() - - dataSource.add(CallHistoryCellModel()) - dataSource.add(CallHistoryCellModel()) - dataSource.add(CallHistoryCellModel()) + +// for index in 1...50 { +// dataSource.add(CallHistoryCellModel()) +// } completionHandler((dataSource as? [CallHistoryCellModel])!) } diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift index 537c0639e..d8931d073 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift @@ -38,7 +38,7 @@ class CallHistoryDataSource: NSObject, CallHistoryTableViewCellDelegate { extension CallHistoryDataSource: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return 50 //self.dataSource.count + return self.dataSource.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { diff --git a/Nynja/Modules/CallHistory/View/TableView/EmptyCallHistoryView.swift b/Nynja/Modules/CallHistory/View/TableView/EmptyCallHistoryView.swift new file mode 100644 index 000000000..486fe8235 --- /dev/null +++ b/Nynja/Modules/CallHistory/View/TableView/EmptyCallHistoryView.swift @@ -0,0 +1,69 @@ +// +// EmptyCallHistoryView.swift +// Nynja +// +// Created by Bozhko Terziev on 9.11.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +class EmptyCallHistoryView: UIView { + + private lazy var callHistoryImageView: UIImageView = { + let iv = UIImageView() + iv.image = UIImage.nynja.CallHistory.icCallHistoryEmpty.image + self.addSubview(iv) + iv.snp.makeConstraints { (make) in + make.width.equalTo(Constraints.image.width) + make.height.equalTo(Constraints.image.height) + make.centerY.equalToSuperview().offset(-Constraints.image.height/2) + make.centerX.equalToSuperview() + } + + return iv + }() + + private lazy var label: UILabel = { + let label = UILabel() + label.textAlignment = .center + label.font = UIFont.makeFont(with: FontFamily.NotoSans.medium.name, height: 23.0) + label.textColor = UIColor.nynja.lightGray + label.backgroundColor = UIColor.nynja.clear + label.text = String.localizable.callHistoryEmptyTitle + + self.addSubview(label) + label.snp.makeConstraints { (make) in + make.top.equalTo(callHistoryImageView.snp.bottom).offset(Constraints.label.topOffset) + make.centerX.equalToSuperview() + make.left.greaterThanOrEqualToSuperview().offset(Constraints.label.sideOffset) + make.right.lessThanOrEqualToSuperview().offset(-Constraints.label.sideOffset) + } + + return label + }() + + func should(shown:Bool) { + callHistoryImageView.isHidden = !shown + label.isHidden = !shown + self.isHidden = !shown + } +} + +extension EmptyCallHistoryView { + + struct Constraints { + + struct image { + static let width = 64.0 + static let height = 64.0 + } + + struct label { + static let sideOffset = 16.0 + static let topOffset = 20.0 + + } + } +} + diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_call_history_empty.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_call_history_empty.imageset/Contents.json new file mode 100644 index 000000000..22438d131 --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_call_history_empty.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_search_empty.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_call_history_empty.imageset/ic_search_empty.pdf b/Nynja/Resources/Assets.xcassets/callHistory/ic_call_history_empty.imageset/ic_search_empty.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a29fa749c8808208926e9152f24dac0014f76d3a GIT binary patch literal 5010 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 literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_video.imageset/Contents.json index 156d8b331..1c4edfe23 100644 --- a/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_video.imageset/Contents.json +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_video.imageset/Contents.json @@ -2,16 +2,7 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icons_Message_ic_canceled_video_call.pdf", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" + "filename" : "Icons_Message_ic_canceled_video_call.pdf" } ], "info" : { diff --git a/Nynja/Resources/en.lproj/Localizable.strings b/Nynja/Resources/en.lproj/Localizable.strings index 2b5c91758..835c60414 100644 --- a/Nynja/Resources/en.lproj/Localizable.strings +++ b/Nynja/Resources/en.lproj/Localizable.strings @@ -994,3 +994,5 @@ "call_history_button_outgoing_title" = "Outgoing"; "call_history_button_incoming_title" = "Incoming"; "call_history_button_missed_title" = "Missed"; +"call_history_empty_title" = "Call history is empty"; + -- GitLab From 47c9702bb1889df75bf2863361e601a506bf8110 Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Tue, 13 Nov 2018 12:47:54 +0200 Subject: [PATCH 06/59] Changes to support Call History API from the SDK --- Nynja.xcodeproj/project.pbxproj | 60 ++++++++++++++++++- .../View/TableView/CallHistoryCellModel.swift | 21 +++++++ .../TableView/CallHistoryDataController.swift | 26 ++++++-- .../NynjaCalls/NynjaCommunicatorService.swift | 22 +++++++ Podfile | 2 +- Podfile.lock | 7 +-- 6 files changed, 125 insertions(+), 13 deletions(-) diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index f30d31653..b4c38ed16 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -726,6 +726,8 @@ 5A48445F21178E33000657ED /* AlertTextFieldViewControllerLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A48445E21178E33000657ED /* AlertTextFieldViewControllerLayout.swift */; }; 5A6237362268CC9BD4792230 /* EditUsernameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B772E08B9E40EB48DD87082 /* EditUsernameViewController.swift */; }; 5AD8110B5B87B1AB9F1C5B52 /* CreateGroupPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CBACEAABEE65D7EC5572C4E /* CreateGroupPresenter.swift */; }; + 5B4F14102194A8810083E105 /* NynjaSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B4F13FE219470F70083E105 /* NynjaSDK.framework */; }; + 5B4F14112194A8810083E105 /* NynjaSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5B4F13FE219470F70083E105 /* NynjaSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 5B5EE777EF301CFC1FDCF307 /* CreateGroupInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFC76E2B3DD0BCA0A622A5CD /* CreateGroupInteractor.swift */; }; 5BBEF53C212DE09F00F10768 /* ringback.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5BBEF53B212DE09F00F10768 /* ringback.m4a */; }; 5BC1D37920D3B4A8002A44B3 /* GroupCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC1D37420D3B4A6002A44B3 /* GroupCollectionViewCell.swift */; }; @@ -2308,6 +2310,27 @@ remoteGlobalIDString = 8514D4C020EE27080002378A; remoteInfo = NynjaUIKit; }; + 5B4F13FD219470F70083E105 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5B4F13F8219470F70083E105 /* sdk.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 5B87E4082088DE100063D5BB; + remoteInfo = NynjaSDK; + }; + 5B4F140E2194A80F0083E105 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5B4F13F8219470F70083E105 /* sdk.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 5B87E4072088DE100063D5BB; + remoteInfo = NynjaSDK; + }; + 5B4F14122194A8810083E105 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5B4F13F8219470F70083E105 /* sdk.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 5B87E4072088DE100063D5BB; + remoteInfo = NynjaSDK; + }; 5B80A2842102177B0008D6AD /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 85C65C6620EE58EC00C468B2 /* NynjaUIKit.xcodeproj */; @@ -2379,6 +2402,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + 5B4F14112194A8810083E105 /* NynjaSDK.framework in Embed Frameworks */, 85C65C7520EE5A5A00C468B2 /* NynjaUIKit.framework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -2987,6 +3011,7 @@ 5A48445E21178E33000657ED /* AlertTextFieldViewControllerLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertTextFieldViewControllerLayout.swift; sourceTree = ""; }; 5AEEB3D82E9CF02760DA4CE7 /* Pods-Nynja-Share.channels.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Nynja-Share.channels.xcconfig"; path = "Pods/Target Support Files/Pods-Nynja-Share/Pods-Nynja-Share.channels.xcconfig"; sourceTree = ""; }; 5B377AA90A6B6BA0120C31F1 /* EditProfileProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EditProfileProtocols.swift; sourceTree = ""; }; + 5B4F13F8219470F70083E105 /* sdk.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = sdk.xcodeproj; path = "../mobile-sdk/src/sdk/ios/sdk.xcodeproj"; sourceTree = ""; }; 5BBEF53B212DE09F00F10768 /* ringback.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = ringback.m4a; sourceTree = ""; }; 5BC1D37420D3B4A6002A44B3 /* GroupCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupCollectionViewCell.swift; sourceTree = ""; }; 5BC1D37620D3B4A7002A44B3 /* GroupAddParticipantsCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupAddParticipantsCollectionViewCell.swift; sourceTree = ""; }; @@ -4345,6 +4370,7 @@ files = ( 85C65C7420EE5A5A00C468B2 /* NynjaUIKit.framework in Frameworks */, 63E6537BBBD814F6DF3DC589 /* Pods_Nynja.framework in Frameworks */, + 5B4F14102194A8810083E105 /* NynjaSDK.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6140,6 +6166,7 @@ 3ABCE8E41EC9330D00A80B15 = { isa = PBXGroup; children = ( + 5B4F13F8219470F70083E105 /* sdk.xcodeproj */, 85C65C6620EE58EC00C468B2 /* NynjaUIKit.xcodeproj */, A4A242442060370E00B0A804 /* Shared */, 3ABCE8EF1EC9330D00A80B15 /* Nynja */, @@ -7296,6 +7323,14 @@ path = WireFrame; sourceTree = ""; }; + 5B4F13F9219470F70083E105 /* Products */ = { + isa = PBXGroup; + children = ( + 5B4F13FE219470F70083E105 /* NynjaSDK.framework */, + ); + name = Products; + sourceTree = ""; + }; 5B80A2812102177B0008D6AD /* Products */ = { isa = PBXGroup; children = ( @@ -14067,9 +14102,11 @@ buildRules = ( ); dependencies = ( + 5B4F140F2194A80F0083E105 /* PBXTargetDependency */, 264FFA921FC590580028243D /* PBXTargetDependency */, 85C65C7220EE5A2800C468B2 /* PBXTargetDependency */, 85C65C7720EE5A5A00C468B2 /* PBXTargetDependency */, + 5B4F14132194A8810083E105 /* PBXTargetDependency */, ); name = Nynja; productName = Nynja; @@ -14185,6 +14222,10 @@ ProductGroup = 5B80A2812102177B0008D6AD /* Products */; ProjectRef = 85C65C6620EE58EC00C468B2 /* NynjaUIKit.xcodeproj */; }, + { + ProductGroup = 5B4F13F9219470F70083E105 /* Products */; + ProjectRef = 5B4F13F8219470F70083E105 /* sdk.xcodeproj */; + }, ); projectRoot = ""; targets = ( @@ -14197,6 +14238,13 @@ /* End PBXProject section */ /* Begin PBXReferenceProxy section */ + 5B4F13FE219470F70083E105 /* NynjaSDK.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = NynjaSDK.framework; + remoteRef = 5B4F13FD219470F70083E105 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 5B80A2852102177B0008D6AD /* NynjaUIKit.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; @@ -14381,7 +14429,6 @@ "${BUILT_PRODUCTS_DIR}/MDFTextAccessibility/MDFTextAccessibility.framework", "${BUILT_PRODUCTS_DIR}/MaterialComponents/MaterialComponents.framework", "${BUILT_PRODUCTS_DIR}/MulticastDelegateSwift/MulticastDelegateSwift.framework", - "${PODS_ROOT}/NynjaSDK/NynjaSDK.framework", "${BUILT_PRODUCTS_DIR}/QRCode/QRCode.framework", "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", "${BUILT_PRODUCTS_DIR}/SQLCipher/SQLCipher.framework", @@ -14406,7 +14453,6 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MDFTextAccessibility.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MaterialComponents.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MulticastDelegateSwift.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NynjaSDK.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/QRCode.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SQLCipher.framework", @@ -16831,6 +16877,16 @@ name = NynjaUIKit; targetProxy = 26DC81EC213838CD003E5FD9 /* PBXContainerItemProxy */; }; + 5B4F140F2194A80F0083E105 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = NynjaSDK; + targetProxy = 5B4F140E2194A80F0083E105 /* PBXContainerItemProxy */; + }; + 5B4F14132194A8810083E105 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = NynjaSDK; + targetProxy = 5B4F14122194A8810083E105 /* PBXContainerItemProxy */; + }; 85C65C7220EE5A2800C468B2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = NynjaUIKit; diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift index 321d58b3e..661548ebd 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift @@ -10,5 +10,26 @@ import UIKit class CallHistoryCellModel: NSObject { + private var _log: NYNCallLog + var identifier: String {get{return log.identifier}} + var kind: NYNCallLogKind {get{return log.kind}} + var status: NYNCallLogStatus {get{return log.status}} + var direction: NYNCallLogDir {get{return log.direction}} + var media: NYNCallLogMedia {get{return log.media}} + + var subject: String {get{return log.subject}} + var startTime: Date {get{return log.startTime}} + var duration: UInt {get{return log.duration}} + var participantsCount: UInt {get{return log.participantsCount}} + + init(log: NYNCallLog) { + self._log = log + } + + var log:NYNCallLog { + get { + return _log + } + } } diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift index 12a777358..532d6f594 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift @@ -15,10 +15,28 @@ class CallHistoryDataController: NSObject { func buildDataSourceWith(mode: CallHistoryMode, completionHandler: CompletionHandler) { let dataSource = NSMutableArray() - -// for index in 1...50 { -// dataSource.add(CallHistoryCellModel()) -// } + var results:NYNCallLogFetchedResults? = nil + + switch mode { + case .all: + results = NynjaCommunicatorService.sharedInstance.callHistoryFetchAll() + case .missed: + results = NynjaCommunicatorService.sharedInstance.callHistoryFetchMissed() + case .outgoing: + results = NynjaCommunicatorService.sharedInstance.callHistoryFetchOutgoing() + case .incoming: + results = NynjaCommunicatorService.sharedInstance.callHistoryFetchIncoming() + } + + if let r = results { + let count = r.count() + for i in 0...count { + if let log = r.object(at: i) { + let model:CallHistoryCellModel = CallHistoryCellModel(log: log) + dataSource.add(model) + } + } + } completionHandler((dataSource as? [CallHistoryCellModel])!) } diff --git a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift index 39a8fb5cf..c0795f10f 100644 --- a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift +++ b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift @@ -56,6 +56,12 @@ extension NynjaCallDelegate { } class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDelegate, NYNCallManagerDelegate, ConnectionServiceDelegate { + func callDidPauseAudio(_ call: NYNCall) { + } + + func callDidResumeAudio(_ call: NYNCall) { + } + private var initialized: Bool = false private let storageService = StorageService.sharedInstance @@ -461,6 +467,22 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele } } + func callHistoryFetchAll() -> NYNCallLogFetchedResults? { + return self.nynComm.getCallHistoryManager().fetchAll() + } + + func callHistoryFetchMissed() -> NYNCallLogFetchedResults? { + return self.nynComm.getCallHistoryManager().fetchMissed() + } + + func callHistoryFetchOutgoing() -> NYNCallLogFetchedResults? { + return self.nynComm.getCallHistoryManager().fetchOutgoing() + } + + func callHistoryFetchIncoming() -> NYNCallLogFetchedResults? { + return self.nynComm.getCallHistoryManager().fetchIncoming() + } + //MARK: Helpers func getMySelf() -> Contact? { diff --git a/Podfile b/Podfile index a50c4ef09..b947aefb5 100644 --- a/Podfile +++ b/Podfile @@ -39,7 +39,7 @@ def commonPodsForNynja pod 'MaterialComponents/FlexibleHeader', '= 55.3.0' pod 'JTAppleCalendar', '= 7.1.5' - pod 'NynjaSDK', '= 1.7.1' + #pod 'NynjaSDK', '= 1.7.1' pod 'CryptoSwift', '= 0.10.0' diff --git a/Podfile.lock b/Podfile.lock index 839be3a78..6107a0104 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -62,7 +62,6 @@ PODS: - MaterialComponents/private/Application - MDFTextAccessibility (1.2.0) - MulticastDelegateSwift (2.1.1) - - NynjaSDK (1.7.1) - QRCode (2.0) - SDWebImage (4.4.2): - SDWebImage/Core (= 4.4.2) @@ -95,7 +94,6 @@ DEPENDENCIES: - libPhoneNumber-iOS (= 0.9.13) - MaterialComponents/FlexibleHeader (= 55.3.0) - MulticastDelegateSwift (= 2.1.1) - - NynjaSDK (= 1.7.1) - QRCode (= 2.0) - SDWebImage (= 4.4.2) - SnapKit (= 4.0.0) @@ -135,8 +133,6 @@ SPEC REPOS: - SwiftyJSON - SwiftyTimer - TestFairy - https://nynjagroup.jfrog.io/nynjagroup/api/pods/cocoapods-local: - - NynjaSDK EXTERNAL SOURCES: CocoaLumberjack: @@ -174,7 +170,6 @@ SPEC CHECKSUMS: MaterialComponents: 915f4e844400a35db3ea4c710a9af40aa8bcb093 MDFTextAccessibility: 94098925e0853551c5a311ce7c1ecefbe297cdb6 MulticastDelegateSwift: 93eb077c24f50574b3f8a3f23bf71be6de6e3b41 - NynjaSDK: 77eed21eba9e95484230fc0edf1ae9cd00a30e6b QRCode: f98a1886c8f37523704a7512a4c0cd45b34c18a4 SDWebImage: 624d6e296c69b244bcede364c72ae0430ac14681 SnapKit: a42d492c16e80209130a3379f73596c3454b7694 @@ -183,6 +178,6 @@ SPEC CHECKSUMS: SwiftyTimer: 2efd74b060d69ad4f1496baf5bbedbe132125fcf TestFairy: 842f8ddc45477b208eb85326b0418047b40f7137 -PODFILE CHECKSUM: f206ab413c7bb2af1ba8a5ce0e66489b21851a6f +PODFILE CHECKSUM: 5d312dcd3c6dd8e289b64d8cf5986b936b364e88 COCOAPODS: 1.5.3 -- GitLab From ca921e10264a8a330ad49079f3cbaca8cdb6cf9f Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Tue, 13 Nov 2018 20:13:33 +0200 Subject: [PATCH 07/59] Partial work for call history is done (bussines logic and UI) --- Nynja/Generated/LocalizableConstants.swift | 14 +++ .../View/TableView/CallHistoryCellModel.swift | 95 +++++++++++++++++++ .../TableView/CallHistoryDataSource.swift | 2 +- .../TableView/CallHistoryTableViewCell.swift | 35 +++---- .../ic_canceled_voice.imageset/Contents.json | 11 +-- .../ic_incoming_video.imageset/Contents.json | 11 +-- .../ic_incoming_voice.imageset/Contents.json | 11 +-- .../ic_missed_video.imageset/Contents.json | 11 +-- .../ic_missed_voice.imageset/Contents.json | 11 +-- .../ic_no_answer_video.imageset/Contents.json | 11 +-- .../ic_no_answer_voice.imageset/Contents.json | 11 +-- .../ic_outgoing_video.imageset/Contents.json | 11 +-- .../ic_outgoing_voice.imageset/Contents.json | 11 +-- Nynja/Resources/en.lproj/Localizable.strings | 8 ++ 14 files changed, 145 insertions(+), 108 deletions(-) diff --git a/Nynja/Generated/LocalizableConstants.swift b/Nynja/Generated/LocalizableConstants.swift index c72e01f51..25dcdebbb 100644 --- a/Nynja/Generated/LocalizableConstants.swift +++ b/Nynja/Generated/LocalizableConstants.swift @@ -140,8 +140,22 @@ internal extension String { static var callHistoryButtonOutgoingTitle: String { return localizable.tr("Localizable", "call_history_button_outgoing_title") } /// Call history is empty static var callHistoryEmptyTitle: String { return localizable.tr("Localizable", "call_history_empty_title") } + /// Incoming Call + static var callHistoryLogDirInbound: String { return localizable.tr("Localizable", "call_history_log_dir_inbound") } + /// Outgoing Call + static var callHistoryLogDirOutbound: String { return localizable.tr("Localizable", "call_history_log_dir_outbound") } + /// Canceled Call + static var callHistoryLogStatusCanceled: String { return localizable.tr("Localizable", "call_history_log_status_canceled") } + /// Declined Call + static var callHistoryLogStatusDeclined: String { return localizable.tr("Localizable", "call_history_log_status_declined") } + /// Missed Call + static var callHistoryLogStatusMissed: String { return localizable.tr("Localizable", "call_history_log_status_missed") } + /// Unanswered Call + static var callHistoryLogStatusUnanswered: String { return localizable.tr("Localizable", "call_history_log_status_unanswered") } /// call history static var callHistoryTitle: String { return localizable.tr("Localizable", "call_history_title") } + /// Yesterday + static var callHistoryYesterdayTitle: String { return localizable.tr("Localizable", "call_history_yesterday_title") } /// Incoming Voice Call... static var callIncoming: String { return localizable.tr("Localizable", "call_incoming") } /// Audio Conference diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift index 661548ebd..6d67c3220 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift @@ -12,6 +12,27 @@ class CallHistoryCellModel: NSObject { private var _log: NYNCallLog + static let todayDateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateStyle = .none + formatter.timeStyle = .short + return formatter + }() + + static let lastWeekDateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "EEEE" + formatter.timeZone = TimeZone.current + return formatter + }() + + static let dateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateStyle = .short + formatter.timeStyle = .none + return formatter + }() + var identifier: String {get{return log.identifier}} var kind: NYNCallLogKind {get{return log.kind}} var status: NYNCallLogStatus {get{return log.status}} @@ -32,4 +53,78 @@ class CallHistoryCellModel: NSObject { return _log } } + + class func isDateInLastWeek(date:Date) ->Bool { + let calendar = NSCalendar.current + let unitFlags = Set([.day]) + let components = calendar.dateComponents(unitFlags, from: date, to: Date()) + var isInLastWeek:Bool = false + + if let d = components.day { + isInLastWeek = (d < 7) + } + + return isInLastWeek + } + + class func stringFrom(date:Date) ->String { + if Calendar.current.isDateInToday(date) { + return todayDateFormatter.string(from:date) + } else if Calendar.current.isDateInYesterday(date) { + return String.localizable.callHistoryYesterdayTitle + } else if CallHistoryCellModel.isDateInLastWeek(date:date) { + return lastWeekDateFormatter.string(from:date) + } else { + return dateFormatter.string(from:date) + } + } + + class func stringFrom(status:NYNCallLogStatus, direction:NYNCallLogDir)-> String { + switch status { + case .ANSWERED: + if direction == .INBOUND { + return String.localizable.callHistoryLogDirInbound + } else { + return String.localizable.callHistoryLogDirOutbound + } + case .CANCELED: + return String.localizable.callHistoryLogStatusCanceled + case .DECLINED: + return String.localizable.callHistoryLogStatusDeclined + case .MISSED: + return String.localizable.callHistoryLogStatusMissed + case .UNANSWERED: + return String.localizable.callHistoryLogStatusUnanswered + } + } + +class func imageFrom(status:NYNCallLogStatus, media:NYNCallLogMedia, direction:NYNCallLogDir)-> UIImage { + if media == .AUDIO { + switch status { + case .ANSWERED: + return (direction == .INBOUND) ? UIImage.nynja.CallHistory.icIncomingVoice.image : UIImage.nynja.CallHistory.icOutgoingVoice.image + case .CANCELED: + return UIImage.nynja.CallHistory.icCanceledVoice.image + case .DECLINED: + return UIImage.nynja.CallHistory.icMissedVoice.image + case .MISSED: + return UIImage.nynja.CallHistory.icMissedVoice.image + case .UNANSWERED: + return UIImage.nynja.CallHistory.icNoAnswerVoice.image + } + } else { + switch status { + case .ANSWERED: + return (direction == .INBOUND) ? UIImage.nynja.CallHistory.icIncomingVideo.image : UIImage.nynja.CallHistory.icOutgoingVideo.image + case .CANCELED: + return UIImage.nynja.CallHistory.icCanceledVideo.image + case .DECLINED: + return UIImage.nynja.CallHistory.icMissedVideo.image + case .MISSED: + return UIImage.nynja.CallHistory.icMissedVideo.image + case .UNANSWERED: + return UIImage.nynja.CallHistory.icNoAnswerVideo.image + } + } + } } diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift index d8931d073..3fae4d31f 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift @@ -43,7 +43,7 @@ extension CallHistoryDataSource: UITableViewDataSource { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: CallHistoryTableViewCell.cellId, for: indexPath) as! CallHistoryTableViewCell - + cell.model = self.dataSource[indexPath.row] cell.updateCell() cell.delegate = self return cell diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift index 7dd8335c0..f8ba358f7 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift @@ -38,7 +38,7 @@ class CallHistoryTableViewCell: UITableViewCell { return av }() - private lazy var callTypeImageView: UIImageView = { + private lazy var statusImageView: UIImageView = { let av = UIImageView() av.contentMode = .scaleToFill av.backgroundColor = .clear @@ -46,9 +46,9 @@ class CallHistoryTableViewCell: UITableViewCell { self.contentView.addSubview(av) av.snp.makeConstraints { (make) in - make.left.equalTo(avatarImageView.snp.right).offset(Constraints.callTypeImageView.leftOffset) - make.bottom.equalToSuperview().offset(-Constraints.callTypeImageView.bottomOffset) - make.height.width.equalTo(Constraints.callTypeImageView.height) + make.left.equalTo(avatarImageView.snp.right).offset(Constraints.statusImageView.leftOffset) + make.bottom.equalToSuperview().offset(-Constraints.statusImageView.bottomOffset) + make.height.width.equalTo(Constraints.statusImageView.height) } return av @@ -65,13 +65,13 @@ class CallHistoryTableViewCell: UITableViewCell { button.snp.makeConstraints { (make) in make.right.equalToSuperview().offset(-Constraints.infoButton.rightOffset) make.height.width.equalTo(Constraints.infoButton.height) - make.centerY.equalTo(callTypeImageView.snp.centerY) + make.centerY.equalTo(statusImageView.snp.centerY) } return button }() - private lazy var callTypeLabel: UILabel = { + private lazy var statusLabel: UILabel = { let label = UILabel() label.textAlignment = .left label.font = UIFont.makeFont(with: FontFamily.NotoSans.regular.name, height: 20.0) @@ -81,9 +81,9 @@ class CallHistoryTableViewCell: UITableViewCell { self.contentView.addSubview(label) label.snp.makeConstraints { (make) in - make.left.equalTo(callTypeImageView.snp.right).offset(Constraints.callTypelabel.leftOffset) - make.right.equalTo(infoButton.snp.left).offset(-Constraints.callTypelabel.rightOffset) - make.centerY.equalTo(callTypeImageView.snp.centerY) + make.left.equalTo(statusImageView.snp.right).offset(Constraints.statusLabel.leftOffset) + make.right.equalTo(infoButton.snp.left).offset(-Constraints.statusLabel.rightOffset) + make.centerY.equalTo(statusImageView.snp.centerY) } return label @@ -152,13 +152,14 @@ class CallHistoryTableViewCell: UITableViewCell { // MARK: - Public func updateCell() { - - avatarImageView.isHidden = false - timeLabel.isHidden = false - nameLabel.isHidden = false - callTypeImageView.isHidden = false - callTypeLabel.isHidden = false + if let m = self.model { + nameLabel.text = m.subject + timeLabel.text = CallHistoryCellModel.stringFrom(date: m.startTime) + statusLabel.text = CallHistoryCellModel.stringFrom(status: m.status, direction: m.direction) + statusImageView.image = CallHistoryCellModel.imageFrom(status: m.status, media: m.media, direction: m.direction) + } + infoButton.isHidden = false } @@ -202,13 +203,13 @@ extension CallHistoryTableViewCell { static let horInset = 5.0 } - struct callTypeImageView { + struct statusImageView { static let leftOffset = 16.0 static let bottomOffset = 11.0 static let height = 18.0 } - struct callTypelabel { + struct statusLabel { static let leftOffset = 8.0 static let rightOffset = 8.0 } diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_voice.imageset/Contents.json index acc23756f..8350bc5af 100644 --- a/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_voice.imageset/Contents.json +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_canceled_voice.imageset/Contents.json @@ -2,16 +2,7 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icons_Message_ic_сanceled_voice_call.pdf", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" + "filename" : "Icons_Message_ic_сanceled_voice_call.pdf" } ], "info" : { diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_video.imageset/Contents.json index dbc1fe921..cb9817aeb 100644 --- a/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_video.imageset/Contents.json +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_video.imageset/Contents.json @@ -2,16 +2,7 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icons_Message_ic_incoming_video_call.pdf", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" + "filename" : "Icons_Message_ic_incoming_video_call.pdf" } ], "info" : { diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_voice.imageset/Contents.json index e450ee5b7..04e2fb7b4 100644 --- a/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_voice.imageset/Contents.json +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_incoming_voice.imageset/Contents.json @@ -2,16 +2,7 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icons_Message_ic_incoming_voice_call.pdf", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" + "filename" : "Icons_Message_ic_incoming_voice_call.pdf" } ], "info" : { diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_video.imageset/Contents.json index c4458f7c1..c77157a4f 100644 --- a/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_video.imageset/Contents.json +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_video.imageset/Contents.json @@ -2,16 +2,7 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icons_Message_ic_missed_video_call.pdf", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" + "filename" : "Icons_Message_ic_missed_video_call.pdf" } ], "info" : { diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_voice.imageset/Contents.json index 57ad928fa..315c12ec0 100644 --- a/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_voice.imageset/Contents.json +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_missed_voice.imageset/Contents.json @@ -2,16 +2,7 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icons_Message_ic_missed_voice_call.pdf", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" + "filename" : "Icons_Message_ic_missed_voice_call.pdf" } ], "info" : { diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_video.imageset/Contents.json index 6ff0c0f2e..b32026990 100644 --- a/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_video.imageset/Contents.json +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_video.imageset/Contents.json @@ -2,16 +2,7 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icons_Message_ic_no_answer_video_call.pdf", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" + "filename" : "Icons_Message_ic_no_answer_video_call.pdf" } ], "info" : { diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_voice.imageset/Contents.json index b83e6f414..07f4bb026 100644 --- a/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_voice.imageset/Contents.json +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_no_answer_voice.imageset/Contents.json @@ -2,16 +2,7 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icons_Message_ic_no_answer_voice_call.pdf", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" + "filename" : "Icons_Message_ic_no_answer_voice_call.pdf" } ], "info" : { diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_video.imageset/Contents.json index 38b545a97..3ab1b8752 100644 --- a/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_video.imageset/Contents.json +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_video.imageset/Contents.json @@ -2,16 +2,7 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icons_Message_ic_outgoing_video_call.pdf", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" + "filename" : "Icons_Message_ic_outgoing_video_call.pdf" } ], "info" : { diff --git a/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_voice.imageset/Contents.json index 9bd484450..fa4164147 100644 --- a/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_voice.imageset/Contents.json +++ b/Nynja/Resources/Assets.xcassets/callHistory/ic_outgoing_voice.imageset/Contents.json @@ -2,16 +2,7 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Icons_Message_ic_outgoing_voice_call.pdf", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" + "filename" : "Icons_Message_ic_outgoing_voice_call.pdf" } ], "info" : { diff --git a/Nynja/Resources/en.lproj/Localizable.strings b/Nynja/Resources/en.lproj/Localizable.strings index 835c60414..383c05a46 100644 --- a/Nynja/Resources/en.lproj/Localizable.strings +++ b/Nynja/Resources/en.lproj/Localizable.strings @@ -995,4 +995,12 @@ "call_history_button_incoming_title" = "Incoming"; "call_history_button_missed_title" = "Missed"; "call_history_empty_title" = "Call history is empty"; +"call_history_yesterday_title" = "Yesterday"; +"call_history_log_status_missed" = "Missed Call"; +"call_history_log_status_declined" = "Declined Call"; +"call_history_log_status_canceled" = "Canceled Call"; +"call_history_log_status_unanswered" = "Unanswered Call"; +"call_history_log_dir_inbound" = "Incoming Call"; +"call_history_log_dir_outbound" = "Outgoing Call"; + -- GitLab From 238446ee656c6e0ec702ad371490300f40aea290 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Wed, 14 Nov 2018 12:02:49 +0200 Subject: [PATCH 08/59] Delete entry is done --- Nynja/Modules/CallHistory/CallHistoryProtocols.swift | 2 ++ .../CallHistory/Interactor/CallHistoryInteractor.swift | 5 +++++ .../CallHistory/Presenter/CallHistoryPresenter.swift | 5 ++++- .../CallHistory/View/CallHistoryViewController.swift | 10 ++++++++++ .../View/TableView/CallHistoryDataSource.swift | 2 +- .../Services/NynjaCalls/NynjaCommunicatorService.swift | 3 +++ 6 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift index 985d4556c..dbf648f8a 100644 --- a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift +++ b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift @@ -36,6 +36,7 @@ protocol CallHistoryPresenterProtocol: NavigationProtocol { var interactor: CallHistoryInteractorInputProtocol! { get set } var wireFrame: CallHistoryWireFrameProtocol! { get set } func closeController() + func removeCallLogBy(id:String) } protocol CallHistoryInteractorOutputProtocol: class { @@ -52,4 +53,5 @@ protocol CallHistoryInteractorInputProtocol: class { */ var presenter: CallHistoryInteractorOutputProtocol! { get set } + func removeCallLogBy(id:String) } diff --git a/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift index 42f9abcdf..3848a636e 100644 --- a/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift +++ b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift @@ -11,4 +11,9 @@ import UIKit class CallHistoryInteractor: CallHistoryInteractorInputProtocol { weak var presenter: CallHistoryInteractorOutputProtocol! + let callService:NynjaCommunicatorService = NynjaCommunicatorService.sharedInstance + + func removeCallLogBy(id:String){ + callService.removeCallLogBy(id:id) + } } diff --git a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift index aa712c9ed..1d79c7249 100644 --- a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift +++ b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift @@ -13,7 +13,6 @@ class CallHistoryPresenter: CallHistoryPresenterProtocol, CallHistoryInteractorO weak var view: CallHistoryViewProtocol! var interactor: CallHistoryInteractorInputProtocol! var wireFrame: CallHistoryWireFrameProtocol! - var contact: Contact? func closeController() { wireFrame.closeController() @@ -23,4 +22,8 @@ class CallHistoryPresenter: CallHistoryPresenterProtocol, CallHistoryInteractorO func back() { closeController() } + + func removeCallLogBy(id:String) { + interactor.removeCallLogBy(id:id) + } } diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index b811b15d9..497ab58a1 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -360,6 +360,16 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe let cancelAction = UIAlertAction(title: String.localizable.cancel, style: .cancel) let deleteAction = UIAlertAction(title: String.localizable.delete, style: .default) { [weak self] _ in + if let m = callHistoryCell.model { + if let ds = self?.tableViewDataSource { + if let ip = self?.tableView.indexPath(for: callHistoryCell) { + self?.presenter.removeCallLogBy(id:m.identifier) + ds.dataSource.remove(at: ip.row) + + self?.tableView.deleteRows(at: [ip], with: UITableViewRowAnimation.middle) + } + } + } } arrActions.append(deleteAction) diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift index 3fae4d31f..f8f6fa219 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataSource.swift @@ -16,7 +16,7 @@ protocol CallHistoryDataSourceDelegate: class { class CallHistoryDataSource: NSObject, CallHistoryTableViewCellDelegate { - let dataSource: Array + var dataSource: Array weak var delegate:CallHistoryDataSourceDelegate? init(tableView: UITableView, dataSource: Array) { diff --git a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift index c0795f10f..cb749b0a2 100644 --- a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift +++ b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift @@ -483,6 +483,9 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele return self.nynComm.getCallHistoryManager().fetchIncoming() } + func removeCallLogBy(id:String) { + self.nynComm.getCallHistoryManager().deleteCallLog(by: id) + } //MARK: Helpers func getMySelf() -> Contact? { -- GitLab From fa33b7ce203442c7ddf1bb07e5fe4a3a94bb2da8 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Wed, 14 Nov 2018 18:34:07 +0200 Subject: [PATCH 09/59] shown participant details and group details --- .../CallHistory/CallHistoryProtocols.swift | 9 +++++++++ .../Interactor/CallHistoryInteractor.swift | 10 +++++++++- .../Presenter/CallHistoryPresenter.swift | 16 ++++++++++++++++ .../View/CallHistoryViewController.swift | 12 ++++++++++++ .../View/TableView/CallHistoryCellModel.swift | 1 + .../WireFrame/CallHistoryWireFrame.swift | 8 ++++++++ Nynja/Modules/Main/WireFrame/MainWireframe.swift | 7 +++++++ 7 files changed, 62 insertions(+), 1 deletion(-) diff --git a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift index dbf648f8a..4a8d7d3db 100644 --- a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift +++ b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift @@ -15,6 +15,8 @@ protocol CallHistoryWireFrameProtocol: class { */ func closeController() + func showContact(contact:Contact) + func showRoom(room:Room) } protocol CallHistoryViewProtocol: class { @@ -37,6 +39,10 @@ protocol CallHistoryPresenterProtocol: NavigationProtocol { var wireFrame: CallHistoryWireFrameProtocol! { get set } func closeController() func removeCallLogBy(id:String) + func findContactBy(phoneId:String)-> Contact? + func findRoomBy(roomId:String)-> Room? + func showContact(contact: Contact) + func showRoom(room: Room) } protocol CallHistoryInteractorOutputProtocol: class { @@ -54,4 +60,7 @@ protocol CallHistoryInteractorInputProtocol: class { var presenter: CallHistoryInteractorOutputProtocol! { get set } func removeCallLogBy(id:String) + func findContactBy(phoneId:String)-> Contact? + func findRoomBy(roomId:String)-> Room? + } diff --git a/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift index 3848a636e..865235ee1 100644 --- a/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift +++ b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift @@ -13,7 +13,15 @@ class CallHistoryInteractor: CallHistoryInteractorInputProtocol { weak var presenter: CallHistoryInteractorOutputProtocol! let callService:NynjaCommunicatorService = NynjaCommunicatorService.sharedInstance - func removeCallLogBy(id:String){ + func removeCallLogBy(id:String) { callService.removeCallLogBy(id:id) } + + func findContactBy(phoneId:String)-> Contact? { + return ContactDAO.findContactBy(phoneId: phoneId) + } + + func findRoomBy(roomId:String)-> Room? { + return RoomDAO.findRoom(by:roomId) + } } diff --git a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift index 1d79c7249..91ab5833d 100644 --- a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift +++ b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift @@ -26,4 +26,20 @@ class CallHistoryPresenter: CallHistoryPresenterProtocol, CallHistoryInteractorO func removeCallLogBy(id:String) { interactor.removeCallLogBy(id:id) } + + func findContactBy(phoneId:String)-> Contact? { + return interactor.findContactBy(phoneId:phoneId) + } + + func findRoomBy(roomId:String)-> Room? { + return interactor.findRoomBy(roomId:roomId) + } + + func showContact(contact: Contact) { + self.wireFrame.showContact(contact: contact) + } + + func showRoom(room: Room) { + self.wireFrame.showRoom(room: room) + } } diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index 497ab58a1..0f24b76ae 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -379,6 +379,18 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe } func showInfoWith(callHistoryCell: CallHistoryTableViewCell) { + + if let m = callHistoryCell.model { + if m.kind == .DIRECT { + if let contact = presenter.findContactBy(phoneId: m.address) { + presenter.showContact(contact: contact) + } + } else { + if let room = presenter.findRoomBy(roomId: m.address) { + presenter.showRoom(room: room) + } + } + } } // MARK: - Actions diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift index 6d67c3220..b9425511b 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift @@ -40,6 +40,7 @@ class CallHistoryCellModel: NSObject { var media: NYNCallLogMedia {get{return log.media}} var subject: String {get{return log.subject}} + var address: String {get{return log.address}} var startTime: Date {get{return log.startTime}} var duration: UInt {get{return log.duration}} var participantsCount: UInt {get{return log.participantsCount}} diff --git a/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift b/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift index 7e58324b5..560829116 100644 --- a/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift +++ b/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift @@ -38,4 +38,12 @@ class CallHistoryWireFrame: CallHistoryWireFrameProtocol { func closeController() { self.navigation?.popViewController(animated: true) } + + func showContact(contact:Contact) { + mainWF?.showAddContact(contact: contact) + } + + func showRoom(room:Room) { + mainWF?.showAddParticipantsToViewFromHistory(room: room) + } } diff --git a/Nynja/Modules/Main/WireFrame/MainWireframe.swift b/Nynja/Modules/Main/WireFrame/MainWireframe.swift index 0e8e1d299..f4dc97021 100644 --- a/Nynja/Modules/Main/WireFrame/MainWireframe.swift +++ b/Nynja/Modules/Main/WireFrame/MainWireframe.swift @@ -467,6 +467,13 @@ class MainWireFrame: MainWireFrameProtocol, NynjaCommunicatorServiceDelegate { // MARK: Add Participants to group call + func showAddParticipantsToViewFromHistory(room: Room) { + + if let mem = room.allMembers { + ParticipantsWireFrame().present(navigation: contentNavigation!, main: self, contacts: mem) + } + } + func showAddParticipantsToCreateCallWith(room: Room) { AddParticipantsWireFrame().presentAddParticipants(navigation: contentNavigation!, main: self, selectedContacts: [], delegate: self.external, mode: .createGroupCall, members: room.allMembers, room: room) -- GitLab From 09ed77b719f2ce971f40a1d386584d9b10d68e48 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Thu, 15 Nov 2018 16:20:07 +0200 Subject: [PATCH 10/59] Added avatars and callback in history controller --- Nynja.xcodeproj/project.pbxproj | 8 ++-- Nynja/CallHistoryItemsFactory.swift | 16 ++++++++ Nynja/ChatItemsFactory.swift | 7 ++++ Nynja/Generated/LocalizableConstants.swift | 4 ++ .../View/CallInProgressViewController.swift | 1 - .../CallHistory/CallHistoryProtocols.swift | 11 +++++- .../Interactor/CallHistoryInteractor.swift | 4 ++ .../Presenter/CallHistoryPresenter.swift | 23 ++++++++++- .../View/CallHistoryViewController.swift | 38 +++++++++++++++++-- .../View/TableView/CallHistoryCellModel.swift | 25 ++++++++++-- .../TableView/CallHistoryDataController.swift | 3 +- .../View/TableView/CallHistoryDelegate.swift | 27 ------------- .../TableView/CallHistoryTableViewCell.swift | 19 ++++++++-- .../WireFrame/CallHistoryWireFrame.swift | 15 ++++++++ .../Main/Interactor/MainInteractor.swift | 1 - Nynja/Modules/Main/MainProtocols.swift | 4 ++ .../Main/Presenter/MainPresenter.swift | 22 ++++++++++- .../Main/View/MainNavigationItem.swift | 1 + .../MainViewController+NavigateProtocol.swift | 6 ++- .../Modules/Main/View/NavigateProtocol.swift | 2 +- .../Main/WireFrame/MainWireframe.swift | 23 ++++++++--- Nynja/Resources/en.lproj/Localizable.strings | 3 +- .../NynjaCalls/NynjaCommunicatorService.swift | 5 +++ 23 files changed, 212 insertions(+), 56 deletions(-) create mode 100644 Nynja/CallHistoryItemsFactory.swift delete mode 100644 Nynja/Modules/CallHistory/View/TableView/CallHistoryDelegate.swift diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index b4c38ed16..011474b95 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -1183,10 +1183,10 @@ 9B2C6693216F82AB00116486 /* NynjaJoinByLinkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B2C6692216F82AB00116486 /* NynjaJoinByLinkService.swift */; }; 9B517995218333B2006E1A4B /* CallHistoryCellModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B517994218333B2006E1A4B /* CallHistoryCellModel.swift */; }; 9B517997218333E1006E1A4B /* CallHistoryTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B517996218333E1006E1A4B /* CallHistoryTableViewCell.swift */; }; - 9B51799A21834B95006E1A4B /* CallHistoryDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */; }; 9B51799C21834BA7006E1A4B /* CallHistoryDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */; }; 9B804AB9219326A1000606EC /* CallHistoryDataController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804AB8219326A1000606EC /* CallHistoryDataController.swift */; }; 9B804ABB2195A93E000606EC /* EmptyCallHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804ABA2195A93E000606EC /* EmptyCallHistoryView.swift */; }; + 9B804AC0219D6AFA000606EC /* CallHistoryItemsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804ABF219D6AF9000606EC /* CallHistoryItemsFactory.swift */; }; 9B81AD92215A5EEA00993A8C /* ActiveSpeakerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B81AD91215A5EEA00993A8C /* ActiveSpeakerView.swift */; }; 9B96705F214BE3FE0058E98F /* MultiPageCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B96705E214BE3FE0058E98F /* MultiPageCollectionView.swift */; }; 9B967098215151760058E98F /* LeaveVoiceMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B967097215151760058E98F /* LeaveVoiceMessageViewController.swift */; }; @@ -3426,10 +3426,10 @@ 9B2C6692216F82AB00116486 /* NynjaJoinByLinkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NynjaJoinByLinkService.swift; sourceTree = ""; }; 9B517994218333B2006E1A4B /* CallHistoryCellModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryCellModel.swift; sourceTree = ""; }; 9B517996218333E1006E1A4B /* CallHistoryTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryTableViewCell.swift; sourceTree = ""; }; - 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDelegate.swift; sourceTree = ""; }; 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDataSource.swift; sourceTree = ""; }; 9B804AB8219326A1000606EC /* CallHistoryDataController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDataController.swift; sourceTree = ""; }; 9B804ABA2195A93E000606EC /* EmptyCallHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyCallHistoryView.swift; sourceTree = ""; }; + 9B804ABF219D6AF9000606EC /* CallHistoryItemsFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryItemsFactory.swift; sourceTree = ""; }; 9B810991D7143259040DCA31 /* LanguageSettingsViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LanguageSettingsViewController.swift; sourceTree = ""; }; 9B81AD91215A5EEA00993A8C /* ActiveSpeakerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSpeakerView.swift; sourceTree = ""; }; 9B96705E214BE3FE0058E98F /* MultiPageCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiPageCollectionView.swift; sourceTree = ""; }; @@ -6602,6 +6602,7 @@ 4B1D7E0A2029D8CD00703228 /* GroupOptionsItemsFactory.swift */, 4B1D7E042029CF2900703228 /* ShareContactsItemsFactory.swift */, A47785A320D286680053E0D2 /* ChannelChatItemsFactory.swift */, + 9B804ABF219D6AF9000606EC /* CallHistoryItemsFactory.swift */, ); name = Chat; sourceTree = ""; @@ -9478,7 +9479,6 @@ children = ( 9B517994218333B2006E1A4B /* CallHistoryCellModel.swift */, 9B517996218333E1006E1A4B /* CallHistoryTableViewCell.swift */, - 9B51799921834B95006E1A4B /* CallHistoryDelegate.swift */, 9B51799B21834BA7006E1A4B /* CallHistoryDataSource.swift */, 9B804AB8219326A1000606EC /* CallHistoryDataController.swift */, 9B804ABA2195A93E000606EC /* EmptyCallHistoryView.swift */, @@ -15512,6 +15512,7 @@ 85E1DD2520BEBE17008AD211 /* MessageVC+StickerInputModuleDelegate.swift in Sources */, 266AD07A20F51AAE00EA275F /* TranscriptionInfo.swift in Sources */, 8E9601951FF2A04E00E0C21D /* ItemSelectorCell.swift in Sources */, + 9B804AC0219D6AFA000606EC /* CallHistoryItemsFactory.swift in Sources */, FEA655F72167777E00B44029 /* PaymentViewControllerModel.swift in Sources */, FB351F9220AC22A70042ACB1 /* ImagePreviewTransitionHelpers.swift in Sources */, 2683F75E203F36150003181A /* actExtension+BERT.swift in Sources */, @@ -16129,7 +16130,6 @@ 26CD3FDD2104D1DD00597E62 /* AudioConvertOperation.swift in Sources */, 8509FC7D2158DCFB00734D93 /* Feature+Construct.swift in Sources */, 26771CC1212ECE08006112B5 /* ConvertMessageTable.swift in Sources */, - 9B51799A21834B95006E1A4B /* CallHistoryDelegate.swift in Sources */, 8514F17C20EA219F00883513 /* ContextMenuConfiguration.swift in Sources */, FBCE840D20E525A6003B7558 /* HTTPResponseResult.swift in Sources */, A43B259F20AB1DFA00FF8107 /* PickerCell.swift in Sources */, diff --git a/Nynja/CallHistoryItemsFactory.swift b/Nynja/CallHistoryItemsFactory.swift new file mode 100644 index 000000000..05c41e103 --- /dev/null +++ b/Nynja/CallHistoryItemsFactory.swift @@ -0,0 +1,16 @@ +// +// CallHistoryItemsFactory.swift +// Nynja +// +// Created by Bozhko Terziev on 11/15/18. +// Copyright © 2018 Softavail. All rights reserved. +// + +class CallHistoryItemsFactory: ChatBaseFactory { + + // MARK: - Second lvl + override var secondLevelItems: ItemModels { + return [clearHistory] + } + +} diff --git a/Nynja/ChatItemsFactory.swift b/Nynja/ChatItemsFactory.swift index 14cc2957a..225efa4de 100644 --- a/Nynja/ChatItemsFactory.swift +++ b/Nynja/ChatItemsFactory.swift @@ -64,6 +64,13 @@ class ChatItemsFactory: WCBaseItemsFactory { return item } + var clearHistory: ImageActionItemModel { + let item = ImageActionItemModel(nameImage: "ic_delete_context_menu", navItem: .clearHistory, action: { [weak navigateDelegate] (item, indexPath) in + navigateDelegate?.clearCallHistory(indexPath: indexPath) + }) + return item + } + // MARK: - Locations var recents: ImageFilledItemModel { diff --git a/Nynja/Generated/LocalizableConstants.swift b/Nynja/Generated/LocalizableConstants.swift index 25dcdebbb..275d5a934 100644 --- a/Nynja/Generated/LocalizableConstants.swift +++ b/Nynja/Generated/LocalizableConstants.swift @@ -138,6 +138,8 @@ internal extension String { static var callHistoryButtonMissedTitle: String { return localizable.tr("Localizable", "call_history_button_missed_title") } /// Outgoing static var callHistoryButtonOutgoingTitle: String { return localizable.tr("Localizable", "call_history_button_outgoing_title") } + /// Are you sure you want to clear all call history? + static var callHistoryClearQuestionAlert: String { return localizable.tr("Localizable", "call_history_clear_question_alert") } /// Call history is empty static var callHistoryEmptyTitle: String { return localizable.tr("Localizable", "call_history_empty_title") } /// Incoming Call @@ -1368,6 +1370,8 @@ internal extension String { static var wheelItemChatOptions: String { return localizable.tr("Localizable", "wheel_item_chatOptions") } /// Chats static var wheelItemChats: String { return localizable.tr("Localizable", "wheel_item_chats") } + /// Clear History + static var wheelItemClearHistory: String { return localizable.tr("Localizable", "wheel_item_clear_history") } /// Contact static var wheelItemContact: String { return localizable.tr("Localizable", "wheel_item_contact") } /// Contacts diff --git a/Nynja/Modules/Call/CallScreens/CallInProgress/View/CallInProgressViewController.swift b/Nynja/Modules/Call/CallScreens/CallInProgress/View/CallInProgressViewController.swift index 2ed92f550..41ff36140 100644 --- a/Nynja/Modules/Call/CallScreens/CallInProgress/View/CallInProgressViewController.swift +++ b/Nynja/Modules/Call/CallScreens/CallInProgress/View/CallInProgressViewController.swift @@ -329,7 +329,6 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, AudioSes if let contact = self.contact { presenter.messageAcion(with: contact, isVideo: false) } else { - presenter.messageAcion(with: roomId, isVideo: false) } } diff --git a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift index 4a8d7d3db..bc67ba988 100644 --- a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift +++ b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift @@ -17,6 +17,9 @@ protocol CallHistoryWireFrameProtocol: class { func closeController() func showContact(contact:Contact) func showRoom(room:Room) + func callBackFor(contact:Contact) + func callBackVideoFor(contact:Contact) + func callBackFor(room:Room) } protocol CallHistoryViewProtocol: class { @@ -28,7 +31,7 @@ protocol CallHistoryViewProtocol: class { var presenter: CallHistoryPresenterProtocol! { get set } } -protocol CallHistoryPresenterProtocol: NavigationProtocol { +protocol CallHistoryPresenterProtocol: BasePresenterProtocol, NavigationProtocol { /** * Add here your methods for communication VIEW -> PRESENTER @@ -43,6 +46,10 @@ protocol CallHistoryPresenterProtocol: NavigationProtocol { func findRoomBy(roomId:String)-> Room? func showContact(contact: Contact) func showRoom(room: Room) + func clearCallHistory() + func callBackFor(contact:Contact) + func callBackVideoFor(contact:Contact) + func callBackFor(room:Room) } protocol CallHistoryInteractorOutputProtocol: class { @@ -62,5 +69,5 @@ protocol CallHistoryInteractorInputProtocol: class { func removeCallLogBy(id:String) func findContactBy(phoneId:String)-> Contact? func findRoomBy(roomId:String)-> Room? - + func clearCallHistory() } diff --git a/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift index 865235ee1..f2b03e93a 100644 --- a/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift +++ b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift @@ -24,4 +24,8 @@ class CallHistoryInteractor: CallHistoryInteractorInputProtocol { func findRoomBy(roomId:String)-> Room? { return RoomDAO.findRoom(by:roomId) } + + func clearCallHistory() { + callService.clearCallHistory() + } } diff --git a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift index 91ab5833d..5f4e5fef8 100644 --- a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift +++ b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift @@ -8,8 +8,12 @@ import UIKit -class CallHistoryPresenter: CallHistoryPresenterProtocol, CallHistoryInteractorOutputProtocol { +class CallHistoryPresenter: BasePresenter, CallHistoryPresenterProtocol, CallHistoryInteractorOutputProtocol { + override var itemsFactory: WCItemsFactory? { + return CallHistoryItemsFactory() + } + weak var view: CallHistoryViewProtocol! var interactor: CallHistoryInteractorInputProtocol! var wireFrame: CallHistoryWireFrameProtocol! @@ -42,4 +46,21 @@ class CallHistoryPresenter: CallHistoryPresenterProtocol, CallHistoryInteractorO func showRoom(room: Room) { self.wireFrame.showRoom(room: room) } + + func clearCallHistory() { + interactor.clearCallHistory() + } + + func callBackFor(contact:Contact) { + self.wireFrame.callBackFor(contact:contact) + } + + func callBackVideoFor(contact:Contact) { + self.wireFrame.callBackVideoFor(contact:contact) + } + + func callBackFor(room:Room) { + self.wireFrame.callBackFor(room:room) + } + } diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index 0f24b76ae..f24f4751c 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -17,14 +17,18 @@ enum CallHistoryMode { class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDelegate, CallHistoryDataSourceDelegate, UITableViewDelegate { - var presenter: CallHistoryPresenterProtocol! + var presenter: CallHistoryPresenterProtocol! { + didSet { + _presenter = presenter + } + } + let buttonFontSize: CGFloat = CGFloat(17.0.adjustedByWidth) var contentWidth: CGFloat = Constraints.button.buttonOffset var callHistoryMode: CallHistoryMode = .all var dataController: CallHistoryDataController? var tableViewDataSource: CallHistoryDataSource? - var tableViewDelegate: CallHistoryDelegate? private struct Constraints { @@ -51,7 +55,6 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe private func cleanUpBeforeReloading() { tableViewDataSource = nil - tableViewDelegate = nil } private func reloadTableView() { @@ -299,6 +302,18 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe return button }() + public func clearHistory() { + AlertManager.sharedInstance.showAlertWithTwoActions(title: "", + message: String.localizable.callHistoryClearQuestionAlert, + firstActionTitle: String.localizable.no, + secondActionTitle: String.localizable.yes, + firstAction: nil, + secondAction: { + self.presenter.clearCallHistory() + self.reloadTableView() + }) + } + public init() { super.init(nibName: nil, bundle: nil) } @@ -341,7 +356,23 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe } private func callBackFor(indexPath: IndexPath) { + let cell:CallHistoryTableViewCell = tableView.cellForRow(at: indexPath) as! CallHistoryTableViewCell + if let m = cell.model { + if m.kind == .DIRECT { + if let contact = presenter.findContactBy(phoneId: m.address) { + if m.media == .VIDEO { + presenter.callBackVideoFor(contact: contact) + } else { + presenter.callBackFor(contact: contact) + } + } + } else { + if let room = presenter.findRoomBy(roomId: m.address) { + presenter.callBackFor(room: room) + } + } + } } // MARK UIScrollView Delegates @@ -379,7 +410,6 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe } func showInfoWith(callHistoryCell: CallHistoryTableViewCell) { - if let m = callHistoryCell.model { if m.kind == .DIRECT { if let contact = presenter.findContactBy(phoneId: m.address) { diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift index b9425511b..9e799b4c5 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift @@ -80,13 +80,32 @@ class CallHistoryCellModel: NSObject { } } - class func stringFrom(status:NYNCallLogStatus, direction:NYNCallLogDir)-> String { + class func stringFrom(duration:UInt)-> String? { + let formatter = DateComponentsFormatter() + formatter.unitsStyle = .abbreviated + formatter.allowedUnits = [.hour, .minute, .second] + formatter.zeroFormattingBehavior = [ .default ] + + let formattedDuration = formatter.string(from: Double(duration)) + + return formattedDuration + } + + class func stringFrom(status:NYNCallLogStatus, direction:NYNCallLogDir, duration:UInt)-> String { switch status { case .ANSWERED: if direction == .INBOUND { - return String.localizable.callHistoryLogDirInbound + if duration > 0, let duration = stringFrom(duration:duration) { + return String(format: "%@ (%@)", String.localizable.callHistoryLogDirInbound, duration) + } else { + return String.localizable.callHistoryLogDirInbound + } } else { - return String.localizable.callHistoryLogDirOutbound + if duration > 0, let duration = stringFrom(duration:duration) { + return String(format: "%@ (%@)", String.localizable.callHistoryLogDirOutbound, duration) + } else { + return String.localizable.callHistoryLogDirOutbound + } } case .CANCELED: return String.localizable.callHistoryLogStatusCanceled diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift index 532d6f594..d411efe81 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryDataController.swift @@ -30,7 +30,8 @@ class CallHistoryDataController: NSObject { if let r = results { let count = r.count() - for i in 0...count { + + for i in 0.. - - init(tableView: UITableView, dataSource: Array) { - self.dataSource = dataSource - super.init() - tableView.delegate = self - } -} - -extension CallHistoryDelegate: UITableViewDelegate { - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - tableView.deselectRow(at: indexPath, animated: false) - } -} - diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift index f8ba358f7..f76b50ac5 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift @@ -27,7 +27,7 @@ class CallHistoryTableViewCell: UITableViewCell { av.contentMode = .scaleToFill av.layer.cornerRadius = CGFloat(Constraints.avatar.height/2) av.backgroundColor = UIColor.nynja.lightGray - + av.clipsToBounds = true self.contentView.addSubview(av) av.snp.makeConstraints { (make) in make.left.equalToSuperview().offset(Constraints.avatar.leftOffset) @@ -152,12 +152,25 @@ class CallHistoryTableViewCell: UITableViewCell { // MARK: - Public func updateCell() { - if let m = self.model { nameLabel.text = m.subject timeLabel.text = CallHistoryCellModel.stringFrom(date: m.startTime) - statusLabel.text = CallHistoryCellModel.stringFrom(status: m.status, direction: m.direction) + statusLabel.text = CallHistoryCellModel.stringFrom(status: m.status, direction: m.direction, duration:m.duration) statusImageView.image = CallHistoryCellModel.imageFrom(status: m.status, media: m.media, direction: m.direction) + + if m.kind == .DIRECT { + if let ctc = ContactDAO.findContactBy(phoneId: m.address) { + self.avatarImageView.setImage(url: ctc.photoURL, placeHolder: UIImage.nynja.Contacts.avaPlaceholder.image) + } else { + self.avatarImageView.image = UIImage.nynja.Contacts.avaPlaceholder.image + } + } else { + if let r = RoomDAO.findRoom(by: m.address) { + self.avatarImageView.setImage(url: r.photoURL, placeHolder: UIImage.nynja.Contacts.avaPlaceholder.image) + } else { + self.avatarImageView.image = UIImage.nynja.Contacts.avaPlaceholder.image + } + } } infoButton.isHidden = false diff --git a/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift b/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift index 560829116..7e531cb37 100644 --- a/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift +++ b/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift @@ -46,4 +46,19 @@ class CallHistoryWireFrame: CallHistoryWireFrameProtocol { func showRoom(room:Room) { mainWF?.showAddParticipantsToViewFromHistory(room: room) } + + func callBackFor(contact:Contact) { + self.navigation?.popViewController(animated: false) + mainWF?.callBack(contact:contact) + } + + func callBackVideoFor(contact:Contact) { + self.navigation?.popViewController(animated: false) + mainWF?.callBackVideo(contact:contact) + } + + func callBackFor(room:Room) { + self.navigation?.popViewController(animated: false) + mainWF?.callBack(room:room) + } } diff --git a/Nynja/Modules/Main/Interactor/MainInteractor.swift b/Nynja/Modules/Main/Interactor/MainInteractor.swift index a2ad1f2ff..71e0b45e1 100644 --- a/Nynja/Modules/Main/Interactor/MainInteractor.swift +++ b/Nynja/Modules/Main/Interactor/MainInteractor.swift @@ -35,7 +35,6 @@ class MainInteractor: MainInteractorInputProtocol, EditPhotoDelegate, MQTTServic } func call(phoneId: String) { - if let ctc = ContactDAO.findContactBy(phoneId: phoneId), let name = ctc.fullName { NynjaCommunicatorService.sharedInstance.call(userId: phoneId, name: name, withVideo: false) } diff --git a/Nynja/Modules/Main/MainProtocols.swift b/Nynja/Modules/Main/MainProtocols.swift index ec91bb1c0..d25594c90 100644 --- a/Nynja/Modules/Main/MainProtocols.swift +++ b/Nynja/Modules/Main/MainProtocols.swift @@ -47,6 +47,7 @@ protocol MainWireFrameProtocol: class { func showAddParticipantsToCreateCallWith(room:Room) func showAddParticipantsToCreateConferenceCall() func showCallHistory() + func clearCallHistory() func showPayment(profile: Profile, to contact: Contact) func showScheduleMessage(with mode: ScheduledMessageMode, delegate: ScheduleMessageDelegate?) @@ -192,6 +193,7 @@ protocol MainPresenterProtocol: class { func conferenceVoiceCall() func conferenceVideoCall() func callHistory() + func clearCallHistory() // Group func showAddParticipants() @@ -207,6 +209,8 @@ protocol MainPresenterProtocol: class { func voiceCall() func callBack(contact:Contact?) + func callBackVideo(contact:Contact?) + func callBack(room:Room?) func voiceGroupCall() func videoCall() func videoGroupCall() diff --git a/Nynja/Modules/Main/Presenter/MainPresenter.swift b/Nynja/Modules/Main/Presenter/MainPresenter.swift index a8e2ae48f..41d804865 100644 --- a/Nynja/Modules/Main/Presenter/MainPresenter.swift +++ b/Nynja/Modules/Main/Presenter/MainPresenter.swift @@ -65,8 +65,24 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu interactor.call(phoneId: contactId) } - func voiceGroupCall() { + func callBackVideo(contact: Contact?) { + guard let contactId = contact?.id else { + return + } + wireFrame.isVideo = true + wireFrame.isGroup = false + interactor.videoCall(phoneId: contactId) + } + + func callBack(room: Room?) { + if let r = room { + wireFrame.isVideo = false + wireFrame.isGroup = true + interactor.createGroupCall(callId: nil, contacts: (r.members?.contacts)!, room: r) + } + } + func voiceGroupCall() { if let room = wireFrame.getRoom() { wireFrame.isVideo = false wireFrame.isGroup = true @@ -198,6 +214,10 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu wireFrame.showCallHistory() } + func clearCallHistory() { + wireFrame.clearCallHistory() + } + func showThemePicker() { self.wireFrame.showThemePicker() } diff --git a/Nynja/Modules/Main/View/MainNavigationItem.swift b/Nynja/Modules/Main/View/MainNavigationItem.swift index 3afe4b57a..fc76d5569 100644 --- a/Nynja/Modules/Main/View/MainNavigationItem.swift +++ b/Nynja/Modules/Main/View/MainNavigationItem.swift @@ -47,6 +47,7 @@ enum MainNavigationItem: String { case phoneNumber = "wheel_item_changeNumber" case payment = "wheel_item_transfer" case help = "wheel_item_help" + case clearHistory = "wheel_item_clear_history" // Chats section case starred = "wheel_item_starred" diff --git a/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift b/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift index 688f62dbd..7ff194329 100644 --- a/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift +++ b/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift @@ -218,7 +218,11 @@ extension MainViewController: NavigateProtocol { presenter.callHistory() closeWheel(indexPath: indexPath) } - + + func clearCallHistory(indexPath: IndexPath?) { + presenter.clearCallHistory() + closeWheel(indexPath: indexPath) + } // MARK: - Contact Actions func showListContacts(indexPath: IndexPath?) { diff --git a/Nynja/Modules/Main/View/NavigateProtocol.swift b/Nynja/Modules/Main/View/NavigateProtocol.swift index 973f78851..eb2ef2241 100644 --- a/Nynja/Modules/Main/View/NavigateProtocol.swift +++ b/Nynja/Modules/Main/View/NavigateProtocol.swift @@ -71,7 +71,7 @@ protocol SecondLevelNavigateProtocol: class { func conferenceVoiceCall(indexPath: IndexPath?) func conferenceVideoCall(indexPath: IndexPath?) func callHistory(indexPath: IndexPath?) - + func clearCallHistory(indexPath: IndexPath?) // MARK: - Contact Actions func showListContacts(indexPath: IndexPath?) diff --git a/Nynja/Modules/Main/WireFrame/MainWireframe.swift b/Nynja/Modules/Main/WireFrame/MainWireframe.swift index f4dc97021..5f002a942 100644 --- a/Nynja/Modules/Main/WireFrame/MainWireframe.swift +++ b/Nynja/Modules/Main/WireFrame/MainWireframe.swift @@ -487,23 +487,24 @@ class MainWireFrame: MainWireFrameProtocol, NynjaCommunicatorServiceDelegate { CallHistoryWireFrame().presentCallHistory(navigation: contentNavigation!, main: self) } + func clearCallHistory() { + if let callHistory = contentNavigation.viewControllers.last as? CallHistoryViewController { + callHistory.clearHistory() + } + } + func presentLeaveVoiceMessageViewForContact(contact:Contact) { LeaveVoiceMessageWireFrame().presentLeaveVoiceMessage(navigation: navigation!, contact: contact, main: self) } func presentCallInProgressViewForCall(call:NYNCall, isIncomingRingig:Bool) { - self.isVideo = call.recvVideo let callMode: CallInProgressMode = self.isVideo ? .oneToOneVideo : call.isConference() ? .groupAudio : .oneToOneAudio if callMode == .groupAudio { - CallInProgressWireframe().presentCreateGroupCall(navigation: navigation!, callInProgressMode: callMode, main: self, call: call, isIncomingRingig:isIncomingRingig) - } else { - var contact:Contact? = nil - if call.isOutgoing() { if let messageVC = contentNavigation.viewControllers.last as? MessageVC { @@ -530,6 +531,18 @@ class MainWireFrame: MainWireFrameProtocol, NynjaCommunicatorServiceDelegate { view?.presenter.callBack(contact: ctc) } } + + func callBackVideo(contact:Contact?) { + if let ctc = contact { + view?.presenter.callBackVideo(contact: ctc) + } + } + + func callBack(room:Room?) { + if let r = room { + view?.presenter.callBack(room: r) + } + } func incomingCallRinging(call: NYNCall) { diff --git a/Nynja/Resources/en.lproj/Localizable.strings b/Nynja/Resources/en.lproj/Localizable.strings index 383c05a46..326d36ee6 100644 --- a/Nynja/Resources/en.lproj/Localizable.strings +++ b/Nynja/Resources/en.lproj/Localizable.strings @@ -600,6 +600,7 @@ "wheel_invite_friends"="Invite Friends"; "wheel_item_transfer" = "Transfer"; "wheel_item_help" = "Help & Feedback"; +"wheel_item_clear_history" = "Clear History"; // MARK: Main "main_undefined"="Undefined"; @@ -1002,5 +1003,5 @@ "call_history_log_status_unanswered" = "Unanswered Call"; "call_history_log_dir_inbound" = "Incoming Call"; "call_history_log_dir_outbound" = "Outgoing Call"; - +"call_history_clear_question_alert" = "Are you sure you want to clear all call history?"; diff --git a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift index cb749b0a2..e31a3922e 100644 --- a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift +++ b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift @@ -486,6 +486,11 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele func removeCallLogBy(id:String) { self.nynComm.getCallHistoryManager().deleteCallLog(by: id) } + + func clearCallHistory() { + self.nynComm.getCallHistoryManager().deleteAllHistory() + } + //MARK: Helpers func getMySelf() -> Contact? { -- GitLab From f941b9fe32ea32d110fa829de5d703769bc09f8b Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Thu, 15 Nov 2018 18:32:51 +0200 Subject: [PATCH 11/59] Fixed broken build --- Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift index 5bf4b9016..634a7aea8 100644 --- a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift +++ b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift @@ -59,13 +59,7 @@ extension NynjaCallDelegate { } class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDelegate, NYNCallManagerDelegate, ConnectionServiceDelegate { - func callDidPauseAudio(_ call: NYNCall) { - } - - func callDidResumeAudio(_ call: NYNCall) { - } - private var initialized: Bool = false private let storageService = StorageService.sharedInstance let nynComm: NynjaCommunicator -- GitLab From 69a1f5b9a40539fd96bc05485f8bd59043ed7ccf Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Fri, 16 Nov 2018 18:58:34 +0200 Subject: [PATCH 12/59] Group call History info is done --- Nynja.xcodeproj/project.pbxproj | 68 +++++++++++ Nynja/Generated/LocalizableConstants.swift | 4 +- .../CallHistory/CallHistoryProtocols.swift | 4 +- .../Presenter/CallHistoryPresenter.swift | 6 +- .../View/CallHistoryViewController.swift | 4 +- .../WireFrame/CallHistoryWireFrame.swift | 4 +- .../Main/WireFrame/MainWireframe.swift | 8 +- .../View/ParticipantHistoryHeaderView.swift | 106 ++++++++++++++++++ Nynja/Resources/en.lproj/Localizable.strings | 1 + 9 files changed, 188 insertions(+), 17 deletions(-) create mode 100644 Nynja/Modules/ParticipantsHistory/View/ParticipantHistoryHeaderView.swift diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 8c01e274c..68f9f0cd6 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -1180,6 +1180,7 @@ 990A25B2C84CE09B4CE64533 /* MyGroupAliasPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9D0CBC2BAD6DC6C7047A26 /* MyGroupAliasPresenter.swift */; }; 99B9D27D2F0EFE051E6581ED /* CreateGroupProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE9DC6ADA0E71241C49A328 /* CreateGroupProtocols.swift */; }; 9B0C32F12153CF1600094ECF /* HintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B0C32F02153CF1600094ECF /* HintView.swift */; }; + 9B294510219F1F1500F30EA7 /* ParticipantHistoryHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B29450F219F1F1500F30EA7 /* ParticipantHistoryHeaderView.swift */; }; 9B2C6693216F82AB00116486 /* NynjaJoinByLinkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B2C6692216F82AB00116486 /* NynjaJoinByLinkService.swift */; }; 9B517995218333B2006E1A4B /* CallHistoryCellModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B517994218333B2006E1A4B /* CallHistoryCellModel.swift */; }; 9B517997218333E1006E1A4B /* CallHistoryTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B517996218333E1006E1A4B /* CallHistoryTableViewCell.swift */; }; @@ -1187,6 +1188,12 @@ 9B804AB9219326A1000606EC /* CallHistoryDataController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804AB8219326A1000606EC /* CallHistoryDataController.swift */; }; 9B804ABB2195A93E000606EC /* EmptyCallHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804ABA2195A93E000606EC /* EmptyCallHistoryView.swift */; }; 9B804AC0219D6AFA000606EC /* CallHistoryItemsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804ABF219D6AF9000606EC /* CallHistoryItemsFactory.swift */; }; + 9B804AD5219EF9E1000606EC /* ParticipantsHistoryProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804AD4219EF9E1000606EC /* ParticipantsHistoryProtocols.swift */; }; + 9B804AD8219EFA66000606EC /* ParticipantsHistoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804AD6219EFA66000606EC /* ParticipantsHistoryViewController.swift */; }; + 9B804AD9219EFA66000606EC /* ParticipantsHistoryViewControllerLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804AD7219EFA66000606EC /* ParticipantsHistoryViewControllerLayout.swift */; }; + 9B804ADB219EFBE8000606EC /* ParticipantsHistoryPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804ADA219EFBE8000606EC /* ParticipantsHistoryPresenter.swift */; }; + 9B804ADD219EFC7B000606EC /* ParticipantsHistoryInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804ADC219EFC7B000606EC /* ParticipantsHistoryInteractor.swift */; }; + 9B804ADF219EFCD1000606EC /* ParticipantsHistoryWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B804ADE219EFCD1000606EC /* ParticipantsHistoryWireframe.swift */; }; 9B81AD92215A5EEA00993A8C /* ActiveSpeakerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B81AD91215A5EEA00993A8C /* ActiveSpeakerView.swift */; }; 9B96705F214BE3FE0058E98F /* MultiPageCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B96705E214BE3FE0058E98F /* MultiPageCollectionView.swift */; }; 9B967098215151760058E98F /* LeaveVoiceMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B967097215151760058E98F /* LeaveVoiceMessageViewController.swift */; }; @@ -3427,6 +3434,7 @@ 92F29C1A91BF5FD3A0AEEA0D /* AddContactInteractor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AddContactInteractor.swift; sourceTree = ""; }; 997E1A59FCAB5602A049C6E7 /* EditUsernamePresenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EditUsernamePresenter.swift; sourceTree = ""; }; 9B0C32F02153CF1600094ECF /* HintView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HintView.swift; sourceTree = ""; }; + 9B29450F219F1F1500F30EA7 /* ParticipantHistoryHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParticipantHistoryHeaderView.swift; sourceTree = ""; }; 9B2C6692216F82AB00116486 /* NynjaJoinByLinkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NynjaJoinByLinkService.swift; sourceTree = ""; }; 9B517994218333B2006E1A4B /* CallHistoryCellModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryCellModel.swift; sourceTree = ""; }; 9B517996218333E1006E1A4B /* CallHistoryTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryTableViewCell.swift; sourceTree = ""; }; @@ -3434,6 +3442,12 @@ 9B804AB8219326A1000606EC /* CallHistoryDataController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallHistoryDataController.swift; sourceTree = ""; }; 9B804ABA2195A93E000606EC /* EmptyCallHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyCallHistoryView.swift; sourceTree = ""; }; 9B804ABF219D6AF9000606EC /* CallHistoryItemsFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallHistoryItemsFactory.swift; sourceTree = ""; }; + 9B804AD4219EF9E1000606EC /* ParticipantsHistoryProtocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParticipantsHistoryProtocols.swift; sourceTree = ""; }; + 9B804AD6219EFA66000606EC /* ParticipantsHistoryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParticipantsHistoryViewController.swift; sourceTree = ""; }; + 9B804AD7219EFA66000606EC /* ParticipantsHistoryViewControllerLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParticipantsHistoryViewControllerLayout.swift; sourceTree = ""; }; + 9B804ADA219EFBE8000606EC /* ParticipantsHistoryPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParticipantsHistoryPresenter.swift; sourceTree = ""; }; + 9B804ADC219EFC7B000606EC /* ParticipantsHistoryInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParticipantsHistoryInteractor.swift; sourceTree = ""; }; + 9B804ADE219EFCD1000606EC /* ParticipantsHistoryWireframe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParticipantsHistoryWireframe.swift; sourceTree = ""; }; 9B810991D7143259040DCA31 /* LanguageSettingsViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LanguageSettingsViewController.swift; sourceTree = ""; }; 9B81AD91215A5EEA00993A8C /* ActiveSpeakerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSpeakerView.swift; sourceTree = ""; }; 9B96705E214BE3FE0058E98F /* MultiPageCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiPageCollectionView.swift; sourceTree = ""; }; @@ -6442,6 +6456,7 @@ E57956502ACFC6A27ACC9EB9 /* MyGroupAlias */, AC2BC09EF5DBC423CCC26475 /* EditGroupName */, 1C069BFF3612D9D4D5E23840 /* EditGroupPhoto */, + 9B804ACF219EF96F000606EC /* ParticipantsHistory */, 267BE2971FE13AB600C47E18 /* Participants */, 267BE27D1FDE900900C47E18 /* SettingsGroup */, 6BAAF8CD92351F9115795AAC /* CreateGroup */, @@ -9497,6 +9512,52 @@ path = TableView; sourceTree = ""; }; + 9B804ACF219EF96F000606EC /* ParticipantsHistory */ = { + isa = PBXGroup; + children = ( + 9B804AD4219EF9E1000606EC /* ParticipantsHistoryProtocols.swift */, + 9B804AD3219EF9A8000606EC /* View */, + 9B804AD2219EF99E000606EC /* Presenter */, + 9B804AD1219EF992000606EC /* Interactor */, + 9B804AD0219EF98B000606EC /* WireFrame */, + ); + path = ParticipantsHistory; + sourceTree = ""; + }; + 9B804AD0219EF98B000606EC /* WireFrame */ = { + isa = PBXGroup; + children = ( + 9B804ADE219EFCD1000606EC /* ParticipantsHistoryWireframe.swift */, + ); + path = WireFrame; + sourceTree = ""; + }; + 9B804AD1219EF992000606EC /* Interactor */ = { + isa = PBXGroup; + children = ( + 9B804ADC219EFC7B000606EC /* ParticipantsHistoryInteractor.swift */, + ); + path = Interactor; + sourceTree = ""; + }; + 9B804AD2219EF99E000606EC /* Presenter */ = { + isa = PBXGroup; + children = ( + 9B804ADA219EFBE8000606EC /* ParticipantsHistoryPresenter.swift */, + ); + path = Presenter; + sourceTree = ""; + }; + 9B804AD3219EF9A8000606EC /* View */ = { + isa = PBXGroup; + children = ( + 9B804AD6219EFA66000606EC /* ParticipantsHistoryViewController.swift */, + 9B804AD7219EFA66000606EC /* ParticipantsHistoryViewControllerLayout.swift */, + 9B29450F219F1F1500F30EA7 /* ParticipantHistoryHeaderView.swift */, + ); + path = View; + sourceTree = ""; + }; 9B96709221514CA30058E98F /* LeaveVoiceMessage */ = { isa = PBXGroup; children = ( @@ -14963,16 +15024,19 @@ A42D52B6206A53AA00EEB952 /* Service_Spec.swift in Sources */, 4B8996C8204ECE9B00DCB183 /* ContactDAO.swift in Sources */, 4B6D20EC2164D4AB003ADB29 /* DeliveryStatus.swift in Sources */, + 9B804AD9219EFA66000606EC /* ParticipantsHistoryViewControllerLayout.swift in Sources */, 4B7C73F3215A5509007924DB /* LogWriter.swift in Sources */, 262D43872033417F002F1E45 /* FriendExtansion+BERT.swift in Sources */, 2600CCC1216D47DC00EDC9C3 /* OptionallyActionCellViewModel.swift in Sources */, FE58F9B1208F00FE004AFDD3 /* MessageEditActionTable.swift in Sources */, + 9B804ADF219EFCD1000606EC /* ParticipantsHistoryWireframe.swift in Sources */, F105C6A0209F71BF0091786A /* CameraInteractor.swift in Sources */, 4B4266BA204D898900194BC1 /* ForwardSelectorDisplayMode.swift in Sources */, 8572C3B92092364C00E4840C /* StickerPackageDataSource.swift in Sources */, A42D51B6206A361400EEB952 /* iter.swift in Sources */, 9B967098215151760058E98F /* LeaveVoiceMessageViewController.swift in Sources */, 2603139E20A0A4BA009AC66D /* ChatLanguageSettingsPresenter.swift in Sources */, + 9B804AD8219EFA66000606EC /* ParticipantsHistoryViewController.swift in Sources */, 4B1D7DFC2029C37900703228 /* FavoritesItemsFactory.swift in Sources */, 26771CC3212ED109006112B5 /* DBConvertMessage.swift in Sources */, 269848CA200E9F1300590D6F /* StarModels.swift in Sources */, @@ -15197,6 +15261,7 @@ 00E9824C205C1E19008BF03D /* SecurityItemsFactory.swift in Sources */, 26342CA920ECBAEF00D2196B /* TranscribeNetworkClient.swift in Sources */, 852003F620D4194A007C0036 /* DBRecentSticker.swift in Sources */, + 9B804ADD219EFC7B000606EC /* ParticipantsHistoryInteractor.swift in Sources */, 267BE2831FDE905D00C47E18 /* SettingsProtocols.swift in Sources */, 264638231FFFE269002590E6 /* RepliesHeaderView.swift in Sources */, 263D66331FE8D95100A509F8 /* TypingHandler.swift in Sources */, @@ -15244,6 +15309,7 @@ 85E1DD2720BEE961008AD211 /* ScalableCell.swift in Sources */, 5BC1D37B20D3B4A8002A44B3 /* GroupAddParticipantsCollectionViewCell.swift in Sources */, 269D9DF01FC3AF0D00324263 /* CGSizeExtension.swift in Sources */, + 9B804AD5219EF9E1000606EC /* ParticipantsHistoryProtocols.swift in Sources */, 4BB0EFBD2151347900704136 /* AlertManager.swift in Sources */, D30EB73829E48C0B1C1FD1C9 /* LoginViewController.swift in Sources */, FEA65471216775CD00B44029 /* ServiceWalletExtension.swift in Sources */, @@ -16321,6 +16387,7 @@ 0062D9422062EC4100B915AC /* InviteFriendsSelectionViewModel.swift in Sources */, A4679BA520B2DD0F0021FE9C /* SubscribersSelectorPresenter.swift in Sources */, F105C6BC20A1347E0091786A /* PhotoPreviewWireframeProtocol.swift in Sources */, + 9B294510219F1F1500F30EA7 /* ParticipantHistoryHeaderView.swift in Sources */, A43B25A620AB1DFA00FF8107 /* RecordingAudioWaveform.swift in Sources */, 26C1A3EB2031AAD20009F7F0 /* OtherUserInteractor.swift in Sources */, 26D8317520EA65200067C5B4 /* TranslationInfo.swift in Sources */, @@ -16612,6 +16679,7 @@ 8562853220D140FC000C9739 /* InputBar+ButtonType.swift in Sources */, A43B25AC20AB1DFA00FF8107 /* BaseInputView.swift in Sources */, F127F3BA20BF03BF007A6F87 /* DateFormatterExtension.swift in Sources */, + 9B804ADB219EFBE8000606EC /* ParticipantsHistoryPresenter.swift in Sources */, 4B3B35D9217119BF005A214A /* AmazonInitializerImpl.swift in Sources */, B7B546AE210D9C8C002DCA55 /* CircleView.swift in Sources */, E79061B81FBF2243009FD83A /* FeatureTable.swift in Sources */, diff --git a/Nynja/Generated/LocalizableConstants.swift b/Nynja/Generated/LocalizableConstants.swift index e95a07b85..09d8c4f25 100644 --- a/Nynja/Generated/LocalizableConstants.swift +++ b/Nynja/Generated/LocalizableConstants.swift @@ -156,6 +156,8 @@ internal extension String { static var callHistoryLogStatusMissed: String { return localizable.tr("Localizable", "call_history_log_status_missed") } /// Unanswered Call static var callHistoryLogStatusUnanswered: String { return localizable.tr("Localizable", "call_history_log_status_unanswered") } + /// started a call + static var callHistoryParticipantStartedCall: String { return localizable.tr("Localizable", "call_history_participant_started_call") } /// call history static var callHistoryTitle: String { return localizable.tr("Localizable", "call_history_title") } /// Yesterday @@ -1158,7 +1160,7 @@ internal extension String { static var tpTranslation: String { return localizable.tr("Localizable", "tp_translation") } /// Translation failed. Please try again. static var tpTranslationFailed: String { return localizable.tr("Localizable", "tp_translation_failed") } - /// Original and translated messages language is the same. + /// Original and translated message are the same language. static var tpTranslationLanguageIsEqual: String { return localizable.tr("Localizable", "tp_translation_language_is_equal") } /// Transcribe with Google static var transcribe: String { return localizable.tr("Localizable", "transcribe") } diff --git a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift index bc67ba988..84cb1fb63 100644 --- a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift +++ b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift @@ -16,7 +16,7 @@ protocol CallHistoryWireFrameProtocol: class { func closeController() func showContact(contact:Contact) - func showRoom(room:Room) + func show(callLog: NYNCallLog) func callBackFor(contact:Contact) func callBackVideoFor(contact:Contact) func callBackFor(room:Room) @@ -45,7 +45,7 @@ protocol CallHistoryPresenterProtocol: BasePresenterProtocol, NavigationProtocol func findContactBy(phoneId:String)-> Contact? func findRoomBy(roomId:String)-> Room? func showContact(contact: Contact) - func showRoom(room: Room) + func show(callLog: NYNCallLog) func clearCallHistory() func callBackFor(contact:Contact) func callBackVideoFor(contact:Contact) diff --git a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift index 5f4e5fef8..7c92ee02d 100644 --- a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift +++ b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift @@ -8,7 +8,7 @@ import UIKit -class CallHistoryPresenter: BasePresenter, CallHistoryPresenterProtocol, CallHistoryInteractorOutputProtocol { +class CallHistoryPresenter: BasePresenter, CallHistoryPresenterProtocol, CallHistoryInteractorOutputProtocol { override var itemsFactory: WCItemsFactory? { return CallHistoryItemsFactory() @@ -43,8 +43,8 @@ class CallHistoryPresenter: BasePresenter, CallHistoryPresenterProtocol, CallHis self.wireFrame.showContact(contact: contact) } - func showRoom(room: Room) { - self.wireFrame.showRoom(room: room) + func show(callLog: NYNCallLog) { + self.wireFrame.show(callLog: callLog) } func clearCallHistory() { diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index f24f4751c..4ee5469cb 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -416,9 +416,7 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe presenter.showContact(contact: contact) } } else { - if let room = presenter.findRoomBy(roomId: m.address) { - presenter.showRoom(room: room) - } + presenter.show(callLog: NYNCallLog()) } } } diff --git a/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift b/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift index 7e531cb37..2d7b56647 100644 --- a/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift +++ b/Nynja/Modules/CallHistory/WireFrame/CallHistoryWireFrame.swift @@ -43,8 +43,8 @@ class CallHistoryWireFrame: CallHistoryWireFrameProtocol { mainWF?.showAddContact(contact: contact) } - func showRoom(room:Room) { - mainWF?.showAddParticipantsToViewFromHistory(room: room) + func show(callLog: NYNCallLog){ + mainWF?.showAddParticipantsToViewFromHistory(callLog: callLog) } func callBackFor(contact:Contact) { diff --git a/Nynja/Modules/Main/WireFrame/MainWireframe.swift b/Nynja/Modules/Main/WireFrame/MainWireframe.swift index 7a9735d8f..09e5ad13e 100644 --- a/Nynja/Modules/Main/WireFrame/MainWireframe.swift +++ b/Nynja/Modules/Main/WireFrame/MainWireframe.swift @@ -467,15 +467,11 @@ class MainWireFrame: MainWireFrameProtocol, NynjaCommunicatorServiceDelegate { // MARK: Add Participants to group call - func showAddParticipantsToViewFromHistory(room: Room) { - - if let mem = room.allMembers { - ParticipantsWireFrame().present(navigation: contentNavigation!, main: self, contacts: mem) - } + func showAddParticipantsToViewFromHistory(callLog: NYNCallLog) { + ParticipantsHistoryWireFrame().present(navigation: contentNavigation!, main: self, callLog: callLog) } func showAddParticipantsToCreateCallWith(room: Room) { - AddParticipantsWireFrame().presentAddParticipants(navigation: contentNavigation!, main: self, selectedContacts: [], delegate: self.external, mode: .createGroupCall, members: room.allMembers, room: room) } diff --git a/Nynja/Modules/ParticipantsHistory/View/ParticipantHistoryHeaderView.swift b/Nynja/Modules/ParticipantsHistory/View/ParticipantHistoryHeaderView.swift new file mode 100644 index 000000000..2e6d734b4 --- /dev/null +++ b/Nynja/Modules/ParticipantsHistory/View/ParticipantHistoryHeaderView.swift @@ -0,0 +1,106 @@ +// +// ParticipantHistoryHeaderView.swift +// Nynja +// +// Created by Bozhko Terziev on 16.11.18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import UIKit + +class ParticipantHistoryHeaderView: UIView { + + private lazy var avatarImageView: UIImageView = { + let av = UIImageView() + av.contentMode = .scaleToFill + av.layer.cornerRadius = CGFloat(Constraints.avatar.height/2) + av.backgroundColor = UIColor.nynja.lightGray + av.clipsToBounds = true + av.layer.borderWidth = 1.0 + av.layer.borderColor = UIColor.nynja.callGreen.cgColor + + self.addSubview(av) + av.snp.makeConstraints { (make) in + make.left.equalToSuperview().offset(Constraints.avatar.leftOffset) + make.centerY.equalToSuperview() + make.height.width.equalTo(Constraints.avatar.height) + } + + return av + }() + + private lazy var nameLabel: UILabel = { + let label = UILabel() + label.textAlignment = .left + label.font = UIFont.makeFont(with: FontFamily.NotoSans.regular.name, height: 22.0) + label.textColor = UIColor.nynja.white + label.backgroundColor = UIColor.nynja.clear + label.text = "Carlos Caytanu Bledorn Veri" + + self.addSubview(label) + label.snp.makeConstraints { (make) in + make.left.equalTo(avatarImageView.snp.right).offset(Constraints.labelName.leftOffset) + make.centerY.equalTo(avatarImageView.snp.centerY) + } + + return label + }() + + private lazy var infoLabel: UILabel = { + let label = UILabel() + label.textAlignment = .right + label.font = UIFont.makeFont(with: FontFamily.NotoSans.regular.name, height: 16.0) + label.textColor = UIColor.nynja.lightGray + label.backgroundColor = UIColor.nynja.clear + label.text = String.localizable.callHistoryParticipantStartedCall + + self.addSubview(label) + label.snp.makeConstraints { (make) in + make.right.equalToSuperview().offset(-Constraints.labelTime.rightOffset) + make.centerY.equalTo(nameLabel.snp.centerY) + make.left.equalTo(nameLabel.snp.right).offset(Constraints.labelTime.horInset) + } + + return label + }() + + // MARK: - Init + + override init(frame: CGRect) { + super.init(frame: frame) + baseSetup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + baseSetup() + } + + private func baseSetup() { + self.backgroundColor = UIColor.nynja.clear + self.avatarImageView.isHidden = false + self.infoLabel.isHidden = false + self.nameLabel.isHidden = false + } +} + +extension ParticipantHistoryHeaderView { + + struct Constraints { + + struct avatar { + static let leftOffset = 16.0 + static let height = 44.0 + } + + struct labelName { + static let leftOffset = 16.0 + static let topOffset = 11.0 + } + + struct labelTime { + static let rightOffset = 16.0 + static let horInset = 5.0 + } + } +} diff --git a/Nynja/Resources/en.lproj/Localizable.strings b/Nynja/Resources/en.lproj/Localizable.strings index 1a0e9d603..b66100fa0 100644 --- a/Nynja/Resources/en.lproj/Localizable.strings +++ b/Nynja/Resources/en.lproj/Localizable.strings @@ -1006,4 +1006,5 @@ "call_history_log_dir_inbound" = "Incoming Call"; "call_history_log_dir_outbound" = "Outgoing Call"; "call_history_clear_question_alert" = "Are you sure you want to clear all call history?"; +"call_history_participant_started_call" = "started a call"; -- GitLab From 96e0c16315ef960e6151f932f9f577c68a48d21c Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Mon, 19 Nov 2018 08:47:48 +0200 Subject: [PATCH 13/59] Added forgotten files --- .../ParticipantsHistoryInteractor.swift | 116 +++++++++++++ .../ParticipantsHistoryProtocols.swift | 80 +++++++++ .../ParticipantsHistoryPresenter.swift | 73 ++++++++ .../ParticipantsHistoryViewController.swift | 160 ++++++++++++++++++ ...ticipantsHistoryViewControllerLayout.swift | 40 +++++ .../ParticipantsHistoryWireframe.swift | 54 ++++++ 6 files changed, 523 insertions(+) create mode 100644 Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift create mode 100644 Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift create mode 100644 Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift create mode 100644 Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift create mode 100644 Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewControllerLayout.swift create mode 100644 Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift diff --git a/Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift b/Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift new file mode 100644 index 000000000..56b5d241d --- /dev/null +++ b/Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift @@ -0,0 +1,116 @@ +// +// ParticipantsHistoryInteractor.swift +// Project +// +// Created by Bozhko Terziev on 15/11/2018. +// Copyright © 2018 Softavail. All rights reserved. +// + + +class ParticipantsHistoryInteractor: BaseInteractor, ParticipantsHistoryInteractorInputProtocol, IoHandlerDelegate { + + weak var presenter: ParticipantsHistoryInteractorOutputProtocol! + + var includedMembers: [Member] = [] + + private var participants: [Participant] = [] + + override init() { + super.init() + IoHandler.delegate = self + } + + + //MARK: - BaseInteractor + + override func loadData() { + super.loadData() + self.loadContacts() + } + + + // MARK: - StorageSubscriber + + override var subscribes: [SubscribeType]? { + return [.room(nil)] + } + + override func update(with changes: [StorageChange], type: SubscribeType) { + if case .room = type { + guard let dbRoom = changes.first?.entity as? DBRoom else { return } + guard let updatedMembers = Room(room: dbRoom).allMembers else { return } + self.includedMembers = updatedMembers + self.loadContacts() + } + } + + + //MARK: - ParticipantsHistoryInteractorInputProtocol + + func filterParticipants(with text: String) { + let filtered = participants.filter { + guard let name = $0.contact.nick ?? $0.contact.fullName else { + return false + } + return name.starts(with: text, by: { String($0).lowercased() == String($1).lowercased() }) + } + presenter.participantsFiltered(filtered) + } + + func findContact(by contact: Contact) { + guard let myPhoneId = StorageService.sharedInstance.phoneId else { return } + if contact.phoneId == myPhoneId { + presenter.showMyProfile() + } else if let contact = ContactDAO.findContactBy(phoneId: contact.phoneId) { + presenter.showProfile(contact) + } else { + guard let phoneNumber = contact.phoneNumber else { return } + MQTTService.sharedInstance.tryFindContact(number: phoneNumber) + } + } + + + //MARK: - IoHandlerDelegate + + func getContactSuccess(contact: Contact) { + self.presenter.showProfile(contact) + } + + func contactNotFound() { + self.presenter.showContactNotFound() + } + + + //MARK: - Private + + private func loadContacts() { + let contacts = ContactDAO.fetchContacts(with: [.friend, .ban, .banned]) + mapToParticipants(contacts) + } + + private func mapToParticipants(_ contacts: [Contact]) { + let mergedContacts = mergeMembersWith(contacts) + participants = mergedContacts.map{ makeParticipantFromContact($0.contact, isAdmin: $0.isAdmin, alias: $0.alias) } + presenter.participantsFetched(participants) + } + + private func makeParticipantFromContact(_ contact: Contact, isAdmin: Bool, alias: String?) -> Participant { + let participant = Participant(contact: contact) + participant.isSelectable = false + participant.showAdmin = isAdmin + participant.alias = alias + return participant + } + + private func mergeContactFrom(contacts: [Contact], with member: Member) -> Contact { + return contacts.first { $0.phone_id == member.phone_id } ?? Contact(member: member) + } + + private func mergeMembersWith(_ contacts: [Contact]) -> [(contact: Contact, isAdmin: Bool, alias: String?)] { + return includedMembers.map { + let contact = mergeContactFrom(contacts: contacts, with: $0) + let isAdmin = $0.memberStatus == .admin + return (contact, isAdmin, $0.alias) + } + } +} diff --git a/Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift b/Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift new file mode 100644 index 000000000..afd8c3d10 --- /dev/null +++ b/Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift @@ -0,0 +1,80 @@ +// +// ParticipantsHistoryProtocols.swift +// Project +// +// Created by Bozhko Terziev on 15/11/2018. +// Copyright © 2018 Softavail. All rights reserved. +// + +import UIKit + +protocol ParticipantsHistoryWireFrameProtocol: class { + + func present(navigation: UINavigationController, main: MainWireFrame?, callLog: NYNCallLog) + + /** + * Add here your methods for communication PRESENTER -> WIREFRAME + */ + func hide() + + func showMyProfileScreen() + func showProfileScreen(contact: Contact) + func closeController() +} + +protocol ParticipantsHistoryViewProtocol: class { + + var presenter: ParticipantsHistoryPresenterProtocol! { get set } + + /** + * Add here your methods for communication PRESENTER -> VIEW + */ + func setupParticipants(_ participants: GroupedParticipants) + func updateParticipantsList(_ participants: GroupedParticipants) +} + +protocol ParticipantsHistoryPresenterProtocol: BasePresenterProtocol, NavigationProtocol { + + var view: ParticipantsHistoryViewProtocol! { get set } + var interactor: ParticipantsHistoryInteractorInputProtocol! { get set } + var wireFrame: ParticipantsHistoryWireFrameProtocol! { get set } + + + /** + * Add here your methods for communication VIEW -> PRESENTER + */ + func hide() + + func filter(with text: String) + + func didTapMember(_ member: Participant) + + func closeController() +} + +protocol ParticipantsHistoryInteractorOutputProtocol: class { + + /** + * Add here your methods for communication INTERACTOR -> PRESENTER + */ + func participantsFetched(_ participants: [Participant]) + func participantsFiltered(_ participants: [Participant]) + + func showMyProfile() + func showProfile(_ contact: Contact) + func showContactNotFound() +} + +protocol ParticipantsHistoryInteractorInputProtocol: BaseInteractorProtocol { + + var presenter: ParticipantsHistoryInteractorOutputProtocol! { get set } + + var includedMembers: [Member] { get set } + /** + * Add here your methods for communication PRESENTER -> INTERACTOR + */ + + func filterParticipants(with text: String) + + func findContact(by contact: Contact) +} diff --git a/Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift b/Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift new file mode 100644 index 000000000..cd3180543 --- /dev/null +++ b/Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift @@ -0,0 +1,73 @@ +// +// ParticipantsHistoryPresenter.swift +// Project +// +// Created by Bozhko Terziev on 15/11/2018. +// Copyright © 2018 Softavail. All rights reserved. +// + +class ParticipantsHistoryPresenter: BasePresenter, ParticipantsHistoryPresenterProtocol, ParticipantsHistoryInteractorOutputProtocol { + + //MARK: - NavigationProtocol + + func back() { + closeController() + } + + //MARK: - BasePresenter + + override var itemsFactory: WCItemsFactory? { + return GroupOptionsItemsFactory() + } + + //MARK: - ParticipantsHistoryPresenterProtocol + + weak var view: ParticipantsHistoryViewProtocol! + var interactor: ParticipantsHistoryInteractorInputProtocol! { + didSet { + _interactor = interactor + } + } + var wireFrame: ParticipantsHistoryWireFrameProtocol! + + func hide() { + wireFrame.hide() + } + + //MARK: - Actions + + func filter(with text: String) { + interactor.filterParticipants(with: text) + } + + func didTapMember(_ member: Participant) { + interactor.findContact(by: member.contact) + } + + + //MARK: - ParticipantsHistoryInteractorOutputProtocol + + func participantsFetched(_ participants: [Participant]) { + view.setupParticipants(participants.groupedByAlias()) + } + + func participantsFiltered(_ participants: [Participant]) { + view.setupParticipants(participants.groupedByAlias()) + } + + func showMyProfile() { + wireFrame.showMyProfileScreen() + } + + func showProfile(_ contact: Contact) { + wireFrame.showProfileScreen(contact: contact) + } + + func showContactNotFound() { + AlertManager.sharedInstance.showAlertOk(message: String.localizable.profileNotFound) + } + + func closeController() { + wireFrame.closeController() + } +} diff --git a/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift b/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift new file mode 100644 index 000000000..d9f44185b --- /dev/null +++ b/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift @@ -0,0 +1,160 @@ +// +// ParticipantsHistoryProtocols.swift +// Project +// +// Created by Bozhko Terziev on 15/11/2018. +// Copyright © 2018 Softavail. All rights reserved. +// + +import UIKit + +class ParticipantsHistoryViewController: BaseVC, ParticipantsHistoryViewProtocol, KeyboardInteractive { + + var presenter: ParticipantsHistoryPresenterProtocol! { + didSet { + _presenter = presenter + } + } + + private let bottomInset = Constraints.controlContainerView.bottomInset.adjustedByWidth + + var participantsDataSource: ParticipantsDataSource! + var participantsDelegate: ParticipantsDelegate! + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + self.tableHeaderView.snp.updateConstraints { make in + + make.top.left.equalToSuperview() + make.height.equalTo(Constraints.headerTableView.height) + make.width.equalTo(UIScreen.main.bounds.size.width) + } + } + + // MARK: - Views + + private lazy var tableHeaderView:ParticipantHistoryHeaderView = { + let header = ParticipantHistoryHeaderView() + + return header + } () + + private lazy var tableView: UITableView = { + let tblView = UITableView() + + tblView.backgroundColor = UIColor.nynja.clear + tblView.separatorStyle = .none + tblView.tableFooterView = UIView() + tblView.showsHorizontalScrollIndicator = false + tblView.rowHeight = ParticipantsContactCell.Constraints.height + tblView.estimatedRowHeight = tblView.rowHeight + tblView.sectionHeaderHeight = ParticipantsHeaderView.height + tblView.estimatedSectionHeaderHeight = tblView.sectionHeaderHeight + + self.view.addSubview(tblView) + tblView.snp.makeConstraints { make in + make.top.equalTo(navigationView.snp.bottom) + make.left.right.bottom.equalToSuperview() + } + + return tblView + }() + + + var scrollBar: ScrollBar! + + + // MARK: - BaseVC + + override func initialize() { + super.initialize() + self.navigationView.isSeparatorVisible = false + + let title:String = String.localizable.callHistoryTitle.uppercased() + let backBtnImage:UIImage? = UIImage.nynja.icBackNavigation.image + let navHandler:NavigationProtocol? = presenter + + navigationView.configure(config: NavigationView.Config( + isVisibleSeparator: navigationView.isSeparatorVisible ?? false, + isVisibleBackButton: (nil != backBtnImage), + title: title, + navigationHandler: navHandler, + backButtonImage: backBtnImage) + ) + + screenTitle = title + + self.tableView.tableHeaderView = self.tableHeaderView + + configure() + } + + // MARK: Configure + + private func configure() { + configureTableView() + } + + private func configureTableView() { + tableView.register(ParticipantsContactCell.self, forCellReuseIdentifier: ParticipantsContactCell.cellId) + tableView.register(headerFooter: ParticipantsHeaderView.self) + + participantsDataSource = ParticipantsDataSource() + tableView.dataSource = participantsDataSource + + participantsDelegate = ParticipantsDelegate() + participantsDelegate.actionsDelegate = self + + tableView.delegate = participantsDelegate + + scrollBar = ScrollBar(scrollView: tableView) + participantsDelegate.scrollBar = scrollBar + } + +// private func createLayout() -> UICollectionViewLayout { +// let layout = UICollectionViewFlowLayout() +// +// let horizontalInset = Constraints.avatarsView.horizontalInset.adjustedByWidth +// let side = Constraints.avatarsView.height.adjustedByWidth +// +// layout.sectionInset = UIEdgeInsets(top: 0, left: horizontalInset, bottom: 0, right: horizontalInset) +// layout.itemSize = CGSize(width: side, height: side) +// layout.minimumInteritemSpacing = horizontalInset +// layout.scrollDirection = .horizontal +// +// return layout +// } + + + // MARK: - Actions + + @objc private func doneTapped(_ button: UIButton) { + view.endEditing(true) + presenter.hide() + } + + // MARK: - Keyboard + + func keyboardNotified(endFrame: CGRect) { + } + + // MARK: - AddParticipantsViewProtocol + + func updateParticipantsList(_ participants: GroupedParticipants) { + participantsDataSource.groupedParticipants = participants + tableView.reloadData() + } + + func setupParticipants(_ participants: GroupedParticipants) { + participantsDataSource.groupedParticipants = participants + tableView.reloadData() + } +} + + +extension ParticipantsHistoryViewController: ParticipantsActionsDelegate { + + func participantTapped(_ participant: Participant) { + presenter.didTapMember(participant) + } +} diff --git a/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewControllerLayout.swift b/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewControllerLayout.swift new file mode 100644 index 000000000..b67912c6a --- /dev/null +++ b/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewControllerLayout.swift @@ -0,0 +1,40 @@ +// +// ParticipantsHistoryViewControllerLayout.swift +// Project +// +// Created by Bozhko Terziev on 15/11/2018. +// Copyright © 2018 Softavail. All rights reserved. +// + +extension ParticipantsHistoryViewController { + + struct Constraints { + + struct avatarsView { + static let height: CGFloat = 44.0 + + static let topInset = 8.0 + static let horizontalInset: CGFloat = 16.0 + } + + struct tableView { + static let topInset = 16.0 + } + + struct headerTableView { + static let height = 64.0 + } + + struct controlContainerView { + static let bottomInset: CGFloat = 28.0 + } + + struct doneButton { + static let width: CGFloat = 82.0 + static let height: CGFloat = 44.0 + + static let rightInset: CGFloat = 48.0 + static let contentRightInset: CGFloat = 16.0 + } + } +} diff --git a/Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift b/Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift new file mode 100644 index 000000000..a226539f6 --- /dev/null +++ b/Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift @@ -0,0 +1,54 @@ +// +// ParticipantsHistoryWireframe.swift +// Project +// +// Created by Bozhko Terziev on 15/11/2018. +// Copyright © 2018 Softavail. All rights reserved. +// + +import UIKit + +class ParticipantsHistoryWireFrame: ParticipantsHistoryWireFrameProtocol { + + weak var navigation: UINavigationController? + weak var main: MainWireFrame? + + func present(navigation: UINavigationController, + main: MainWireFrame?, + callLog: NYNCallLog) { + let view = ParticipantsHistoryViewController() + let presenter = ParticipantsHistoryPresenter() + let interactor = ParticipantsHistoryInteractor() + + self.navigation = navigation + self.main = main + + interactor.includedMembers = [] + + // Connecting + view.presenter = presenter + presenter.view = view + presenter.wireFrame = self + presenter.interactor = interactor + interactor.presenter = presenter + + navigation.pushViewController(view, animated: true) + } + + func hide() { + // TODO: implement transition to the 'Group Details' screen. + navigation?.popViewController(animated: true) + } + + func showMyProfileScreen() { + main?.showProfile() + } + + func showProfileScreen(contact: Contact) { + main?.showAddContact(contact: contact) + } + + func closeController() { + self.navigation?.popViewController(animated: true) + } +} -- GitLab From 215085c172d1cb8c88e2f50b0fdef95f3fe0152f Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Mon, 19 Nov 2018 16:51:34 +0200 Subject: [PATCH 14/59] Finished call info from call history screen --- .../View/CallHistoryViewController.swift | 2 +- .../ParticipantsHistoryInteractor.swift | 13 +++++ .../ParticipantsHistoryProtocols.swift | 4 ++ .../ParticipantsHistoryPresenter.swift | 4 ++ .../View/ParticipantHistoryHeaderView.swift | 6 +- .../ParticipantsHistoryViewController.swift | 58 ++++++++----------- ...ticipantsHistoryViewControllerLayout.swift | 2 +- .../ParticipantsHistoryWireframe.swift | 14 ++++- 8 files changed, 64 insertions(+), 39 deletions(-) diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index 4ee5469cb..e7414d391 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -416,7 +416,7 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe presenter.showContact(contact: contact) } } else { - presenter.show(callLog: NYNCallLog()) + presenter.show(callLog: m.log) } } } diff --git a/Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift b/Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift index 56b5d241d..9ddeef7cc 100644 --- a/Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift +++ b/Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift @@ -69,6 +69,19 @@ class ParticipantsHistoryInteractor: BaseInteractor, ParticipantsHistoryInteract } } + func getCallHost()->Contact? { + if includedMembers.count > 0 { + let mem = includedMembers[0] + + if let phone = mem.phone_id { + if let ctc = ContactDAO.findContactBy(phoneId: phone) { + return ctc + } + } + } + + return nil + } //MARK: - IoHandlerDelegate diff --git a/Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift b/Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift index afd8c3d10..ec2dfbf1a 100644 --- a/Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift +++ b/Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift @@ -50,6 +50,8 @@ protocol ParticipantsHistoryPresenterProtocol: BasePresenterProtocol, Navigation func didTapMember(_ member: Participant) func closeController() + + func getCallHost()->Contact? } protocol ParticipantsHistoryInteractorOutputProtocol: class { @@ -77,4 +79,6 @@ protocol ParticipantsHistoryInteractorInputProtocol: BaseInteractorProtocol { func filterParticipants(with text: String) func findContact(by contact: Contact) + + func getCallHost()->Contact? } diff --git a/Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift b/Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift index cd3180543..29f2da744 100644 --- a/Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift +++ b/Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift @@ -34,6 +34,10 @@ class ParticipantsHistoryPresenter: BasePresenter, ParticipantsHistoryPresenterP wireFrame.hide() } + func getCallHost()->Contact? { + return interactor.getCallHost() + } + //MARK: - Actions func filter(with text: String) { diff --git a/Nynja/Modules/ParticipantsHistory/View/ParticipantHistoryHeaderView.swift b/Nynja/Modules/ParticipantsHistory/View/ParticipantHistoryHeaderView.swift index 2e6d734b4..f4f807ba0 100644 --- a/Nynja/Modules/ParticipantsHistory/View/ParticipantHistoryHeaderView.swift +++ b/Nynja/Modules/ParticipantsHistory/View/ParticipantHistoryHeaderView.swift @@ -10,7 +10,7 @@ import UIKit class ParticipantHistoryHeaderView: UIView { - private lazy var avatarImageView: UIImageView = { + lazy var avatarImageView: UIImageView = { let av = UIImageView() av.contentMode = .scaleToFill av.layer.cornerRadius = CGFloat(Constraints.avatar.height/2) @@ -29,13 +29,13 @@ class ParticipantHistoryHeaderView: UIView { return av }() - private lazy var nameLabel: UILabel = { + lazy var nameLabel: UILabel = { let label = UILabel() label.textAlignment = .left label.font = UIFont.makeFont(with: FontFamily.NotoSans.regular.name, height: 22.0) label.textColor = UIColor.nynja.white label.backgroundColor = UIColor.nynja.clear - label.text = "Carlos Caytanu Bledorn Veri" + label.text = "" self.addSubview(label) label.snp.makeConstraints { (make) in diff --git a/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift b/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift index d9f44185b..360ff2aad 100644 --- a/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift +++ b/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift @@ -21,23 +21,13 @@ class ParticipantsHistoryViewController: BaseVC, ParticipantsHistoryViewProtocol var participantsDataSource: ParticipantsDataSource! var participantsDelegate: ParticipantsDelegate! - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - self.tableHeaderView.snp.updateConstraints { make in - - make.top.left.equalToSuperview() - make.height.equalTo(Constraints.headerTableView.height) - make.width.equalTo(UIScreen.main.bounds.size.width) - } + + override func viewDidLoad() { + super.viewDidLoad() } - + // MARK: - Views - private lazy var tableHeaderView:ParticipantHistoryHeaderView = { - let header = ParticipantHistoryHeaderView() - - return header - } () private lazy var tableView: UITableView = { let tblView = UITableView() @@ -53,13 +43,25 @@ class ParticipantsHistoryViewController: BaseVC, ParticipantsHistoryViewProtocol self.view.addSubview(tblView) tblView.snp.makeConstraints { make in - make.top.equalTo(navigationView.snp.bottom) + make.top.equalTo(tableHeaderView.snp.bottom) make.left.right.bottom.equalToSuperview() } return tblView }() + private lazy var tableHeaderView:ParticipantHistoryHeaderView = { + let header = ParticipantHistoryHeaderView() + + self.view.addSubview(header) + header.snp.updateConstraints { make in + make.top.equalTo(navigationView.snp.bottom) + make.left.right.equalToSuperview() + make.height.equalTo(Constraints.headerTableView.height) + } + + return header + } () var scrollBar: ScrollBar! @@ -84,12 +86,17 @@ class ParticipantsHistoryViewController: BaseVC, ParticipantsHistoryViewProtocol screenTitle = title - self.tableView.tableHeaderView = self.tableHeaderView - configure() + setupCallHost() } // MARK: Configure + private func setupCallHost() { + if let contact = presenter.getCallHost() { + tableHeaderView.nameLabel.text = "\(contact.names ?? "") \(contact.surnames ?? "")" + tableHeaderView.avatarImageView.setImage(url: contact.avatarUrl, placeHolder: UIImage.nynja.Contacts.avaPlaceholder.image) + } + } private func configure() { configureTableView() @@ -110,22 +117,7 @@ class ParticipantsHistoryViewController: BaseVC, ParticipantsHistoryViewProtocol scrollBar = ScrollBar(scrollView: tableView) participantsDelegate.scrollBar = scrollBar } - -// private func createLayout() -> UICollectionViewLayout { -// let layout = UICollectionViewFlowLayout() -// -// let horizontalInset = Constraints.avatarsView.horizontalInset.adjustedByWidth -// let side = Constraints.avatarsView.height.adjustedByWidth -// -// layout.sectionInset = UIEdgeInsets(top: 0, left: horizontalInset, bottom: 0, right: horizontalInset) -// layout.itemSize = CGSize(width: side, height: side) -// layout.minimumInteritemSpacing = horizontalInset -// layout.scrollDirection = .horizontal -// -// return layout -// } - - + // MARK: - Actions @objc private func doneTapped(_ button: UIButton) { diff --git a/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewControllerLayout.swift b/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewControllerLayout.swift index b67912c6a..f62c6ebd4 100644 --- a/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewControllerLayout.swift +++ b/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewControllerLayout.swift @@ -22,7 +22,7 @@ extension ParticipantsHistoryViewController { } struct headerTableView { - static let height = 64.0 + static let height = 84.0 } struct controlContainerView { diff --git a/Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift b/Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift index a226539f6..b8ee57ad2 100644 --- a/Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift +++ b/Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift @@ -23,7 +23,19 @@ class ParticipantsHistoryWireFrame: ParticipantsHistoryWireFrameProtocol { self.navigation = navigation self.main = main - interactor.includedMembers = [] + var members = [Member]() + + for i in 0.. Date: Mon, 19 Nov 2018 19:50:20 +0200 Subject: [PATCH 15/59] added call items in main wheel --- Nynja.xcodeproj/project.pbxproj | 4 ++++ Nynja/ChatItemsFactory.swift | 14 +++++++------- Nynja/Modules/Main/View/MainNavigationItem.swift | 2 ++ .../View/MainViewController+NavigateProtocol.swift | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 68f9f0cd6..062cedb64 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -1201,6 +1201,7 @@ 9B96709C215151B50058E98F /* LeaveVoiceMessageInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B96709B215151B50058E98F /* LeaveVoiceMessageInteractor.swift */; }; 9B96709E215151D20058E98F /* LeaveVoiceMessageWireFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B96709D215151D20058E98F /* LeaveVoiceMessageWireFrame.swift */; }; 9B9670A02152356D0058E98F /* LeaveVoiceMessageProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B96709F2152356D0058E98F /* LeaveVoiceMessageProtocols.swift */; }; + 9B9D439521A327550000A189 /* CallsItemsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B9D439421A327550000A189 /* CallsItemsFactory.swift */; }; 9BB33F3E2146A14B009FB252 /* HoldToSpeakView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BB33F3D2146A14B009FB252 /* HoldToSpeakView.swift */; }; 9BB33F412146CC7C009FB252 /* CallInProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BB33F402146CC7C009FB252 /* CallInProgressView.swift */; }; 9BC9657620FF042E00052AE1 /* CallInProgressProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BC9657520FF042D00052AE1 /* CallInProgressProtocols.swift */; }; @@ -3456,6 +3457,7 @@ 9B96709B215151B50058E98F /* LeaveVoiceMessageInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaveVoiceMessageInteractor.swift; sourceTree = ""; }; 9B96709D215151D20058E98F /* LeaveVoiceMessageWireFrame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaveVoiceMessageWireFrame.swift; sourceTree = ""; }; 9B96709F2152356D0058E98F /* LeaveVoiceMessageProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaveVoiceMessageProtocols.swift; sourceTree = ""; }; + 9B9D439421A327550000A189 /* CallsItemsFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallsItemsFactory.swift; sourceTree = ""; }; 9BB33F3D2146A14B009FB252 /* HoldToSpeakView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HoldToSpeakView.swift; sourceTree = ""; }; 9BB33F402146CC7C009FB252 /* CallInProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallInProgressView.swift; sourceTree = ""; }; 9BC9657520FF042D00052AE1 /* CallInProgressProtocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallInProgressProtocols.swift; sourceTree = ""; }; @@ -6588,6 +6590,7 @@ 4B1D7DFF2029C4A900703228 /* Options */, 4B06D30B2028A25D003B275B /* HomeItemsFactory.swift */, 4B1D7DFB2029C37900703228 /* FavoritesItemsFactory.swift */, + 9B9D439421A327550000A189 /* CallsItemsFactory.swift */, 4B1D7E062029D00000703228 /* OtherUserProfileItemsFactory.swift */, B7F5051C2061252100C28FA1 /* DataAndStorageItemsFactory.swift */, ); @@ -15801,6 +15804,7 @@ 8551CF1121708F7500829CF1 /* Array+Desc.swift in Sources */, A497F56720EFA538005CC60F /* HandlerFactory.swift in Sources */, 8557988820932401007050B8 /* StickerStaticMenuActionCellModel.swift in Sources */, + 9B9D439521A327550000A189 /* CallsItemsFactory.swift in Sources */, 267BE2921FDEA0C100C47E18 /* SettingsGroupInteractor.swift in Sources */, A43B25AB20AB1DFA00FF8107 /* ALTextView.swift in Sources */, 4BDC7E61203492CA00BCD381 /* TopSwipable.swift in Sources */, diff --git a/Nynja/ChatItemsFactory.swift b/Nynja/ChatItemsFactory.swift index 225efa4de..ba26b8421 100644 --- a/Nynja/ChatItemsFactory.swift +++ b/Nynja/ChatItemsFactory.swift @@ -64,13 +64,6 @@ class ChatItemsFactory: WCBaseItemsFactory { return item } - var clearHistory: ImageActionItemModel { - let item = ImageActionItemModel(nameImage: "ic_delete_context_menu", navItem: .clearHistory, action: { [weak navigateDelegate] (item, indexPath) in - navigateDelegate?.clearCallHistory(indexPath: indexPath) - }) - return item - } - // MARK: - Locations var recents: ImageFilledItemModel { @@ -113,6 +106,13 @@ class ChatItemsFactory: WCBaseItemsFactory { navigateDelegate?.showVideoCall(indexPath: indexPath) }) } + + var clearHistory: ImageActionItemModel { + let item = ImageActionItemModel(nameImage: "ic_delete_context_menu", navItem: .clearHistory, action: { [weak navigateDelegate] (item, indexPath) in + navigateDelegate?.clearCallHistory(indexPath: indexPath) + }) + return item + } var videoGroupCall: ImageFilledItemModel { return ImageFilledItemModel(nameImage: "ic_video", navItem: .videoCall, isSelectable: false, action: { [weak navigateDelegate] (item, indexPath) in diff --git a/Nynja/Modules/Main/View/MainNavigationItem.swift b/Nynja/Modules/Main/View/MainNavigationItem.swift index fc76d5569..577fbf14c 100644 --- a/Nynja/Modules/Main/View/MainNavigationItem.swift +++ b/Nynja/Modules/Main/View/MainNavigationItem.swift @@ -122,6 +122,8 @@ enum MainNavigationItem: String { anyClass = ContactsItemsFactory.self case .options: anyClass = OptionsItemsFactory.self + case .calls: + anyClass = CallsItemsFactory.self default: anyClass = nil } diff --git a/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift b/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift index 7ff194329..c7ca23db5 100644 --- a/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift +++ b/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift @@ -41,7 +41,7 @@ extension MainViewController: NavigateProtocol { } func showCalls(indexPath: IndexPath?) { - // TODO: will be implemented in future with 'Calls' module. + openNextLevel(indexPath: indexPath) } func showMarketplace(indexPath: IndexPath?) { -- GitLab From f0e4a86f37ab6c336656b9068132acbd739293c9 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Mon, 19 Nov 2018 19:50:37 +0200 Subject: [PATCH 16/59] added forgotten file --- Nynja/CallsItemsFactory.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Nynja/CallsItemsFactory.swift diff --git a/Nynja/CallsItemsFactory.swift b/Nynja/CallsItemsFactory.swift new file mode 100644 index 000000000..b561830f7 --- /dev/null +++ b/Nynja/CallsItemsFactory.swift @@ -0,0 +1,15 @@ +// +// GroupChatsItemsFactory.swift +// Nynja +// +// Created by Volodymyr Hryhoriev on 2/5/18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +class CallsItemsFactory: HomeItemsFactory { + + // MARK: - Second lvl + override var secondLevelItems: ItemModels { + return [callHistory, videoCall, voiceCall] + } +} -- GitLab From 64193bc9d22cf41acf49395a947db51b45db9786 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Tue, 20 Nov 2018 11:45:22 +0200 Subject: [PATCH 17/59] Polishing wheel items --- Nynja/CallHistoryItemsFactory.swift | 8 +++++++- Nynja/CallsItemsFactory.swift | 22 ++++++++++++++++++++-- Nynja/ChatItemsFactory.swift | 7 ------- Nynja/Modules/Main/View/ActionsItem.swift | 3 +-- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Nynja/CallHistoryItemsFactory.swift b/Nynja/CallHistoryItemsFactory.swift index 05c41e103..57fcefcab 100644 --- a/Nynja/CallHistoryItemsFactory.swift +++ b/Nynja/CallHistoryItemsFactory.swift @@ -6,11 +6,17 @@ // Copyright © 2018 Softavail. All rights reserved. // -class CallHistoryItemsFactory: ChatBaseFactory { +class CallHistoryItemsFactory: WCBaseItemsFactory { // MARK: - Second lvl override var secondLevelItems: ItemModels { return [clearHistory] } + var clearHistory: ImageActionItemModel { + let item = ImageActionItemModel(nameImage: "ic_delete_context_menu", navItem: .clearHistory, action: { [weak navigateDelegate] (item, indexPath) in + navigateDelegate?.clearCallHistory(indexPath: indexPath) + }) + return item + } } diff --git a/Nynja/CallsItemsFactory.swift b/Nynja/CallsItemsFactory.swift index b561830f7..52d523b88 100644 --- a/Nynja/CallsItemsFactory.swift +++ b/Nynja/CallsItemsFactory.swift @@ -6,10 +6,28 @@ // Copyright © 2018 TecSynt Solutions. All rights reserved. // -class CallsItemsFactory: HomeItemsFactory { +class CallsItemsFactory: WCBaseItemsFactory { // MARK: - Second lvl override var secondLevelItems: ItemModels { - return [callHistory, videoCall, voiceCall] + return [history, video, voice] + } + + var voice: ImageActionItemModel { + return ImageActionItemModel(nameImage: "ic_calls", navItem: .voiceCall, action: { [weak navigateDelegate] (item, indexPath) in + navigateDelegate?.conferenceVoiceCall(indexPath: indexPath) + }) + } + + var video: ImageActionItemModel { + return ImageActionItemModel(nameImage: "ic_video", navItem: .videoCall, action: { [weak navigateDelegate] (item, indexPath) in + navigateDelegate?.unavailableFunctionality() + }) + } + + var history: ImageActionItemModel { + return ImageActionItemModel(nameImage: "ic_history", navItem: .callHistory, action: { [weak navigateDelegate] (item, indexPath) in + navigateDelegate?.callHistory(indexPath: indexPath) + }) } } diff --git a/Nynja/ChatItemsFactory.swift b/Nynja/ChatItemsFactory.swift index ba26b8421..14cc2957a 100644 --- a/Nynja/ChatItemsFactory.swift +++ b/Nynja/ChatItemsFactory.swift @@ -106,13 +106,6 @@ class ChatItemsFactory: WCBaseItemsFactory { navigateDelegate?.showVideoCall(indexPath: indexPath) }) } - - var clearHistory: ImageActionItemModel { - let item = ImageActionItemModel(nameImage: "ic_delete_context_menu", navItem: .clearHistory, action: { [weak navigateDelegate] (item, indexPath) in - navigateDelegate?.clearCallHistory(indexPath: indexPath) - }) - return item - } var videoGroupCall: ImageFilledItemModel { return ImageFilledItemModel(nameImage: "ic_video", navItem: .videoCall, isSelectable: false, action: { [weak navigateDelegate] (item, indexPath) in diff --git a/Nynja/Modules/Main/View/ActionsItem.swift b/Nynja/Modules/Main/View/ActionsItem.swift index c3a19ddcf..4d0068f26 100644 --- a/Nynja/Modules/Main/View/ActionsItem.swift +++ b/Nynja/Modules/Main/View/ActionsItem.swift @@ -10,8 +10,7 @@ enum ActionsItem: Int { case location case camera case gallery - case voiceCall - case videoCall + case calls case contact case event } -- GitLab From 6e90ca11d2c865450ae5415bff296fede8d4cd85 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Tue, 20 Nov 2018 13:37:32 +0200 Subject: [PATCH 18/59] Disabled call back for room --- .../CallHistory/View/CallHistoryViewController.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index e7414d391..70d5a7ca2 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -367,11 +367,7 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe presenter.callBackFor(contact: contact) } } - } else { - if let room = presenter.findRoomBy(roomId: m.address) { - presenter.callBackFor(room: room) - } - } + } } } -- GitLab From 90ed30df457e499f1ce5a6a51a394d224f1c6509 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Tue, 20 Nov 2018 18:28:56 +0200 Subject: [PATCH 19/59] Call history group call info: update host name and image --- .../ParticipantsHistoryInteractor.swift | 29 ++++++++++++------- .../ParticipantsHistoryProtocols.swift | 8 +++-- .../ParticipantsHistoryPresenter.swift | 8 +++-- .../ParticipantsHistoryViewController.swift | 12 ++++++-- .../ParticipantsHistoryWireframe.swift | 1 + 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift b/Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift index 9ddeef7cc..10c3febaa 100644 --- a/Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift +++ b/Nynja/Modules/ParticipantsHistory/Interactor/ParticipantsHistoryInteractor.swift @@ -12,6 +12,7 @@ class ParticipantsHistoryInteractor: BaseInteractor, ParticipantsHistoryInteract weak var presenter: ParticipantsHistoryInteractorOutputProtocol! var includedMembers: [Member] = [] + var ownerId:String? private var participants: [Participant] = [] @@ -28,7 +29,6 @@ class ParticipantsHistoryInteractor: BaseInteractor, ParticipantsHistoryInteract self.loadContacts() } - // MARK: - StorageSubscriber override var subscribes: [SubscribeType]? { @@ -69,18 +69,27 @@ class ParticipantsHistoryInteractor: BaseInteractor, ParticipantsHistoryInteract } } - func getCallHost()->Contact? { - if includedMembers.count > 0 { - let mem = includedMembers[0] - - if let phone = mem.phone_id { - if let ctc = ContactDAO.findContactBy(phoneId: phone) { - return ctc + func getCallHostName()->String? { + var hostName:String? + for m in includedMembers { + if m.phone_id == ownerId { + hostName = m.alias + break + } + } + return hostName + } + + func getCallHostImage()->UIImage? { + var hostImage:UIImage? + if let owner = ownerId { + if let ctc = ContactDAO.findContactBy(phoneId: owner) { + if let url = ctc.avatarUrl { + hostImage = UIImage.init(fileUrl: url) } } } - - return nil + return hostImage } //MARK: - IoHandlerDelegate diff --git a/Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift b/Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift index ec2dfbf1a..a58ea9a5e 100644 --- a/Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift +++ b/Nynja/Modules/ParticipantsHistory/ParticipantsHistoryProtocols.swift @@ -51,7 +51,9 @@ protocol ParticipantsHistoryPresenterProtocol: BasePresenterProtocol, Navigation func closeController() - func getCallHost()->Contact? + func getCallHostName()->String? + + func getCallHostImage()->UIImage? } protocol ParticipantsHistoryInteractorOutputProtocol: class { @@ -80,5 +82,7 @@ protocol ParticipantsHistoryInteractorInputProtocol: BaseInteractorProtocol { func findContact(by contact: Contact) - func getCallHost()->Contact? + func getCallHostName()->String? + + func getCallHostImage()->UIImage? } diff --git a/Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift b/Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift index 29f2da744..ff217fdbd 100644 --- a/Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift +++ b/Nynja/Modules/ParticipantsHistory/Presenter/ParticipantsHistoryPresenter.swift @@ -34,8 +34,12 @@ class ParticipantsHistoryPresenter: BasePresenter, ParticipantsHistoryPresenterP wireFrame.hide() } - func getCallHost()->Contact? { - return interactor.getCallHost() + func getCallHostName()->String? { + return interactor.getCallHostName() + } + + func getCallHostImage()->UIImage? { + return interactor.getCallHostImage() } //MARK: - Actions diff --git a/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift b/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift index 360ff2aad..8d07dcdab 100644 --- a/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift +++ b/Nynja/Modules/ParticipantsHistory/View/ParticipantsHistoryViewController.swift @@ -92,9 +92,15 @@ class ParticipantsHistoryViewController: BaseVC, ParticipantsHistoryViewProtocol // MARK: Configure private func setupCallHost() { - if let contact = presenter.getCallHost() { - tableHeaderView.nameLabel.text = "\(contact.names ?? "") \(contact.surnames ?? "")" - tableHeaderView.avatarImageView.setImage(url: contact.avatarUrl, placeHolder: UIImage.nynja.Contacts.avaPlaceholder.image) + + if let name = presenter.getCallHostName() { + tableHeaderView.nameLabel.text = name + } + + if let img = presenter.getCallHostImage() { + tableHeaderView.avatarImageView.image = img + } else { + tableHeaderView.avatarImageView.image = UIImage.nynja.Contacts.avaPlaceholder.image } } diff --git a/Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift b/Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift index b8ee57ad2..971bc829f 100644 --- a/Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift +++ b/Nynja/Modules/ParticipantsHistory/WireFrame/ParticipantsHistoryWireframe.swift @@ -36,6 +36,7 @@ class ParticipantsHistoryWireFrame: ParticipantsHistoryWireFrameProtocol { } interactor.includedMembers = members + interactor.ownerId = callLog.owner // Connecting view.presenter = presenter -- GitLab From efcdf2b1fc3a4e61cf53af8ab9aba505ac516b54 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Thu, 22 Nov 2018 19:21:17 +0200 Subject: [PATCH 20/59] connect history with the backend --- .../CallHistory/CallHistoryProtocols.swift | 16 ++--- .../Interactor/CallHistoryInteractor.swift | 12 ++-- .../Presenter/CallHistoryPresenter.swift | 12 ++-- .../View/CallHistoryViewController.swift | 58 +++++++++++++++---- .../View/TableView/EmptyCallHistoryView.swift | 2 +- .../NynjaCalls/NynjaCommunicatorService.swift | 16 +++-- 6 files changed, 80 insertions(+), 36 deletions(-) diff --git a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift index 84cb1fb63..e5e7f3d65 100644 --- a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift +++ b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift @@ -41,12 +41,12 @@ protocol CallHistoryPresenterProtocol: BasePresenterProtocol, NavigationProtocol var interactor: CallHistoryInteractorInputProtocol! { get set } var wireFrame: CallHistoryWireFrameProtocol! { get set } func closeController() - func removeCallLogBy(id:String) - func findContactBy(phoneId:String)-> Contact? - func findRoomBy(roomId:String)-> Room? + func removeCallLogBy(id:String) -> NYNCallHistoryCode + func findContactBy(phoneId:String) -> Contact? + func findRoomBy(roomId:String) -> Room? func showContact(contact: Contact) func show(callLog: NYNCallLog) - func clearCallHistory() + func clearCallHistory() -> NYNCallHistoryCode func callBackFor(contact:Contact) func callBackVideoFor(contact:Contact) func callBackFor(room:Room) @@ -66,8 +66,8 @@ protocol CallHistoryInteractorInputProtocol: class { */ var presenter: CallHistoryInteractorOutputProtocol! { get set } - func removeCallLogBy(id:String) - func findContactBy(phoneId:String)-> Contact? - func findRoomBy(roomId:String)-> Room? - func clearCallHistory() + func removeCallLogBy(id:String) -> NYNCallHistoryCode + func findContactBy(phoneId:String) -> Contact? + func findRoomBy(roomId:String) -> Room? + func clearCallHistory() -> NYNCallHistoryCode } diff --git a/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift index f2b03e93a..1e86b85dc 100644 --- a/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift +++ b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift @@ -13,19 +13,19 @@ class CallHistoryInteractor: CallHistoryInteractorInputProtocol { weak var presenter: CallHistoryInteractorOutputProtocol! let callService:NynjaCommunicatorService = NynjaCommunicatorService.sharedInstance - func removeCallLogBy(id:String) { - callService.removeCallLogBy(id:id) + func removeCallLogBy(id:String) -> NYNCallHistoryCode { + return callService.removeCallLogBy(id:id) } - func findContactBy(phoneId:String)-> Contact? { + func findContactBy(phoneId:String) -> Contact? { return ContactDAO.findContactBy(phoneId: phoneId) } - func findRoomBy(roomId:String)-> Room? { + func findRoomBy(roomId:String) -> Room? { return RoomDAO.findRoom(by:roomId) } - func clearCallHistory() { - callService.clearCallHistory() + func clearCallHistory() -> NYNCallHistoryCode { + return callService.clearCallHistory() } } diff --git a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift index 7c92ee02d..7049b7403 100644 --- a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift +++ b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift @@ -27,15 +27,15 @@ class CallHistoryPresenter: BasePresenter, CallHistoryPresenterProtocol, CallHis closeController() } - func removeCallLogBy(id:String) { - interactor.removeCallLogBy(id:id) + func removeCallLogBy(id:String) -> NYNCallHistoryCode { + return interactor.removeCallLogBy(id:id) } - func findContactBy(phoneId:String)-> Contact? { + func findContactBy(phoneId:String) -> Contact? { return interactor.findContactBy(phoneId:phoneId) } - func findRoomBy(roomId:String)-> Room? { + func findRoomBy(roomId:String) -> Room? { return interactor.findRoomBy(roomId:roomId) } @@ -47,8 +47,8 @@ class CallHistoryPresenter: BasePresenter, CallHistoryPresenterProtocol, CallHis self.wireFrame.show(callLog: callLog) } - func clearCallHistory() { - interactor.clearCallHistory() + func clearCallHistory() -> NYNCallHistoryCode { + return interactor.clearCallHistory() } func callBackFor(contact:Contact) { diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index 70d5a7ca2..eb2db9cde 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -15,7 +15,7 @@ enum CallHistoryMode { case missed } -class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDelegate, CallHistoryDataSourceDelegate, UITableViewDelegate { +class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDelegate, CallHistoryDataSourceDelegate, UITableViewDelegate, NynjaCallHistoryManagerDelegate { var presenter: CallHistoryPresenterProtocol! { didSet { @@ -58,10 +58,18 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe } private func reloadTableView() { + if NynjaCommunicatorService.sharedInstance.synchronizeHistory() == .PENDING { + showSpinner() + } else { + buildDataSource() + } + } + + private func buildDataSource() { self.dataController?.buildDataSourceWith(mode: self.callHistoryMode, completionHandler: { (dataSource) -> Void in - cleanUpBeforeReloading() - tableViewDataSource = CallHistoryDataSource(tableView:tableView, dataSource: dataSource) - tableViewDataSource?.delegate = self + self.cleanUpBeforeReloading() + self.tableViewDataSource = CallHistoryDataSource(tableView:self.tableView, dataSource: dataSource) + self.tableViewDataSource?.delegate = self self.emptyHistoryView.should(shown: dataSource.isEmpty) self.tableView.isHidden = dataSource.isEmpty @@ -309,8 +317,12 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe secondActionTitle: String.localizable.yes, firstAction: nil, secondAction: { - self.presenter.clearCallHistory() - self.reloadTableView() + + if .PENDING == self.presenter.clearCallHistory() { + self.showSpinner() + } else { + self.reloadTableView() + } }) } @@ -326,10 +338,11 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe super.initialize() setupUI() + + NynjaCommunicatorService.sharedInstance.setCallHistory(delegate: self) } private func setupUI() { - navigationView.isSeparatorVisible = true tableView.isHidden = false scrollView.isHidden = false @@ -390,10 +403,12 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe if let m = callHistoryCell.model { if let ds = self?.tableViewDataSource { if let ip = self?.tableView.indexPath(for: callHistoryCell) { - self?.presenter.removeCallLogBy(id:m.identifier) - ds.dataSource.remove(at: ip.row) - - self?.tableView.deleteRows(at: [ip], with: UITableViewRowAnimation.middle) + if let slf = self { + if .PENDING != slf.presenter.removeCallLogBy(id:m.identifier) { + ds.dataSource.remove(at: ip.row) + slf.tableView.deleteRows(at: [ip], with: UITableViewRowAnimation.middle) + } + } } } } @@ -453,4 +468,25 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe tableView.deselectRow(at: indexPath, animated: false) callBackFor(indexPath: indexPath) } + + // MARK: NynjaCallHistoryManager Delegates + func managerHistoryDidUpdate(_ manager: NynjaCallHistoryManager) { + DispatchQueue.main.async{ + self.hideSpinner() + self.buildDataSource() + } + } + + func managerHistoryDidClear(_ manager: NynjaCallHistoryManager) { + DispatchQueue.main.async{ + self.hideSpinner() + self.reloadTableView() + } + } + + func manager(_ manager: NynjaCallHistoryManager, didDeleteRecordWithId identifier: String) { + DispatchQueue.main.async{ + self.reloadTableView() + } + } } diff --git a/Nynja/Modules/CallHistory/View/TableView/EmptyCallHistoryView.swift b/Nynja/Modules/CallHistory/View/TableView/EmptyCallHistoryView.swift index 486fe8235..86d642071 100644 --- a/Nynja/Modules/CallHistory/View/TableView/EmptyCallHistoryView.swift +++ b/Nynja/Modules/CallHistory/View/TableView/EmptyCallHistoryView.swift @@ -17,7 +17,7 @@ class EmptyCallHistoryView: UIView { iv.snp.makeConstraints { (make) in make.width.equalTo(Constraints.image.width) make.height.equalTo(Constraints.image.height) - make.centerY.equalToSuperview().offset(-Constraints.image.height/2) + make.centerY.equalToSuperview().offset(-Constraints.image.height/4) make.centerX.equalToSuperview() } diff --git a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift index 634a7aea8..a86de9641 100644 --- a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift +++ b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift @@ -463,7 +463,15 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele call.switchCamera() } } + + func setCallHistory(delegate:NynjaCallHistoryManagerDelegate?) { + self.nynComm.getCallHistoryManager().delegate = delegate + } + func synchronizeHistory() -> NYNCallHistoryCode { + return self.nynComm.getCallHistoryManager().synchronize() + } + func callHistoryFetchAll() -> NYNCallLogFetchedResults? { return self.nynComm.getCallHistoryManager().fetchAll() } @@ -480,12 +488,12 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele return self.nynComm.getCallHistoryManager().fetchIncoming() } - func removeCallLogBy(id:String) { - self.nynComm.getCallHistoryManager().deleteCallLog(by: id) + func removeCallLogBy(id:String) -> NYNCallHistoryCode { + return self.nynComm.getCallHistoryManager().deleteCallLog(by: id) } - func clearCallHistory() { - self.nynComm.getCallHistoryManager().deleteAllHistory() + func clearCallHistory() -> NYNCallHistoryCode { + return self.nynComm.getCallHistoryManager().deleteAllHistory() } //MARK: Helpers -- GitLab From 38d72d2dad7308e5bdd05d56f46b03393109c86b Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Mon, 26 Nov 2018 18:21:18 +0200 Subject: [PATCH 21/59] Removed old implementation delegates for call bubbles --- .../Interactor/CallInProgressInteractor.swift | 40 +------------------ .../NynjaCalls/NynjaCommunicatorService.swift | 4 -- 2 files changed, 1 insertion(+), 43 deletions(-) diff --git a/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift b/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift index 454383e50..b3fb74e61 100644 --- a/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift +++ b/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift @@ -48,31 +48,6 @@ class CallInProgressInteractor: CallInProgressInteractorInputProtocol, NynjaCall weak var nynCall: NYNCall? var duration = 0 - let storageService: StorageService = .sharedInstance - let payloadBuilder: MessagePayloadBuilderInput = MessagePayloadBuilder() - private let mqttService: MQTTService = .sharedInstance - let processingManager = DefaultMessagesProcessingManager.shared - - private(set) lazy var messageFactory: MessageFactoryProtocol = { - let dependencies = MessageFactory.Dependencies( - storageService: storageService, - payloadBuilder: payloadBuilder - ) - - return MessageFactory(dependencies: dependencies) - }() - - private(set) lazy var messageSendingService: MessageSendingServiceProtocol = { - let dependencies = MessageSendingService.Dependencies( - mqttService: mqttService, - storageService: storageService, - processingManager: processingManager, - typingSenderService: TypingSenderService(dependencies: .init(mqttService: mqttService, - storageService: storageService)) - ) - return MessageSendingService(dependencies: dependencies) - }() - private func callClosed(isMissed: Bool) { try? audioSessionManager.resetAudioSession() presenter.callClosed(isMissed: isMissed) @@ -374,20 +349,7 @@ class CallInProgressInteractor: CallInProgressInteractorInputProtocol, NynjaCall self.presenter.update(participants: ncall.participants) } } - - func conferenceCreated(call: NYNCall) { - sendCall(ncall: call) - } - - func sendCall(ncall: NYNCall) { - let room = Room() - room.id = ncall.externalInfo - let membersIds = ncall.participants.map({ $0.address ?? "" }) - let message = messageFactory.makeCallMessage(members: membersIds, room: room) - try? storageService.perform(action: .save, with: message) - messageSendingService.sendMessage(message) - } - + func updateGroupCall(contacts: [Contact]) { if let ncall = self.nynCall { diff --git a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift index 8636a192b..198d74260 100644 --- a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift +++ b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift @@ -36,7 +36,6 @@ protocol NynjaCallDelegate: class { func callEnded(call: NYNCall, isMissed: Bool) func stateDidChange(call: NYNCall, state: NYNCallState) func participantsUpdated(call: NYNCall) - func conferenceCreated(call: NYNCall) func didAddVideoStreamForCall(call: NYNCall) func didRemoveVideoStreamForCall(call: NYNCall) func didStartLocalCapturerForCall(call: NYNCall) @@ -49,7 +48,6 @@ extension NynjaCallDelegate { func callEnded(call: NYNCall, isMissed: Bool) {} func stateDidChange(call: NYNCall, state: NYNCallState) {} func participantsUpdated(call: NYNCall){} - func conferenceCreated(call: NYNCall) {} func didAddVideoStreamForCall(call: NYNCall) {} func didRemoveVideoStreamForCall(call: NYNCall) {} func didStartLocalCapturerForCall(call: NYNCall) {} @@ -743,8 +741,6 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele self.nynComm.getCallManager().startConference(withRequestId: cr.startId!, withConferenceId: cr.conferenceId!) - guard let call = self.call else { return } - self.callDelegate?.conferenceCreated(call: call) } } } -- GitLab From b8b5e157a5e7949adbcbd7c9e13eea3e4e1b21fb Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Mon, 26 Nov 2018 18:38:48 +0200 Subject: [PATCH 22/59] Implemented call bubbles filtering by seenBy --- .../Models/Message/Message+DB.swift | 2 +- Nynja/Generated/LocalizableConstants.swift | 2 +- .../Interactor/MessageInteractor+Fetch.swift | 21 +++++++++++++------ Nynja/Services/Models/SendModel.swift | 4 ++-- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Nynja/Extensions/Models/Message/Message+DB.swift b/Nynja/Extensions/Models/Message/Message+DB.swift index 7f4df71cf..cace0d74e 100644 --- a/Nynja/Extensions/Models/Message/Message+DB.swift +++ b/Nynja/Extensions/Models/Message/Message+DB.swift @@ -27,7 +27,7 @@ extension Message { if message.feedType == FeedType.p2p.rawValue { self.seenby = message.seenBy?.splitByComma { $0 as AnyObject } } else { - self.seenby = message.seenBy?.splitIntegerIdentifiers() + self.seenby = message.seenBy?.splitByComma { $0 as AnyObject } } self.repliedby = message.repliedBy?.splitIntegerIdentifiers() diff --git a/Nynja/Generated/LocalizableConstants.swift b/Nynja/Generated/LocalizableConstants.swift index 377325bf8..08137e75e 100644 --- a/Nynja/Generated/LocalizableConstants.swift +++ b/Nynja/Generated/LocalizableConstants.swift @@ -1130,7 +1130,7 @@ internal extension String { static var tpTranslation: String { return localizable.tr("Localizable", "tp_translation") } /// Translation failed. Please try again. static var tpTranslationFailed: String { return localizable.tr("Localizable", "tp_translation_failed") } - /// Original and translated messages language is the same. + /// Original and translated message are the same language. static var tpTranslationLanguageIsEqual: String { return localizable.tr("Localizable", "tp_translation_language_is_equal") } /// Transcribe with Google static var transcribe: String { return localizable.tr("Localizable", "transcribe") } diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift b/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift index 3988d67a3..58fa328b2 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift @@ -109,17 +109,26 @@ extension MessageInteractor { .fetchMessages(type) .filter { message in guard let desc = message.files?.first, - desc.mime == SendMessageType.audioCall.rawValue else { + desc.mime == SendMessageType.audioCall.rawValue || + desc.mime == SendMessageType.videoCall.rawValue else { return true } - guard desc.data?.first?.key == FeatureKeys.File.Call.users.rawValue, - let ids = desc.data?.first?.value?.splitByComma(), - let phoneId = storageService.phoneId else { - return false + guard let seenBy = message.seenby else { + return true } - return ids.contains { $0 == phoneId } + guard let phoneId = storageService.phoneId else { + return false + } + + return seenBy.contains { + guard let sid = $0 as? String else { + return false + } + + return sid == phoneId + } } } diff --git a/Nynja/Services/Models/SendModel.swift b/Nynja/Services/Models/SendModel.swift index ccba64a16..726b987e2 100644 --- a/Nynja/Services/Models/SendModel.swift +++ b/Nynja/Services/Models/SendModel.swift @@ -18,8 +18,8 @@ enum SendMessageType: String { case sticker = "sticker" case location = "location" case place = "place" - case videoCall = "videoCall" - case audioCall = "audioCall" + case videoCall = "videocall" + case audioCall = "audiocall" case file = "file" case thumbnails = "thumb" case contact = "contact" -- GitLab From a9702eda274939c12a9da2d865947528ca87c438 Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Wed, 28 Nov 2018 11:15:00 +0200 Subject: [PATCH 23/59] Changed back sendmodel's bubble from audiocall to audioCall --- Nynja/Services/Models/SendModel.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Nynja/Services/Models/SendModel.swift b/Nynja/Services/Models/SendModel.swift index 726b987e2..ccba64a16 100644 --- a/Nynja/Services/Models/SendModel.swift +++ b/Nynja/Services/Models/SendModel.swift @@ -18,8 +18,8 @@ enum SendMessageType: String { case sticker = "sticker" case location = "location" case place = "place" - case videoCall = "videocall" - case audioCall = "audiocall" + case videoCall = "videoCall" + case audioCall = "audioCall" case file = "file" case thumbnails = "thumb" case contact = "contact" -- GitLab From e9d77cc6292630df829643810ce18d02e03db0d1 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Wed, 28 Nov 2018 12:26:10 +0200 Subject: [PATCH 24/59] Call bubbles layout --- .../Models/Desc/Desc+DescMime.swift | 9 +- .../Models/Feature/FeatureExtension.swift | 18 +- Nynja/Generated/LocalizableConstants.swift | 4 + .../Message/Presenter/MessagePresenter.swift | 73 ++++ .../BaseChatCellModel/BaseChatCellModel.swift | 8 + .../Cells/Views/Message/MessageCallView.swift | 345 +++++++++++++++--- Nynja/Resources/en.lproj/Localizable.strings | 1 + .../HandleServices/MessageHandler.swift | 17 +- 8 files changed, 402 insertions(+), 73 deletions(-) diff --git a/Nynja/Extensions/Models/Desc/Desc+DescMime.swift b/Nynja/Extensions/Models/Desc/Desc+DescMime.swift index cdbfc9034..79d55d64c 100644 --- a/Nynja/Extensions/Models/Desc/Desc+DescMime.swift +++ b/Nynja/Extensions/Models/Desc/Desc+DescMime.swift @@ -47,8 +47,8 @@ extension Desc { setupFile(.file, filename: filename, filepath: filepath, size: size) case .payment(let mime, let payload, let notes): setupPayment(mime, payload: payload, notes: notes) - case .call(let members): - setupCall(members) + case .call( _): break + } self.id = IdBuilder(format: .defaultId).build() @@ -142,11 +142,6 @@ extension Desc { self.data = Feature.fileRepresentation(size: Int64(size), filename: filename) } - private func setupCall(_ members: [String]) { - self.mime = SendMessageType.audioCall.rawValue - self.data = Feature.callRepresentation(members: members) - } - private func setupPayment(_ mime: SendMessageType, payload: String, notes: String?) { self.mime = mime.rawValue self.payload = payload diff --git a/Nynja/Extensions/Models/Feature/FeatureExtension.swift b/Nynja/Extensions/Models/Feature/FeatureExtension.swift index 554992abd..c5acf5182 100644 --- a/Nynja/Extensions/Models/Feature/FeatureExtension.swift +++ b/Nynja/Extensions/Models/Feature/FeatureExtension.swift @@ -71,8 +71,13 @@ enum FeatureKeys { } enum Call: String { - case users = "USERS" + case duration = "DURATION" + case starttime = "START_TIME" + case conferenceid = "CONFERENCE_ID" + case endedby = "ENDED_BY" + case count = "COUNT" } + enum Payment: String { case description = "DESCRIPTION" case text = "text" @@ -208,17 +213,6 @@ extension Feature { fileDataFeature(forKey: FeatureKeys.File.File.filename, value: filename)] } - static func callRepresentation(members: [String]) -> [Feature] { - let _members = members.joinedByComma() - let feature = Feature() - feature.id = IdBuilder.init(format: .defaultId) - .build() - feature.key = FeatureKeys.File.Call.users.rawValue - feature.group = FeatureGroup.fileData.rawValue - feature.value = _members - return [feature] - } - static func payment(notes: String) -> [Feature] { let feature = Feature() feature.id = IdBuilder.init(format: .featureId) diff --git a/Nynja/Generated/LocalizableConstants.swift b/Nynja/Generated/LocalizableConstants.swift index 09d8c4f25..9c5714c40 100644 --- a/Nynja/Generated/LocalizableConstants.swift +++ b/Nynja/Generated/LocalizableConstants.swift @@ -852,6 +852,10 @@ internal extension String { static var outgoingCall: String { return localizable.tr("Localizable", "outgoing_call") } /// Group Participants static var participants: String { return localizable.tr("Localizable", "participants") } + /// %d participants + static func participantsCount(_ p1: Int) -> String { + return localizable.tr("Localizable", "participants_count", p1) + } /// photo static var photo: String { return localizable.tr("Localizable", "photo") } /// Your photo is not saved to gallery diff --git a/Nynja/Modules/Message/Presenter/MessagePresenter.swift b/Nynja/Modules/Message/Presenter/MessagePresenter.swift index 48b28d443..4ae536588 100644 --- a/Nynja/Modules/Message/Presenter/MessagePresenter.swift +++ b/Nynja/Modules/Message/Presenter/MessagePresenter.swift @@ -823,6 +823,42 @@ class MessagePresenter: BasePresenter, MessagePresenterProtocol, MessageInteract break } model.transferNotes = files.data?.first?.value + case .audioCall, .videoCall: + guard let data = attach.data else {break} + for feature in data { + if let k = feature.key { + switch k { + case FeatureKeys.File.Call.duration.rawValue: + if let duration = feature.value { + model.callDuration = UInt(duration) + } else { + model.callDuration = 0 + } + case FeatureKeys.File.Call.starttime.rawValue: + guard let starttime = feature.value else {break} + model.callStartTime = Date(timeIntervalSince1970: TimeInterval(starttime) ?? 0) + case FeatureKeys.File.Call.conferenceid.rawValue: + guard let callId = feature.value else {break} + model.callId = callId + case FeatureKeys.File.Call.endedby.rawValue: + guard let endedby = feature.value else {break} + model.callEndedBy = endedby + case FeatureKeys.File.Call.count.rawValue: + if let count = feature.value { + model.callMembersCount = UInt(count) + } else { + model.callMembersCount = 0 + } + default: + break + } + } + } + + if let pl = attach.payload, let dur = model.callDuration, let endby = model.callEndedBy { + model.callStatus = callStatus(from: pl, duration: dur, endedby: endby, isgroup:model.isGroup, isowner:model.isOwner) + } + default: break } @@ -865,6 +901,43 @@ class MessagePresenter: BasePresenter, MessagePresenterProtocol, MessageInteract return nil } + private func callStatus(from payload:String, duration:UInt, endedby:String, isgroup:Bool, isowner:Bool) -> NYNCallLogStatus { + var status = NYNCallLogStatus.UNANSWERED + + if (!isgroup) { + if (duration == 0) { + switch endedby { + case "system": + status = isowner ? NYNCallLogStatus.UNANSWERED : NYNCallLogStatus.MISSED + break + case "callee": + status = NYNCallLogStatus.DECLINED + break + case "caller": + status = isowner ? NYNCallLogStatus.CANCELED : NYNCallLogStatus.MISSED + break + default: + break + } + } else { + status = NYNCallLogStatus.ANSWERED + } + } else { + if isowner, 0 == duration { + status = NYNCallLogStatus.CANCELED + } else { + if (isowner || duration > 0) { + status = NYNCallLogStatus.ANSWERED + } else { + status = NYNCallLogStatus.MISSED + } + } + } + + + return status + } + private func deliveryStatusFrom(readerID: MessageServerId?, messageID: MessageServerId?) -> DeliveryStatus { switch (readerID, messageID) { case (.none, .some): return .sent diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Models/BaseChatCellModel/BaseChatCellModel.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Models/BaseChatCellModel/BaseChatCellModel.swift index 30d904cb1..b2cf2d1bf 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Models/BaseChatCellModel/BaseChatCellModel.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Models/BaseChatCellModel/BaseChatCellModel.swift @@ -79,6 +79,14 @@ final class BaseChatCellModel: ChatCellModel, AudioPlayable, ProgressObservable var links: [String]? var mentions: [MentionInfo]? + // MARK: - Bubbles + var callStatus: NYNCallLogStatus? + var callEndedBy: String? // TO DO convert to enum + var callDuration: UInt? + var callMembersCount: UInt? + var callStartTime: Date? + var callId: String? + var hasMentions: Bool { guard let mentions = mentions else { return false diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift index f572f8561..7e87d03a7 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift @@ -9,13 +9,35 @@ import Foundation import SnapKit + final class MessageCallView: MessageContentView { + static let todayDateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateStyle = .none + formatter.timeStyle = .short + return formatter + }() + + static let lastWeekDateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "EEEE" + formatter.timeZone = TimeZone.current + return formatter + }() + + static let dateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateStyle = .short + formatter.timeStyle = .none + return formatter + }() + override var coloredViews: [UIView] { return [self, imageView, title] } - + static var viewHeight:CGFloat = Constraints.height // MARK: - Constraints private enum Constraints { @@ -23,29 +45,17 @@ final class MessageCallView: MessageContentView { static let height = CGFloat(44.adjustedByWidth) enum imageView { - static let verticalInset = CGFloat(8.adjustedByWidth) - static let width = CGFloat(48.adjustedByWidth) + static let verticalInset = 8.adjustedByWidth + static let width = 18.0 static let leftInset = 8.adjustedByWidth } enum nameLabel { - static let width = 188.adjustedByWidth - - static let horizontalPadding = 8.adjustedByWidth - static let topInset = 4.adjustedByWidth - static let labelHeight = CGFloat(22.adjustedByWidth) - } - - enum infoView { - static let inset = CGPoint(x: 0, y: 2.adjustedByWidth) + static let verticalInset = 4.adjustedByWidth + static let fontSizeLabel = CGFloat(12.adjustedByWidth) } } - override var infoInset: CGPoint { - return Constraints.infoView.inset - } - - // MARK: - Views private lazy var imageView: UIImageView = { @@ -60,53 +70,296 @@ final class MessageCallView: MessageContentView { imageView.snp.makeConstraints { make in make.width.height.equalTo(width) make.left.equalTo(Constraints.imageView.leftInset) - make.top.equalTo(verticalInset) - make.bottom.lessThanOrEqualTo(-verticalInset) + make.centerY.equalToSuperview() } return imageView }() private lazy var title: UILabel = { - let size = CGSize(width: 100, height: Constraints.nameLabel.labelHeight) - let label = UILabel(size: size, color: UIColor.nynja.darkLight, fontName: FontFamily.NotoSans.regular.name) + let label = UILabel() + label.textColor = UIColor.nynja.darkLight + label.backgroundColor = .yellow + label.font = UIFont(name: FontFamily.NotoSans.regular.name, size: Constraints.nameLabel.fontSizeLabel) + label.numberOfLines = 1 + self.addSubview(label) - label.snp.makeConstraints(self.nameLabelConstraints()) + label.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.left.equalTo(imageView.snp.right).offset(Constraints.imageView.leftInset) + make.top.equalToSuperview().offset(Constraints.nameLabel.verticalInset) + } + return label }() + private lazy var participants: UILabel = { + let label = UILabel() + label.textColor = UIColor.nynja.darkLight + label.backgroundColor = .blue + label.font = UIFont(name: FontFamily.NotoSans.bold.name, size: Constraints.nameLabel.fontSizeLabel) + label.numberOfLines = 1 + + self.addSubview(label) + label.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.left.equalTo(imageView.snp.right).offset(Constraints.imageView.leftInset) + make.top.equalTo(title.snp.bottom).offset(Constraints.nameLabel.verticalInset) + } + + return label + }() + + private lazy var duration: UILabel = { + let label = UILabel() + label.textColor = UIColor.nynja.lightGray + label.backgroundColor = .blue + label.font = UIFont(name: FontFamily.NotoSans.regular.name, size: Constraints.nameLabel.fontSizeLabel) + label.numberOfLines = 1 + + self.addSubview(label) + label.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.left.equalTo(imageView.snp.right).offset(Constraints.imageView.leftInset) + make.top.equalTo(participants.snp.bottom).offset(Constraints.nameLabel.verticalInset) + } + + return label + }() + + private lazy var time: UILabel = { + let label = UILabel() + label.textColor = UIColor.nynja.darkLight + label.backgroundColor = .red + label.font = UIFont(name: FontFamily.NotoSans.regular.name, size: Constraints.nameLabel.fontSizeLabel) + label.numberOfLines = 1 + + self.addSubview(label) + label.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.top.equalTo(duration.snp.bottom).offset(Constraints.nameLabel.verticalInset) + make.left.equalTo(duration.snp.right).offset(Constraints.imageView.leftInset) + } + + return label + }() + + // MARK: - Private Methods + private func updateConstraintsAndControlValues(with model: BaseChatCellModel) { + + time.snp.removeConstraints() + duration.snp.removeConstraints() + participants.snp.removeConstraints() + + if let cs = model.callStatus { + imageView.image = imageFrom(status: cs, isaudio: (model.type == .audioCall), isowner: model.isOwner) + } + + if let cs = model.callStatus, let cd = model.callDuration { + title.text = stringFrom(status:cs, isowner:model.isOwner, duration:cd) + } + + let normalFontHeight = ceil(title.font.lineHeight) + let boldFontHeight = ceil(participants.font.lineHeight) + + if model.isGroup { + if let d = model.callDuration, d > 0 { + participants.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.left.equalTo(imageView.snp.right).offset(Constraints.imageView.leftInset) + make.top.equalTo(title.snp.bottom).offset(Constraints.nameLabel.verticalInset) + } + + if let pc = model.callMembersCount { + participants.text = String.localizable.participantsCount(Int(pc)) + } + + duration.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.left.equalTo(imageView.snp.right).offset(Constraints.imageView.leftInset) + make.top.equalTo(participants.snp.bottom).offset(Constraints.nameLabel.verticalInset) + } + + duration.text = stringFrom(duration: d) + + time.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.top.equalTo(duration.snp.bottom).offset(Constraints.nameLabel.verticalInset) + make.left.equalTo(duration.snp.right).offset(Constraints.imageView.leftInset) + } + + if let d = model.callStartTime { + time.text = stringFrom(date: d) + } + + MessageCallView.viewHeight = 2*normalFontHeight + boldFontHeight + CGFloat(4*Constraints.nameLabel.verticalInset) + } else { + participants.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.left.equalTo(imageView.snp.right).offset(Constraints.imageView.leftInset) + make.top.equalTo(title.snp.bottom).offset(Constraints.nameLabel.verticalInset) + } + + if let pc = model.callMembersCount { + participants.text = String.localizable.participantsCount(Int(pc)) + } + + time.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.top.equalTo(participants.snp.bottom).offset(Constraints.nameLabel.verticalInset) + make.left.equalTo(participants.snp.right).offset(Constraints.imageView.leftInset) + } + + if let d = model.callStartTime { + time.text = stringFrom(date: d) + } + + duration.text = "" + duration.snp.makeConstraints { make in + make.height.width.equalTo(0) + make.top.equalTo(participants.snp.bottom) + } + + MessageCallView.viewHeight = normalFontHeight + boldFontHeight + CGFloat(3*Constraints.nameLabel.verticalInset) + } + } else { + participants.text = "" + participants.snp.makeConstraints { make in + make.height.width.equalTo(0) + make.top.equalTo(title.snp.bottom) + } + + if let d = model.callDuration, d > 0 { + duration.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.left.equalTo(Constraints.imageView.leftInset) + make.top.equalTo(title.snp.bottom).offset(Constraints.nameLabel.verticalInset) + } + + duration.text = stringFrom(duration: d) + + time.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.top.equalTo(duration.snp.bottom).offset(Constraints.nameLabel.verticalInset) + make.left.equalTo(duration.snp.right).offset(Constraints.imageView.leftInset) + } + + if let d = model.callStartTime { + time.text = stringFrom(date: d) + } + + MessageCallView.viewHeight = 2*normalFontHeight + CGFloat(3*Constraints.nameLabel.verticalInset) + } else { + duration.text = "" + duration.snp.makeConstraints { make in + make.height.width.equalTo(0) + make.top.equalTo(title.snp.bottom) + } + + participants.text = "" + participants.snp.makeConstraints { make in + make.height.width.equalTo(0) + make.top.equalTo(title.snp.bottom) + } + + time.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.top.equalTo(title.snp.bottom).offset(Constraints.nameLabel.verticalInset) + make.left.equalTo(title.snp.right).offset(Constraints.imageView.leftInset) + } + + if let d = model.callStartTime { + time.text = stringFrom(date: d) + } + + MessageCallView.viewHeight = normalFontHeight + CGFloat(2*Constraints.nameLabel.verticalInset) + } + } + } + + private func stringFrom(duration:UInt)-> String? { + let formatter = DateComponentsFormatter() + formatter.unitsStyle = .abbreviated + formatter.allowedUnits = [.hour, .minute, .second] + formatter.zeroFormattingBehavior = [ .default ] + + let formattedDuration = formatter.string(from: Double(duration)) + + return formattedDuration + } + + private func stringFrom(status:NYNCallLogStatus, isowner:Bool, duration:UInt)-> String { + switch status { + case .ANSWERED: + if !isowner { + return String.localizable.callHistoryLogDirInbound + } else { + return String.localizable.callHistoryLogDirOutbound + } + case .CANCELED: + return String.localizable.callHistoryLogStatusCanceled + case .DECLINED: + return String.localizable.callHistoryLogStatusDeclined + case .MISSED: + return String.localizable.callHistoryLogStatusMissed + case .UNANSWERED: + return String.localizable.callHistoryLogStatusUnanswered + } + } + + private func stringFrom(date:Date) ->String { + if Calendar.current.isDateInToday(date) { + return MessageCallView.todayDateFormatter.string(from:date) + } else if Calendar.current.isDateInYesterday(date) { + return String.localizable.callHistoryYesterdayTitle + } else if CallHistoryCellModel.isDateInLastWeek(date:date) { + return MessageCallView.lastWeekDateFormatter.string(from:date) + } else { + return MessageCallView.dateFormatter.string(from:date) + } + } + + private func imageFrom(status:NYNCallLogStatus, isaudio:Bool, isowner:Bool)-> UIImage { + if isaudio { + switch status { + case .ANSWERED: + return !isowner ? UIImage.nynja.CallHistory.icIncomingVoice.image : UIImage.nynja.CallHistory.icOutgoingVoice.image + case .CANCELED: + return UIImage.nynja.CallHistory.icCanceledVoice.image + case .DECLINED: + return UIImage.nynja.CallHistory.icMissedVoice.image + case .MISSED: + return UIImage.nynja.CallHistory.icMissedVoice.image + case .UNANSWERED: + return UIImage.nynja.CallHistory.icNoAnswerVoice.image + } + } else { + switch status { + case .ANSWERED: + return !isowner ? UIImage.nynja.CallHistory.icIncomingVideo.image : UIImage.nynja.CallHistory.icOutgoingVideo.image + case .CANCELED: + return UIImage.nynja.CallHistory.icCanceledVideo.image + case .DECLINED: + return UIImage.nynja.CallHistory.icMissedVideo.image + case .MISSED: + return UIImage.nynja.CallHistory.icMissedVideo.image + case .UNANSWERED: + return UIImage.nynja.CallHistory.icNoAnswerVideo.image + } + } + } // MARK: - BubbleInjectible override func configure(with model: BaseChatCellModel) { super.configure(with: model) - guard model.type == .audioCall else { return } - let image = model.isOwner ? UIImage.nynja.icVoiceCallOutgoingDark.image : UIImage.nynja.icIncomingCallDark.image - imageView.image = image - title.text = model.isOwner ? String.localizable.outgoingCall : String.localizable.incomingCall + guard (model.type == .audioCall || model.type == .videoCall) else { return } + + updateConstraintsAndControlValues(with: model) } override class func size(for model: BaseChatCellModel, maxWidth: CGFloat) -> CGSize { - return CGSize(width: maxWidth, height: Constraints.height) - } - - - // MARK: - Private Methods - - private func nameLabelConstraints(default isDefault: Bool = true) -> (ConstraintMaker) -> Void { - return { [weak self] make in - guard let this = self else { return } - let horizontalPadding = Constraints.nameLabel.horizontalPadding - - make.width.equalTo(Constraints.nameLabel.width) - if isDefault { - make.top.equalTo(this.imageView).inset(Constraints.nameLabel.topInset) - } else { - make.centerY.equalTo(this.imageView) - } - make.left.equalTo(this.imageView.snp.right).offset(horizontalPadding) - make.right.equalTo(-horizontalPadding) - } + return CGSize(width: maxWidth, height: viewHeight) } } diff --git a/Nynja/Resources/en.lproj/Localizable.strings b/Nynja/Resources/en.lproj/Localizable.strings index b66100fa0..3c76eea59 100644 --- a/Nynja/Resources/en.lproj/Localizable.strings +++ b/Nynja/Resources/en.lproj/Localizable.strings @@ -269,6 +269,7 @@ "participants"="Group Participants"; "admins"="Group Admins"; "admin"="admin"; +"participants_count" = "%d participants"; // MARK: Add Participants "delete_participants"="Delete Participants"; diff --git a/Nynja/Services/HandleServices/MessageHandler.swift b/Nynja/Services/HandleServices/MessageHandler.swift index 48eec0c0a..bb43800f6 100644 --- a/Nynja/Services/HandleServices/MessageHandler.swift +++ b/Nynja/Services/HandleServices/MessageHandler.swift @@ -160,14 +160,15 @@ final class MessageHandler: BaseHandler { } private static func shouldSkipMessage(_ message: Message) -> Bool { - if let desc = message.files?.first, - desc.mime == SendMessageType.audioCall.rawValue, - desc.data?.first?.key == FeatureKeys.File.Call.users.rawValue, - let ids = desc.data?.first?.value?.splitByComma(), - !ids.contains { $0 == storageService.phoneId } { - - return true - } + //TODO: fix it +// if let desc = message.files?.first, +// desc.mime == SendMessageType.audioCall.rawValue, +// desc.data?.first?.key == FeatureKeys.File.Call.users.rawValue, +// let ids = desc.data?.first?.value?.splitByComma(), +// !ids.contains { $0 == storageService.phoneId } { +// +// return true +// } return false } -- GitLab From ac89ef4cfc3699123af55b0709dcb306a5dbf698 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Wed, 28 Nov 2018 14:03:26 +0200 Subject: [PATCH 25/59] Polishing bubble layout --- .../Message/Presenter/MessagePresenter.swift | 7 +- .../Cells/Views/Message/MessageCallView.swift | 84 ++++++++++++------- 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/Nynja/Modules/Message/Presenter/MessagePresenter.swift b/Nynja/Modules/Message/Presenter/MessagePresenter.swift index 4ae536588..2e9ed85b1 100644 --- a/Nynja/Modules/Message/Presenter/MessagePresenter.swift +++ b/Nynja/Modules/Message/Presenter/MessagePresenter.swift @@ -835,8 +835,11 @@ class MessagePresenter: BasePresenter, MessagePresenterProtocol, MessageInteract model.callDuration = 0 } case FeatureKeys.File.Call.starttime.rawValue: - guard let starttime = feature.value else {break} - model.callStartTime = Date(timeIntervalSince1970: TimeInterval(starttime) ?? 0) + if let starttime = feature.value { + model.callStartTime = Date(timeIntervalSince1970: TimeInterval(starttime) ?? 0) + } else { + model.callStartTime = Date(timeIntervalSince1970: 0) + } case FeatureKeys.File.Call.conferenceid.rawValue: guard let callId = feature.value else {break} model.callId = callId diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift index 7e87d03a7..bec2e20e1 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift @@ -37,12 +37,11 @@ final class MessageCallView: MessageContentView { return [self, imageView, title] } - static var viewHeight:CGFloat = Constraints.height // MARK: - Constraints - private enum Constraints { - static let height = CGFloat(44.adjustedByWidth) + static let height = 44.0 + static let offset = 12.0 enum imageView { static let verticalInset = 8.adjustedByWidth @@ -80,7 +79,7 @@ final class MessageCallView: MessageContentView { let label = UILabel() label.textColor = UIColor.nynja.darkLight label.backgroundColor = .yellow - label.font = UIFont(name: FontFamily.NotoSans.regular.name, size: Constraints.nameLabel.fontSizeLabel) + label.font = MessageCallView.normalFont label.numberOfLines = 1 self.addSubview(label) @@ -96,8 +95,8 @@ final class MessageCallView: MessageContentView { private lazy var participants: UILabel = { let label = UILabel() label.textColor = UIColor.nynja.darkLight - label.backgroundColor = .blue - label.font = UIFont(name: FontFamily.NotoSans.bold.name, size: Constraints.nameLabel.fontSizeLabel) + label.backgroundColor = .clear + label.font = MessageCallView.boldFont label.numberOfLines = 1 self.addSubview(label) @@ -113,8 +112,8 @@ final class MessageCallView: MessageContentView { private lazy var duration: UILabel = { let label = UILabel() label.textColor = UIColor.nynja.lightGray - label.backgroundColor = .blue - label.font = UIFont(name: FontFamily.NotoSans.regular.name, size: Constraints.nameLabel.fontSizeLabel) + label.backgroundColor = .clear + label.font = MessageCallView.normalFont label.numberOfLines = 1 self.addSubview(label) @@ -130,23 +129,26 @@ final class MessageCallView: MessageContentView { private lazy var time: UILabel = { let label = UILabel() label.textColor = UIColor.nynja.darkLight - label.backgroundColor = .red - label.font = UIFont(name: FontFamily.NotoSans.regular.name, size: Constraints.nameLabel.fontSizeLabel) + label.backgroundColor = .clear + label.font = MessageCallView.normalFont label.numberOfLines = 1 self.addSubview(label) label.snp.makeConstraints { make in make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) - make.top.equalTo(duration.snp.bottom).offset(Constraints.nameLabel.verticalInset) + make.centerY.equalTo(duration.snp.centerY) make.left.equalTo(duration.snp.right).offset(Constraints.imageView.leftInset) } return label }() + private static var normalFont = UIFont(name: FontFamily.NotoSans.regular.name, size: Constraints.nameLabel.fontSizeLabel) + private static var boldFont = UIFont(name: FontFamily.NotoSans.bold.name, size: Constraints.nameLabel.fontSizeLabel) + // MARK: - Private Methods private func updateConstraintsAndControlValues(with model: BaseChatCellModel) { - + time.snp.removeConstraints() duration.snp.removeConstraints() participants.snp.removeConstraints() @@ -159,9 +161,6 @@ final class MessageCallView: MessageContentView { title.text = stringFrom(status:cs, isowner:model.isOwner, duration:cd) } - let normalFontHeight = ceil(title.font.lineHeight) - let boldFontHeight = ceil(participants.font.lineHeight) - if model.isGroup { if let d = model.callDuration, d > 0 { participants.snp.makeConstraints { make in @@ -184,15 +183,13 @@ final class MessageCallView: MessageContentView { time.snp.makeConstraints { make in make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) - make.top.equalTo(duration.snp.bottom).offset(Constraints.nameLabel.verticalInset) + make.centerY.equalTo(duration.snp.centerY) make.left.equalTo(duration.snp.right).offset(Constraints.imageView.leftInset) } - if let d = model.callStartTime { + if let d = model.timeStamp { time.text = stringFrom(date: d) } - - MessageCallView.viewHeight = 2*normalFontHeight + boldFontHeight + CGFloat(4*Constraints.nameLabel.verticalInset) } else { participants.snp.makeConstraints { make in make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) @@ -206,11 +203,11 @@ final class MessageCallView: MessageContentView { time.snp.makeConstraints { make in make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) - make.top.equalTo(participants.snp.bottom).offset(Constraints.nameLabel.verticalInset) + make.centerY.equalTo(participants.snp.centerY) make.left.equalTo(participants.snp.right).offset(Constraints.imageView.leftInset) } - if let d = model.callStartTime { + if let d = model.timeStamp { time.text = stringFrom(date: d) } @@ -219,8 +216,6 @@ final class MessageCallView: MessageContentView { make.height.width.equalTo(0) make.top.equalTo(participants.snp.bottom) } - - MessageCallView.viewHeight = normalFontHeight + boldFontHeight + CGFloat(3*Constraints.nameLabel.verticalInset) } } else { participants.text = "" @@ -240,15 +235,13 @@ final class MessageCallView: MessageContentView { time.snp.makeConstraints { make in make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) - make.top.equalTo(duration.snp.bottom).offset(Constraints.nameLabel.verticalInset) + make.centerY.equalTo(duration.snp.centerY) make.left.equalTo(duration.snp.right).offset(Constraints.imageView.leftInset) } - if let d = model.callStartTime { + if let d = model.timeStamp { time.text = stringFrom(date: d) } - - MessageCallView.viewHeight = 2*normalFontHeight + CGFloat(3*Constraints.nameLabel.verticalInset) } else { duration.text = "" duration.snp.makeConstraints { make in @@ -264,15 +257,13 @@ final class MessageCallView: MessageContentView { time.snp.makeConstraints { make in make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) - make.top.equalTo(title.snp.bottom).offset(Constraints.nameLabel.verticalInset) + make.centerY.equalTo(title.snp.centerY) make.left.equalTo(title.snp.right).offset(Constraints.imageView.leftInset) } - if let d = model.callStartTime { + if let d = model.timeStamp { time.text = stringFrom(date: d) } - - MessageCallView.viewHeight = normalFontHeight + CGFloat(2*Constraints.nameLabel.verticalInset) } } } @@ -360,6 +351,35 @@ final class MessageCallView: MessageContentView { } override class func size(for model: BaseChatCellModel, maxWidth: CGFloat) -> CGSize { - return CGSize(width: maxWidth, height: viewHeight) + return calculateSize(for:model, maxWidth:maxWidth) + } + + private static func calculateSize(for model: BaseChatCellModel, maxWidth: CGFloat) -> CGSize { + var viewHeight:CGFloat = 0.0 + var normalFontHeight:CGFloat = 0.0 + if let nf = normalFont { + normalFontHeight = ceil(nf.lineHeight) + } + + var boldFontHeight:CGFloat = 0.0 + if let bf = boldFont { + boldFontHeight = ceil(bf.lineHeight) + } + + if model.isGroup { + if let d = model.callDuration, d > 0 { + viewHeight = 2*normalFontHeight + boldFontHeight + CGFloat(4*Constraints.nameLabel.verticalInset) + } else { + viewHeight = normalFontHeight + boldFontHeight + CGFloat(3*Constraints.nameLabel.verticalInset) + } + } else { + if let d = model.callDuration, d > 0 { + viewHeight = 2*normalFontHeight + CGFloat(3*Constraints.nameLabel.verticalInset) + } else { + viewHeight = normalFontHeight + CGFloat(2*Constraints.nameLabel.verticalInset) + } + } + + return CGSize(width: maxWidth + 100, height: viewHeight + CGFloat(Constraints.offset)) } } -- GitLab From 68d9a7674b03869c9ae50c1bc62f18039ed70961 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Wed, 28 Nov 2018 16:31:54 +0200 Subject: [PATCH 26/59] updated call bubble images --- Nynja/Generated/AssetsConstants.swift | 22 ++++ .../Cells/Views/Message/MessageCallView.swift | 113 ++++++------------ .../Assets.xcassets/callBubbles/Contents.json | 6 + .../ic_canceled_video.imageset/Contents.json | 12 ++ ...roup_Voice_Call_ic_video_call_canceled.pdf | Bin 0 -> 4067 bytes .../ic_canceled_voice.imageset/Contents.json | 12 ++ ...roup_Voice_Call_ic_voice_call_canceled.pdf | Bin 0 -> 4883 bytes .../ic_incoming_video.imageset/Contents.json | 12 ++ ...Voice_Call_ic_video_call_incoming_dark.pdf | Bin 0 -> 4061 bytes .../ic_incoming_voice.imageset/Contents.json | 12 ++ .../ic_incoming_voice.imageset/Icon.pdf | Bin 0 -> 4869 bytes .../ic_missed_video.imageset/Contents.json | 12 ++ ...p_Voice_Call_ic_video_call_missed_dark.pdf | Bin 0 -> 4096 bytes .../ic_missed_voice.imageset/Contents.json | 12 ++ ...p_Voice_Call_ic_voice_call_missed_dark.pdf | Bin 0 -> 4908 bytes .../ic_no_answer_video.imageset/Contents.json | 12 ++ ...oice_Call_ic_video_call_no_answer_dark.pdf | Bin 0 -> 4045 bytes .../ic_no_answer_voice.imageset/Contents.json | 12 ++ ...oice_Call_ic_voice_call_no_answer_dark.pdf | Bin 0 -> 4855 bytes .../ic_outgoing_video.imageset/Contents.json | 12 ++ ...Voice_Call_ic_video_call_outgoing_dark.pdf | Bin 0 -> 4073 bytes .../ic_outgoing_voice.imageset/Contents.json | 12 ++ ...Voice_Call_ic_voice_call_outgoing_dark.pdf | Bin 0 -> 4883 bytes 23 files changed, 187 insertions(+), 74 deletions(-) create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video.imageset/Icons_Group_Voice_Call_ic_video_call_canceled.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_canceled.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video.imageset/Icons_Group_Voice_Call_ic_voice_call_incoming_darkIcons_Group_Voice_Call_ic_video_call_incoming_dark.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_voice.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_voice.imageset/Icon.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_video.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_video.imageset/Icons_Group_Voice_Call_ic_video_call_missed_dark.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_missed_dark.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video.imageset/Icons_Group_Voice_Call_ic_video_call_no_answer_dark.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_voice.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_no_answer_dark.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video.imageset/Icons_Group_Voice_Call_ic_video_call_outgoing_dark.pdf create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_voice.imageset/Contents.json create mode 100644 Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_outgoing_dark.pdf diff --git a/Nynja/Generated/AssetsConstants.swift b/Nynja/Generated/AssetsConstants.swift index a9d3f0584..a381a3cae 100644 --- a/Nynja/Generated/AssetsConstants.swift +++ b/Nynja/Generated/AssetsConstants.swift @@ -658,6 +658,28 @@ internal extension Image { static var btnTakePhotoHighlighted: ImageAsset { return ImageAsset(name: "btn_take_photo_highlighted") } /// "btn_wheel_done" static var btnWheelDone: ImageAsset { return ImageAsset(name: "btn_wheel_done") } + enum CallBubbles { + /// "ic_canceled_video" + static var icCanceledVideo: ImageAsset { return ImageAsset(name: "ic_canceled_video") } + /// "ic_canceled_voice" + static var icCanceledVoice: ImageAsset { return ImageAsset(name: "ic_canceled_voice") } + /// "ic_incoming_video" + static var icIncomingVideo: ImageAsset { return ImageAsset(name: "ic_incoming_video") } + /// "ic_incoming_voice" + static var icIncomingVoice: ImageAsset { return ImageAsset(name: "ic_incoming_voice") } + /// "ic_missed_video" + static var icMissedVideo: ImageAsset { return ImageAsset(name: "ic_missed_video") } + /// "ic_missed_voice" + static var icMissedVoice: ImageAsset { return ImageAsset(name: "ic_missed_voice") } + /// "ic_no_answer_video" + static var icNoAnswerVideo: ImageAsset { return ImageAsset(name: "ic_no_answer_video") } + /// "ic_no_answer_voice" + static var icNoAnswerVoice: ImageAsset { return ImageAsset(name: "ic_no_answer_voice") } + /// "ic_outgoing_video" + static var icOutgoingVideo: ImageAsset { return ImageAsset(name: "ic_outgoing_video") } + /// "ic_outgoing_voice" + static var icOutgoingVoice: ImageAsset { return ImageAsset(name: "ic_outgoing_voice") } + } enum CallHistory { /// "ic_call_history_empty" static var icCallHistoryEmpty: ImageAsset { return ImageAsset(name: "ic_call_history_empty") } diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift index bec2e20e1..5170acb99 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift @@ -41,11 +41,11 @@ final class MessageCallView: MessageContentView { private enum Constraints { static let height = 44.0 - static let offset = 12.0 + static let offset = 16.0 enum imageView { - static let verticalInset = 8.adjustedByWidth - static let width = 18.0 + static let verticalInset = 2.adjustedByWidth + static let width = 32.0 static let leftInset = 8.adjustedByWidth } @@ -53,6 +53,14 @@ final class MessageCallView: MessageContentView { static let verticalInset = 4.adjustedByWidth static let fontSizeLabel = CGFloat(12.adjustedByWidth) } + + enum infoView { + static let inset = CGPoint(x: 0, y: 2.adjustedByWidth) + } + } + + override var infoInset: CGPoint { + return Constraints.infoView.inset } // MARK: - Views @@ -61,13 +69,10 @@ final class MessageCallView: MessageContentView { let imageView = UIImageView() imageView.contentMode = .scaleAspectFit - let width = Constraints.imageView.width - - let verticalInset = Constraints.imageView.verticalInset self.addSubview(imageView) imageView.snp.makeConstraints { make in - make.width.height.equalTo(width) + make.width.height.equalTo(Constraints.imageView.width) make.left.equalTo(Constraints.imageView.leftInset) make.centerY.equalToSuperview() } @@ -126,32 +131,14 @@ final class MessageCallView: MessageContentView { return label }() - private lazy var time: UILabel = { - let label = UILabel() - label.textColor = UIColor.nynja.darkLight - label.backgroundColor = .clear - label.font = MessageCallView.normalFont - label.numberOfLines = 1 - - self.addSubview(label) - label.snp.makeConstraints { make in - make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) - make.centerY.equalTo(duration.snp.centerY) - make.left.equalTo(duration.snp.right).offset(Constraints.imageView.leftInset) - } - - return label - }() - private static var normalFont = UIFont(name: FontFamily.NotoSans.regular.name, size: Constraints.nameLabel.fontSizeLabel) private static var boldFont = UIFont(name: FontFamily.NotoSans.bold.name, size: Constraints.nameLabel.fontSizeLabel) // MARK: - Private Methods private func updateConstraintsAndControlValues(with model: BaseChatCellModel) { - - time.snp.removeConstraints() duration.snp.removeConstraints() participants.snp.removeConstraints() + imageView.snp.removeConstraints() if let cs = model.callStatus { imageView.image = imageFrom(status: cs, isaudio: (model.type == .audioCall), isowner: model.isOwner) @@ -180,15 +167,11 @@ final class MessageCallView: MessageContentView { } duration.text = stringFrom(duration: d) - - time.snp.makeConstraints { make in - make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) - make.centerY.equalTo(duration.snp.centerY) - make.left.equalTo(duration.snp.right).offset(Constraints.imageView.leftInset) - } - if let d = model.timeStamp { - time.text = stringFrom(date: d) + imageView.snp.makeConstraints { make in + make.width.height.equalTo(Constraints.imageView.width) + make.left.equalTo(Constraints.imageView.leftInset) + make.centerY.equalTo(participants.snp.centerY) } } else { participants.snp.makeConstraints { make in @@ -200,15 +183,11 @@ final class MessageCallView: MessageContentView { if let pc = model.callMembersCount { participants.text = String.localizable.participantsCount(Int(pc)) } - - time.snp.makeConstraints { make in - make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) - make.centerY.equalTo(participants.snp.centerY) - make.left.equalTo(participants.snp.right).offset(Constraints.imageView.leftInset) - } - if let d = model.timeStamp { - time.text = stringFrom(date: d) + imageView.snp.makeConstraints { make in + make.width.height.equalTo(Constraints.imageView.width) + make.left.equalTo(Constraints.imageView.leftInset) + make.centerY.equalTo(title.snp.bottom).offset(Constraints.nameLabel.verticalInset/2) } duration.text = "" @@ -233,14 +212,10 @@ final class MessageCallView: MessageContentView { duration.text = stringFrom(duration: d) - time.snp.makeConstraints { make in - make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) - make.centerY.equalTo(duration.snp.centerY) - make.left.equalTo(duration.snp.right).offset(Constraints.imageView.leftInset) - } - - if let d = model.timeStamp { - time.text = stringFrom(date: d) + imageView.snp.makeConstraints { make in + make.width.height.equalTo(Constraints.imageView.width) + make.left.equalTo(Constraints.imageView.leftInset) + make.centerY.equalTo(title.snp.bottom).offset(Constraints.nameLabel.verticalInset/2) } } else { duration.text = "" @@ -249,20 +224,10 @@ final class MessageCallView: MessageContentView { make.top.equalTo(title.snp.bottom) } - participants.text = "" - participants.snp.makeConstraints { make in - make.height.width.equalTo(0) - make.top.equalTo(title.snp.bottom) - } - - time.snp.makeConstraints { make in - make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + imageView.snp.makeConstraints { make in + make.width.height.equalTo(Constraints.imageView.width) + make.left.equalTo(Constraints.imageView.leftInset) make.centerY.equalTo(title.snp.centerY) - make.left.equalTo(title.snp.right).offset(Constraints.imageView.leftInset) - } - - if let d = model.timeStamp { - time.text = stringFrom(date: d) } } } @@ -314,28 +279,28 @@ final class MessageCallView: MessageContentView { if isaudio { switch status { case .ANSWERED: - return !isowner ? UIImage.nynja.CallHistory.icIncomingVoice.image : UIImage.nynja.CallHistory.icOutgoingVoice.image + return !isowner ? UIImage.nynja.CallBubbles.icIncomingVoice.image : UIImage.nynja.CallBubbles.icOutgoingVoice.image case .CANCELED: - return UIImage.nynja.CallHistory.icCanceledVoice.image + return UIImage.nynja.CallBubbles.icCanceledVoice.image case .DECLINED: - return UIImage.nynja.CallHistory.icMissedVoice.image + return UIImage.nynja.CallBubbles.icMissedVoice.image case .MISSED: - return UIImage.nynja.CallHistory.icMissedVoice.image + return UIImage.nynja.CallBubbles.icMissedVoice.image case .UNANSWERED: - return UIImage.nynja.CallHistory.icNoAnswerVoice.image + return UIImage.nynja.CallBubbles.icNoAnswerVoice.image } } else { switch status { case .ANSWERED: - return !isowner ? UIImage.nynja.CallHistory.icIncomingVideo.image : UIImage.nynja.CallHistory.icOutgoingVideo.image + return !isowner ? UIImage.nynja.CallBubbles.icIncomingVideo.image : UIImage.nynja.CallBubbles.icOutgoingVideo.image case .CANCELED: - return UIImage.nynja.CallHistory.icCanceledVideo.image + return UIImage.nynja.CallBubbles.icCanceledVideo.image case .DECLINED: - return UIImage.nynja.CallHistory.icMissedVideo.image + return UIImage.nynja.CallBubbles.icMissedVideo.image case .MISSED: - return UIImage.nynja.CallHistory.icMissedVideo.image + return UIImage.nynja.CallBubbles.icMissedVideo.image case .UNANSWERED: - return UIImage.nynja.CallHistory.icNoAnswerVideo.image + return UIImage.nynja.CallBubbles.icNoAnswerVideo.image } } } @@ -380,6 +345,6 @@ final class MessageCallView: MessageContentView { } } - return CGSize(width: maxWidth + 100, height: viewHeight + CGFloat(Constraints.offset)) + return CGSize(width: maxWidth, height: viewHeight + CGFloat(Constraints.offset)) } } diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callBubbles/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video.imageset/Contents.json new file mode 100644 index 000000000..45bc1e73a --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Icons_Group_Voice_Call_ic_video_call_canceled.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video.imageset/Icons_Group_Voice_Call_ic_video_call_canceled.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video.imageset/Icons_Group_Voice_Call_ic_video_call_canceled.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5cbeae6d47a2417724a532ba4e0826d4469c32d5 GIT binary patch literal 4067 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 IQ5xX?0E8>->;M1& literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice.imageset/Contents.json new file mode 100644 index 000000000..f6ae121f6 --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Icons_Group_Voice_Call_ic_voice_call_canceled.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_canceled.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_canceled.pdf new file mode 100644 index 0000000000000000000000000000000000000000..90eb448e5a5e6b77e58d952aba8e4cedaea9368a GIT binary patch literal 4883 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 literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video.imageset/Contents.json new file mode 100644 index 000000000..a838d3da1 --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Icons_Group_Voice_Call_ic_voice_call_incoming_darkIcons_Group_Voice_Call_ic_video_call_incoming_dark.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video.imageset/Icons_Group_Voice_Call_ic_voice_call_incoming_darkIcons_Group_Voice_Call_ic_video_call_incoming_dark.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video.imageset/Icons_Group_Voice_Call_ic_voice_call_incoming_darkIcons_Group_Voice_Call_ic_video_call_incoming_dark.pdf new file mode 100644 index 0000000000000000000000000000000000000000..447ac6a262e1e058b17e1cd1bdaa08ac2d69f7d7 GIT binary patch literal 4061 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 literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice.imageset/Contents.json new file mode 100644 index 000000000..00a8473dc --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Icons_Group_Voice_Call_ic_voice_call_missed_dark.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_missed_dark.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_missed_dark.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c0aca91ca3bf009031e7177280723b54c7a9b5ac GIT binary patch literal 4908 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 literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video.imageset/Contents.json new file mode 100644 index 000000000..66bae4d5b --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Icons_Group_Voice_Call_ic_video_call_no_answer_dark.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video.imageset/Icons_Group_Voice_Call_ic_video_call_no_answer_dark.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video.imageset/Icons_Group_Voice_Call_ic_video_call_no_answer_dark.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b0d5434f8a4510c7255137efd3431e0015597c49 GIT binary patch literal 4045 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 Z-zDgQC6&gH9|D6xrD*y1RJ2uT{{tgldmR7( literal 0 HcmV?d00001 diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video.imageset/Contents.json new file mode 100644 index 000000000..f40b415af --- /dev/null +++ b/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Icons_Group_Voice_Call_ic_video_call_outgoing_dark.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video.imageset/Icons_Group_Voice_Call_ic_video_call_outgoing_dark.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video.imageset/Icons_Group_Voice_Call_ic_video_call_outgoing_dark.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b8fc4dd9c3d92474d77ec096bf1ce397de7a0493 GIT binary patch literal 4073 zcmai%cT`hb7RD)2ARtY;s8^(jQW6rHO0NNwCP?TZ2@qN^gf3E~JeqV76cItH6d$Mv z0@9m9=!ghNmo7!BkqMT0zIn6O+}xFWvd_L>&N=)0xMu4Oy&V`62P@XO*B32!X#$&L6q9WLXNWh|8 z!9LWUhShGgP^J+w=L6cN=hLmj9xvQf!fz^fPnru-_cD>mMi*I-;15WdD+u8)Z`fFt zP7s=py|Q?1{=q?W^3-*Xd^UKqwdQI!dn->(JjSd;p^cpps^){o@}wdR3TQ;T$~x{| zGl@9fVX1&?_T^rAr#o{t)PQYlE0_qpzo~<#=2pC z9vx+Lc;bi0eE5Vx;D?ikL#f}2an08q3rHHE9KL@Oux>;E_M0gd$lWPSwH z@NPuPya#YtOrygh{nR_0|5aQA0v>IQB?1-{QFTqg3XoL8yWk1N?kF@CIIO;!2NaO~ zDe#+y+;18`4I=+NOY$mZL6RzmCUK)U1dvq6dg0JmBQ4ec@12ah-q(zWxgtn4vNhf8 z0)WsapC1Fzdr6xUWEhDEGN1_$74}j;qRGJ~YKpn`hFU8^0Ik8ncss;yh+&=8przhW zU1Mf6#+hNYSbAeDo!p8XAD(+TH0-b%FjPfl@HGU~Ks2Kcf@hg=tSr`BvLEkk+NR-Q zrDisxeluZj57OFEr|JJ%qmY)Cuia9kW~{rN(I&!khy$I zn0tmM*|@x!SLy)Nv6&(&6%Li+%3^r@RA8#9)MYDg_Cj_0y;R}pEIwox?`!zOm}-Nu zbfJmt7*LkwJ)w^d**EF1HP;a7R5RP>`ucVr=uts9(rn(&31_)PN@;NLu0*cWP|+th z$-gErNAJozKBV%=b(oFM#x?3-T7(ggGvNl8(x7*?JTXJ zo01<*z@h~!6x>$(+OasH)FV#H@7vtoX-3N^w+THJ0pr;%rZ@~i=&=}Y_IRjEJq>$2 z9q|zu9xMT&5wktU9|Uu!9RsLBgS1&`@6t+W)8Ldrf2t_HqXMfy-%)$rc5zfgA^I zvsz?4YohXQw{Sks`P+qAY6c3MXNi1O^j5d`9?^9J@S|kvfKax3G<~RJ@2Fk`4VPWw zr`Kxe{HX53`GAi5&B%mKC6^-e%LeX=6Q8NX!fYCn=#|^(X?rxy=ufPvtHzrNQnQ_L zP7uhUDbPrdXU;kCDpot;#x(8Gh%D4S9^T^ zG89uCwAgrTLU_&R_4zT5)ex3?kI!~D&(wkg`2$al$DMAe6NzUq2RVnZoVg1Kx(Hrl z<)fdYCx@~%zzu`*^@#%EtiDZ_cB0Sjyi<9N;1|A{#DNGG^nd zIg`|W5u-)mK`LA8mk4G8HbN|kN(Ra2ggNwe_%&3AugdGZQubB$ReNG|EZ?o)tngk{ zhPi%?dVo%Vq*f9vbt84Ey*Q~T!8v6y)n7x_}KzY8bSLn$ZKGnV_zP*(d zS1K;P$G(T0)RN8F?@O9*-aP%OW|ILcgteGCH^V=}H&fnWbhH6ty8|=geG-!tQymkx z0iS(Enj($Jl;W%pUW=yeo_9NcGesc9K7~3Zu29beKfp1NQRrHz-w$yTc0xG~JM9lh z6vdMANZt=g88+~P>8}wBWmS=Wm3vNK8W$86lK9g3YWaBiO!!jaEz-Q{Zt3mmGwE~i z)(S^+#^)gO8S}a4){vC6mABXIh03Glvx-ZW^Tc};b4H64iqZMyW)9g`%e#(SB}!Px zs=Ty(Y3!}4uPbRLX;W&rnx$x%S)7?ur&VVW*zu+tcyAl6a=$)5D=MoF^$?Xkfj(Q9 zP}Fli+dTVHiyZpJji@!nDGTAU$P7dxBDVdC@w@)9YqnLS3KEm^tfMfzNV>Z9aoGnX z@~P(FBl*V5Z8x)h@9$n$}=f*@OKOsQ^BN1ccRKKcughB6m*hG;%(}YH_o3rar)#q>p|r4hJqQrl1-ae-ZP+~r0R(M z#JQFWbFphyJJ_!Ypw!SmLwnRyo2(+yh!O-RVv0sz<@ra?KW)~7rwfwfle0x(1w94- z!i84sRP?C|p`ywzSiuxTY9t%s*$}m=4&1GWy0&XesM?fbW+?WMgv9csP4g@3J=UU6nF4jU}79C>xs z+p4~5;!EvfoGaj}J^Z;-vojWZV%#litl#jFVOg!MWBKZAi|Q*?!-*R4E(>OtW*1JE z{(?-(b*m z)|1wTIM0Dg{X??(vdJTU zZ&X0xya+jS>qWPDlzGBB_(um zKDaNR>3wTmwIysVI+8o$;&q~8RmF5~MoC%8SZ8o*srA|`LcvJQ{#TRKB8L)rt4jeH z0X56vMHQ+p&}ZqI68a%`(AVCK$2#tGW!qkAh7 zwf+az9~9;T#>hQ%1uWJ|Z~f%Rj%4)G)MF8_{`rT6O2y=Xogw>zn$4w0L$;*yKOEx1 zE7c?qQg%!A8;_6*NEb9KG#9jrwMa3$F{6IZHk&_p#-#R5h1H3Ed$FC;QW@WB;H0d`O|+p;-nh^$U0p`SmbHfn0=|nkvczivbP+)(Eirm2wEt zznJ(h#`XXtuV67alq%i_uz*lfU{aL(J0yEj$Ques>f$gS6nH*Fbc)(O-k?z9`pO}zgF){O1B>q@`iffIaXt z29uVf?D6md+|7?u&qnsb5DKf(2DV{m>1?3f(e)q?B&Uwz>=iO_sXYI4s^FHs|e0s{N!cY-7HD4=no%r?n#*?1b zHfjVI0(L>!Q(wIb7S+Z&+u&@$VkF1_EUIefh{L*(T1P7!RvC+S!C=9%vefQ4H>{Nt zwKp&3iZdoewY!#MMaEv-ae5rqZB0J@4Jd@FG+slgj!z ze;3QqZR>*efycr%^L=HbtM6+|psI+M^`EYe`Ht*Nl;=;!$)?#^vUkUx=&vok*PTX` zcs=7Bn>*s+gU{{jM%)Y2LA73aCDxj@k}-S#`6f+DZ7IFXh>{+cMV4_UuR8VU+!^fl z5>NFA#{b>RN;@1YHz(`(gBLH`jYibDU_Qk$R7ZT*E-7=q`L3MwF`1#=dBn6mzDqNZ zUm)=#+W^)qxk0D4%Al~5R)oEarM9r3BjbIJ@BL*D%dWfvYJNv)mZ&P7Y)xZ9hEMzS zuO-7~5l^SZ=F0o;vnBn|*GX$$#Oc5&>!rDPBD+0@-@RHqkaC@d11sOJTvv`woDn3> z7qg=!rnSaQ%_B45Qp2i~H z9$_7HI@jXL{5K;p+_Nv)V~>-m0y;FE41CA%K4Oa_bUcM3N@&A{MHA-08w*<&!-0c4 zwv(g7nWNmxDt5!s95;GwPZb^PYVCKi4h0|x1P9=4W#FN_L6G%H)Yjj5%E zKBIRSgL<_!P0HE?fTc)??EH6r`Q!)%p>CZZ4GY`E*?j?^y(9F&D;F{d0^iR-)B&^+ zwnQkG&jK99-zrYb%h5WAu=g%%EKHUx<>o!fc~>@{*(C2l1==-Rr)!2Xi1};`9j%;w zMxJzKv19U{Bp>cJGVba8lUFSb?;&-J>+^D@@x5Pa{T3VeV@4*+yXX$#=bn|BEaK%n zqyhA%am_niQ?gV&7Pek1+Ts0jf_mc3OnpnUfO^5;aLsF(;EOqnvu>;SE?_X_IZgSs zv=Wp8Fk6=t!iCNdpxLz0#NDD$bQkSu&gm~x@~)2qUG-SA<*0gQW`QMSGFwKvZQ11% z_Zd0e+-bQ6CmK=#pLH&FT~+@)fRX?R5_}S98TG!oUNH)iRc{PpoM|#pulfv#lD>9_ zF-!Z?0bm~hY(cTSx$Gw=-v~Ps_<`&r1tl}p63Y&g1q*#CWtGAWqXjauXyT8}3+-fz zKud~j3VJYK9|!9kW{C&!fIPG>^UXQb53R>1LM1X*HoUn{b5r@AZ%-As#gPqS*o1R< zx1+QM7X1QC-YAW`r90Y7PqKE6N&6KN_m95JanIlJyY3Jz5fy^mFqWiaWh>`HZ@BsO z6!m_xq6ysbFOho~MMXH894%Sywp>J(MNwm&F~2y5)H|l8V?H`=p-?FNc=Wgr`-8Tw z-*Lr)MfI#~e!ktX&NwjqFA6ijy1RI|p|S2@@xK5i7iS!4+#P&Odj`jJ_RHV#_-`82 zb8|r(VsYS`B&W)%U~{mjl8d8@o1v=}8Vf$=NhNnESmKw1KYU33;o}#TO8vAFy+#U1 zRN0`jHwz zdSv0D{GQ4uRGAnAjWO37foc&vXceYYcSBIaRO|G5ZB6>hD#UTT1J!Dg*v3TKVLNhi zWbXCwh|Q}1a5X^hAOzHmGXVx6vP_s(zBZYiVeD?*CS#)q(wYDpr>w0(YCFng0|#|7 zsi}GDZ53N9B0-p%F`))Me)plHz<3@BCEk+&YL!9ps{#D1M6x8qinr{rBT(07vLGxR z3S-HldRoXc-CE+f^?denP3OZD{+TQe`IVM?`pH^-ml7ztBhVqb||Cj(F>wMx~x(MIn|*=7K|b8Tj#K#>}# zT!!I?cEtG(>%FxK!(9~ga#D-V)ID!)!e%ASeF$q%iOT~OARp2x)i!>)h;w-vIW%j# z+b}YDF2L|mro(67XpMh~kfDIjKu$U?6^hoe0JeBdA8}RGCmR7OoleRVrwVmf!GQG> zfXa!-8|T6uEfQM4&tPA-50lcX(xB*YkpU=OAm??K^C9#9dXpYX-BDj_TNGd79t-pN zF}KHk$}GxxN?U=)aCVC(7URbERERx$GSsn&>`WX5?g=#_SOh{Qbn7%{5Zsk~0t^TZ zQl}?>KrW(AW+x9SSCIV(pjLo>1bW`JcLfXt`}BaWg^0VJGy~meJnedlCP+=5I=o2> z0-Ol8qYU{*&-_&3MI1{GU8>>`{aI7WJ4y7-zx@WH|2-&yz!zuaXu=n{)O}jC%a-8S;}6 zSym6(SlZa9Barwhl(E$iN)s~p5dF|tn{`&)njRj!8}bY_Se9!dP$=g~CC>0DM!41Z zR_v{tr730PAFY<8IceJ)*}rhQ22`<`!JNg4L9gkC@ijqTTTV~$uX)#AnqXQDp=)yg zhVnaKPaVh^cy2P5yRAVWj>;6|5JGqU0hrg3_c}cXPt6FaY9)ZEyR@)o+qyqRE2KDq=s zy`+o$OuCw!DvBf5q%_~i-;uwg^vvLNp7Vgoi-*2*DzA)UM7kPERJdglXovUU-C=l zNw!V~Cdawq;b@9uyYu3q#)YF*wdWTI@5@0bBOjzThmi7L8e60xtA7@SSq)YhR@qbN3oqgedM{<0W=pq8qF>#PT9ci=$zK|o zu92V-)2US(t=;yf?bg!&IMe4U@F`mlzdrV#KIDC^gFKADdE zAo$_*hwM`{tlwA%gxTDBZ%$THS@)))AT?pPg? z9eVDKZw!B%+Z*231xbPmsphG3K&l{P3fWUIsxv1%KrKzcrkW6L(LPIFvjG+|#RDbJ zu&Y#JH0I2E?rb7Lh(i9QJ5@&B0p4C9VU&upQfrNRY)4;*T67GH7K@i^r`lVUK{Xu} zUzHRUtrQa>WW|gs-V_hcm0{sN%k0bR>6X9UH?9>iz4V28dPM|o_Ml>E)a@lPznf4T zXW4|jed*j;ZmvoCqe#Z)e4=*orsW$iB4{|VCSpHfuI=(%%$oTQ_8=aV5?UVGtDMqm z9*Nc{)?n6{Ceu}T`Prk~ay@t^KPfILTM(Y#oB!S}v~s7iUy;u$s`RosTt=Wyv;~n3 zQL65;8(cABd@A1?uYJ)SXUiEqe0PzjD(uTAY}BxsUHb1BW;bWjW}LgZ zIyXA^1H`PwygY2`J%5BBG>NS^&=!Ra6`PH{x#nfwR6X^*{%fog*hzilTeoU=4EF4# zbJWCu{uBMu`dhXYtFvv2Zxr>X>V!Ysq;-7j$n3a0Ze3AiKbFE{(fb|M{Uz#)F5jnw zuaijs8@uE0wnCTdo^3tb_xkKf>Gf%Rp?bq46@|1I=_&qfUPOGi{&f9y&5fmcW2>9D zZ_(MsVqz;{dF6GQCH88A&lhtRgE?Z;X6qJxUoWSRwvP=rOgaVj17pbFQplcT;;aqq z*w%9>QgC`}^=YcGh4A(1Vs(Q}pk<))vie#)K`l(}S$lJ=$Ds7Uutc6jl6Z4WLR;DN z?RJ;L&)=1N84DKl;Ms3>K$7RB*1ojwaIa?2TphU+<^N(q;4pLRRgY^pYWgCGv61T*sAs?-akq|OCEi4Z$+fu_sHUt%!2>KVJ}5KorT;xAIU@8 zL-f-0Qvqt-OBpZZiVg>NhOP7KHkY0Z-y&4pvxyC_QW8B%-YwB>IYG!LTvn}AT~sSl zBj9)O<344ZZ@+cpQ~IaF8U%m5+D`5*$PDn>ud_jQwtjQy{hBJLIgwW{wKufoG>4g= z>G!f*&3zs5u|y|%`$Hf@kInz-QOOEt<>+Gbmwb2srQ83OMz6Nvi#)(D%j( z{$308cfoK``3ejIl_b>?Vx$``1~r911W3={mVd-Zssu0|Xwo6b&p1eDB1)vQ4;(1~ zmAy#l^(nVqk0VFAPD79Q<<>?ED*p!eFE= zJHGzL5KsiE4*Dksfxt-1`X>g3LH;!t3ja5TfFAG0|ICF;kkaCx7y=^oFFOPbMyi+o z#||d(Zw!w3BNm*Sm7OEj?dM68p`8!u|B;F!0~Z%k&K&0j=|^ffTf2}F=&!yqDTS^| zN Date: Wed, 28 Nov 2018 19:40:21 +0200 Subject: [PATCH 27/59] polishing one to one bubble view --- .../ChatCells/BaseChatCell/BaseChatCell.swift | 7 +++++- .../BaseChatCell/BaseChatCellLayout.swift | 1 + .../BaseChatCell/OponentChatCell.swift | 7 +++++- .../Cells/Views/Message/MessageCallView.swift | 22 ++++++++++++++++--- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/BaseChatCell.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/BaseChatCell.swift index 4f4f85ea5..3ef82dd0d 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/BaseChatCell.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/BaseChatCell.swift @@ -216,7 +216,12 @@ class BaseChatCell: UICollectionViewCell, MessageBaseImageViewDataSource, Messag return { (make) in make.right.equalToSuperview().offset(-Constraints.bubble.horizontalInset) make.top.equalTo(verticalInset) - make.width.lessThanOrEqualTo(BaseChatCell.Constraints.bubble.maxWidth).priority(999) + + if let m = self.model, m.type == .audioCall || m.type == .videoCall { + make.width.equalTo(BaseChatCell.Constraints.bubble.callBubbleWidth) + } else { + make.width.lessThanOrEqualTo(BaseChatCell.Constraints.bubble.maxWidth).priority(999) + } } } diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/BaseChatCellLayout.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/BaseChatCellLayout.swift index b29b0c683..d23ec0bf3 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/BaseChatCellLayout.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/BaseChatCellLayout.swift @@ -12,6 +12,7 @@ extension BaseChatCell { enum bubble { static let maxWidth = CGFloat(290.0.adjustedByWidth) + static let callBubbleWidth = CGFloat(240.0.adjustedByWidth) static let verticalInset = CGFloat(4.0.adjustedByWidth) static let horizontalInset = CGFloat((fromImageView.leftOffset + fromImageView.height / 2).adjustedByWidth) diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/OponentChatCell.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/OponentChatCell.swift index 49e4ec85f..f0ab4fd92 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/OponentChatCell.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/BaseChatCell/OponentChatCell.swift @@ -48,7 +48,12 @@ class OponentChatCell: BaseChatCell { self.bubbleLeftToSuperviewConstraint = make.left.equalToSuperview().offset(horizontalInset).constraint self.bubbleLeftToAvatarConstraint = make.left.equalToSuperview().offset(avatarInset).constraint make.top.equalTo(verticalInset) - make.width.lessThanOrEqualTo(BaseChatCell.Constraints.bubble.maxWidth).priority(999) + + if let m = self.model, m.type == .audioCall || m.type == .videoCall { + make.width.equalTo(BaseChatCell.Constraints.bubble.callBubbleWidth) + } else { + make.width.lessThanOrEqualTo(BaseChatCell.Constraints.bubble.maxWidth).priority(999) + } } } diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift index 5170acb99..f7d1a1c5e 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift @@ -43,6 +43,8 @@ final class MessageCallView: MessageContentView { static let height = 44.0 static let offset = 16.0 + static let minViewHeight = 36 + enum imageView { static let verticalInset = 2.adjustedByWidth static let width = 32.0 @@ -206,7 +208,7 @@ final class MessageCallView: MessageContentView { if let d = model.callDuration, d > 0 { duration.snp.makeConstraints { make in make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) - make.left.equalTo(Constraints.imageView.leftInset) + make.left.equalTo(imageView.snp.right).offset(Constraints.imageView.leftInset) make.top.equalTo(title.snp.bottom).offset(Constraints.nameLabel.verticalInset) } @@ -217,6 +219,13 @@ final class MessageCallView: MessageContentView { make.left.equalTo(Constraints.imageView.leftInset) make.centerY.equalTo(title.snp.bottom).offset(Constraints.nameLabel.verticalInset/2) } + + title.snp.removeConstraints() + title.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.left.equalTo(imageView.snp.right).offset(Constraints.imageView.leftInset) + make.top.equalToSuperview().offset(Constraints.nameLabel.verticalInset) + } } else { duration.text = "" duration.snp.makeConstraints { make in @@ -227,7 +236,14 @@ final class MessageCallView: MessageContentView { imageView.snp.makeConstraints { make in make.width.height.equalTo(Constraints.imageView.width) make.left.equalTo(Constraints.imageView.leftInset) - make.centerY.equalTo(title.snp.centerY) + make.centerY.equalToSuperview() + } + + title.snp.removeConstraints() + title.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) + make.left.equalTo(imageView.snp.right).offset(Constraints.imageView.leftInset) + make.centerY.equalToSuperview() } } } @@ -345,6 +361,6 @@ final class MessageCallView: MessageContentView { } } - return CGSize(width: maxWidth, height: viewHeight + CGFloat(Constraints.offset)) + return CGSize(width: maxWidth, height: max(viewHeight + CGFloat(Constraints.offset), CGFloat(Constraints.minViewHeight))) } } -- GitLab From 8b41ce3e8584fc8734ba3303e2ad2733cc5416fd Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Wed, 28 Nov 2018 19:41:00 +0200 Subject: [PATCH 28/59] Added support for video call bubble --- Nynja/Generated/LocalizableConstants.swift | 2 ++ .../ContextMenu/NynjaContextMenuItemsFactory+Messages.swift | 2 +- .../ChatListMessageCell/Model/ChatListMessageCellModel.swift | 2 +- .../MessageInteractor+MessageHandlerSubscriber.swift | 2 +- Nynja/Modules/Message/Interactor/MessageInteractor.swift | 2 +- .../CollectionView/Cells/ChatCells/MessageCellFactory.swift | 2 +- .../CollectionView/Cells/Views/Base/MessageViewFactory.swift | 4 ++-- .../View/Views/CollectionView/Cells/Views/Info/InfoView.swift | 2 +- .../View/TableView/Cells/StarCell/StarMessageCell.swift | 2 +- Nynja/Resources/en.lproj/Localizable.strings | 2 +- Nynja/Services/Aps.swift | 2 +- Nynja/Services/Models/SendModel.swift | 2 ++ 12 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Nynja/Generated/LocalizableConstants.swift b/Nynja/Generated/LocalizableConstants.swift index 9c5714c40..ee3b78670 100644 --- a/Nynja/Generated/LocalizableConstants.swift +++ b/Nynja/Generated/LocalizableConstants.swift @@ -1229,6 +1229,8 @@ internal extension String { /// VIDEO RESOLUTION static var videoResolution: String { return localizable.tr("Localizable", "VIDEO RESOLUTION") } /// Video Call + static var videoCall: String { return localizable.tr("Localizable", "video_call") } + /// Video Call static var videoCallStatus: String { return localizable.tr("Localizable", "video_call_status") } /// Video Messages static var videoMessages: String { return localizable.tr("Localizable", "video_messages") } diff --git a/Nynja/Library/UI/ContextMenu/NynjaContextMenuItemsFactory+Messages.swift b/Nynja/Library/UI/ContextMenu/NynjaContextMenuItemsFactory+Messages.swift index a031bd165..c54a2543f 100644 --- a/Nynja/Library/UI/ContextMenu/NynjaContextMenuItemsFactory+Messages.swift +++ b/Nynja/Library/UI/ContextMenu/NynjaContextMenuItemsFactory+Messages.swift @@ -27,7 +27,7 @@ extension NynjaContextMenuItemsFactory { rows = NynjaContextMenuItemsFactory.locationMessageItems(for: model) case .sticker: rows = NynjaContextMenuItemsFactory.stickerMessageItems(for: model) - case .audioCall: + case .audioCall, .videoCall: rows = NynjaContextMenuItemsFactory.audioCallMessageItems(for: model) case .transfer: rows = NynjaContextMenuItemsFactory.makeTransferMessageItems(for: model) diff --git a/Nynja/Library/UI/Lists/TableView/Cells/ChatListMessageCell/Model/ChatListMessageCellModel.swift b/Nynja/Library/UI/Lists/TableView/Cells/ChatListMessageCell/Model/ChatListMessageCellModel.swift index 05bb88838..25f0594a2 100644 --- a/Nynja/Library/UI/Lists/TableView/Cells/ChatListMessageCell/Model/ChatListMessageCellModel.swift +++ b/Nynja/Library/UI/Lists/TableView/Cells/ChatListMessageCell/Model/ChatListMessageCellModel.swift @@ -71,7 +71,7 @@ final class ChatListMessageCellModel: CellViewModel { setupSticker(file, in: cell) case .audio, .image, .video, .emoji, .location, .place, .videoCall, .file, .thumbnails, .contact, .reply: setup(mime: type, in: cell) - case .audioCall: + case .audioCall, .videoCall: setup(mime: type, in: cell) case .translate, .autotranslate, .transcribe, .transfer: break diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor+MessageHandlerSubscriber.swift b/Nynja/Modules/Message/Interactor/MessageInteractor+MessageHandlerSubscriber.swift index 6809294bb..20bd65b2f 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor+MessageHandlerSubscriber.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor+MessageHandlerSubscriber.swift @@ -21,7 +21,7 @@ extension MessageInteractor { !localMessage.isDelivered else { return } - if let mime = message.files?.first?.mime, mime == SendMessageType.audioCall.rawValue { + if let mime = message.files?.first?.mime, mime == SendMessageType.audioCall.rawValue || mime == SendMessageType.videoCall.rawValue { return } systemSoundManager.playOutcomingMessageSound() diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor.swift b/Nynja/Modules/Message/Interactor/MessageInteractor.swift index d455ff61b..458b2afe3 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor.swift @@ -1059,7 +1059,7 @@ extension MessageInteractor { return } - let types: [SendMessageType] = [.location, .image, .video, .contact, .place, .audioCall] + let types: [SendMessageType] = [.location, .image, .video, .contact, .place, .audioCall, .videoCall] if let mime = message.mainFile?.mime, let type = SendMessageType(rawValue: mime), types.contains(type) { readUnreadMessages() diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/MessageCellFactory.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/MessageCellFactory.swift index c0392667e..ed6c8f239 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/MessageCellFactory.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/ChatCells/MessageCellFactory.swift @@ -96,7 +96,7 @@ class MessageCellFactory { // MARK: - Helpers private static let types: [SendMessageType] = [ - .contact, .location, .place, .text, .image, .sticker, .file, .video, .audio, .transfer, .audioCall + .contact, .location, .place, .text, .image, .sticker, .file, .video, .audio, .transfer, .audioCall, .videoCall ] private static func ids(for ownerType: OwnerType) -> [String] { diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Base/MessageViewFactory.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Base/MessageViewFactory.swift index fed72bf9f..c2979a5ea 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Base/MessageViewFactory.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Base/MessageViewFactory.swift @@ -144,7 +144,7 @@ final class MessageViewFactory { content = MessageVoiceView(contentAppearance: dependency, delegate: dependency) case .transfer: content = MessageTransferView(contentAppearance: dependency) - case .audioCall: + case .audioCall, .videoCall: content = MessageCallView(contentAppearance: dependency) default: content = nil @@ -175,7 +175,7 @@ final class MessageViewFactory { return MessageVoiceView.self case .transfer: return MessageTransferView.self - case .audioCall: + case .audioCall, .videoCall: return MessageCallView.self default: return nil diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Info/InfoView.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Info/InfoView.swift index b15d94a3b..19e44d494 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Info/InfoView.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Info/InfoView.swift @@ -147,7 +147,7 @@ class InfoView: BaseView, InfoInjectible { } private func adjustBackground(_ model: BaseChatCellModel) { - let types: [SendMessageType] = [.contact, .text, .audio, .file, .place, .audioCall, .transfer] + let types: [SendMessageType] = [.contact, .text, .audio, .file, .place, .audioCall, .videoCall, .transfer] var replyAppearance: CountAppearanceModel diff --git a/Nynja/Modules/Profile/View/TableView/Cells/StarCell/StarMessageCell.swift b/Nynja/Modules/Profile/View/TableView/Cells/StarCell/StarMessageCell.swift index 897e9a736..afac66c32 100644 --- a/Nynja/Modules/Profile/View/TableView/Cells/StarCell/StarMessageCell.swift +++ b/Nynja/Modules/Profile/View/TableView/Cells/StarCell/StarMessageCell.swift @@ -260,7 +260,7 @@ class StarMessageCell: UITableViewCell, ConfigurableCell { } case .sticker: setTextType(mainAttachment.messageRepresentation) - case .audioCall: + case .audioCall, .videoCall: break default: setOther(type) diff --git a/Nynja/Resources/en.lproj/Localizable.strings b/Nynja/Resources/en.lproj/Localizable.strings index 3c76eea59..0b03d5599 100644 --- a/Nynja/Resources/en.lproj/Localizable.strings +++ b/Nynja/Resources/en.lproj/Localizable.strings @@ -201,7 +201,7 @@ "last_message_contact"="Contact"; "voice_message" = "Voice Message"; "audio_call" = "Audio Call"; - +"video_call" = "Video Call"; // MARK: MessageVC "save_to_gallery"="Save to Gallery"; diff --git a/Nynja/Services/Aps.swift b/Nynja/Services/Aps.swift index 371112e55..3850a1019 100644 --- a/Nynja/Services/Aps.swift +++ b/Nynja/Services/Aps.swift @@ -273,7 +273,7 @@ extension Aps { return false } if let mime = message.files?.first?.mime, - mime == SendMessageType.audioCall.rawValue { + mime == SendMessageType.audioCall.rawValue || mime == SendMessageType.videoCall.rawValue { return false } return true diff --git a/Nynja/Services/Models/SendModel.swift b/Nynja/Services/Models/SendModel.swift index ccba64a16..025fd5924 100644 --- a/Nynja/Services/Models/SendModel.swift +++ b/Nynja/Services/Models/SendModel.swift @@ -41,6 +41,8 @@ enum SendMessageType: String { return SendMessageType.location.rawValue.capitalized case .audioCall: return String.localizable.audioCall + case .videoCall: + return String.localizable.video default: return rawValue.capitalized } -- GitLab From de144dcb5f500511c794643fee4da9a6cac7def8 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Wed, 28 Nov 2018 19:51:54 +0200 Subject: [PATCH 29/59] Polishing one to one bubble call view --- .../CollectionView/Cells/Views/Message/MessageCallView.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift index f7d1a1c5e..48adfff48 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift @@ -361,6 +361,7 @@ final class MessageCallView: MessageContentView { } } - return CGSize(width: maxWidth, height: max(viewHeight + CGFloat(Constraints.offset), CGFloat(Constraints.minViewHeight))) + + return CGSize(width: maxWidth, height: max(viewHeight, CGFloat(Constraints.minViewHeight)) + CGFloat(Constraints.offset)) } } -- GitLab From 37b0f35506873d16f4db3f0b7a482e850e5bd4a5 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Thu, 29 Nov 2018 10:46:27 +0200 Subject: [PATCH 30/59] Polishing call bubbles (center image) --- .../Cells/Views/Message/MessageCallView.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift index 48adfff48..050a0edb9 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift @@ -43,7 +43,7 @@ final class MessageCallView: MessageContentView { static let height = 44.0 static let offset = 16.0 - static let minViewHeight = 36 + static let minViewHeight = 2.adjustedByWidth + imageView.width enum imageView { static let verticalInset = 2.adjustedByWidth @@ -236,14 +236,14 @@ final class MessageCallView: MessageContentView { imageView.snp.makeConstraints { make in make.width.height.equalTo(Constraints.imageView.width) make.left.equalTo(Constraints.imageView.leftInset) - make.centerY.equalToSuperview() + make.top.equalToSuperview().offset(Constraints.nameLabel.verticalInset + Constraints.nameLabel.verticalInset/2) } title.snp.removeConstraints() title.snp.makeConstraints { make in make.right.equalToSuperview().offset(-Constraints.imageView.leftInset) make.left.equalTo(imageView.snp.right).offset(Constraints.imageView.leftInset) - make.centerY.equalToSuperview() + make.centerY.equalTo(imageView.snp.centerY) } } } -- GitLab From 088722dab257880af5c205e25aaf072c7bfde686 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Thu, 29 Nov 2018 14:16:10 +0200 Subject: [PATCH 31/59] call back from call bubbles is done --- Nynja/Modules/Message/Presenter/MessagePresenter.swift | 4 ++++ Nynja/Modules/Message/Protocols/MessageProtocols.swift | 2 ++ Nynja/Modules/Message/View/MessageVC+CellDelegate.swift | 8 ++++++++ Nynja/Modules/Message/View/MessageVC.swift | 4 ++++ Nynja/Modules/Message/WireFrame/MessageWireframe.swift | 8 ++++++++ 5 files changed, 26 insertions(+) diff --git a/Nynja/Modules/Message/Presenter/MessagePresenter.swift b/Nynja/Modules/Message/Presenter/MessagePresenter.swift index 2e9ed85b1..a49909897 100644 --- a/Nynja/Modules/Message/Presenter/MessagePresenter.swift +++ b/Nynja/Modules/Message/Presenter/MessagePresenter.swift @@ -187,6 +187,10 @@ class MessagePresenter: BasePresenter, MessagePresenterProtocol, MessageInteract wireFrame.openVideo(videoURL: videoURL) } + func callBackFor(contact:Contact, isAudio:Bool) { + wireFrame.callBackFor(contact: contact, isAudio: isAudio) + } + func openSchedule(content: InputContent, mentions: [Mention]) { let scheduleMessage: InputScheduleMessage switch content { diff --git a/Nynja/Modules/Message/Protocols/MessageProtocols.swift b/Nynja/Modules/Message/Protocols/MessageProtocols.swift index 58b3050bd..b2e67adc9 100644 --- a/Nynja/Modules/Message/Protocols/MessageProtocols.swift +++ b/Nynja/Modules/Message/Protocols/MessageProtocols.swift @@ -32,6 +32,7 @@ protocol MessageWireframeProtocol: DocumentInteractionInput { func openLocation(with type: LocationType) func presentImageModally(imageURL: URL, on view: UIViewController, with transitionInfo: ImagePreviewTransitionInfo) func openVideo(videoURL: URL) + func callBackFor(contact:Contact, isAudio:Bool) func openSchedule(with inputMessage: InputScheduleMessage) func deleteAndLeave() @@ -71,6 +72,7 @@ protocol MessagePresenterProtocol: BasePresenterProtocol, func openImage(imageURL: URL, with transitionInfo: ImagePreviewTransitionInfo) func openFile(at url: URL) func openVideo(videoURL: URL) + func callBackFor(contact:Contact, isAudio:Bool) func openSchedule(content: InputContent, mentions: [Mention]) func sendTyping(_ type: TypingModelType) func sendAudio(withUrl url: URL) diff --git a/Nynja/Modules/Message/View/MessageVC+CellDelegate.swift b/Nynja/Modules/Message/View/MessageVC+CellDelegate.swift index 816236314..5b2d5c1b5 100644 --- a/Nynja/Modules/Message/View/MessageVC+CellDelegate.swift +++ b/Nynja/Modules/Message/View/MessageVC+CellDelegate.swift @@ -48,6 +48,14 @@ extension MessageVC: BaseChatCellDelegate { if let fileUrl = model.fileUrl { openVideo(videoURL: fileUrl) } + case .audioCall: + if !model.isGroup, let contact = presenter.interactor.contact { + callBackFor(contact: contact, isAudio: true) + } + case .videoCall: + if !model.isGroup, let contact = presenter.interactor.contact { + callBackFor(contact: contact, isAudio: false) + } default: break } diff --git a/Nynja/Modules/Message/View/MessageVC.swift b/Nynja/Modules/Message/View/MessageVC.swift index 45c7cf606..0b91756a9 100644 --- a/Nynja/Modules/Message/View/MessageVC.swift +++ b/Nynja/Modules/Message/View/MessageVC.swift @@ -858,6 +858,10 @@ final class MessageVC: BaseVC, MessageViewProtocol, ReplyPreviewDelegate, BackSw func openVideo(videoURL: URL) { presenter.openVideo(videoURL: videoURL) } + + func callBackFor(contact:Contact, isAudio:Bool) { + presenter.callBackFor(contact: contact, isAudio: isAudio) + } // MARK: - MessageViewProtocol diff --git a/Nynja/Modules/Message/WireFrame/MessageWireframe.swift b/Nynja/Modules/Message/WireFrame/MessageWireframe.swift index bdb7e114f..d2fc3be64 100644 --- a/Nynja/Modules/Message/WireFrame/MessageWireframe.swift +++ b/Nynja/Modules/Message/WireFrame/MessageWireframe.swift @@ -126,6 +126,14 @@ class MessageWireFrame: MessageWireframeProtocol, DocumentInteractionWireFrame { } } + func callBackFor(contact:Contact, isAudio:Bool) { + if isAudio { + main?.callBack(contact: contact) + } else { + main?.callBackVideo(contact: contact) + } + } + func openSchedule(with inputMessage: InputScheduleMessage) { main?.showScheduleMessage(with: inputMessage, delegate: nil) } -- GitLab From 3cbd9ce29ae9fd6ca179da4b516e3567ac0477ea Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Thu, 29 Nov 2018 22:18:26 +0200 Subject: [PATCH 32/59] fixed mixed call bubbles and call history images --- Nynja/Generated/AssetsConstants.swift | 40 +++++++++--------- .../Cells/Views/Message/MessageCallView.swift | 20 ++++----- .../Contents.json | 0 ...roup_Voice_Call_ic_video_call_canceled.pdf | Bin .../Contents.json | 0 ...roup_Voice_Call_ic_voice_call_canceled.pdf | Bin .../Contents.json | 0 ...Voice_Call_ic_video_call_incoming_dark.pdf | Bin .../Contents.json | 0 .../Icon.pdf | Bin .../Contents.json | 0 ...p_Voice_Call_ic_video_call_missed_dark.pdf | Bin .../Contents.json | 0 ...p_Voice_Call_ic_voice_call_missed_dark.pdf | Bin .../Contents.json | 0 ...oice_Call_ic_video_call_no_answer_dark.pdf | Bin .../Contents.json | 0 ...oice_Call_ic_voice_call_no_answer_dark.pdf | Bin .../Contents.json | 0 ...Voice_Call_ic_video_call_outgoing_dark.pdf | Bin .../Contents.json | 0 ...Voice_Call_ic_voice_call_outgoing_dark.pdf | Bin 22 files changed, 30 insertions(+), 30 deletions(-) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_canceled_video.imageset => ic_canceled_video_bubble.imageset}/Contents.json (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_canceled_video.imageset => ic_canceled_video_bubble.imageset}/Icons_Group_Voice_Call_ic_video_call_canceled.pdf (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_canceled_voice.imageset => ic_canceled_voice_bubble.imageset}/Contents.json (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_canceled_voice.imageset => ic_canceled_voice_bubble.imageset}/Icons_Group_Voice_Call_ic_voice_call_canceled.pdf (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_incoming_video.imageset => ic_incoming_video_bubble.imageset}/Contents.json (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_incoming_video.imageset => ic_incoming_video_bubble.imageset}/Icons_Group_Voice_Call_ic_voice_call_incoming_darkIcons_Group_Voice_Call_ic_video_call_incoming_dark.pdf (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_incoming_voice.imageset => ic_incoming_voice_bubble.imageset}/Contents.json (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_incoming_voice.imageset => ic_incoming_voice_bubble.imageset}/Icon.pdf (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_missed_video.imageset => ic_missed_video_bubble.imageset}/Contents.json (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_missed_video.imageset => ic_missed_video_bubble.imageset}/Icons_Group_Voice_Call_ic_video_call_missed_dark.pdf (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_missed_voice.imageset => ic_missed_voice_bubble.imageset}/Contents.json (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_missed_voice.imageset => ic_missed_voice_bubble.imageset}/Icons_Group_Voice_Call_ic_voice_call_missed_dark.pdf (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_no_answer_video.imageset => ic_no_answer_video_bubble.imageset}/Contents.json (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_no_answer_video.imageset => ic_no_answer_video_bubble.imageset}/Icons_Group_Voice_Call_ic_video_call_no_answer_dark.pdf (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_no_answer_voice.imageset => ic_no_answer_voice_bubble.imageset}/Contents.json (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_no_answer_voice.imageset => ic_no_answer_voice_bubble.imageset}/Icons_Group_Voice_Call_ic_voice_call_no_answer_dark.pdf (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_outgoing_video.imageset => ic_outgoing_video_bubble.imageset}/Contents.json (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_outgoing_video.imageset => ic_outgoing_video_bubble.imageset}/Icons_Group_Voice_Call_ic_video_call_outgoing_dark.pdf (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_outgoing_voice.imageset => ic_outgoing_voice_bubble.imageset}/Contents.json (100%) rename Nynja/Resources/Assets.xcassets/callBubbles/{ic_outgoing_voice.imageset => ic_outgoing_voice_bubble.imageset}/Icons_Group_Voice_Call_ic_voice_call_outgoing_dark.pdf (100%) diff --git a/Nynja/Generated/AssetsConstants.swift b/Nynja/Generated/AssetsConstants.swift index a381a3cae..4767e42a7 100644 --- a/Nynja/Generated/AssetsConstants.swift +++ b/Nynja/Generated/AssetsConstants.swift @@ -659,26 +659,26 @@ internal extension Image { /// "btn_wheel_done" static var btnWheelDone: ImageAsset { return ImageAsset(name: "btn_wheel_done") } enum CallBubbles { - /// "ic_canceled_video" - static var icCanceledVideo: ImageAsset { return ImageAsset(name: "ic_canceled_video") } - /// "ic_canceled_voice" - static var icCanceledVoice: ImageAsset { return ImageAsset(name: "ic_canceled_voice") } - /// "ic_incoming_video" - static var icIncomingVideo: ImageAsset { return ImageAsset(name: "ic_incoming_video") } - /// "ic_incoming_voice" - static var icIncomingVoice: ImageAsset { return ImageAsset(name: "ic_incoming_voice") } - /// "ic_missed_video" - static var icMissedVideo: ImageAsset { return ImageAsset(name: "ic_missed_video") } - /// "ic_missed_voice" - static var icMissedVoice: ImageAsset { return ImageAsset(name: "ic_missed_voice") } - /// "ic_no_answer_video" - static var icNoAnswerVideo: ImageAsset { return ImageAsset(name: "ic_no_answer_video") } - /// "ic_no_answer_voice" - static var icNoAnswerVoice: ImageAsset { return ImageAsset(name: "ic_no_answer_voice") } - /// "ic_outgoing_video" - static var icOutgoingVideo: ImageAsset { return ImageAsset(name: "ic_outgoing_video") } - /// "ic_outgoing_voice" - static var icOutgoingVoice: ImageAsset { return ImageAsset(name: "ic_outgoing_voice") } + /// "ic_canceled_video_bubble" + static var icCanceledVideoBubble: ImageAsset { return ImageAsset(name: "ic_canceled_video_bubble") } + /// "ic_canceled_voice_bubble" + static var icCanceledVoiceBubble: ImageAsset { return ImageAsset(name: "ic_canceled_voice_bubble") } + /// "ic_incoming_video_bubble" + static var icIncomingVideoBubble: ImageAsset { return ImageAsset(name: "ic_incoming_video_bubble") } + /// "ic_incoming_voice_bubble" + static var icIncomingVoiceBubble: ImageAsset { return ImageAsset(name: "ic_incoming_voice_bubble") } + /// "ic_missed_video_bubble" + static var icMissedVideoBubble: ImageAsset { return ImageAsset(name: "ic_missed_video_bubble") } + /// "ic_missed_voice_bubble" + static var icMissedVoiceBubble: ImageAsset { return ImageAsset(name: "ic_missed_voice_bubble") } + /// "ic_no_answer_video_bubble" + static var icNoAnswerVideoBubble: ImageAsset { return ImageAsset(name: "ic_no_answer_video_bubble") } + /// "ic_no_answer_voice_bubble" + static var icNoAnswerVoiceBubble: ImageAsset { return ImageAsset(name: "ic_no_answer_voice_bubble") } + /// "ic_outgoing_video_bubble" + static var icOutgoingVideoBubble: ImageAsset { return ImageAsset(name: "ic_outgoing_video_bubble") } + /// "ic_outgoing_voice_bubble" + static var icOutgoingVoiceBubble: ImageAsset { return ImageAsset(name: "ic_outgoing_voice_bubble") } } enum CallHistory { /// "ic_call_history_empty" diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift index 050a0edb9..df1940883 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift @@ -295,28 +295,28 @@ final class MessageCallView: MessageContentView { if isaudio { switch status { case .ANSWERED: - return !isowner ? UIImage.nynja.CallBubbles.icIncomingVoice.image : UIImage.nynja.CallBubbles.icOutgoingVoice.image + return !isowner ? UIImage.nynja.CallBubbles.icIncomingVoiceBubble.image : UIImage.nynja.CallBubbles.icOutgoingVoiceBubble.image case .CANCELED: - return UIImage.nynja.CallBubbles.icCanceledVoice.image + return UIImage.nynja.CallBubbles.icCanceledVoiceBubble.image case .DECLINED: - return UIImage.nynja.CallBubbles.icMissedVoice.image + return UIImage.nynja.CallBubbles.icMissedVoiceBubble.image case .MISSED: - return UIImage.nynja.CallBubbles.icMissedVoice.image + return UIImage.nynja.CallBubbles.icMissedVoiceBubble.image case .UNANSWERED: - return UIImage.nynja.CallBubbles.icNoAnswerVoice.image + return UIImage.nynja.CallBubbles.icNoAnswerVoiceBubble.image } } else { switch status { case .ANSWERED: - return !isowner ? UIImage.nynja.CallBubbles.icIncomingVideo.image : UIImage.nynja.CallBubbles.icOutgoingVideo.image + return !isowner ? UIImage.nynja.CallBubbles.icIncomingVideoBubble.image : UIImage.nynja.CallBubbles.icOutgoingVideoBubble.image case .CANCELED: - return UIImage.nynja.CallBubbles.icCanceledVideo.image + return UIImage.nynja.CallBubbles.icCanceledVideoBubble.image case .DECLINED: - return UIImage.nynja.CallBubbles.icMissedVideo.image + return UIImage.nynja.CallBubbles.icMissedVideoBubble.image case .MISSED: - return UIImage.nynja.CallBubbles.icMissedVideo.image + return UIImage.nynja.CallBubbles.icMissedVideoBubble.image case .UNANSWERED: - return UIImage.nynja.CallBubbles.icNoAnswerVideo.image + return UIImage.nynja.CallBubbles.icNoAnswerVideoBubble.image } } } diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video_bubble.imageset/Contents.json similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video.imageset/Contents.json rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video_bubble.imageset/Contents.json diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video.imageset/Icons_Group_Voice_Call_ic_video_call_canceled.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video_bubble.imageset/Icons_Group_Voice_Call_ic_video_call_canceled.pdf similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video.imageset/Icons_Group_Voice_Call_ic_video_call_canceled.pdf rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_video_bubble.imageset/Icons_Group_Voice_Call_ic_video_call_canceled.pdf diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice_bubble.imageset/Contents.json similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice.imageset/Contents.json rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice_bubble.imageset/Contents.json diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_canceled.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice_bubble.imageset/Icons_Group_Voice_Call_ic_voice_call_canceled.pdf similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_canceled.pdf rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_canceled_voice_bubble.imageset/Icons_Group_Voice_Call_ic_voice_call_canceled.pdf diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video_bubble.imageset/Contents.json similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video.imageset/Contents.json rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video_bubble.imageset/Contents.json diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video.imageset/Icons_Group_Voice_Call_ic_voice_call_incoming_darkIcons_Group_Voice_Call_ic_video_call_incoming_dark.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video_bubble.imageset/Icons_Group_Voice_Call_ic_voice_call_incoming_darkIcons_Group_Voice_Call_ic_video_call_incoming_dark.pdf similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video.imageset/Icons_Group_Voice_Call_ic_voice_call_incoming_darkIcons_Group_Voice_Call_ic_video_call_incoming_dark.pdf rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_video_bubble.imageset/Icons_Group_Voice_Call_ic_voice_call_incoming_darkIcons_Group_Voice_Call_ic_video_call_incoming_dark.pdf diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_voice_bubble.imageset/Contents.json similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_voice.imageset/Contents.json rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_voice_bubble.imageset/Contents.json diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_voice.imageset/Icon.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_voice_bubble.imageset/Icon.pdf similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_voice.imageset/Icon.pdf rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_incoming_voice_bubble.imageset/Icon.pdf diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_video_bubble.imageset/Contents.json similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_video.imageset/Contents.json rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_video_bubble.imageset/Contents.json diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_video.imageset/Icons_Group_Voice_Call_ic_video_call_missed_dark.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_video_bubble.imageset/Icons_Group_Voice_Call_ic_video_call_missed_dark.pdf similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_video.imageset/Icons_Group_Voice_Call_ic_video_call_missed_dark.pdf rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_video_bubble.imageset/Icons_Group_Voice_Call_ic_video_call_missed_dark.pdf diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice_bubble.imageset/Contents.json similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice.imageset/Contents.json rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice_bubble.imageset/Contents.json diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_missed_dark.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice_bubble.imageset/Icons_Group_Voice_Call_ic_voice_call_missed_dark.pdf similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_missed_dark.pdf rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_missed_voice_bubble.imageset/Icons_Group_Voice_Call_ic_voice_call_missed_dark.pdf diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video_bubble.imageset/Contents.json similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video.imageset/Contents.json rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video_bubble.imageset/Contents.json diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video.imageset/Icons_Group_Voice_Call_ic_video_call_no_answer_dark.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video_bubble.imageset/Icons_Group_Voice_Call_ic_video_call_no_answer_dark.pdf similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video.imageset/Icons_Group_Voice_Call_ic_video_call_no_answer_dark.pdf rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_video_bubble.imageset/Icons_Group_Voice_Call_ic_video_call_no_answer_dark.pdf diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_voice_bubble.imageset/Contents.json similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_voice.imageset/Contents.json rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_voice_bubble.imageset/Contents.json diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_no_answer_dark.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_voice_bubble.imageset/Icons_Group_Voice_Call_ic_voice_call_no_answer_dark.pdf similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_no_answer_dark.pdf rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_no_answer_voice_bubble.imageset/Icons_Group_Voice_Call_ic_voice_call_no_answer_dark.pdf diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video_bubble.imageset/Contents.json similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video.imageset/Contents.json rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video_bubble.imageset/Contents.json diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video.imageset/Icons_Group_Voice_Call_ic_video_call_outgoing_dark.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video_bubble.imageset/Icons_Group_Voice_Call_ic_video_call_outgoing_dark.pdf similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video.imageset/Icons_Group_Voice_Call_ic_video_call_outgoing_dark.pdf rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_video_bubble.imageset/Icons_Group_Voice_Call_ic_video_call_outgoing_dark.pdf diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_voice.imageset/Contents.json b/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_voice_bubble.imageset/Contents.json similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_voice.imageset/Contents.json rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_voice_bubble.imageset/Contents.json diff --git a/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_outgoing_dark.pdf b/Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_voice_bubble.imageset/Icons_Group_Voice_Call_ic_voice_call_outgoing_dark.pdf similarity index 100% rename from Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_voice.imageset/Icons_Group_Voice_Call_ic_voice_call_outgoing_dark.pdf rename to Nynja/Resources/Assets.xcassets/callBubbles/ic_outgoing_voice_bubble.imageset/Icons_Group_Voice_Call_ic_voice_call_outgoing_dark.pdf -- GitLab From f4d2a2faaf8c15bd104e2168fff1e0a1624a6103 Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Thu, 29 Nov 2018 23:53:55 +0200 Subject: [PATCH 33/59] Fixed a build after the merge --- Nynja/Modules/Message/Presenter/MessagePresenter.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nynja/Modules/Message/Presenter/MessagePresenter.swift b/Nynja/Modules/Message/Presenter/MessagePresenter.swift index bf3cb25ca..c44eb65ea 100644 --- a/Nynja/Modules/Message/Presenter/MessagePresenter.swift +++ b/Nynja/Modules/Message/Presenter/MessagePresenter.swift @@ -826,7 +826,7 @@ class MessagePresenter: BasePresenter, MessagePresenterProtocol, MessageInteract break } model.transferNotes = files.data?.first?.value - case .audioCall, .videoCall: + case .audioCall?, .videoCall?: guard let data = attach.data else {break} for feature in data { if let k = feature.key { -- GitLab From 6634a961b6f4bb3c2cb06512e88172bc678d7788 Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Fri, 30 Nov 2018 11:25:47 +0200 Subject: [PATCH 34/59] Fixed names in call history --- .../CallHistory/View/TableView/CallHistoryTableViewCell.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift index b08e68d34..221d70dab 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryTableViewCell.swift @@ -160,6 +160,7 @@ class CallHistoryTableViewCell: UITableViewCell { if m.kind == .DIRECT { if let ctc = ContactDAO.findContactBy(phoneId: m.address) { + nameLabel.text = "\(ctc.names ?? "") \(ctc.surnames ?? "")" self.avatarImageView.setImage(url: ctc.photoURL, placeHolder: UIImage.nynja.Contacts.avaPlaceholder.image) } else { self.avatarImageView.image = UIImage.nynja.Contacts.avaPlaceholder.image -- GitLab From 07cc7f6f9f588b0b76694d9386f316d9a2aaa9c0 Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Fri, 30 Nov 2018 11:49:31 +0200 Subject: [PATCH 35/59] Update version to 0.5.4.BubbleHistory --- Nynja-Share/Resources/Info.plist | 2 +- Nynja.xcodeproj/project.pbxproj | 2 +- Nynja/Resources/Info.plist | 2 +- Podfile.lock | 40 ++++++++++++++++---------------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Nynja-Share/Resources/Info.plist b/Nynja-Share/Resources/Info.plist index 1a0f04389..b297bdd3e 100644 --- a/Nynja-Share/Resources/Info.plist +++ b/Nynja-Share/Resources/Info.plist @@ -21,7 +21,7 @@ CFBundleShortVersionString 1.0 CFBundleVersion - 0.5.4.SwiftAndHome + 0.5.4.BubbleHistory Config $(Config) ModelsVersion diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index c0b4c235f..4c31cc61b 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -12944,7 +12944,7 @@ 4BBAEBC221ADA9E00089B703 /* CreateGroupFlow */, F105C691209F71BE0091786A /* CameraFlow */, F11786F420ACF017007A9A1B /* CameraSettingsFlow */, - 4BFED75C21A6CE38003CF1B3 /* ExtendedImage.swift */, + 4BFED75C21A6CE38003CF1B3 /* ExtendedImage.swift */, F10B0E0E20B43F8C00528E7A /* GalleryFlow */, F18AEAFB20C15782004FE01C /* SelectAvatarFlow */, ); diff --git a/Nynja/Resources/Info.plist b/Nynja/Resources/Info.plist index 8bfaffe76..93a372b8c 100644 --- a/Nynja/Resources/Info.plist +++ b/Nynja/Resources/Info.plist @@ -23,7 +23,7 @@ CFBundleShortVersionString 1.0 CFBundleVersion - 0.5.4.SwiftAndHome + 0.5.4.BubbleHistory ConfServerAddress $(ConfServerAddress) ConfServerPort diff --git a/Podfile.lock b/Podfile.lock index 75c485db5..694288473 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -16,25 +16,25 @@ PODS: - Fabric (~> 1.6.3) - CryptoSwift (0.13.0) - Fabric (1.6.13) - - Firebase/Auth (5.8.1): + - Firebase/Auth (5.13.0): - Firebase/CoreOnly - - FirebaseAuth (= 5.0.4) - - Firebase/CoreOnly (5.8.1): - - FirebaseCore (= 5.1.3) - - Firebase/Storage (5.8.1): + - FirebaseAuth (= 5.0.5) + - Firebase/CoreOnly (5.13.0): + - FirebaseCore (= 5.1.8) + - Firebase/Storage (5.13.0): - Firebase/CoreOnly - - FirebaseStorage (= 3.0.2) - - FirebaseAuth (5.0.4): + - FirebaseStorage (= 3.0.3) + - FirebaseAuth (5.0.5): - FirebaseAuthInterop (~> 1.0) - - FirebaseCore (~> 5.0) + - FirebaseCore (~> 5.1) - GoogleUtilities/Environment (~> 5.2) - GTMSessionFetcher/Core (~> 1.1) - FirebaseAuthInterop (1.0.0) - - FirebaseCore (5.1.3): + - FirebaseCore (5.1.8): - GoogleUtilities/Logger (~> 5.2) - - FirebaseStorage (3.0.2): + - FirebaseStorage (3.0.3): - FirebaseAuthInterop (~> 1.0) - - FirebaseCore (~> 5.0) + - FirebaseCore (~> 5.1) - GTMSessionFetcher/Core (~> 1.1) - GoogleMaps (2.7.0): - GoogleMaps/Maps (= 2.7.0) @@ -43,12 +43,12 @@ PODS: - GoogleMaps/Base - GooglePlaces (2.7.0): - GoogleMaps/Base (= 2.7.0) - - GoogleUtilities/Environment (5.3.0) - - GoogleUtilities/Logger (5.3.0): + - GoogleUtilities/Environment (5.3.6) + - GoogleUtilities/Logger (5.3.6): - GoogleUtilities/Environment - GRDBCipher (2.10.0): - SQLCipher (~> 3.4.1) - - GTMSessionFetcher/Core (1.1.15) + - GTMSessionFetcher/Core (1.2.1) - Intercom (5.1.6) - JTAppleCalendar (7.1.6) - libPhoneNumber-iOS (0.9.13) @@ -151,16 +151,16 @@ SPEC CHECKSUMS: Crashlytics: 95d05f4e4c19a771250c4bd9ce344d996de32bbf CryptoSwift: 16e78bebf567bad1c87b2d58f6547f25b74c31aa Fabric: 2fb5676bc811af011a04513451f463dac6803206 - Firebase: a870ed114d769b424021a0c8ddb0c86c3250a0c5 - FirebaseAuth: 504b198ceb3472dca5c65bb95544ea44cfc9439e + Firebase: 6df9a6114bc9f106a98fe83d5438d4d9833c2019 + FirebaseAuth: 9299ab178271bec7426967b05b2718bb6fc31f17 FirebaseAuthInterop: 0ffa57668be100582bb7643d4fcb7615496c41fc - FirebaseCore: 27bd80e5bfaaf9552a1f5cacb4c7e8bb925bab22 - FirebaseStorage: fd82e5e5c474897e19972b34b22ac0f589dce04e + FirebaseCore: fba2bfaa691c49028309b92e4dd37cc4b5512fbe + FirebaseStorage: 3d22c041370593e639fba013d1eb698a8dae2881 GoogleMaps: f79af95cb24d869457b1f961c93d3ce8b2f3b848 GooglePlaces: 3d06e6c99654545b4738ce49648745779c25f2ef - GoogleUtilities: 760ccb53b7c7f40f9c02d8c241f76f841a7a6162 + GoogleUtilities: 95996bea7c7d9b8fb811b7507669a4a8762f80c7 GRDBCipher: eef21d242c727a21e0f87ad44f8ea2df03edd252 - GTMSessionFetcher: 5fa5b80fd20e439ef5f545fb2cb3ca6c6714caa2 + GTMSessionFetcher: 32aeca0aa144acea523e1c8e053089dec2cb98ca Intercom: 083a05bf222811b0b5e0a0b24c863544123397f0 JTAppleCalendar: abb30678f42a4ef8a340a932b1dcb8c85a33dac2 libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa -- GitLab From b469631bc1e59caa0b0230277e74e188020d38ec Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Fri, 30 Nov 2018 13:40:56 +0200 Subject: [PATCH 36/59] change wording --- Nynja/Generated/LocalizableConstants.swift | 4 ++-- .../CallHistory/View/TableView/CallHistoryCellModel.swift | 2 +- .../CollectionView/Cells/Views/Message/MessageCallView.swift | 2 +- Nynja/Resources/en.lproj/Localizable.strings | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Nynja/Generated/LocalizableConstants.swift b/Nynja/Generated/LocalizableConstants.swift index 0ac46eaaa..a6c6d8c4d 100644 --- a/Nynja/Generated/LocalizableConstants.swift +++ b/Nynja/Generated/LocalizableConstants.swift @@ -154,8 +154,8 @@ internal extension String { static var callHistoryLogStatusDeclined: String { return localizable.tr("Localizable", "call_history_log_status_declined") } /// Missed Call static var callHistoryLogStatusMissed: String { return localizable.tr("Localizable", "call_history_log_status_missed") } - /// Unanswered Call - static var callHistoryLogStatusUnanswered: String { return localizable.tr("Localizable", "call_history_log_status_unanswered") } + /// No Аnswer + static var callHistoryLogStatusNoanswer: String { return localizable.tr("Localizable", "call_history_log_status_noanswer") } /// started a call static var callHistoryParticipantStartedCall: String { return localizable.tr("Localizable", "call_history_participant_started_call") } /// call history diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift index 9e799b4c5..232df861b 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift @@ -114,7 +114,7 @@ class CallHistoryCellModel: NSObject { case .MISSED: return String.localizable.callHistoryLogStatusMissed case .UNANSWERED: - return String.localizable.callHistoryLogStatusUnanswered + return String.localizable.callHistoryLogStatusNoanswer } } diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift index df1940883..451703acd 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift @@ -275,7 +275,7 @@ final class MessageCallView: MessageContentView { case .MISSED: return String.localizable.callHistoryLogStatusMissed case .UNANSWERED: - return String.localizable.callHistoryLogStatusUnanswered + return String.localizable.callHistoryLogStatusNoanswer } } diff --git a/Nynja/Resources/en.lproj/Localizable.strings b/Nynja/Resources/en.lproj/Localizable.strings index 4fe145f8b..95adea81e 100644 --- a/Nynja/Resources/en.lproj/Localizable.strings +++ b/Nynja/Resources/en.lproj/Localizable.strings @@ -1011,7 +1011,7 @@ "call_history_log_status_missed" = "Missed Call"; "call_history_log_status_declined" = "Declined Call"; "call_history_log_status_canceled" = "Canceled Call"; -"call_history_log_status_unanswered" = "Unanswered Call"; +"call_history_log_status_noanswer" = "No Аnswer"; "call_history_log_dir_inbound" = "Incoming Call"; "call_history_log_dir_outbound" = "Outgoing Call"; "call_history_clear_question_alert" = "Are you sure you want to clear all call history?"; -- GitLab From f44a511c683951d2578c1dea911dadd164837dad Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Mon, 3 Dec 2018 10:22:55 +0200 Subject: [PATCH 37/59] Fixed clear history disabled wheel button --- Nynja/CallHistoryItemsFactory.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nynja/CallHistoryItemsFactory.swift b/Nynja/CallHistoryItemsFactory.swift index 57fcefcab..3da8f0bc8 100644 --- a/Nynja/CallHistoryItemsFactory.swift +++ b/Nynja/CallHistoryItemsFactory.swift @@ -14,7 +14,7 @@ class CallHistoryItemsFactory: WCBaseItemsFactory { } var clearHistory: ImageActionItemModel { - let item = ImageActionItemModel(nameImage: "ic_delete_context_menu", navItem: .clearHistory, action: { [weak navigateDelegate] (item, indexPath) in + let item = ImageActionItemModel(nameImage: "ic_delete_context_menu", navItem: .clearHistory, isSelectable: false, action: { [weak navigateDelegate] (item, indexPath) in navigateDelegate?.clearCallHistory(indexPath: indexPath) }) return item -- GitLab From ed7252eabd1df7af177cf2d024369e1f0525d83c Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Mon, 3 Dec 2018 13:42:29 +0200 Subject: [PATCH 38/59] Action is now selected from wheel for history screen --- Nynja.xcodeproj/project.pbxproj | 2 +- Nynja/CallHistoryItemsFactory.swift | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 4c31cc61b..7da526649 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -6724,6 +6724,7 @@ 4B1D7DFB2029C37900703228 /* FavoritesItemsFactory.swift */, 9B9D439421A327550000A189 /* CallsItemsFactory.swift */, 4B1D7E062029D00000703228 /* OtherUserProfileItemsFactory.swift */, + 9B804ABF219D6AF9000606EC /* CallHistoryItemsFactory.swift */, B7F5051C2061252100C28FA1 /* DataAndStorageItemsFactory.swift */, ); name = Factory; @@ -6760,7 +6761,6 @@ 4B1D7E0A2029D8CD00703228 /* GroupOptionsItemsFactory.swift */, 4B1D7E042029CF2900703228 /* ShareContactsItemsFactory.swift */, A47785A320D286680053E0D2 /* ChannelChatItemsFactory.swift */, - 9B804ABF219D6AF9000606EC /* CallHistoryItemsFactory.swift */, ); name = Chat; sourceTree = ""; diff --git a/Nynja/CallHistoryItemsFactory.swift b/Nynja/CallHistoryItemsFactory.swift index 3da8f0bc8..af01d5d7d 100644 --- a/Nynja/CallHistoryItemsFactory.swift +++ b/Nynja/CallHistoryItemsFactory.swift @@ -13,6 +13,12 @@ class CallHistoryItemsFactory: WCBaseItemsFactory { return [clearHistory] } + override var actions: ImageActionItemModel { + let item = super.actions + item.state = .selected + return item + } + var clearHistory: ImageActionItemModel { let item = ImageActionItemModel(nameImage: "ic_delete_context_menu", navItem: .clearHistory, isSelectable: false, action: { [weak navigateDelegate] (item, indexPath) in navigateDelegate?.clearCallHistory(indexPath: indexPath) -- GitLab From 593f98a25f8e1a8bca26105ca5361b653f292eb1 Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Mon, 3 Dec 2018 15:53:07 +0200 Subject: [PATCH 39/59] ended by empty equal gto caller --- Nynja/Modules/Message/Presenter/MessagePresenter.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nynja/Modules/Message/Presenter/MessagePresenter.swift b/Nynja/Modules/Message/Presenter/MessagePresenter.swift index c44eb65ea..2a8a104ff 100644 --- a/Nynja/Modules/Message/Presenter/MessagePresenter.swift +++ b/Nynja/Modules/Message/Presenter/MessagePresenter.swift @@ -919,7 +919,7 @@ class MessagePresenter: BasePresenter, MessagePresenterProtocol, MessageInteract case "callee": status = NYNCallLogStatus.DECLINED break - case "caller": + case "caller", "": status = isowner ? NYNCallLogStatus.CANCELED : NYNCallLogStatus.MISSED break default: -- GitLab From 70dca368061da0daad07ffde153d4c1c4ba49b1b Mon Sep 17 00:00:00 2001 From: Bozhko Terziev Date: Mon, 3 Dec 2018 16:08:20 +0200 Subject: [PATCH 40/59] Fixed wrong declined icon --- .../CallHistory/View/TableView/CallHistoryCellModel.swift | 4 ++-- .../CollectionView/Cells/Views/Message/MessageCallView.swift | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift index 232df861b..5b916d307 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift @@ -126,7 +126,7 @@ class func imageFrom(status:NYNCallLogStatus, media:NYNCallLogMedia, direction:N case .CANCELED: return UIImage.nynja.CallHistory.icCanceledVoice.image case .DECLINED: - return UIImage.nynja.CallHistory.icMissedVoice.image + return UIImage.nynja.CallHistory.icCanceledVoice.image case .MISSED: return UIImage.nynja.CallHistory.icMissedVoice.image case .UNANSWERED: @@ -139,7 +139,7 @@ class func imageFrom(status:NYNCallLogStatus, media:NYNCallLogMedia, direction:N case .CANCELED: return UIImage.nynja.CallHistory.icCanceledVideo.image case .DECLINED: - return UIImage.nynja.CallHistory.icMissedVideo.image + return UIImage.nynja.CallHistory.icCanceledVideo.image case .MISSED: return UIImage.nynja.CallHistory.icMissedVideo.image case .UNANSWERED: diff --git a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift index 451703acd..a7aba999a 100644 --- a/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift +++ b/Nynja/Modules/Message/View/Views/CollectionView/Cells/Views/Message/MessageCallView.swift @@ -299,7 +299,7 @@ final class MessageCallView: MessageContentView { case .CANCELED: return UIImage.nynja.CallBubbles.icCanceledVoiceBubble.image case .DECLINED: - return UIImage.nynja.CallBubbles.icMissedVoiceBubble.image + return UIImage.nynja.CallBubbles.icCanceledVoiceBubble.image case .MISSED: return UIImage.nynja.CallBubbles.icMissedVoiceBubble.image case .UNANSWERED: @@ -312,7 +312,7 @@ final class MessageCallView: MessageContentView { case .CANCELED: return UIImage.nynja.CallBubbles.icCanceledVideoBubble.image case .DECLINED: - return UIImage.nynja.CallBubbles.icMissedVideoBubble.image + return UIImage.nynja.CallBubbles.icCanceledVideoBubble.image case .MISSED: return UIImage.nynja.CallBubbles.icMissedVideoBubble.image case .UNANSWERED: -- GitLab From dd72b4edd3d1ccb56526290a3e589ec6ee6ea7ae Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Wed, 5 Dec 2018 12:07:07 +0200 Subject: [PATCH 41/59] Update type of `seenby`, `repliedby`, `mentioned` fields in `Message` model, and `mentions` in `Room` one. --- Nynja/ChatService/ChatService.swift | 4 ++-- .../Models/Message/Message+DB.swift | 7 +----- .../MessageFactory/MessageFactory.swift | 8 +++---- .../MessageFactoryProtocol.swift | 2 +- .../Library/UI/Extensions/String+Split.swift | 6 ++--- Nynja/MessageBackgroundTaskHandler.swift | 8 +------ .../Interactor/MessageInteractor.swift | 23 ++++--------------- ...essagePresenter+MentionUnreadCounter.swift | 5 +--- Nynja/RoomDAO.swift | 2 +- Nynja/ServerModel/Model/Message.swift | 6 ++--- Nynja/ServerModel/Model/Room.swift | 2 +- Nynja/ServerModel/Source/Decoder.swift | 8 +++---- Nynja/ServerModel/Spec/Message_Spec.swift | 4 +--- Nynja/ServerModel/Spec/Room_Spec.swift | 4 +--- 14 files changed, 28 insertions(+), 61 deletions(-) diff --git a/Nynja/ChatService/ChatService.swift b/Nynja/ChatService/ChatService.swift index ddd931edd..8ab32037d 100644 --- a/Nynja/ChatService/ChatService.swift +++ b/Nynja/ChatService/ChatService.swift @@ -108,7 +108,7 @@ final class ChatService { room.hasMentions || message.hasMentions, case let .updated(mentions) = RoomDAO.updatedMentions(with: message, roomId: roomId) { - room.mentions = mentions as [AnyObject]? + room.mentions = mentions } do { @@ -155,7 +155,7 @@ final class ChatService { if let phoneId = storageService.phoneId, RoomDAO.isCurrentUserMentioned(in: message, phoneId: phoneId) { mentions.insert(link) } - room.mentions = mentions.sorted() as [AnyObject]? + room.mentions = mentions.sorted() RoomDAO.updateColumns([.mentions], room: room) } diff --git a/Nynja/Extensions/Models/Message/Message+DB.swift b/Nynja/Extensions/Models/Message/Message+DB.swift index 9ede343ec..5a6e4fa4a 100644 --- a/Nynja/Extensions/Models/Message/Message+DB.swift +++ b/Nynja/Extensions/Models/Message/Message+DB.swift @@ -24,12 +24,7 @@ extension Message { self.types = Set(message.type?.components(separatedBy: Constants.commaSeparator) ?? []) self.linkedId = message.link - if message.feedType == FeedType.p2p.rawValue { - self.seenby = message.seenBy?.splitByComma { $0 as AnyObject } - } else { - self.seenby = message.seenBy?.splitIntegerIdentifiers() - } - + self.seenby = message.seenBy?.splitIntegerIdentifiers() 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 2b7161bd2..3960d1452 100644 --- a/Nynja/Library/MessageFactory/MessageFactory.swift +++ b/Nynja/Library/MessageFactory/MessageFactory.swift @@ -73,7 +73,7 @@ final class MessageFactory: MessageFactoryProtocol, InitializeInjectable { message.messageStatus = .edit message.markAsEdited() - message.mentioned = newInputText.mentions.map { $0.memberId }.uniqueWithPreservedOrder() as [AnyObject]? + message.mentioned = newInputText.mentions.map { $0.memberId }.uniqueWithPreservedOrder() return message } @@ -86,7 +86,7 @@ final class MessageFactory: MessageFactoryProtocol, InitializeInjectable { message.messageStatus = .edit message.markAsEdited() - message.mentioned = action.mentioned?.splitByComma(Int64.self)?.uniqueWithPreservedOrder() as [AnyObject]? + message.mentioned = action.mentioned?.splitIntegerIdentifiers().uniqueWithPreservedOrder() return message } @@ -247,7 +247,7 @@ final class MessageFactory: MessageFactoryProtocol, InitializeInjectable { return makeMessage(descs: descs, phoneId: phoneId, contact: nil, room: room) } - func makeMessageForDelete(message: Message, seenBy: [AnyObject]) -> Message { + func makeMessageForDelete(message: Message, seenBy: [Int64]) -> Message { let message = Message(message: message) message.from = storageService.phoneId message.seenby = seenBy @@ -264,7 +264,7 @@ private extension MessageFactory { message.created = Date.currentTimestamp message.files = descs message.messageStatus = nil - message.mentioned = mentioned as [AnyObject]? + message.mentioned = mentioned return message } diff --git a/Nynja/Library/MessageFactory/MessageFactoryProtocol.swift b/Nynja/Library/MessageFactory/MessageFactoryProtocol.swift index 3e19e0772..f605a7f4e 100644 --- a/Nynja/Library/MessageFactory/MessageFactoryProtocol.swift +++ b/Nynja/Library/MessageFactory/MessageFactoryProtocol.swift @@ -40,7 +40,7 @@ protocol MessageFactoryProtocol: class { func makeCallMessage(members: [String], room: Room?) -> Message - func makeMessageForDelete(message: Message, seenBy: [AnyObject]) -> Message + func makeMessageForDelete(message: Message, seenBy: [Int64]) -> Message } extension MessageFactoryProtocol { diff --git a/Nynja/Library/UI/Extensions/String+Split.swift b/Nynja/Library/UI/Extensions/String+Split.swift index 62ee4b13b..40baba1aa 100644 --- a/Nynja/Library/UI/Extensions/String+Split.swift +++ b/Nynja/Library/UI/Extensions/String+Split.swift @@ -13,7 +13,7 @@ protocol StringInitializable { extension Int64: StringInitializable { } extension String { - func splitByComma(_ type: T.Type) -> [T]? { + func splitByComma(_ type: T.Type) -> [T] { return components(separatedBy: ",").compactMap(T.init) } @@ -25,8 +25,8 @@ extension String { return components(separatedBy: ",") } - func splitIntegerIdentifiers() -> [AnyObject]? { - return splitByComma(Int64.self) as [AnyObject]? + func splitIntegerIdentifiers() -> [Int64] { + return splitByComma(Int64.self) as [Int64] } func split(by length: Int) -> [String] { diff --git a/Nynja/MessageBackgroundTaskHandler.swift b/Nynja/MessageBackgroundTaskHandler.swift index eddc6be66..ee6560132 100644 --- a/Nynja/MessageBackgroundTaskHandler.swift +++ b/Nynja/MessageBackgroundTaskHandler.swift @@ -113,13 +113,7 @@ final class MessageBackgroundTaskHandler: BackgroundTaskHandler { return nil } - let messageForDelete: Message - if action.phoneId.isEmpty { - messageForDelete = messageFactory.makeMessageForDelete(message: message, seenBy: [action.seenBy] as [AnyObject]) - } else { - let seenBy = action.seenBy == -1 ? -1 as AnyObject : action.phoneId as AnyObject - messageForDelete = messageFactory.makeMessageForDelete(message: message, seenBy: [seenBy] ) - } + let messageForDelete = messageFactory.makeMessageForDelete(message: message, seenBy: [action.seenBy]) return messageForDelete } diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor.swift b/Nynja/Modules/Message/Interactor/MessageInteractor.swift index 140aa53c7..ed2830b58 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor.swift @@ -811,31 +811,16 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H func deleteMessage(localId: MessageLocalId, forBoth: Bool) { guard let message = messageBy(localId: localId), let messageId = message.id, - let phoneId = myContact?.phoneId else { + let rosterId = myContact?.rosterId else { return } - let messageAction: DBMessageAction - var seenBy: AnyObject = -1 as AnyObject - switch chat { - case is Room: - if !forBoth, let memberId = room?.allMembers?.first(where: { $0.phone_id == phoneId })?.id { - seenBy = memberId as AnyObject - } - messageAction = DBMessageAction(messageId: messageId, - seenBy: (seenBy as? Int64) ?? -1, + let seenBy: Int64 = forBoth ? 0 : rosterId + let messageAction = DBMessageAction(messageId: messageId, + seenBy: seenBy, phoneId: "", action: .delete) - default: - if !forBoth { - seenBy = phoneId as AnyObject - } - messageAction = DBMessageAction(messageId: messageId, - seenBy: forBoth ? -1 : 0, - phoneId: phoneId, - action: .delete) - } try? storageService.perform(action: .save, with: messageAction) diff --git a/Nynja/Modules/Message/Presenter/MessagePresenter+MentionUnreadCounter.swift b/Nynja/Modules/Message/Presenter/MessagePresenter+MentionUnreadCounter.swift index 225f75791..6506a3ce0 100644 --- a/Nynja/Modules/Message/Presenter/MessagePresenter+MentionUnreadCounter.swift +++ b/Nynja/Modules/Message/Presenter/MessagePresenter+MentionUnreadCounter.swift @@ -144,10 +144,7 @@ extension MessagePresenter { } var unique: Set = [] for mention in mentions { - guard let id = MessageServerId(mention) else { - continue - } - unique.insert(id) + unique.insert(mention) } for mention in unreadMentionIds { unique.insert(mention) diff --git a/Nynja/RoomDAO.swift b/Nynja/RoomDAO.swift index a8fb9a393..f7c004835 100644 --- a/Nynja/RoomDAO.swift +++ b/Nynja/RoomDAO.swift @@ -143,7 +143,7 @@ class RoomDAO: RoomDAOProtocol { return } - let unreadMentions = mentions.compactMap { $0 > reader ? $0 as AnyObject : nil } + let unreadMentions = mentions.filter { $0 > reader } let room = Room() room.id = roomId diff --git a/Nynja/ServerModel/Model/Message.swift b/Nynja/ServerModel/Model/Message.swift index ff382502c..56f3433dd 100644 --- a/Nynja/ServerModel/Model/Message.swift +++ b/Nynja/ServerModel/Model/Message.swift @@ -12,9 +12,9 @@ class Message { var files: [Desc]? var type: [AnyObject]? var link: AnyObject? - var seenby: [AnyObject]? - var repliedby: [AnyObject]? - var mentioned: [AnyObject]? + var seenby: [Int64]? + var repliedby: [Int64]? + var mentioned: [Int64]? var status: AnyObject? diff --git a/Nynja/ServerModel/Model/Room.swift b/Nynja/ServerModel/Model/Room.swift index 99a85499b..dbc28d4ce 100755 --- a/Nynja/ServerModel/Model/Room.swift +++ b/Nynja/ServerModel/Model/Room.swift @@ -12,7 +12,7 @@ class Room { var tos: String? var tos_update: Int64? var unread: Int64? - var mentions: [AnyObject]? + var mentions: [Int64]? var readers: [AnyObject]? var last_msg: Message? var update: Int64? diff --git a/Nynja/ServerModel/Source/Decoder.swift b/Nynja/ServerModel/Source/Decoder.swift index 0af94781c..c2107c167 100644 --- a/Nynja/ServerModel/Source/Decoder.swift +++ b/Nynja/ServerModel/Source/Decoder.swift @@ -239,9 +239,9 @@ func parseObject(name: String, body:[Model], tuple: BertTuple) -> AnyObject? 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? 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] + a_Message.seenby = body[12].parse(bert: tuple.elements[13]) as? [Int64] + a_Message.repliedby = body[13].parse(bert: tuple.elements[14]) as? [Int64] + a_Message.mentioned = body[14].parse(bert: tuple.elements[15]) as? [Int64] a_Message.status = body[15].parse(bert: tuple.elements[16]) as? AnyObject return a_Message case "Link": @@ -268,7 +268,7 @@ func parseObject(name: String, body:[Model], tuple: BertTuple) -> AnyObject? a_Room.tos = body[9].parse(bert: tuple.elements[10]) as? String a_Room.tos_update = body[10].parse(bert: tuple.elements[11]) as? Int64 a_Room.unread = body[11].parse(bert: tuple.elements[12]) as? Int64 - a_Room.mentions = body[12].parse(bert: tuple.elements[13]) as? [AnyObject] + a_Room.mentions = body[12].parse(bert: tuple.elements[13]) as? [Int64] a_Room.readers = body[13].parse(bert: tuple.elements[14]) as? [AnyObject] a_Room.last_msg = body[14].parse(bert: tuple.elements[15]) as? Message a_Room.update = body[15].parse(bert: tuple.elements[16]) as? Int64 diff --git a/Nynja/ServerModel/Spec/Message_Spec.swift b/Nynja/ServerModel/Spec/Message_Spec.swift index ba04a9473..c4690991e 100644 --- a/Nynja/ServerModel/Spec/Message_Spec.swift +++ b/Nynja/ServerModel/Spec/Message_Spec.swift @@ -51,9 +51,7 @@ private func get_Message(recursive: Bool) -> Model { Model(value:Atom(constant:"cursor"))]))))])), Model(value:Chain(types: linkTypes)), - 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:List(constant:nil, model:Model(value:Number()))), Model(value:Chain(types:[ diff --git a/Nynja/ServerModel/Spec/Room_Spec.swift b/Nynja/ServerModel/Spec/Room_Spec.swift index aaa00bf25..49e799450 100755 --- a/Nynja/ServerModel/Spec/Room_Spec.swift +++ b/Nynja/ServerModel/Spec/Room_Spec.swift @@ -32,9 +32,7 @@ func get_Room() -> Model { 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: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:"")), -- GitLab From c31b5500646c541e6aa5604c36b82641d1a6a0ad Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Wed, 5 Dec 2018 12:12:52 +0200 Subject: [PATCH 42/59] skip save call bubble if seenBy is not for me --- .../HandleServices/MessageHandler.swift | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/Nynja/Services/HandleServices/MessageHandler.swift b/Nynja/Services/HandleServices/MessageHandler.swift index 5e69c284d..0be625370 100644 --- a/Nynja/Services/HandleServices/MessageHandler.swift +++ b/Nynja/Services/HandleServices/MessageHandler.swift @@ -137,6 +137,7 @@ final class MessageHandler: BaseHandler { private static func saveMessage(_ message: Message, data: BertTuple) { guard !shouldSkipMessage(message) else { + LogService.log(topic: .db) { "\(#function), line: \(#line) - id: \(message.id ?? 0)" } return } @@ -180,15 +181,19 @@ final class MessageHandler: BaseHandler { } private static func shouldSkipMessage(_ message: Message) -> Bool { - //TODO: fix it -// if let desc = message.files?.first, -// desc.mime == SendMessageType.audioCall.rawValue, -// desc.data?.first?.key == FeatureKeys.File.Call.users.rawValue, -// let ids = desc.data?.first?.value?.splitByComma(), -// !ids.contains { $0 == storageService.phoneId } { -// -// return true -// } + if let desc = message.files?.first, + desc.mime == SendMessageType.audioCall.rawValue || desc.mime == SendMessageType.videoCall.rawValue, + let seenBy = message.seenby, + !seenBy.contains(where: { (anyObj) -> Bool in + guard let sid = anyObj as? String else { + return false + } + + return sid == storageService.phoneId + }) + { + return true + } return false } -- GitLab From 228e05cd3fe9d37e23da8b8866c3d1ee758e28ce Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Wed, 5 Dec 2018 12:14:14 +0200 Subject: [PATCH 43/59] Changed spotify server to SPA --- Nynja/Resources/SpotifyConfig.xcconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Nynja/Resources/SpotifyConfig.xcconfig b/Nynja/Resources/SpotifyConfig.xcconfig index c3018ac85..4965c8d4f 100644 --- a/Nynja/Resources/SpotifyConfig.xcconfig +++ b/Nynja/Resources/SpotifyConfig.xcconfig @@ -9,13 +9,13 @@ BundleIdentifier = com.nynja.loc.mobile.communicator ExtensionBundleIdentifier = com.nynja.loc.mobile.communicator.NynjaShare -ServerURL = csdk.ci.nynja.net -AppName = NYNJASpot -ServerPort = 1883 +ServerURL = im-fallback.dev-eu.nynja.net +AppName = NYNJASPA +ServerPort = 8443 Config = spotify AppGroup = group.com.nynja.mobile.communicator.loc ModelsVersion = 10 -isServerConnectionSecure = false +isServerConnectionSecure = true ConfServerAddress = 18.197.109.137 ConfServerPort = 80 ConfServerSecure = false -- GitLab From e197ba8b7ffa369b2586f60f2b419b8222d83877 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Wed, 5 Dec 2018 12:48:14 +0200 Subject: [PATCH 44/59] Update `MessageActionTable` and connected files. --- Nynja/DB/Models/DBMessageAction.swift | 31 ++++----------- Nynja/DB/Tables/MessageActionTable.swift | 12 ------ Nynja/MessageActionDAO.swift | 6 ++- .../Interactor/MessageInteractor.swift | 39 ++++++++++++------- 4 files changed, 35 insertions(+), 53 deletions(-) diff --git a/Nynja/DB/Models/DBMessageAction.swift b/Nynja/DB/Models/DBMessageAction.swift index 099a5176b..f7ce52ce5 100644 --- a/Nynja/DB/Models/DBMessageAction.swift +++ b/Nynja/DB/Models/DBMessageAction.swift @@ -16,13 +16,11 @@ final class DBMessageAction: Record, DBModel { var messageId: MessageServerId var seenBy: Int64 - var phoneId: String var action: Action - init(messageId: MessageServerId, seenBy: Int64, phoneId: String, action: Action) { + init(messageId: MessageServerId, seenBy: Int64, action: Action) { self.messageId = messageId self.seenBy = seenBy - self.phoneId = phoneId self.action = action super.init() @@ -35,19 +33,17 @@ final class DBMessageAction: Record, DBModel { } required init(row: Row) { - messageId = row[MessageActionTable.Column.messageId.title] - seenBy = row[MessageActionTable.Column.seenBy.title] - phoneId = row[MessageActionTable.Column.phoneId.title] - action = Action(rawValue: row[MessageActionTable.Column.action.title])! + messageId = row[Column.messageId] + seenBy = row[Column.seenBy] + action = Action(rawValue: row[Column.action])! super.init() } override func encode(to container: inout PersistenceContainer) { - container[MessageActionTable.Column.messageId.title] = messageId - container[MessageActionTable.Column.seenBy.title] = seenBy - container[MessageActionTable.Column.phoneId.title] = phoneId - container[MessageActionTable.Column.action.title] = action.rawValue + container[Column.messageId] = messageId + container[Column.seenBy] = seenBy + container[Column.action] = action.rawValue } @@ -61,17 +57,4 @@ final class DBMessageAction: Record, DBModel { func deleteAggregate(_ db: Database) throws -> Bool { return try self.delete(db) } - - - // MARK: - Fetching - - static func action(_ db: Database, messageId: Int64) throws -> DBMessageAction? { - let messageIdColumn = Column(MessageActionTable.Column.messageId.title) - - guard let message = try DBMessageAction.filter(messageIdColumn == messageId).fetchOne(db) else { - return nil - } - - return message - } } diff --git a/Nynja/DB/Tables/MessageActionTable.swift b/Nynja/DB/Tables/MessageActionTable.swift index ed0bd81cf..1d8af1950 100644 --- a/Nynja/DB/Tables/MessageActionTable.swift +++ b/Nynja/DB/Tables/MessageActionTable.swift @@ -18,19 +18,7 @@ final class MessageActionTable: Table { try db.create(self) { t in t.column(Column.messageId, .integer).primaryKey(onConflict: .replace, autoincrement: false) t.column(Column.seenBy, .integer) - t.column(Column.phoneId, .text) t.column(Column.action, .text) } } } - -// MARK: Column -extension MessageActionTable { - - enum Column: Int, Describable { - case messageId - case seenBy - case phoneId - case action - } -} diff --git a/Nynja/MessageActionDAO.swift b/Nynja/MessageActionDAO.swift index 32f2cb49a..baae7b46c 100644 --- a/Nynja/MessageActionDAO.swift +++ b/Nynja/MessageActionDAO.swift @@ -14,14 +14,16 @@ final class MessageActionDAO: MessageActionDAOProtocol { // MARK: -- Action static func fetchMessageAction(by messageServerId: MessageServerId) -> DBMessageAction? { return dbManager.fetch { db in - return try DBMessageAction.action(db, messageId: messageServerId) + return try DBMessageAction + .filter(Column.messageId == messageServerId) + .fetchOne(db) } } static func containsDeleteAction(for messageServerId: MessageServerId) -> Bool { return dbManager.rowExists( in: MessageActionTable.self, - where: "\(MessageActionTable.Column.messageId) = ? AND \(MessageActionTable.Column.action) = ?", + where: "\(Column.messageId) = ? AND \(Column.action) = ?", arguments: [messageServerId, DBMessageAction.Action.delete.rawValue] ) } diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor.swift b/Nynja/Modules/Message/Interactor/MessageInteractor.swift index ed2830b58..454a0234e 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor.swift @@ -817,24 +817,12 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H let seenBy: Int64 = forBoth ? 0 : rosterId - let messageAction = DBMessageAction(messageId: messageId, - seenBy: seenBy, - phoneId: "", - action: .delete) - - try? storageService.perform(action: .save, with: messageAction) - - let messageForDelete = messageFactory.makeMessageForDelete(message: message, seenBy: [seenBy]) - mqttService.sendMessage(message: messageForDelete) + saveDeleteAction(messageId: messageId, seenBy: seenBy) - let messageForSave = Message(message: messageForDelete) - messageForSave.messageStatus = message.messageStatus - messageForSave.localStatus = .deleted + performDeleting(message: message, seenBy: seenBy) message.localStatus = .deleted - message.seenby = messageForSave.seenby - - try? storageService.perform(action: .save, with: messageForSave) + message.seenby = [seenBy] if let feed = self.feed, let newLastMessage = MessageDAO.fetchLastMessage(feed: feed) { ChatService.updateLastMessage(newLastMessage, shouldChangeUnread: false) @@ -842,7 +830,28 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H handleMessageDelete(message) } + + private func saveDeleteAction(messageId: MessageServerId, seenBy: Int64) { + let messageAction = DBMessageAction(messageId: messageId, + seenBy: seenBy, + action: .delete) + try? storageService.perform(action: .save, with: messageAction) + } + private func performDeleting(message: Message, seenBy: Int64) { + let messageForDelete = messageFactory.makeMessageForDelete(message: message, seenBy: [seenBy]) + mqttService.sendMessage(message: messageForDelete) + + saveDeleted(message: messageForDelete) + } + + private func saveDeleted(message: Message) { + let messageForSave = Message(message: message) + messageForSave.messageStatus = message.messageStatus + messageForSave.localStatus = .deleted + try? storageService.perform(action: .save, with: messageForSave) + } + // MARK: - Reply func prepareToReply(localId: MessageLocalId) { -- GitLab From a10f9ea7ac6ca155c1a75f2d33e8088808439d8f Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Wed, 5 Dec 2018 13:58:11 +0200 Subject: [PATCH 45/59] Correct `Bert` encoding for `Room` and `Message` models. --- Nynja/MQTTModels/MessageExtension+BERT.swift | 14 ++------------ Nynja/MQTTModels/RoomExtension+BERT.swift | 2 +- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/Nynja/MQTTModels/MessageExtension+BERT.swift b/Nynja/MQTTModels/MessageExtension+BERT.swift index d93009058..c35670148 100644 --- a/Nynja/MQTTModels/MessageExtension+BERT.swift +++ b/Nynja/MQTTModels/MessageExtension+BERT.swift @@ -25,17 +25,7 @@ extension Message: BERTEncodable { let localID = Bert.getBin(msg_id) var _seenBy: BertObject = BertNil() - - if let se = seenby as? [String] { - var obj = [BertObject]() - for i in se { - if let item = Bert.getBin(i) as? BertBinary { - obj.append(item) - } - } - _seenBy = BertList(fromElements: obj) - } - if let se = seenby as? [Int64] { + if let se = seenby { var obj = [BertObject]() for i in se { if let item = Bert.getBin(i) as? BertNumber { @@ -88,7 +78,7 @@ extension Message: BERTEncodable { } let mentioned: BertObject - if let objects = (self.mentioned as? [Int64])?.compactMap({ Bert.getBin($0) as? BertNumber }), !objects.isEmpty { + if let objects = self.mentioned?.compactMap({ Bert.getBin($0) as? BertNumber }), !objects.isEmpty { mentioned = BertList(fromElements: objects) } else { mentioned = BertNil() diff --git a/Nynja/MQTTModels/RoomExtension+BERT.swift b/Nynja/MQTTModels/RoomExtension+BERT.swift index cb7131681..687839e3b 100644 --- a/Nynja/MQTTModels/RoomExtension+BERT.swift +++ b/Nynja/MQTTModels/RoomExtension+BERT.swift @@ -31,7 +31,7 @@ extension Room: BERTEncodable { _name = Bert.getBin(name) } - if let objects = (self.mentions as? [Int64])?.compactMap({ Bert.getBin($0) as? BertNumber }) { + if let objects = self.mentions?.compactMap({ Bert.getBin($0) as? BertNumber }) { _mentions = BertList(fromElements: objects) } -- GitLab From 157eaf4ef9b574a6da0791082fd9d7fe3bcd19ce Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Wed, 5 Dec 2018 13:59:02 +0200 Subject: [PATCH 46/59] Correct `seenby` logic in `Message` and connected files. --- Nynja/DB/Models/DBMessage.swift | 10 +----- Nynja/MessageDAO.swift | 35 +++++-------------- .../Interactor/MessageInteractor.swift | 2 +- 3 files changed, 11 insertions(+), 36 deletions(-) diff --git a/Nynja/DB/Models/DBMessage.swift b/Nynja/DB/Models/DBMessage.swift index 414d6098e..cba90a077 100644 --- a/Nynja/DB/Models/DBMessage.swift +++ b/Nynja/DB/Models/DBMessage.swift @@ -57,15 +57,7 @@ final class DBMessage: Record, DBModel { self.created = message.created self.type = message.types.joinedByCommaIfNotEmpty() self.link = message.linkedId - self.seenBy = message.seenby? - .compactMap { id -> String? in - if let id = id as? Int64 { - return String(id) - } else if let id = id as? String { - return id - } - return nil - }.joinedByComma() + self.seenBy = message.seenby?.joinedByComma self.status = message.statusString self.localStatus = message.localStatus diff --git a/Nynja/MessageDAO.swift b/Nynja/MessageDAO.swift index b15690f94..ffbee2050 100644 --- a/Nynja/MessageDAO.swift +++ b/Nynja/MessageDAO.swift @@ -10,6 +10,10 @@ import GRDBCipher final class MessageDAO: MessageDAOProtocol { + private static var userInfo: UserInfo { + return StorageService.sharedInstance + } + // MARK: - Save @@ -105,7 +109,7 @@ final class MessageDAO: MessageDAOProtocol { // MARK: -- Messages static func fetchMessages(to: String) -> [Message] { - guard let from = StorageService.sharedInstance.phoneId else { + guard let from = userInfo.phoneId else { return [] } @@ -276,15 +280,7 @@ final class MessageDAO: MessageDAOProtocol { guard let seenBy = message.seenby else { return false } - return seenBy.contains { id in - if let id = id as? String { - return id == "-1" - } else if let id = id as? Int64 { - return id == -1 - } else { - return false - } - } + return seenBy.contains(0) } @@ -311,25 +307,12 @@ final class MessageDAO: MessageDAOProtocol { guard !isMessageDeletedForAll(message) else { return true } - guard let phoneId = StorageService.sharedInstance.phoneId else { - assertionFailure("Check phoneId") + guard let rosterId = userInfo.rosterId else { + assertionFailure("rosterId should exist") return false } - if message.p2pFeed != nil { - if let identifiers = seenBy as? [String] { - return identifiers.contains(phoneId) - } - } else if let roomId = message.mucFeed?.name, - let member = MemberDAO.findMemberBy(roomId: roomId, phoneId: phoneId), - let memberId = member.id { - - if let identifiers = message.seenby as? [Int64] { - return identifiers.contains(memberId) - } - } - - return false + return seenBy.contains(-rosterId) } diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor.swift b/Nynja/Modules/Message/Interactor/MessageInteractor.swift index 454a0234e..0e15b9d46 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor.swift @@ -816,7 +816,7 @@ final class MessageInteractor: BaseInteractor, MessageInteractorInputProtocol, H } - let seenBy: Int64 = forBoth ? 0 : rosterId + let seenBy: Int64 = forBoth ? 0 : -rosterId saveDeleteAction(messageId: messageId, seenBy: seenBy) performDeleting(message: message, seenBy: seenBy) -- GitLab From 2340f84f009e9d70b724f453eda3f35df9597586 Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Wed, 5 Dec 2018 16:42:50 +0200 Subject: [PATCH 47/59] Updated call history implementation to match the latest SDK API --- .../CallHistory/CallHistoryProtocols.swift | 4 +-- .../Interactor/CallHistoryInteractor.swift | 4 +-- .../Presenter/CallHistoryPresenter.swift | 4 +-- .../View/CallHistoryViewController.swift | 35 +++++++++++++++---- .../View/TableView/CallHistoryCellModel.swift | 3 +- .../NynjaCalls/NynjaCommunicatorService.swift | 8 +++-- 6 files changed, 43 insertions(+), 15 deletions(-) diff --git a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift index e5e7f3d65..c788ade28 100644 --- a/Nynja/Modules/CallHistory/CallHistoryProtocols.swift +++ b/Nynja/Modules/CallHistory/CallHistoryProtocols.swift @@ -41,7 +41,7 @@ protocol CallHistoryPresenterProtocol: BasePresenterProtocol, NavigationProtocol var interactor: CallHistoryInteractorInputProtocol! { get set } var wireFrame: CallHistoryWireFrameProtocol! { get set } func closeController() - func removeCallLogBy(id:String) -> NYNCallHistoryCode + func removeCallLogBy(index:UInt) -> NYNCallHistoryCode func findContactBy(phoneId:String) -> Contact? func findRoomBy(roomId:String) -> Room? func showContact(contact: Contact) @@ -66,7 +66,7 @@ protocol CallHistoryInteractorInputProtocol: class { */ var presenter: CallHistoryInteractorOutputProtocol! { get set } - func removeCallLogBy(id:String) -> NYNCallHistoryCode + func removeCallLogBy(index:UInt) -> NYNCallHistoryCode func findContactBy(phoneId:String) -> Contact? func findRoomBy(roomId:String) -> Room? func clearCallHistory() -> NYNCallHistoryCode diff --git a/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift index 1e86b85dc..d499b9ebb 100644 --- a/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift +++ b/Nynja/Modules/CallHistory/Interactor/CallHistoryInteractor.swift @@ -13,8 +13,8 @@ class CallHistoryInteractor: CallHistoryInteractorInputProtocol { weak var presenter: CallHistoryInteractorOutputProtocol! let callService:NynjaCommunicatorService = NynjaCommunicatorService.sharedInstance - func removeCallLogBy(id:String) -> NYNCallHistoryCode { - return callService.removeCallLogBy(id:id) + func removeCallLogBy(index:UInt) -> NYNCallHistoryCode { + return callService.removeCallLogBy(index:index) } func findContactBy(phoneId:String) -> Contact? { diff --git a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift index 7049b7403..41b5a1f1d 100644 --- a/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift +++ b/Nynja/Modules/CallHistory/Presenter/CallHistoryPresenter.swift @@ -27,8 +27,8 @@ class CallHistoryPresenter: BasePresenter, CallHistoryPresenterProtocol, CallHis closeController() } - func removeCallLogBy(id:String) -> NYNCallHistoryCode { - return interactor.removeCallLogBy(id:id) + func removeCallLogBy(index:UInt) -> NYNCallHistoryCode { + return interactor.removeCallLogBy(index:index) } func findContactBy(phoneId:String) -> Contact? { diff --git a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift index acd0cbf56..117adcc45 100644 --- a/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift +++ b/Nynja/Modules/CallHistory/View/CallHistoryViewController.swift @@ -404,7 +404,7 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe if let ds = self?.tableViewDataSource { if let ip = self?.tableView.indexPath(for: callHistoryCell) { if let slf = self { - if .PENDING != slf.presenter.removeCallLogBy(id:m.identifier) { + if .PENDING != slf.presenter.removeCallLogBy(index:m.index) { ds.dataSource.remove(at: ip.row) slf.tableView.deleteRows(at: [ip], with: UITableView.RowAnimation.middle) } @@ -427,7 +427,16 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe presenter.showContact(contact: contact) } } else { - presenter.show(callLog: m.log) + + switch NynjaCommunicatorService.sharedInstance.getCallHistoryRecordMembers(id: m.log.identifier) { + case .PENDING: + self.showSpinner() + break + case .OK: + presenter.show(callLog: m.log) + case .UNIMPLEMENTED,.UNKNOWN: + break + } } } } @@ -471,22 +480,36 @@ class CallHistoryViewController: BaseVC, CallHistoryViewProtocol, UIScrollViewDe // MARK: NynjaCallHistoryManager Delegates func managerHistoryDidUpdate(_ manager: NynjaCallHistoryManager) { - DispatchQueue.main.async{ + DispatchQueue.main.async { self.hideSpinner() self.buildDataSource() } } func managerHistoryDidClear(_ manager: NynjaCallHistoryManager) { - DispatchQueue.main.async{ + DispatchQueue.main.async { self.hideSpinner() self.reloadTableView() } } - func manager(_ manager: NynjaCallHistoryManager, didDeleteRecordWithId identifier: String) { - DispatchQueue.main.async{ + func manager(_ manager: NynjaCallHistoryManager, didDeleteRecordWith index: UInt) { + DispatchQueue.main.async { self.reloadTableView() } } + + func manager(_ manager: NynjaCallHistoryManager, didFetchParticipantsWithRecordId identifier: String) { + DispatchQueue.main.async { + self.hideSpinner() + + for cell in self.tableView.visibleCells { + if let histCell = cell as? CallHistoryTableViewCell, + let model = histCell.model, model.log.identifier.elementsEqual(identifier) { + self.presenter.show(callLog: model.log) + break + } + } + } + } } diff --git a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift index 5b916d307..b1374f755 100644 --- a/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift +++ b/Nynja/Modules/CallHistory/View/TableView/CallHistoryCellModel.swift @@ -32,7 +32,8 @@ class CallHistoryCellModel: NSObject { formatter.timeStyle = .none return formatter }() - + + var index: UInt {get{return log.index}} var identifier: String {get{return log.identifier}} var kind: NYNCallLogKind {get{return log.kind}} var status: NYNCallLogStatus {get{return log.status}} diff --git a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift index 69b8f296f..c587b2e2b 100644 --- a/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift +++ b/Nynja/Services/NynjaCalls/NynjaCommunicatorService.swift @@ -486,14 +486,18 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele return self.nynComm.getCallHistoryManager().fetchIncoming() } - func removeCallLogBy(id:String) -> NYNCallHistoryCode { - return self.nynComm.getCallHistoryManager().deleteCallLog(by: id) + func removeCallLogBy(index:UInt) -> NYNCallHistoryCode { + return self.nynComm.getCallHistoryManager().deleteCallLog(by: index) } func clearCallHistory() -> NYNCallHistoryCode { return self.nynComm.getCallHistoryManager().deleteAllHistory() } + func getCallHistoryRecordMembers(id:String) -> NYNCallHistoryCode{ + return self.nynComm.getCallHistoryManager().fetchCallRecordParticipants(id); + } + //MARK: Helpers func getMySelf() -> Contact? { -- GitLab From d2a16b15d7560391c3ec39c6d6318421afbcd33c Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Wed, 5 Dec 2018 17:06:41 +0200 Subject: [PATCH 48/59] Write migration. --- Nynja.xcodeproj/project.pbxproj | 4 + Nynja/DB/Models/DBMessage.swift | 2 +- .../Migrations/UpdateSeenByLogic.swift | 99 +++++++++++++++++++ .../MigrationsProviderImpl.swift | 3 +- 4 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 Nynja/MigrationManager/Migrations/UpdateSeenByLogic.swift diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index a572cf8e3..707445089 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -618,6 +618,7 @@ 4B4266BF204D916000194BC1 /* ActionsView+Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4266BE204D916000194BC1 /* ActionsView+Action.swift */; }; 4B4266C1204D917800194BC1 /* ActionsView+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4266C0204D917800194BC1 /* ActionsView+Layout.swift */; }; 4B4266C3204D923400194BC1 /* Array+UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4266C2204D923400194BC1 /* Array+UIView.swift */; }; + 4B4D519421B7F62E00797C5D /* UpdateSeenByLogic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D519321B7F62E00797C5D /* UpdateSeenByLogic.swift */; }; 4B5A0B73216E3BDD002C4160 /* ActionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A0B6F216E3BDD002C4160 /* ActionsView.swift */; }; 4B5A0B74216E3BDD002C4160 /* ForwardAvatarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A0B70216E3BDD002C4160 /* ForwardAvatarViewModel.swift */; }; 4B5A0B75216E3BDD002C4160 /* ProgressHUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A0B71216E3BDD002C4160 /* ProgressHUD.swift */; }; @@ -2925,6 +2926,7 @@ 4B4266BE204D916000194BC1 /* ActionsView+Action.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ActionsView+Action.swift"; sourceTree = ""; }; 4B4266C0204D917800194BC1 /* ActionsView+Layout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ActionsView+Layout.swift"; sourceTree = ""; }; 4B4266C2204D923400194BC1 /* Array+UIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+UIView.swift"; sourceTree = ""; }; + 4B4D519321B7F62E00797C5D /* UpdateSeenByLogic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateSeenByLogic.swift; sourceTree = ""; }; 4B5A0B6F216E3BDD002C4160 /* ActionsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionsView.swift; sourceTree = ""; }; 4B5A0B70216E3BDD002C4160 /* ForwardAvatarViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ForwardAvatarViewModel.swift; sourceTree = ""; }; 4B5A0B71216E3BDD002C4160 /* ProgressHUD.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressHUD.swift; sourceTree = ""; }; @@ -6766,6 +6768,7 @@ 4B2C502F21B56AE900FBA9B1 /* CorrectMessageIdTypeInStarTable.swift */, 4B2C503121B56B2300FBA9B1 /* RemoveRoomMemberTable.swift */, 4B2C503821B573A100FBA9B1 /* RemoveP2pAndMucTables.swift */, + 4B4D519321B7F62E00797C5D /* UpdateSeenByLogic.swift */, ); path = Migrations; sourceTree = ""; @@ -16007,6 +16010,7 @@ 4B7C73F2215A5509007924DB /* MotionManager.swift in Sources */, 4B030F322195CD4500F293B7 /* MQTTServiceDelegate.swift in Sources */, F11786BB20A8A63F007A9A1B /* CoordinatorProtocol.swift in Sources */, + 4B4D519421B7F62E00797C5D /* UpdateSeenByLogic.swift in Sources */, F105C6BE20A1347E0091786A /* PhotoPreviewInteractor.swift in Sources */, F18AEAFD20C15792004FE01C /* SelectAvatarCoordinator.swift in Sources */, 85D66A1220BD965300FBD803 /* UserMentionTableViewCell.swift in Sources */, diff --git a/Nynja/DB/Models/DBMessage.swift b/Nynja/DB/Models/DBMessage.swift index cba90a077..426d146b8 100644 --- a/Nynja/DB/Models/DBMessage.swift +++ b/Nynja/DB/Models/DBMessage.swift @@ -57,7 +57,7 @@ final class DBMessage: Record, DBModel { self.created = message.created self.type = message.types.joinedByCommaIfNotEmpty() self.link = message.linkedId - self.seenBy = message.seenby?.joinedByComma + self.seenBy = message.seenby?.joinedByComma() self.status = message.statusString self.localStatus = message.localStatus diff --git a/Nynja/MigrationManager/Migrations/UpdateSeenByLogic.swift b/Nynja/MigrationManager/Migrations/UpdateSeenByLogic.swift new file mode 100644 index 000000000..3d757bb87 --- /dev/null +++ b/Nynja/MigrationManager/Migrations/UpdateSeenByLogic.swift @@ -0,0 +1,99 @@ +// +// UpdateSeenByLogic.swift +// Nynja +// +// Created by Volodymyr Hryhoriev on 12/5/18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import GRDBCipher + +final class UpdateSeenByLogic: Migration { + + func migrate(_ db: Database) throws { + try updateSeenByValuesInMessageTable(db) + try removePhoneIdFromMessageActionTable(db) + } + + private func updateSeenByValuesInMessageTable(_ db: Database) throws { + try updateSeenByForP2pAndBoth(db) + try updateSeenByForMuc(db) + } + + private func updateSeenByForP2pAndBoth(_ db: Database) throws { + let messageTable = MessageTable.name + let seenByColumn = Column.seenBy.asString(tableName: messageTable) + + let sql = """ + update \(messageTable) + set \(seenByColumn) = + case + when \(seenByColumn) = '-1' then '0' + when \(Column.feedType.asString(tableName: messageTable)) = 0 and \(seenByColumn) <> '-1' then '-' || substr(\(seenByColumn), instr(\(seenByColumn), '_') + 1) + else \(seenByColumn) + end + """ + + try db.execute(sql) + } + + private func updateSeenByForMuc(_ db: Database) throws { + let rows = try fetchSeenByRows(db) + try updateSeenByForMuc(db, rows: rows) + } + + private func updateSeenByForMuc(_ db: Database, rows: [SeenByRow]) throws { + try rows.forEach { row in + let ids = try fetchMemberIdRows(db, seenBy: row.seenBy) + try updateSeenBy(db, messageLocalId: row.localId, ids: ids) + } + } + + private func fetchSeenByRows(_ db: Database) throws -> [SeenByRow] { + let columns: [Column] = [.localId, .seenBy] + return try DBMessage + .filter(Column.feedType == FeedType.muc.rawValue) + .select(columns) + .asRequest(of: SeenByRow.self) + .fetchAll(db) + } + + private func fetchMemberIdRows(_ db: Database, seenBy: String) throws -> [Int64] { + let sql = """ + select substr(phoneId, instr(phoneId, '_') + 1) + from member + where + """ + + return try SQLRequest(sql).asRequest(of: Int64.self).fetchAll(db) + } + + private func updateSeenBy(_ db: Database, messageLocalId: MessageLocalId, ids: [Int64]) throws { + let seenBy = ids + .map { -$0 } + .joinedByComma() + + let messageTable = MessageTable.name + + let sql = """ + update \(messageTable) + set \(Column.seenBy.asString(tableName: messageTable)) = \(seenBy) + where \(Column.localId.asString(tableName: messageTable)) = '\(messageLocalId)' + """ + + try db.execute(sql) + } + + private func removePhoneIdFromMessageActionTable(_ db: Database) throws { + let columns: [Column] = [.messageId, .seenBy, .action] + try db.recreate(table: MessageActionTable.self, sharedColumns: Set(columns)) + } +} + +extension UpdateSeenByLogic { + + struct SeenByRow: RowConvertible, Codable { + let localId: String + let seenBy: String + } +} diff --git a/Nynja/MigrationManager/MigrationsProvider/MigrationsProviderImpl.swift b/Nynja/MigrationManager/MigrationsProvider/MigrationsProviderImpl.swift index cdc25bc2c..58babc166 100644 --- a/Nynja/MigrationManager/MigrationsProvider/MigrationsProviderImpl.swift +++ b/Nynja/MigrationManager/MigrationsProvider/MigrationsProviderImpl.swift @@ -14,6 +14,7 @@ final class MigrationsProviderImpl: MigrationsProvider { AddAutoColumnToConvertMessage(), CorrectMessageIdTypeInStarTable(), RemoveRoomMemberTable(), - RemoveP2pAndMucTables() + RemoveP2pAndMucTables(), + UpdateSeenByLogic() ] } -- GitLab From 9931bf793295297bf77ed32f10ef4f3550b4ec72 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Wed, 5 Dec 2018 18:38:59 +0200 Subject: [PATCH 49/59] Correct migration. --- .../Migrations/UpdateSeenByLogic.swift | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/Nynja/MigrationManager/Migrations/UpdateSeenByLogic.swift b/Nynja/MigrationManager/Migrations/UpdateSeenByLogic.swift index 3d757bb87..1d5a93f08 100644 --- a/Nynja/MigrationManager/Migrations/UpdateSeenByLogic.swift +++ b/Nynja/MigrationManager/Migrations/UpdateSeenByLogic.swift @@ -21,16 +21,13 @@ final class UpdateSeenByLogic: Migration { } private func updateSeenByForP2pAndBoth(_ db: Database) throws { - let messageTable = MessageTable.name - let seenByColumn = Column.seenBy.asString(tableName: messageTable) - let sql = """ - update \(messageTable) - set \(seenByColumn) = + update \(MessageTable.name) + set \(Column.seenBy) = case - when \(seenByColumn) = '-1' then '0' - when \(Column.feedType.asString(tableName: messageTable)) = 0 and \(seenByColumn) <> '-1' then '-' || substr(\(seenByColumn), instr(\(seenByColumn), '_') + 1) - else \(seenByColumn) + when \(Column.seenBy) = '-1' then '0' + when \(Column.feedType) = 0 and \(Column.seenBy) <> '-1' then '-' || substr(\(Column.seenBy), instr(\(Column.seenBy), '_') + 1) + else \(Column.seenBy) end """ @@ -53,6 +50,8 @@ final class UpdateSeenByLogic: Migration { let columns: [Column] = [.localId, .seenBy] return try DBMessage .filter(Column.feedType == FeedType.muc.rawValue) + .filter(Column.seenBy != nil) + .filter(Column.seenBy != "0") .select(columns) .asRequest(of: SeenByRow.self) .fetchAll(db) @@ -60,25 +59,25 @@ final class UpdateSeenByLogic: Migration { private func fetchMemberIdRows(_ db: Database, seenBy: String) throws -> [Int64] { let sql = """ - select substr(phoneId, instr(phoneId, '_') + 1) - from member - where + select substr(\(Column.phoneId), instr(\(Column.phoneId), '_') + 1) + from \(MemberTable.name) + where \(Column.id) in (\(seenBy)) """ return try SQLRequest(sql).asRequest(of: Int64.self).fetchAll(db) } private func updateSeenBy(_ db: Database, messageLocalId: MessageLocalId, ids: [Int64]) throws { - let seenBy = ids + let joinedsIds = ids .map { -$0 } .joinedByComma() - let messageTable = MessageTable.name - + let seenBy = joinedsIds.isEmpty ? "NULL" : "'\(joinedsIds)'" + let sql = """ - update \(messageTable) - set \(Column.seenBy.asString(tableName: messageTable)) = \(seenBy) - where \(Column.localId.asString(tableName: messageTable)) = '\(messageLocalId)' + update \(MessageTable.name) + set \(Column.seenBy) = \(seenBy) + where \(Column.localId) = '\(messageLocalId)' """ try db.execute(sql) -- GitLab From 124f6e07a1d050a2bdc52f13b018f7036112da48 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Wed, 5 Dec 2018 19:20:29 +0200 Subject: [PATCH 50/59] Correct logic connected with setting `localStatus` as `.deleted`. --- Nynja/MessageDAO.swift | 9 +---- Nynja/MessageDAOProtocol.swift | 1 - .../Interactor/MessageInteractor+Reply.swift | 2 +- .../MessageInteractor+StorageSubscriber.swift | 3 +- .../HandleServices/MessageHandler.swift | 33 +++++++++++++------ Nynja/Services/PushService.swift | 6 ++++ .../Models/Message/MessageExtension.swift | 30 +++++++++++++++++ 7 files changed, 62 insertions(+), 22 deletions(-) diff --git a/Nynja/MessageDAO.swift b/Nynja/MessageDAO.swift index ffbee2050..877acd3a4 100644 --- a/Nynja/MessageDAO.swift +++ b/Nynja/MessageDAO.swift @@ -276,13 +276,6 @@ final class MessageDAO: MessageDAOProtocol { return shouldMarkMessageAsDelete } - static func isMessageDeletedForAll(_ message: Message) -> Bool { - guard let seenBy = message.seenby else { - return false - } - return seenBy.contains(0) - } - // MARK: - Primary Key @@ -304,7 +297,7 @@ final class MessageDAO: MessageDAOProtocol { guard let seenBy = message.seenby else { return false } - guard !isMessageDeletedForAll(message) else { + guard !message.isDeletedForAll else { return true } guard let rosterId = userInfo.rosterId else { diff --git a/Nynja/MessageDAOProtocol.swift b/Nynja/MessageDAOProtocol.swift index ab7372b18..e299f7544 100644 --- a/Nynja/MessageDAOProtocol.swift +++ b/Nynja/MessageDAOProtocol.swift @@ -61,7 +61,6 @@ protocol MessageDAOProtocol: DAOProtocol { // MARK: - Remove static func removeMessage(using message: Message) -> Bool - static func isMessageDeletedForAll(_ message: Message) -> Bool static func shouldMarkMessageAsDeleted(_ message: Message) -> Bool //MARK: - Primary Key diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor+Reply.swift b/Nynja/Modules/Message/Interactor/MessageInteractor+Reply.swift index 76a3cfb3f..09e77f200 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor+Reply.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor+Reply.swift @@ -12,7 +12,7 @@ extension MessageInteractor { let sender = self.sender(for: repliedMessage) let author = sender.nick ?? sender.fullname let mentions = payloadParser.parse(repliedMessage) - let isDeleted = repliedMessage.isDeleted && MessageDAO.isMessageDeletedForAll(repliedMessage) + let isDeleted = repliedMessage.isDeleted && repliedMessage.isDeletedForAll return RepliedMessageModel(message: repliedMessage, author: author, diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift b/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift index 2d0a2fee0..35f7ca7a0 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor+StorageSubscriber.swift @@ -149,8 +149,7 @@ extension MessageInteractor { // MARK: - Handle message func handleMessageDelete(_ message: Message) { - let deletedForAll = MessageDAO.isMessageDeletedForAll(message) - presenter?.removeMessage(message, isForAllUsers: deletedForAll) + presenter?.removeMessage(message, isForAllUsers: message.isDeletedForAll) } private func handleMessageInsertOrUpdate(_ message: Message) { diff --git a/Nynja/Services/HandleServices/MessageHandler.swift b/Nynja/Services/HandleServices/MessageHandler.swift index 7caa63230..c67d824a8 100644 --- a/Nynja/Services/HandleServices/MessageHandler.swift +++ b/Nynja/Services/HandleServices/MessageHandler.swift @@ -151,16 +151,9 @@ final class MessageHandler: BaseHandler { let isMessageExistsInLocalDatabase = message.id .flatMap { try? MessageDAO.messageExists(serverId: $0) } ?? false - if message.isInOwnChat, !message.isCursor { - ChatService.updateReader(from: message, kind: .other) - ChatService.updateReader(from: message, kind: .own) - } else if !message.isInOwnChat, shouldUpdateOwnReader(from: message) { - ChatService.updateReader(from: message, kind: .own) - ChatService.resetUnreadCount(from: message) - } else if !shouldUpdateOwnReader(from: message) { - ChatService.updateReader(from: message, kind: .other) - } - + updateReaderWhenSaving(message: message) + updateLocalStatus(message: message) + try? save(message) if message.isForward { @@ -181,6 +174,26 @@ final class MessageHandler: BaseHandler { } } + private static func updateReaderWhenSaving(message: Message) { + if message.isInOwnChat, !message.isCursor { + ChatService.updateReader(from: message, kind: .other) + ChatService.updateReader(from: message, kind: .own) + } else if !message.isInOwnChat, shouldUpdateOwnReader(from: message) { + ChatService.updateReader(from: message, kind: .own) + ChatService.resetUnreadCount(from: message) + } else if !shouldUpdateOwnReader(from: message) { + ChatService.updateReader(from: message, kind: .other) + } + } + + private static func updateLocalStatus(message: Message) { + guard let rosterId = storageService.rosterId else { + return + } + + message.addDeletedLocalStatusIfNeeded(rosterId: rosterId) + } + private static func shouldSkipMessage(_ message: Message) -> Bool { if let desc = message.files?.first, desc.mime == SendMessageType.audioCall.rawValue, diff --git a/Nynja/Services/PushService.swift b/Nynja/Services/PushService.swift index 74a93335d..2f78bf60e 100644 --- a/Nynja/Services/PushService.swift +++ b/Nynja/Services/PushService.swift @@ -284,12 +284,18 @@ final class PushService: NSObject, PKPushRegistryDelegate, UserSettingsRespondab if let repliedMessage = message.repliedMessage { repliedMessage.localStatus = try MessageDAO.localStatusForRepliedMessage(repliedMessage) } + if let status = try MessageDAO.localStatus(message: message) { message.localStatus = status } + if message.messageStatus == .clear { ChatService.clearMessages(before: message) } + + if let rosterId = storageService.rosterId { + message.addDeletedLocalStatusIfNeeded(rosterId: rosterId) + } } private func sendNewNotification(title: String, sound: String?, id: String, data: [AnyHashable: Any]) { diff --git a/Shared/Library/Extensions/Models/Message/MessageExtension.swift b/Shared/Library/Extensions/Models/Message/MessageExtension.swift index 44d288a25..01bd25de4 100644 --- a/Shared/Library/Extensions/Models/Message/MessageExtension.swift +++ b/Shared/Library/Extensions/Models/Message/MessageExtension.swift @@ -55,6 +55,36 @@ extension Message { var payload: String? { return files?.first?.payload } + + var isDeletedForAll: Bool { + guard let seenBy = seenby else { + return false + } + return seenBy.contains(0) + } + + func isSeenBy(rosterId: Int64) -> Bool { + guard let seenBy = seenby else { + return true + } + + return seenBy.contains(rosterId) + } + + func addDeletedLocalStatusIfNeeded(rosterId: Int64) { + guard !isSeenBy(rosterId: rosterId) else { + return + } + + let localStatus: LocalStatus + if let status = self.localStatus { + localStatus = status.union(.deleted) + } else { + localStatus = .deleted + } + + self.localStatus = localStatus + } } // MARK: - Actions -- GitLab From fcdc606b10ecf338dea6bc4be98b2ba4d37ff434 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Thu, 6 Dec 2018 11:43:25 +0200 Subject: [PATCH 51/59] Correct `isSeenBy(rosterId:)` method in `MessageExtension`. --- Nynja/MessageDAO.swift | 8 +------- .../Extensions/Models/Message/MessageExtension.swift | 4 +++- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Nynja/MessageDAO.swift b/Nynja/MessageDAO.swift index 877acd3a4..56f9cc31f 100644 --- a/Nynja/MessageDAO.swift +++ b/Nynja/MessageDAO.swift @@ -294,18 +294,12 @@ final class MessageDAO: MessageDAOProtocol { } static func shouldMarkMessageAsDeleted(_ message: Message) -> Bool { - guard let seenBy = message.seenby else { - return false - } - guard !message.isDeletedForAll else { - return true - } guard let rosterId = userInfo.rosterId else { assertionFailure("rosterId should exist") return false } - return seenBy.contains(-rosterId) + return !message.isSeenBy(rosterId: rosterId) } diff --git a/Shared/Library/Extensions/Models/Message/MessageExtension.swift b/Shared/Library/Extensions/Models/Message/MessageExtension.swift index 01bd25de4..3118b8ce8 100644 --- a/Shared/Library/Extensions/Models/Message/MessageExtension.swift +++ b/Shared/Library/Extensions/Models/Message/MessageExtension.swift @@ -68,7 +68,9 @@ extension Message { return true } - return seenBy.contains(rosterId) + let isInSeenBySet = seenBy.contains(rosterId) + let isInNotSeenBySet = !seenBy.contains(-rosterId) + return isInSeenBySet && isInNotSeenBySet } func addDeletedLocalStatusIfNeeded(rosterId: Int64) { -- GitLab From f011b34e34b844f4d6a206893078f7beae8a5867 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Thu, 6 Dec 2018 11:44:08 +0200 Subject: [PATCH 52/59] Correct structure of `LogService` folder. --- Nynja.xcodeproj/project.pbxproj | 36 +++++++++++-------- .../LogService/LogService/LogService.swift | 1 - .../{LogService => }/LogServiceProtocol.swift | 1 - .../{LogService => }/LogServiceTopic.swift | 0 .../{ => LogWriter}/LogWriter.swift | 0 .../LogWriterProtocol.swift | 0 6 files changed, 21 insertions(+), 17 deletions(-) rename Nynja/Services/Debug/LogService/{LogService => }/LogServiceProtocol.swift (82%) rename Nynja/Services/Debug/LogService/{LogService => }/LogServiceTopic.swift (100%) rename Nynja/Services/Debug/LogService/{ => LogWriter}/LogWriter.swift (100%) rename Nynja/Services/Debug/LogService/{LogService => LogWriter}/LogWriterProtocol.swift (100%) diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 707445089..256ee8bfd 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -718,6 +718,9 @@ 4BB0EFBC2151347900704136 /* AlertImageViewControllerConstraints.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB0EFB92151347900704136 /* AlertImageViewControllerConstraints.swift */; }; 4BB0EFBD2151347900704136 /* AlertManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB0EFBA2151347900704136 /* AlertManager.swift */; }; 4BB35E23219AF46E0007C18E /* RosterRelatedQueryArgs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB35E22219AF46E0007C18E /* RosterRelatedQueryArgs.swift */; }; + 4BB5920321B923FA001FB393 /* Feed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8566BB10215BC39500320E15 /* Feed.swift */; }; + 4BB5920621B92538001FB393 /* LogWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C73EE215A5508007924DB /* LogWriter.swift */; }; + 4BB5920721B92538001FB393 /* LogWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C73EE215A5508007924DB /* LogWriter.swift */; }; 4BBAEBBA21AC62740089B703 /* LengthValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAEBB921AC62740089B703 /* LengthValidator.swift */; }; 4BBAEBBD21AC68FD0089B703 /* Validator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAEBBC21AC68FD0089B703 /* Validator.swift */; }; 4BBAEBBF21AC6DF10089B703 /* ClosureValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAEBBE21AC6DF10089B703 /* ClosureValidator.swift */; }; @@ -2965,7 +2968,7 @@ 4B7C73EA215A5508007924DB /* SMSCodeProviding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SMSCodeProviding.swift; sourceTree = ""; }; 4B7C73EC215A5508007924DB /* MotionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionManager.swift; sourceTree = ""; }; 4B7C73EE215A5508007924DB /* LogWriter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogWriter.swift; sourceTree = ""; }; - 4B7C73EF215A5508007924DB /* LogService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogService.swift; sourceTree = ""; }; + 4B7C73EF215A5508007924DB /* LogService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LogService.swift; path = LogService/LogService.swift; sourceTree = ""; }; 4B7C73F6215A5522007924DB /* DebugLogs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugLogs.swift; sourceTree = ""; }; 4B7C73F7215A5522007924DB /* UIView+Debug.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Debug.swift"; sourceTree = ""; }; 4B7C73F8215A5522007924DB /* UILabel+Debug.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UILabel+Debug.swift"; sourceTree = ""; }; @@ -6053,7 +6056,6 @@ 3A768E1C1ECD152300108F7C /* Services */ = { isa = PBXGroup; children = ( - 4B2C502521B568FD00FBA9B1 /* MigrationManager */, 851769D420D584CA008ACF6B /* Amazon */, 26ABCA3D21189DA400EA4782 /* Aps.swift */, 4BE2C5CE2142EAC500A73DD9 /* Audio */, @@ -6083,6 +6085,7 @@ 26E3229120E4F18100271413 /* MessageParser */, E7EC77A21FD1B9BD00DC8245 /* MessageProcessing */, F11786D220A98D0A007A9A1B /* MessageSendingService */, + 4B2C502521B568FD00FBA9B1 /* MigrationManager */, 3AC321761EEAC4700068F3C8 /* Models */, 3A8045CC1F60C8E200AED866 /* MQTT */, A458FAC020EBA4D70075D55E /* MuteChatService */, @@ -7064,8 +7067,10 @@ 4B7C73ED215A5508007924DB /* LogService */ = { isa = PBXGroup; children = ( - 4BF090B721635B3700DCCA5C /* LogService */, - 4B7C73EE215A5508007924DB /* LogWriter.swift */, + 4B7C73EF215A5508007924DB /* LogService.swift */, + 4BF090B821635B4700DCCA5C /* LogServiceProtocol.swift */, + 4BF090BA21635B6600DCCA5C /* LogServiceTopic.swift */, + 4BB5920521B92528001FB393 /* LogWriter */, ); path = LogService; sourceTree = ""; @@ -7308,6 +7313,15 @@ path = AlertImageViewController; sourceTree = ""; }; + 4BB5920521B92528001FB393 /* LogWriter */ = { + isa = PBXGroup; + children = ( + 4B7C73EE215A5508007924DB /* LogWriter.swift */, + 2611CEF62182090900FFD4DD /* LogWriterProtocol.swift */, + ); + path = LogWriter; + sourceTree = ""; + }; 4BBAEBBB21AC68F00089B703 /* Validator */ = { isa = PBXGroup; children = ( @@ -7449,17 +7463,6 @@ path = Services/NynjaCalls; sourceTree = ""; }; - 4BF090B721635B3700DCCA5C /* LogService */ = { - isa = PBXGroup; - children = ( - 4B7C73EF215A5508007924DB /* LogService.swift */, - 4BF090B821635B4700DCCA5C /* LogServiceProtocol.swift */, - 2611CEF62182090900FFD4DD /* LogWriterProtocol.swift */, - 4BF090BA21635B6600DCCA5C /* LogServiceTopic.swift */, - ); - path = LogService; - sourceTree = ""; - }; 4BF2C3EE2189F58100E59F6C /* Entities */ = { isa = PBXGroup; children = ( @@ -16969,6 +16972,7 @@ buildActionMask = 2147483647; files = ( FB816EF520B5B87300093DCD /* Bert.swift in Sources */, + 4BB5920321B923FA001FB393 /* Feed.swift in Sources */, FB61D664214FF96200CB2A1F /* ColorsConstants.swift in Sources */, 85458CE8212D73E600BA8814 /* MucExtension.swift in Sources */, 4BF2C3E32188BA7B00E59F6C /* IdentifierComponentValue.swift in Sources */, @@ -17012,6 +17016,7 @@ 4BF090C921635F4300DCCA5C /* Message+LocalStatus.swift in Sources */, A4AB8E582105F47C005F9B0C /* InputsCachePolicyTest.swift in Sources */, FB816EF920B5B8A700093DCD /* Desc.swift in Sources */, + 4BB5920721B92538001FB393 /* LogWriter.swift in Sources */, 852003FC20D45B48007C0036 /* BertBinConvertible.swift in Sources */, 4BF2C3E42188BABC00E59F6C /* UIDeviceExtension.swift in Sources */, FB816EF320B5B85900093DCD /* Contact.swift in Sources */, @@ -17055,6 +17060,7 @@ FE21ACBA2113AB4B006010A0 /* KeychainService.swift in Sources */, 4BF2C3E92189B49500E59F6C /* Localizable.swift in Sources */, 85458CDC212D6FFF00BA8814 /* String+Split.swift in Sources */, + 4BB5920621B92538001FB393 /* LogWriter.swift in Sources */, FB61D652214FEC8300CB2A1F /* LocalizableConstants.swift in Sources */, 85458CE5212D731300BA8814 /* MessageIdentifiers.swift in Sources */, FB61D64F214FEC7E00CB2A1F /* FontsConstants.swift in Sources */, diff --git a/Nynja/Services/Debug/LogService/LogService/LogService.swift b/Nynja/Services/Debug/LogService/LogService/LogService.swift index 3ca220fce..c05f2a6d7 100644 --- a/Nynja/Services/Debug/LogService/LogService/LogService.swift +++ b/Nynja/Services/Debug/LogService/LogService/LogService.swift @@ -57,5 +57,4 @@ final class LogService { i += 1 } } - } diff --git a/Nynja/Services/Debug/LogService/LogService/LogServiceProtocol.swift b/Nynja/Services/Debug/LogService/LogServiceProtocol.swift similarity index 82% rename from Nynja/Services/Debug/LogService/LogService/LogServiceProtocol.swift rename to Nynja/Services/Debug/LogService/LogServiceProtocol.swift index 94822e1a5..64ed8ea0e 100644 --- a/Nynja/Services/Debug/LogService/LogService/LogServiceProtocol.swift +++ b/Nynja/Services/Debug/LogService/LogServiceProtocol.swift @@ -7,7 +7,6 @@ // protocol LogServiceProtocol { - static var enabledTopics: [LogServiceTopic] { get } static func log(topic: LogServiceTopic, block: () -> String) } diff --git a/Nynja/Services/Debug/LogService/LogService/LogServiceTopic.swift b/Nynja/Services/Debug/LogService/LogServiceTopic.swift similarity index 100% rename from Nynja/Services/Debug/LogService/LogService/LogServiceTopic.swift rename to Nynja/Services/Debug/LogService/LogServiceTopic.swift diff --git a/Nynja/Services/Debug/LogService/LogWriter.swift b/Nynja/Services/Debug/LogService/LogWriter/LogWriter.swift similarity index 100% rename from Nynja/Services/Debug/LogService/LogWriter.swift rename to Nynja/Services/Debug/LogService/LogWriter/LogWriter.swift diff --git a/Nynja/Services/Debug/LogService/LogService/LogWriterProtocol.swift b/Nynja/Services/Debug/LogService/LogWriter/LogWriterProtocol.swift similarity index 100% rename from Nynja/Services/Debug/LogService/LogService/LogWriterProtocol.swift rename to Nynja/Services/Debug/LogService/LogWriter/LogWriterProtocol.swift -- GitLab From 519cb4edcde965456522e2b9f82dd7f314959fdd Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Thu, 6 Dec 2018 12:10:17 +0200 Subject: [PATCH 53/59] Add ability to launch tests. --- .../Services/LogService/LogService.swift | 14 ++++++ Nynja.xcodeproj/project.pbxproj | 46 +++++++++++++------ .../LogService/LogService/LogService.swift | 19 +++----- .../Debug/LogService/LogServiceProtocol.swift | 2 +- .../Services/MQTT/Entities/MQTTMessage.swift | 19 ++++++++ Nynja/Services/MQTT/MQTTService.swift | 16 +------ Nynja/Services/Models/BaseMQTTModel.swift | 2 +- 7 files changed, 74 insertions(+), 44 deletions(-) create mode 100644 Nynja-Share/Services/LogService/LogService.swift create mode 100644 Nynja/Services/MQTT/Entities/MQTTMessage.swift diff --git a/Nynja-Share/Services/LogService/LogService.swift b/Nynja-Share/Services/LogService/LogService.swift new file mode 100644 index 000000000..449c24e4f --- /dev/null +++ b/Nynja-Share/Services/LogService/LogService.swift @@ -0,0 +1,14 @@ +// +// LogService.swift +// Nynja-Share +// +// Created by Volodymyr Hryhoriev on 12/6/18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import Foundation + +// NOTE: Stub for NynjaUnitTests target. +final class LogService: LogServiceProtocol { + static func log(topic: LogServiceTopic, block: (() -> String)?) {} +} diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 256ee8bfd..df6ac1edf 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -143,8 +143,6 @@ 2606F3BC20BFE20500CF7F15 /* MessageInteractor+Translation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2606F3BB20BFE20400CF7F15 /* MessageInteractor+Translation.swift */; }; 2611CEF72182090900FFD4DD /* LogWriterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2611CEF62182090900FFD4DD /* LogWriterProtocol.swift */; }; 2611CEF82182090900FFD4DD /* LogWriterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2611CEF62182090900FFD4DD /* LogWriterProtocol.swift */; }; - 2611CEF92182090900FFD4DD /* LogWriterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2611CEF62182090900FFD4DD /* LogWriterProtocol.swift */; }; - 2611CEFA2182090900FFD4DD /* LogWriterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2611CEF62182090900FFD4DD /* LogWriterProtocol.swift */; }; 26131E02210399BA00BE94F9 /* TranscribeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26131E01210399BA00BE94F9 /* TranscribeService.swift */; }; 26142B1120472ECD004E5FE4 /* MessageLinkTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26142B1020472ECD004E5FE4 /* MessageLinkTable.swift */; }; 26142B1320473BFD004E5FE4 /* DBMessageLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26142B1220473BFD004E5FE4 /* DBMessageLink.swift */; }; @@ -665,7 +663,6 @@ 4B7C73F9215A5522007924DB /* DebugLogs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C73F6215A5522007924DB /* DebugLogs.swift */; }; 4B7C73FA215A5522007924DB /* UIView+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C73F7215A5522007924DB /* UIView+Debug.swift */; }; 4B7C73FB215A5522007924DB /* UILabel+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C73F8215A5522007924DB /* UILabel+Debug.swift */; }; - 4B7C73FC215A552C007924DB /* LogService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C73EF215A5508007924DB /* LogService.swift */; }; 4B7C73FD215A553F007924DB /* LogWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C73EE215A5508007924DB /* LogWriter.swift */; }; 4B7E93382170D1BC001558CF /* RootNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7E93372170D1BC001558CF /* RootNavigationController.swift */; }; 4B7E933B2170D410001558CF /* ForwardSelectorWireFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7E933A2170D410001558CF /* ForwardSelectorWireFrame.swift */; }; @@ -719,8 +716,13 @@ 4BB0EFBD2151347900704136 /* AlertManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB0EFBA2151347900704136 /* AlertManager.swift */; }; 4BB35E23219AF46E0007C18E /* RosterRelatedQueryArgs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB35E22219AF46E0007C18E /* RosterRelatedQueryArgs.swift */; }; 4BB5920321B923FA001FB393 /* Feed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8566BB10215BC39500320E15 /* Feed.swift */; }; - 4BB5920621B92538001FB393 /* LogWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C73EE215A5508007924DB /* LogWriter.swift */; }; - 4BB5920721B92538001FB393 /* LogWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C73EE215A5508007924DB /* LogWriter.swift */; }; + 4BB5920921B92702001FB393 /* MQTTMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5920821B92702001FB393 /* MQTTMessage.swift */; }; + 4BB5920A21B9270E001FB393 /* MQTTMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5920821B92702001FB393 /* MQTTMessage.swift */; }; + 4BB5920B21B92729001FB393 /* MQTTMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5920821B92702001FB393 /* MQTTMessage.swift */; }; + 4BB5920C21B928AA001FB393 /* Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8512349121221B9E000129A2 /* Collection.swift */; }; + 4BB5920F21B9295D001FB393 /* LogService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5920E21B9295D001FB393 /* LogService.swift */; }; + 4BB5921021B929CC001FB393 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4F3DAA22084935400FF71C7 /* Constants.swift */; }; + 4BB5921121B92CCD001FB393 /* LogService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5920E21B9295D001FB393 /* LogService.swift */; }; 4BBAEBBA21AC62740089B703 /* LengthValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAEBB921AC62740089B703 /* LengthValidator.swift */; }; 4BBAEBBD21AC68FD0089B703 /* Validator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAEBBC21AC68FD0089B703 /* Validator.swift */; }; 4BBAEBBF21AC6DF10089B703 /* ClosureValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAEBBE21AC6DF10089B703 /* ClosureValidator.swift */; }; @@ -3016,6 +3018,8 @@ 4BB0EFB92151347900704136 /* AlertImageViewControllerConstraints.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertImageViewControllerConstraints.swift; sourceTree = ""; }; 4BB0EFBA2151347900704136 /* AlertManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertManager.swift; sourceTree = ""; }; 4BB35E22219AF46E0007C18E /* RosterRelatedQueryArgs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RosterRelatedQueryArgs.swift; sourceTree = ""; }; + 4BB5920821B92702001FB393 /* MQTTMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MQTTMessage.swift; sourceTree = ""; }; + 4BB5920E21B9295D001FB393 /* LogService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogService.swift; sourceTree = ""; }; 4BBAEBB921AC62740089B703 /* LengthValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LengthValidator.swift; sourceTree = ""; }; 4BBAEBBC21AC68FD0089B703 /* Validator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Validator.swift; sourceTree = ""; }; 4BBAEBBE21AC6DF10089B703 /* ClosureValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClosureValidator.swift; sourceTree = ""; }; @@ -5978,9 +5982,10 @@ 359EB2721F9A27EB00147437 /* Services */ = { isa = PBXGroup; children = ( - 4B7E933C2170D4F0001558CF /* ServiceFactory */, 4B5A0B79216E3C6F002C4160 /* AttachmentProvider */, 356275751F9D337400D2A7F0 /* Handlers */, + 4BB5920D21B9294A001FB393 /* LogService */, + 4B7E933C2170D4F0001558CF /* ServiceFactory */, ); path = Services; sourceTree = ""; @@ -6126,8 +6131,8 @@ 3A8045CC1F60C8E200AED866 /* MQTT */ = { isa = PBXGroup; children = ( - 4B030F392195CF7600F293B7 /* Entities */, 4B030F342195CD4A00F293B7 /* API */, + 4B030F392195CF7600F293B7 /* Entities */, 4B030F382195CDDA00F293B7 /* Extensions */, 3A8045CD1F60C8E200AED866 /* MQTTService.swift */, 4B030F312195CD4500F293B7 /* MQTTServiceDelegate.swift */, @@ -6520,14 +6525,14 @@ 4B030F342195CD4A00F293B7 /* API */ = { isa = PBXGroup; children = ( - FBCE83D420E52396003B7558 /* MQTTServiceWallet.swift */, + 3A8045D01F60C8E200AED866 /* MQTTServiceAuth.swift */, 3A8045D51F60C93D00AED866 /* MQTTServiceChat.swift */, 3A8045CE1F60C8E200AED866 /* MQTTServiceFriend.swift */, + A48C153E20EF765E002DA994 /* MQTTServiceLink.swift */, 3A8045CF1F60C8E200AED866 /* MQTTServiceProfile.swift */, - 3A8045D01F60C8E200AED866 /* MQTTServiceAuth.swift */, 0008E9122032D5AC003E316E /* MQTTServiceSchedule.swift */, 855EF422202CC85300541BE3 /* MQTTServiceStars.swift */, - A48C153E20EF765E002DA994 /* MQTTServiceLink.swift */, + FBCE83D420E52396003B7558 /* MQTTServiceWallet.swift */, ); path = API; sourceTree = ""; @@ -6545,6 +6550,7 @@ isa = PBXGroup; children = ( 4B030F3A2195CF8100F293B7 /* Host.swift */, + 4BB5920821B92702001FB393 /* MQTTMessage.swift */, ); path = Entities; sourceTree = ""; @@ -7322,6 +7328,14 @@ path = LogWriter; sourceTree = ""; }; + 4BB5920D21B9294A001FB393 /* LogService */ = { + isa = PBXGroup; + children = ( + 4BB5920E21B9295D001FB393 /* LogService.swift */, + ); + path = LogService; + sourceTree = ""; + }; 4BBAEBBB21AC68F00089B703 /* Validator */ = { isa = PBXGroup; children = ( @@ -14815,6 +14829,7 @@ 261522642084D5EC00AF72A5 /* Testable.swift in Sources */, 267D465A20AB4C4000D42242 /* FeatureExtension.swift in Sources */, A42CE57E20692EDB000889CC /* userTask.swift in Sources */, + 4BB5920F21B9295D001FB393 /* LogService.swift in Sources */, A4679B9120B2DA640021FE9C /* SelectorCell.swift in Sources */, 35B98FA21F9CB948009B8DEC /* Layout.swift in Sources */, A42CE5AE20692EDB000889CC /* StringAtom.swift in Sources */, @@ -14949,7 +14964,6 @@ 26A856292074C7BE00C642EA /* ActionsView+Action.swift in Sources */, 26A0CFE2200513B4006F6617 /* MemberExtension+BERT.swift in Sources */, A4F3DA9D2084910C00FF71C7 /* ContactHandler.swift in Sources */, - 4B7C73FC215A552C007924DB /* LogService.swift in Sources */, 4B7E933B2170D410001558CF /* ForwardSelectorWireFrame.swift in Sources */, 35B1ABB01FA34B2600E65233 /* SearchModel.swift in Sources */, 4B052CB12036193900BC2A9B /* StringAtomExtension.swift in Sources */, @@ -15066,6 +15080,7 @@ 8524C4D7217772CD003BF374 /* Member+Construct.swift in Sources */, 85D669E820BD95B300FBD803 /* UIView+Shadow.swift in Sources */, 2651094020ADBB0200F1B38B /* NotificationSettingProtocol.swift in Sources */, + 4BB5920A21B9270E001FB393 /* MQTTMessage.swift in Sources */, F11DF06920BD9E7900F3E005 /* NavigationProtocol.swift in Sources */, 2600CCB1216B8DC600EDC9C3 /* Language.swift in Sources */, 26A8562A2074C7FB00C642EA /* UIView+SafeArea.swift in Sources */, @@ -16658,6 +16673,7 @@ 2689CDEA20C48AD8007816B9 /* TranslationManualView.swift in Sources */, 4B2C502A21B569B500FBA9B1 /* AddSeenByColumnToMessage.swift in Sources */, 6C25C4720B043D98729C02C8 /* TopUpAccountPresenter.swift in Sources */, + 4BB5920921B92702001FB393 /* MQTTMessage.swift in Sources */, A42D51CE206A361400EEB952 /* Search.swift in Sources */, B77C11DB2109242200CCB42E /* AssigningInterpreterPresenter.swift in Sources */, 26342CB220ECDDC400D2196B /* Encodable+Dictionary.swift in Sources */, @@ -16977,9 +16993,11 @@ 85458CE8212D73E600BA8814 /* MucExtension.swift in Sources */, 4BF2C3E32188BA7B00E59F6C /* IdentifierComponentValue.swift in Sources */, 4B348FFB2163836D00CCB0E3 /* ReversableDataSource.swift in Sources */, + 4BB5920C21B928AA001FB393 /* Collection.swift in Sources */, FB61D64E214FEC7D00CB2A1F /* FontsConstants.swift in Sources */, FB816EF220B5B6F100093DCD /* BaseMQTTModel.swift in Sources */, 4B8FC31D2163D6A700602D6B /* Cloneable.swift in Sources */, + 4BB5921121B92CCD001FB393 /* LogService.swift in Sources */, 4B752B5E2163A4F900E852B9 /* GApiResponse.swift in Sources */, FB816EF020B5B36D00093DCD /* HistoryRequestModelTests.swift in Sources */, 85458CEA212D742300BA8814 /* muc.swift in Sources */, @@ -16990,6 +17008,7 @@ A4AB8E522105EC46005F9B0C /* TextField.swift in Sources */, 85458D00212D7C0C00BA8814 /* Int+AnyObject.swift in Sources */, 4B6D20F02164D4B0003ADB29 /* ChatCellModelType.swift in Sources */, + 4BB5920B21B92729001FB393 /* MQTTMessage.swift in Sources */, FB816EF820B5B89700093DCD /* StringAtom.swift in Sources */, 4BF090BE21635B9400DCCA5C /* LogServiceProtocol.swift in Sources */, 4B8FC3122163C50E00602D6B /* SpeedStringRepresentable.swift in Sources */, @@ -17004,7 +17023,7 @@ 4BF090CE21635FEE00DCCA5C /* Message+Type.swift in Sources */, A49EE6D7210B110800B700B1 /* Link.swift in Sources */, 4B8FC31C2163CD8C00602D6B /* ChatCellModel.swift in Sources */, - 2611CEF92182090900FFD4DD /* LogWriterProtocol.swift in Sources */, + 4BB5921021B929CC001FB393 /* Constants.swift in Sources */, 85458CE4212D731300BA8814 /* MessageIdentifiers.swift in Sources */, FB61D651214FEC8200CB2A1F /* LocalizableConstants.swift in Sources */, A4330A562109D60D0060BD93 /* QueryFactoryProtocol.swift in Sources */, @@ -17016,7 +17035,6 @@ 4BF090C921635F4300DCCA5C /* Message+LocalStatus.swift in Sources */, A4AB8E582105F47C005F9B0C /* InputsCachePolicyTest.swift in Sources */, FB816EF920B5B8A700093DCD /* Desc.swift in Sources */, - 4BB5920721B92538001FB393 /* LogWriter.swift in Sources */, 852003FC20D45B48007C0036 /* BertBinConvertible.swift in Sources */, 4BF2C3E42188BABC00E59F6C /* UIDeviceExtension.swift in Sources */, FB816EF320B5B85900093DCD /* Contact.swift in Sources */, @@ -17052,7 +17070,6 @@ buildActionMask = 2147483647; files = ( 4B348FD8216366AE00CCB0E3 /* LogServiceTopic.swift in Sources */, - 2611CEFA2182090900FFD4DD /* LogWriterProtocol.swift in Sources */, FE21ACB92113AB3C006010A0 /* KeychainServiceTest.swift in Sources */, FE21ACBC2113AB92006010A0 /* QueryFactoryProtocol.swift in Sources */, 4B348FD7216366A900CCB0E3 /* LogServiceProtocol.swift in Sources */, @@ -17060,7 +17077,6 @@ FE21ACBA2113AB4B006010A0 /* KeychainService.swift in Sources */, 4BF2C3E92189B49500E59F6C /* Localizable.swift in Sources */, 85458CDC212D6FFF00BA8814 /* String+Split.swift in Sources */, - 4BB5920621B92538001FB393 /* LogWriter.swift in Sources */, FB61D652214FEC8300CB2A1F /* LocalizableConstants.swift in Sources */, 85458CE5212D731300BA8814 /* MessageIdentifiers.swift in Sources */, FB61D64F214FEC7E00CB2A1F /* FontsConstants.swift in Sources */, diff --git a/Nynja/Services/Debug/LogService/LogService/LogService.swift b/Nynja/Services/Debug/LogService/LogService/LogService.swift index c05f2a6d7..8edabeee9 100644 --- a/Nynja/Services/Debug/LogService/LogService/LogService.swift +++ b/Nynja/Services/Debug/LogService/LogService/LogService.swift @@ -9,7 +9,7 @@ import Foundation import os.log -final class LogService { +final class LogService: LogServiceProtocol { private static let logWriter: LogWriterProtocol? = ServiceFactory().makeLogWriter() @@ -19,21 +19,16 @@ final class LogService { .passphrase, .connectionState] private static let backgroundQueue = DispatchQueue(label:"logQueue",qos:.background) - - static func log(topic: LogServiceTopic, - file: String = #file, - function: String = #function, - line: Int = #line, - block: (() -> String)?) { + + static func log(topic: LogServiceTopic, block: (() -> String)?) { #if !RELEASE backgroundQueue.async { - if !enabledTopics.contains(topic) { return } - - let header = "File: \(file), function: \(function), line: \(line)" - let message = block?() ?? "" - let text = "\(header)\n\(message)" + guard enabledTopics.contains(topic) else { + return + } + let text = block?() ?? "" LogService.executeLogs(topic: topic, text: text, thread: Thread.current.debugDescription) } #endif diff --git a/Nynja/Services/Debug/LogService/LogServiceProtocol.swift b/Nynja/Services/Debug/LogService/LogServiceProtocol.swift index 64ed8ea0e..1a2dc2e37 100644 --- a/Nynja/Services/Debug/LogService/LogServiceProtocol.swift +++ b/Nynja/Services/Debug/LogService/LogServiceProtocol.swift @@ -7,6 +7,6 @@ // protocol LogServiceProtocol { - static func log(topic: LogServiceTopic, block: () -> String) + static func log(topic: LogServiceTopic, block: (() -> String)?) } diff --git a/Nynja/Services/MQTT/Entities/MQTTMessage.swift b/Nynja/Services/MQTT/Entities/MQTTMessage.swift new file mode 100644 index 000000000..e55c8d821 --- /dev/null +++ b/Nynja/Services/MQTT/Entities/MQTTMessage.swift @@ -0,0 +1,19 @@ +// +// MQTTMessage.swift +// Nynja +// +// Created by Volodymyr Hryhoriev on 12/6/18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import Foundation + +struct MQTTMessage { + let payload: Data? + let topic: String? + + init(payload: Data?, topic: String?) { + self.payload = payload + self.topic = topic + } +} diff --git a/Nynja/Services/MQTT/MQTTService.swift b/Nynja/Services/MQTT/MQTTService.swift index b77c4d60a..e26350e87 100644 --- a/Nynja/Services/MQTT/MQTTService.swift +++ b/Nynja/Services/MQTT/MQTTService.swift @@ -162,7 +162,7 @@ final class MQTTService: NSObject, MQTTServiceProtocol, ConnectionServiceDelegat queuePool.processingQueue.async { [weak mqtt] in guard let mqtt = mqtt, mqtt.status == .connected else { return } let finalModel: MQTTMessage = model.getMessage() - mqtt.publishData(finalModel.payload, onTopic: finalModel.topic, retain: false, qos: finalModel.qos) + mqtt.publishData(finalModel.payload, onTopic: finalModel.topic, retain: false, qos: .exactlyOnce) } } @@ -300,17 +300,3 @@ final class MQTTService: NSObject, MQTTServiceProtocol, ConnectionServiceDelegat } } } - - -struct MQTTMessage { - let payload: Data? - let topic: String? - var qos: MQTTQosLevel! - - init(payload: Data?, topic: String?, qos: MQTTQosLevel? = nil) { - self.payload = payload - self.topic = topic - self.qos = qos - if qos == nil { self.qos = .exactlyOnce } - } -} diff --git a/Nynja/Services/Models/BaseMQTTModel.swift b/Nynja/Services/Models/BaseMQTTModel.swift index ee269c20e..126069209 100644 --- a/Nynja/Services/Models/BaseMQTTModel.swift +++ b/Nynja/Services/Models/BaseMQTTModel.swift @@ -17,7 +17,7 @@ class BaseMQTTModel { func getMessage() -> MQTTMessage { let topic = "events/1//api/anon//" let payload = self.getBert() - let msg = MQTTMessage(payload: payload, topic: topic, qos: .exactlyOnce) + let msg = MQTTMessage(payload: payload, topic: topic) return msg } } -- GitLab From c59e7877ad6b720b9a1e711ac781ec0678a12a90 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Thu, 6 Dec 2018 13:42:29 +0200 Subject: [PATCH 54/59] Correct `isSeenBy(rosterId:)` method --- Nynja.xcodeproj/project.pbxproj | 24 +++++++++- .../LogService/LogService/LogService.swift | 2 +- NynjaUnitTests/Models/MessageTests.swift | 44 ++++++++++++++++++ .../Models/Message/Message+SeenBy.swift | 46 +++++++++++++++++++ .../Models/Message/MessageExtension.swift | 32 ------------- 5 files changed, 113 insertions(+), 35 deletions(-) create mode 100644 NynjaUnitTests/Models/MessageTests.swift create mode 100644 Shared/Library/Extensions/Models/Message/Message+SeenBy.swift diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index df6ac1edf..2f797638e 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -723,6 +723,10 @@ 4BB5920F21B9295D001FB393 /* LogService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5920E21B9295D001FB393 /* LogService.swift */; }; 4BB5921021B929CC001FB393 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4F3DAA22084935400FF71C7 /* Constants.swift */; }; 4BB5921121B92CCD001FB393 /* LogService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5920E21B9295D001FB393 /* LogService.swift */; }; + 4BB5921721B93022001FB393 /* MessageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5921621B93022001FB393 /* MessageTests.swift */; }; + 4BB5921A21B93323001FB393 /* Message+SeenBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5921921B93323001FB393 /* Message+SeenBy.swift */; }; + 4BB5921B21B9332C001FB393 /* Message+SeenBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5921921B93323001FB393 /* Message+SeenBy.swift */; }; + 4BB5921C21B9332C001FB393 /* Message+SeenBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB5921921B93323001FB393 /* Message+SeenBy.swift */; }; 4BBAEBBA21AC62740089B703 /* LengthValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAEBB921AC62740089B703 /* LengthValidator.swift */; }; 4BBAEBBD21AC68FD0089B703 /* Validator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAEBBC21AC68FD0089B703 /* Validator.swift */; }; 4BBAEBBF21AC6DF10089B703 /* ClosureValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAEBBE21AC6DF10089B703 /* ClosureValidator.swift */; }; @@ -3020,6 +3024,8 @@ 4BB35E22219AF46E0007C18E /* RosterRelatedQueryArgs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RosterRelatedQueryArgs.swift; sourceTree = ""; }; 4BB5920821B92702001FB393 /* MQTTMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MQTTMessage.swift; sourceTree = ""; }; 4BB5920E21B9295D001FB393 /* LogService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogService.swift; sourceTree = ""; }; + 4BB5921621B93022001FB393 /* MessageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageTests.swift; sourceTree = ""; }; + 4BB5921921B93323001FB393 /* Message+SeenBy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Message+SeenBy.swift"; sourceTree = ""; }; 4BBAEBB921AC62740089B703 /* LengthValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LengthValidator.swift; sourceTree = ""; }; 4BBAEBBC21AC68FD0089B703 /* Validator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Validator.swift; sourceTree = ""; }; 4BBAEBBE21AC6DF10089B703 /* ClosureValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClosureValidator.swift; sourceTree = ""; }; @@ -7336,6 +7342,14 @@ path = LogService; sourceTree = ""; }; + 4BB5921321B92FD9001FB393 /* Models */ = { + isa = PBXGroup; + children = ( + 4BB5921621B93022001FB393 /* MessageTests.swift */, + ); + path = Models; + sourceTree = ""; + }; 4BBAEBBB21AC68F00089B703 /* Validator */ = { isa = PBXGroup; children = ( @@ -10830,13 +10844,14 @@ A45F114220B421AB00F45004 /* Message */ = { isa = PBXGroup; children = ( - 85458CE1212D730E00BA8814 /* MessageIdentifiers.swift */, - A45F114320B421AB00F45004 /* MessageExtension.swift */, 8551CF0D2170856B00829CF1 /* Message+Construct.swift */, 85458CF4212D770100BA8814 /* Message+Files.swift */, 4BF090C421635E8600DCCA5C /* Message+LinkedId.swift */, 4BF090C721635F3300DCCA5C /* Message+LocalStatus.swift */, + 4BB5921921B93323001FB393 /* Message+SeenBy.swift */, 4BF090CB21635FDC00DCCA5C /* Message+Type.swift */, + A45F114320B421AB00F45004 /* MessageExtension.swift */, + 85458CE1212D730E00BA8814 /* MessageIdentifiers.swift */, ); path = Message; sourceTree = ""; @@ -13459,6 +13474,7 @@ F1C37AAA209A1BF4005EA197 /* NynjaUnitTests */ = { isa = PBXGroup; children = ( + 4BB5921321B92FD9001FB393 /* Models */, 4B348FE92163802100CCB0E3 /* Modules */, A421BB74210B4EC2006F2608 /* Extensions */, A4AB8E4F2105EB39005F9B0C /* InputsCachePolicy */, @@ -14863,6 +14879,7 @@ 4B5A0B7D216E3D20002C4160 /* AttachmentProvider.swift in Sources */, 26C0C1E72073DABB00C530DA /* DateExtensions.swift in Sources */, 26A8561E2074C38F00C642EA /* NavigationView.swift in Sources */, + 4BB5921C21B9332C001FB393 /* Message+SeenBy.swift in Sources */, 359EB2571F9A1E5000147437 /* BaseMQTTModel.swift in Sources */, A42CE5FE20692EDB000889CC /* Test_Spec.swift in Sources */, A42CE58C20692EDB000889CC /* sequenceFlow.swift in Sources */, @@ -16569,6 +16586,7 @@ FEA655CE2167777E00B44029 /* SeedVerificationWalletCollectionViewCell.swift in Sources */, 8E6C4BE81FFB9B23009C8374 /* RoundProgressIndicator.swift in Sources */, 3D7B572828F83EAFEDA78CEA /* MapViewController.swift in Sources */, + 4BB5921A21B93323001FB393 /* Message+SeenBy.swift in Sources */, 54FFFD58388E2B660C1E5A05 /* MapPresenter.swift in Sources */, A42D52D6206A53AB00EEB952 /* serviceTask_Spec.swift in Sources */, 0AB08BA89A51118248FA3233 /* MapInteractor.swift in Sources */, @@ -17004,6 +17022,8 @@ 8513F072218D0753003B901B /* BERTEncodable.swift in Sources */, A4CB153B21039C1100C3B68B /* JailbreakDetectorProtocol.swift in Sources */, 4B8C05952164A9D60034D8F3 /* ChatCellModelMock.swift in Sources */, + 4BB5921B21B9332C001FB393 /* Message+SeenBy.swift in Sources */, + 4BB5921721B93022001FB393 /* MessageTests.swift in Sources */, 85458D01212D7C1A00BA8814 /* StringAtomExtension.swift in Sources */, A4AB8E522105EC46005F9B0C /* TextField.swift in Sources */, 85458D00212D7C0C00BA8814 /* Int+AnyObject.swift in Sources */, diff --git a/Nynja/Services/Debug/LogService/LogService/LogService.swift b/Nynja/Services/Debug/LogService/LogService/LogService.swift index 8edabeee9..f7468bc35 100644 --- a/Nynja/Services/Debug/LogService/LogService/LogService.swift +++ b/Nynja/Services/Debug/LogService/LogService/LogService.swift @@ -18,7 +18,7 @@ final class LogService: LogServiceProtocol { .system, .network, .galery, .videoConverter, .QRCode, .passphrase, .connectionState] - private static let backgroundQueue = DispatchQueue(label:"logQueue",qos:.background) + private static let backgroundQueue = DispatchQueue(label: "logQueue", qos: .background) static func log(topic: LogServiceTopic, block: (() -> String)?) { diff --git a/NynjaUnitTests/Models/MessageTests.swift b/NynjaUnitTests/Models/MessageTests.swift new file mode 100644 index 000000000..6f0442d99 --- /dev/null +++ b/NynjaUnitTests/Models/MessageTests.swift @@ -0,0 +1,44 @@ +// +// MessageTests.swift +// NynjaUnitTests +// +// Created by Volodymyr Hryhoriev on 12/6/18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +import XCTest + +class MessageTests: XCTestCase { + + func testIsSeenByAll() { + assert(seenBy: nil, rosterId: 123, expectedResult: true) + } + + func testIsSeenByNone() { + assert(seenBy: [0], rosterId: 123, expectedResult: false) + } + + func testIsSeenByMe() { + assert(seenBy: [1, 12, 123], rosterId: 123, expectedResult: true) + assert(seenBy: [-1, -12, -13], rosterId: 123, expectedResult: true) + } + + func testIsSeenByNotMe() { + assert(seenBy: [1, 12], rosterId: 123, expectedResult: false) + assert(seenBy: [-1, -123, -13], rosterId: 123, expectedResult: false) + } + + private func assert(seenBy: [Int64]?, rosterId: Int64, expectedResult: Bool) { + let message = makeMessage(seenBy: seenBy) + + let result = message.isSeenBy(rosterId: rosterId) + + XCTAssertEqual(result, expectedResult) + } + + private func makeMessage(seenBy: [Int64]?) -> Message { + let message = Message() + message.seenby = seenBy + return message + } +} diff --git a/Shared/Library/Extensions/Models/Message/Message+SeenBy.swift b/Shared/Library/Extensions/Models/Message/Message+SeenBy.swift new file mode 100644 index 000000000..c43eb5cc3 --- /dev/null +++ b/Shared/Library/Extensions/Models/Message/Message+SeenBy.swift @@ -0,0 +1,46 @@ +// +// Message+SeenBy.swift +// Nynja +// +// Created by Volodymyr Hryhoriev on 12/6/18. +// Copyright © 2018 TecSynt Solutions. All rights reserved. +// + +extension Message { + + var isDeletedForAll: Bool { + guard let seenBy = seenby else { + return false + } + return seenBy.contains(0) + } + + func isSeenBy(rosterId: Int64) -> Bool { + guard let seenBy = seenby, let firstRosterId = seenBy.first else { + return true + } + + if firstRosterId > 0, seenBy.contains(rosterId) { + return true + } else if firstRosterId < 0, !seenBy.contains(-rosterId) { + return true + } else { + return false + } + } + + func addDeletedLocalStatusIfNeeded(rosterId: Int64) { + guard !isSeenBy(rosterId: rosterId) else { + return + } + + let localStatus: LocalStatus + if let status = self.localStatus { + localStatus = status.union(.deleted) + } else { + localStatus = .deleted + } + + self.localStatus = localStatus + } +} diff --git a/Shared/Library/Extensions/Models/Message/MessageExtension.swift b/Shared/Library/Extensions/Models/Message/MessageExtension.swift index 3118b8ce8..44d288a25 100644 --- a/Shared/Library/Extensions/Models/Message/MessageExtension.swift +++ b/Shared/Library/Extensions/Models/Message/MessageExtension.swift @@ -55,38 +55,6 @@ extension Message { var payload: String? { return files?.first?.payload } - - var isDeletedForAll: Bool { - guard let seenBy = seenby else { - return false - } - return seenBy.contains(0) - } - - func isSeenBy(rosterId: Int64) -> Bool { - guard let seenBy = seenby else { - return true - } - - let isInSeenBySet = seenBy.contains(rosterId) - let isInNotSeenBySet = !seenBy.contains(-rosterId) - return isInSeenBySet && isInNotSeenBySet - } - - func addDeletedLocalStatusIfNeeded(rosterId: Int64) { - guard !isSeenBy(rosterId: rosterId) else { - return - } - - let localStatus: LocalStatus - if let status = self.localStatus { - localStatus = status.union(.deleted) - } else { - localStatus = .deleted - } - - self.localStatus = localStatus - } } // MARK: - Actions -- GitLab From 147cc8611a6380ff66ef0b2870836b060815f036 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Thu, 6 Dec 2018 16:49:59 +0200 Subject: [PATCH 55/59] Temp. --- Nynja/DB/Models/DBMessage.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Nynja/DB/Models/DBMessage.swift b/Nynja/DB/Models/DBMessage.swift index 426d146b8..584391684 100644 --- a/Nynja/DB/Models/DBMessage.swift +++ b/Nynja/DB/Models/DBMessage.swift @@ -60,6 +60,11 @@ final class DBMessage: Record, DBModel { self.seenBy = message.seenby?.joinedByComma() self.status = message.statusString + + if let rosterId = StorageService.sharedInstance.rosterId { + message.addDeletedLocalStatusIfNeeded(rosterId: rosterId) + } + self.localStatus = message.localStatus self.isTrusted = message.isTrusted -- GitLab From 7787d364ab4390d264cee5a6e47c5b636c659c1a Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Thu, 6 Dec 2018 18:59:20 +0200 Subject: [PATCH 56/59] Ignore message which is not seen by me. --- .../HandleServices/MessageHandler.swift | 20 +++---------------- Nynja/Services/PushService.swift | 4 ---- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/Nynja/Services/HandleServices/MessageHandler.swift b/Nynja/Services/HandleServices/MessageHandler.swift index c67d824a8..10954aee5 100644 --- a/Nynja/Services/HandleServices/MessageHandler.swift +++ b/Nynja/Services/HandleServices/MessageHandler.swift @@ -152,7 +152,6 @@ final class MessageHandler: BaseHandler { .flatMap { try? MessageDAO.messageExists(serverId: $0) } ?? false updateReaderWhenSaving(message: message) - updateLocalStatus(message: message) try? save(message) @@ -186,25 +185,12 @@ final class MessageHandler: BaseHandler { } } - private static func updateLocalStatus(message: Message) { - guard let rosterId = storageService.rosterId else { - return - } - - message.addDeletedLocalStatusIfNeeded(rosterId: rosterId) - } - private static func shouldSkipMessage(_ message: Message) -> Bool { - if let desc = message.files?.first, - desc.mime == SendMessageType.audioCall.rawValue, - desc.data?.first?.key == FeatureKeys.File.Call.users.rawValue, - let ids = desc.data?.first?.value?.splitByComma(), - !ids.contains { $0 == storageService.phoneId } { - - return true + guard let rosterId = storageService.rosterId else { + return false } - return false + return !message.isSeenBy(rosterId: rosterId) } private static func save(_ message: Message) throws { diff --git a/Nynja/Services/PushService.swift b/Nynja/Services/PushService.swift index 2f78bf60e..4d2cd6877 100644 --- a/Nynja/Services/PushService.swift +++ b/Nynja/Services/PushService.swift @@ -292,10 +292,6 @@ final class PushService: NSObject, PKPushRegistryDelegate, UserSettingsRespondab if message.messageStatus == .clear { ChatService.clearMessages(before: message) } - - if let rosterId = storageService.rosterId { - message.addDeletedLocalStatusIfNeeded(rosterId: rosterId) - } } private func sendNewNotification(title: String, sound: String?, id: String, data: [AnyHashable: Any]) { -- GitLab From dc3ae36af5a204654cc2b03b0f1fc2297a6013d4 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Thu, 6 Dec 2018 20:52:28 +0200 Subject: [PATCH 57/59] Remove `send call message`. --- Nynja/Library/MessageFactory/MessageFactory.swift | 8 -------- .../MessageFactory/MessageFactoryProtocol.swift | 2 -- .../Interactor/CallInProgressInteractor.swift | 13 ------------- 3 files changed, 23 deletions(-) diff --git a/Nynja/Library/MessageFactory/MessageFactory.swift b/Nynja/Library/MessageFactory/MessageFactory.swift index 3960d1452..e82f109ed 100644 --- a/Nynja/Library/MessageFactory/MessageFactory.swift +++ b/Nynja/Library/MessageFactory/MessageFactory.swift @@ -239,14 +239,6 @@ final class MessageFactory: MessageFactoryProtocol, InitializeInjectable { return message } - func makeCallMessage(members: [String], room: Room?) -> Message { - let descMimes = [DescMime.call(members: members)] - let descs = descMimes.map { Desc(mime: $0) } - let phoneId = storageService.phoneId - - return makeMessage(descs: descs, phoneId: phoneId, contact: nil, room: room) - } - func makeMessageForDelete(message: Message, seenBy: [Int64]) -> Message { let message = Message(message: message) message.from = storageService.phoneId diff --git a/Nynja/Library/MessageFactory/MessageFactoryProtocol.swift b/Nynja/Library/MessageFactory/MessageFactoryProtocol.swift index f605a7f4e..384e6636e 100644 --- a/Nynja/Library/MessageFactory/MessageFactoryProtocol.swift +++ b/Nynja/Library/MessageFactory/MessageFactoryProtocol.swift @@ -38,8 +38,6 @@ protocol MessageFactoryProtocol: class { func makePaymentMessage(inputText: String, contact: Contact, notes: String?) -> Message - func makeCallMessage(members: [String], room: Room?) -> Message - func makeMessageForDelete(message: Message, seenBy: [Int64]) -> Message } diff --git a/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift b/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift index aeca6525f..ab50e5a04 100644 --- a/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift +++ b/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift @@ -375,19 +375,6 @@ class CallInProgressInteractor: CallInProgressInteractorInputProtocol, NynjaCall } } - func conferenceCreated(call: NYNCall) { - sendCall(ncall: call) - } - - func sendCall(ncall: NYNCall) { - let room = Room() - room.id = ncall.externalInfo - let membersIds = ncall.participants.map({ $0.address ?? "" }) - let message = messageFactory.makeCallMessage(members: membersIds, room: room) - try? storageService.perform(action: .save, with: message) - messageSendingService.sendMessage(message) - } - func updateGroupCall(contacts: [Contact]) { if let ncall = self.nynCall { -- GitLab From aecfbe2f81324650983de8cbfe6d778d990e0d0e Mon Sep 17 00:00:00 2001 From: Volodymyr Hryhoriev Date: Fri, 7 Dec 2018 17:44:41 +0200 Subject: [PATCH 58/59] Increment `ModelsVersion` for `NynjaSpotify` scheme. --- Nynja/Resources/SpotifyConfig.xcconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nynja/Resources/SpotifyConfig.xcconfig b/Nynja/Resources/SpotifyConfig.xcconfig index c3018ac85..cad86f017 100644 --- a/Nynja/Resources/SpotifyConfig.xcconfig +++ b/Nynja/Resources/SpotifyConfig.xcconfig @@ -14,7 +14,7 @@ AppName = NYNJASpot ServerPort = 1883 Config = spotify AppGroup = group.com.nynja.mobile.communicator.loc -ModelsVersion = 10 +ModelsVersion = 11 isServerConnectionSecure = false ConfServerAddress = 18.197.109.137 ConfServerPort = 80 -- GitLab From 4bdd8123fe12085677eb6d80199707723f9400b3 Mon Sep 17 00:00:00 2001 From: Angel Terziev Date: Wed, 12 Dec 2018 15:03:56 +0200 Subject: [PATCH 59/59] Fixed seenBy logic for call bubbles --- .../Interactor/MessageInteractor+Fetch.swift | 26 ++++--------------- Nynja/Resources/SpotifyConfig.xcconfig | 8 +++--- 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift b/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift index aa8283b2c..269dcb192 100644 --- a/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift +++ b/Nynja/Modules/Message/Interactor/MessageInteractor+Fetch.swift @@ -94,30 +94,14 @@ extension MessageInteractor { } private func fetchMessagesFromStorage(feed: Feed) -> [Message] { + guard let rosterId = storageService.rosterId else { + return MessageDAO.fetchMessages(feed: feed) + } + return MessageDAO .fetchMessages(feed: feed) .filter { message in - guard let desc = message.files?.first, - desc.mime == SendMessageType.audioCall.rawValue || - desc.mime == SendMessageType.videoCall.rawValue else { - return true - } - - guard let seenBy = message.seenby else { - return true - } - - guard let phoneId = storageService.phoneId else { - return false - } - - return seenBy.contains { - guard let sid = $0 as? String else { - return false - } - - return sid == phoneId - } + return message.isSeenBy(rosterId: rosterId) } } diff --git a/Nynja/Resources/SpotifyConfig.xcconfig b/Nynja/Resources/SpotifyConfig.xcconfig index 13ce40d9e..2c595357c 100644 --- a/Nynja/Resources/SpotifyConfig.xcconfig +++ b/Nynja/Resources/SpotifyConfig.xcconfig @@ -9,14 +9,14 @@ BundleIdentifier = com.nynja.loc.mobile.communicator ExtensionBundleIdentifier = com.nynja.loc.mobile.communicator.NynjaShare -ServerURL = im-fallback.dev-eu.nynja.net -AppName = NYNJASPA -ServerPort = 8443 +ServerURL = seenby.ci.nynja.net +AppName = NYNJASeen +ServerPort = 1883 Config = spotify AppGroup = group.com.nynja.mobile.communicator.loc ModelsVersion = 11 isServerConnectionSecure = false -ConfServerAddress = 18.197.109.137 +ConfServerAddress = dev.awsjvb.lastviking.eu ConfServerPort = 80 ConfServerSecure = false AssociatedDomain = applinks:join.dev-eu.nynja.net -- GitLab