diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..b05092af3af7aed3fd1c8784caf6f2621c9c1c6b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,8 @@ +[submodule "Mobile-SDK-S3"] + path = externals/mobile-sdk-ext + url = https://github.com/NYNJA-MC/Mobile-SDK.git + branch = sprint3 +[submodule "Mobile-SDK-S4"] + path = externals/mobile-sdk-s4 + url = https://github.com/NYNJA-MC/Mobile-SDK.git + branch = sprint4 diff --git a/Frameworks/NynjaUIKit/NynjaUIKit.xcodeproj/project.pbxproj b/Frameworks/NynjaUIKit/NynjaUIKit.xcodeproj/project.pbxproj index d227aa9667c4a83d7a6505aa14378e2c445a08ab..3cfbcb64137cf551dc6c197081c2586a5e8ebc26 100644 --- a/Frameworks/NynjaUIKit/NynjaUIKit.xcodeproj/project.pbxproj +++ b/Frameworks/NynjaUIKit/NynjaUIKit.xcodeproj/project.pbxproj @@ -328,6 +328,7 @@ 8514D4BD20EE27080002378A /* Frameworks */, 8514D4BE20EE27080002378A /* Headers */, 8514D4BF20EE27080002378A /* Resources */, + 46657F61D06BBC36D9E1E7E9 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -380,6 +381,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 46657F61D06BBC36D9E1E7E9 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/../../Pods/Target Support Files/Pods-NynjaUIKit/Pods-NynjaUIKit-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 79BB170804CAF73DF4C1F030 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/Nynja.xcodeproj/project.pbxproj b/Nynja.xcodeproj/project.pbxproj index 3aa8a8d1b4ed386dc4ec078a3dd690c9a71fd0ca..8666269d0aa64c28f52a50ebb707c16ca8be8956 100644 --- a/Nynja.xcodeproj/project.pbxproj +++ b/Nynja.xcodeproj/project.pbxproj @@ -51,7 +51,6 @@ 0062D94E2062EDB000B915AC /* InviteFriendsItemsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0062D94D2062EDAF00B915AC /* InviteFriendsItemsFactory.swift */; }; 0070FB0004EFB510C3409746 /* AddContactByUsernamePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505C687860C446A37E2FE4FF /* AddContactByUsernamePresenter.swift */; }; 00772A49F4B53A5EB669E8F2 /* AddParticipantsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9BA5392968EF1C9E844C927 /* AddParticipantsInteractor.swift */; }; - 00BB79AE09C68C716BF81645 /* CallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE839D7AC2C332E0234BC166 /* CallViewController.swift */; }; 00D7B5C720285BA7004B0E2B /* ScheduleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00D7B5C620285BA7004B0E2B /* ScheduleView.swift */; }; 00E4A65F201A287100CEC61F /* MapSearchDS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00E4A65E201A287100CEC61F /* MapSearchDS.swift */; }; 00E8513B2021E96E007DC792 /* GApiResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00E8513A2021E96E007DC792 /* GApiResponse.swift */; }; @@ -436,7 +435,6 @@ 2CB54DD94DA23D7160F36472 /* SecurityWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48276F2EE408C27334B2894C /* SecurityWireframe.swift */; }; 2F2A5C12A7202E7834F923DC /* GroupRulesWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 520422E90094C6C267AECE7E /* GroupRulesWireframe.swift */; }; 2F7C7F7837BDE6F5767A3A8C /* GroupStorageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D5302025583482829BBF2E /* GroupStorageViewController.swift */; }; - 314D0EEBF8C227FD046D43BA /* CallWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C0974A63763BCB33814FC7A /* CallWireframe.swift */; }; 3219C8F242591BA17953FF33 /* SecurityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F509C0C8B9C738DBC7ABE07 /* SecurityViewController.swift */; }; 32868DD51F31CADF0028B260 /* ChatsListProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32868DD41F31CADF0028B260 /* ChatsListProtocols.swift */; }; 32868DDB1F31CB500028B260 /* ChatsListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32868DDA1F31CB500028B260 /* ChatsListViewController.swift */; }; @@ -574,7 +572,6 @@ 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 */; }; 4B5A714D204F069000A551F5 /* ChatService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A714C204F069000A551F5 /* ChatService.swift */; }; - 4B6AA4B1F92A45DB56BDC44C /* CallProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12456F574C62670B98C16E4B /* CallProtocols.swift */; }; 4B736D4720237C140028F2CB /* CGSizeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269D9DEF1FC3AF0D00324263 /* CGSizeExtension.swift */; }; 4B736D4920238FA40028F2CB /* ThumbnailGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B736D4820238FA40028F2CB /* ThumbnailGenerator.swift */; }; 4B7B81C62044790700C2EFCF /* TimeZoneLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7B81C52044790700C2EFCF /* TimeZoneLocal.swift */; }; @@ -605,7 +602,6 @@ 4D53FE7454959323B1CCFD96 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D270F638DBB2D8FC1BDEB633 /* ProfileViewController.swift */; }; 4DAEBCF361B86B0AD3C98749 /* EditUsernameInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE3BAC9B7EA418FB463EF04 /* EditUsernameInteractor.swift */; }; 50960A9A3A3E544A494B4642 /* EditPhotoProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F09BDC006C92CF84A481E /* EditPhotoProtocols.swift */; }; - 52720EA907F60135673F1A46 /* CallPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5373874E1CD82B33214ED96 /* CallPresenter.swift */; }; 54FFFD58388E2B660C1E5A05 /* MapPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10E04C696850BAF082139AAD /* MapPresenter.swift */; }; 553819525871F7D28AB90364 /* GroupRulesPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 705B62097A99515B3C778F35 /* GroupRulesPresenter.swift */; }; 5683555B8382F7F37FEE1AF5 /* ProfileWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BA66D21FFC1A74CFD2F63C4 /* ProfileWireframe.swift */; }; @@ -646,7 +642,6 @@ 6D5157D01F30B36A002A27DB /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D5157CF1F30B36A002A27DB /* ChatView.swift */; }; 6D5157D21F30B822002A27DB /* MicrophoneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D5157D11F30B822002A27DB /* MicrophoneView.swift */; }; 6D5168A21F30430900DA3728 /* SpeakerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D5168A11F30430900DA3728 /* SpeakerView.swift */; }; - 6D5168A41F30638400DA3728 /* CallInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D5168A31F30638400DA3728 /* CallInteractor.swift */; }; 6D56F2101F39FC6A00CBF56D /* AmazonManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D56F20F1F39FC6A00CBF56D /* AmazonManager.swift */; }; 6D6234F61F1E150600EF375F /* HistoryTableDS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6234F51F1E150600EF375F /* HistoryTableDS.swift */; }; 6D6234F81F1E158600EF375F /* HistoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6234F71F1E158600EF375F /* HistoryCell.swift */; }; @@ -2142,7 +2137,6 @@ 0E7F09BDC006C92CF84A481E /* EditPhotoProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EditPhotoProtocols.swift; sourceTree = ""; }; 0FF56F6F8D90FB98A6B42971 /* EditGroupNameInteractor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EditGroupNameInteractor.swift; sourceTree = ""; }; 10E04C696850BAF082139AAD /* MapPresenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MapPresenter.swift; sourceTree = ""; }; - 12456F574C62670B98C16E4B /* CallProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CallProtocols.swift; sourceTree = ""; }; 1457809A715A3526EBF39205 /* MainViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 1746BDC1030434814FE63E0A /* DateTimePickerPresenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DateTimePickerPresenter.swift; sourceTree = ""; }; 17B34E74A0246B17348E9597 /* Pods-Nynja.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Nynja.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Nynja/Pods-Nynja.debug.xcconfig"; sourceTree = ""; }; @@ -2617,7 +2611,6 @@ 6D5157CF1F30B36A002A27DB /* ChatView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatView.swift; sourceTree = ""; }; 6D5157D11F30B822002A27DB /* MicrophoneView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MicrophoneView.swift; sourceTree = ""; }; 6D5168A11F30430900DA3728 /* SpeakerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpeakerView.swift; sourceTree = ""; }; - 6D5168A31F30638400DA3728 /* CallInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallInteractor.swift; sourceTree = ""; }; 6D56F20F1F39FC6A00CBF56D /* AmazonManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AmazonManager.swift; sourceTree = ""; }; 6D5A57913B84E0665E3ABC0E /* EditGroupPhotoPresenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EditGroupPhotoPresenter.swift; sourceTree = ""; }; 6D6234F51F1E150600EF375F /* HistoryTableDS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HistoryTableDS.swift; sourceTree = ""; }; @@ -2635,7 +2628,6 @@ 718EF22D86A9656BB6ED89D5 /* Pods-Nynja.translate.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Nynja.translate.xcconfig"; path = "Pods/Target Support Files/Pods-Nynja/Pods-Nynja.translate.xcconfig"; sourceTree = ""; }; 7625A2CFF245BC8A47701724 /* AddParticipantsPresenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AddParticipantsPresenter.swift; sourceTree = ""; }; 762BA232B5D027BD943DFA18 /* SecurityPresenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SecurityPresenter.swift; sourceTree = ""; }; - 7C0974A63763BCB33814FC7A /* CallWireframe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CallWireframe.swift; sourceTree = ""; }; 7C19AFE8E64821851F4112EE /* ProfileProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ProfileProtocols.swift; sourceTree = ""; }; 7C2CBB5F32D209160D00F744 /* CreateGroupViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CreateGroupViewController.swift; sourceTree = ""; }; 7CFD3063186FFCB048E843FD /* SelectCountryViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SelectCountryViewController.swift; sourceTree = ""; }; @@ -3721,7 +3713,6 @@ F1EED41420C57C30001060C4 /* PhotoPreviewSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoPreviewSource.swift; sourceTree = ""; }; F1F219FC7966064C555AC2A4 /* TopUpAccountViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TopUpAccountViewController.swift; sourceTree = ""; }; F46A5D92A279FA0A509DA508 /* Pods-NynjaUnitTests.translate.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NynjaUnitTests.translate.xcconfig"; path = "Pods/Target Support Files/Pods-NynjaUnitTests/Pods-NynjaUnitTests.translate.xcconfig"; sourceTree = ""; }; - F5373874E1CD82B33214ED96 /* CallPresenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CallPresenter.swift; sourceTree = ""; }; F56141F2CF85255940EA304F /* EditPhotoWireframe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EditPhotoWireframe.swift; sourceTree = ""; }; F79C9355E1AA4B373567F765 /* LanguageSettingsInteractor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LanguageSettingsInteractor.swift; sourceTree = ""; }; F96FD91024D36848A4A4277C /* AddContactViaPhoneProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AddContactViaPhoneProtocols.swift; sourceTree = ""; }; @@ -3775,7 +3766,6 @@ FE2D7CCC211C71AD00520D78 /* WalletService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletService.swift; sourceTree = ""; }; FE58F9B0208F00FE004AFDD3 /* MessageEditActionTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageEditActionTable.swift; sourceTree = ""; }; FE58F9B2208F0583004AFDD3 /* DBMessageEditAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DBMessageEditAction.swift; sourceTree = ""; }; - FE839D7AC2C332E0234BC166 /* CallViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CallViewController.swift; sourceTree = ""; }; FE9E70CF21175DDC0034067A /* ChatScreenAlertFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatScreenAlertFactory.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -8376,7 +8366,6 @@ A33FA59FE338E9660AB10CD1 /* Presenter */ = { isa = PBXGroup; children = ( - F5373874E1CD82B33214ED96 /* CallPresenter.swift */, ); path = Presenter; sourceTree = ""; @@ -9771,7 +9760,6 @@ A4D0787972A19641165C28B6 /* WireFrame */ = { isa = PBXGroup; children = ( - 7C0974A63763BCB33814FC7A /* CallWireframe.swift */, ); path = WireFrame; sourceTree = ""; @@ -9800,7 +9788,6 @@ A895793051E246613AC4F30F /* View */ = { isa = PBXGroup; children = ( - FE839D7AC2C332E0234BC166 /* CallViewController.swift */, 6D67310F1F29E1F4003E8F8F /* BottomCallView.swift */, 6D5168A11F30430900DA3728 /* SpeakerView.swift */, 6D5157CF1F30B36A002A27DB /* ChatView.swift */, @@ -9969,7 +9956,6 @@ 9BD8E3EC20EF7776001384EC /* CallScreens */, 5BC1D38320D3B670002A44B3 /* CallCreatorMediator.swift */, 9BC9657520FF042D00052AE1 /* CallInProgressProtocols.swift */, - 12456F574C62670B98C16E4B /* CallProtocols.swift */, A895793051E246613AC4F30F /* View */, A33FA59FE338E9660AB10CD1 /* Presenter */, D6365C3D94F0150AFA59F586 /* Interactor */, @@ -10234,7 +10220,6 @@ D6365C3D94F0150AFA59F586 /* Interactor */ = { isa = PBXGroup; children = ( - 6D5168A31F30638400DA3728 /* CallInteractor.swift */, ); path = Interactor; sourceTree = ""; @@ -12193,6 +12178,7 @@ 3578099F1F9765CF00C9680C /* Sources */, 357809A01F9765CF00C9680C /* Frameworks */, 357809A11F9765CF00C9680C /* Resources */, + 61CA315D0DB89815DE10E66F /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -12460,6 +12446,21 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + 61CA315D0DB89815DE10E66F /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Nynja-Share/Pods-Nynja-Share-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 6A031053FD7153DBCCD6098C /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -13654,7 +13655,6 @@ C9C695032022306D00A57297 /* SelectCountryTableDataSource.swift in Sources */, 8584C90F20920F3C001A0BBB /* StickerGridCellModel.swift in Sources */, A42D51A4206A361400EEB952 /* Feature.swift in Sources */, - 6D5168A41F30638400DA3728 /* CallInteractor.swift in Sources */, 260552A61F9E1CD100D68DE6 /* SearchHandler.swift in Sources */, F1607B1F20B21A9D00BDF60A /* CameraViewController.swift in Sources */, 853E595B20D71E6C007799B9 /* StickerPack+DB.swift in Sources */, @@ -14055,7 +14055,6 @@ 4BAB9CE02035CAE700385520 /* ScheduleInfo.swift in Sources */, 8ECC067E1FC5BCC6002CF225 /* TransferManager.swift in Sources */, A42D52B2206A53AA00EEB952 /* Cursor_Spec.swift in Sources */, - 4B6AA4B1F92A45DB56BDC44C /* CallProtocols.swift in Sources */, E76D13311FA35F3500B07F0E /* TextCellModel.swift in Sources */, E734831C1F9F53050090A4DB /* ProfileViewSectionDelegate.swift in Sources */, F10AFEB720F7B1B000C7CE83 /* WheelMediaFullItemPreview.swift in Sources */, @@ -14063,14 +14062,12 @@ F105C69D209F71BF0091786A /* CameraWireframe.swift in Sources */, A458FABF20EB8BB50075D55E /* MessageInteractor+ChannelActions.swift in Sources */, 26CD3FDD2104D1DD00597E62 /* AudioConvertionOperation.swift in Sources */, - 00BB79AE09C68C716BF81645 /* CallViewController.swift in Sources */, 8514F17C20EA219F00883513 /* ContextMenuConfiguration.swift in Sources */, FBCE840D20E525A6003B7558 /* HTTPResponseResult.swift in Sources */, A43B259F20AB1DFA00FF8107 /* PickerCell.swift in Sources */, 2661D12E1F373D1700F3E125 /* BadgeView.swift in Sources */, F10B0E1F20B4CC5400528E7A /* CameraSettingsCoordinator.swift in Sources */, F119E67920D27EA50043A532 /* VideoPreviewCVCell.swift in Sources */, - 52720EA907F60135673F1A46 /* CallPresenter.swift in Sources */, 8502DB542061030100613C8C /* WheelPositionPickerViewController.swift in Sources */, A45F116120B422AF00F45004 /* Message+System.swift in Sources */, FBCE83E020E52496003B7558 /* ContactServices.swift in Sources */, @@ -14081,7 +14078,6 @@ 85433F2C204D5AA500B373A7 /* NynjaCloseButton.swift in Sources */, A44B4D5A20CE9BDF00CA700A /* SwitchCell.swift in Sources */, F1607B3020B2FD5A00BDF60A /* QRNotificationVIew.swift in Sources */, - 314D0EEBF8C227FD046D43BA /* CallWireframe.swift in Sources */, 260313A420A0A4BA009AC66D /* DirectableActionCellViewModel.swift in Sources */, 859773232087965700B03B4A /* NynjaControlContainerView.swift in Sources */, E743B58A1FB0911200F72F92 /* ParticipantsContactCell.swift in Sources */, @@ -15104,7 +15100,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = "Nynja-Share/Resources/Nynja-Share.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Manual; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 9GKQ5AMF2B; @@ -15116,8 +15112,8 @@ OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" -DSHARE_EXTENSION"; PRODUCT_BUNDLE_IDENTIFIER = "$(ExtensionBundleIdentifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = "99725127-a6e8-4f22-98eb-18164dfae6db"; - PROVISIONING_PROFILE_SPECIFIER = DevBundle_AdHocExt; + PROVISIONING_PROFILE = "3d8b88dd-22c4-457b-864c-32d6378f5f64"; + PROVISIONING_PROFILE_SPECIFIER = DevBundle_DevExt; SKIP_INSTALL = YES; SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -15279,7 +15275,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Nynja/Resources/Nynja.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Manual; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 9GKQ5AMF2B; @@ -15289,8 +15285,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "$(BundleIdentifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = "50dd2a41-0a8c-4a0a-a8b9-744fa4bf3bb4"; - PROVISIONING_PROFILE_SPECIFIER = DevBundle_adhoc; + PROVISIONING_PROFILE = "8a9243cd-515b-4739-b9d6-f73ba97c3403"; + PROVISIONING_PROFILE_SPECIFIER = DevBundle_Dev; SWIFT_OBJC_BRIDGING_HEADER = "Nynja-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; diff --git a/Nynja/Modules/AddParticipants/AddParticipantsProtocols.swift b/Nynja/Modules/AddParticipants/AddParticipantsProtocols.swift index 00dd6bad42094ecba02aec7f1452c4494c0dcb0a..98cd7d6406bc31278b0727b5ce1a5d9c58ec3899 100644 --- a/Nynja/Modules/AddParticipants/AddParticipantsProtocols.swift +++ b/Nynja/Modules/AddParticipants/AddParticipantsProtocols.swift @@ -40,7 +40,7 @@ protocol AddParticipantsViewProtocol: class { func updateParticipantsList(_ participants: GroupedParticipants) } -protocol AddParticipantsPresenterProtocol: BasePresenterProtocol { +protocol AddParticipantsPresenterProtocol: BasePresenterProtocol, NavigationProtocol { var view: AddParticipantsViewProtocol! { get set } var interactor: AddParticipantsInteractorInputProtocol! { get set } diff --git a/Nynja/Modules/AddParticipants/Presenter/AddParticipantsPresenter.swift b/Nynja/Modules/AddParticipants/Presenter/AddParticipantsPresenter.swift index 66579585c28dccbc4afb05f139c5d14cc9a70f55..bfca0fb1c3e3b5e8cd8c87633bc3671025984153 100644 --- a/Nynja/Modules/AddParticipants/Presenter/AddParticipantsPresenter.swift +++ b/Nynja/Modules/AddParticipants/Presenter/AddParticipantsPresenter.swift @@ -117,6 +117,12 @@ class AddParticipantsPresenter: BasePresenter, AddParticipantsPresenterProtocol, } } } + + // MARK: NavigationProtocol + func back() { + let arr:[Contact] = [] + hide(with: arr) + } // MARK: - AddParticipantsInteractorOutputProtocol diff --git a/Nynja/Modules/AddParticipants/View/AddParticipantsViewController.swift b/Nynja/Modules/AddParticipants/View/AddParticipantsViewController.swift index 312e4140651fc7812f2730715cc7e47806d0cec3..3fba25e6885c23418c7742effbd86f57b1d49c61 100644 --- a/Nynja/Modules/AddParticipants/View/AddParticipantsViewController.swift +++ b/Nynja/Modules/AddParticipants/View/AddParticipantsViewController.swift @@ -8,7 +8,7 @@ import UIKit -class AddParticipantsViewController: BaseVC, AddParticipantsViewProtocol, NavigationProtocol { +class AddParticipantsViewController: BaseVC, AddParticipantsViewProtocol { var presenter: AddParticipantsPresenterProtocol! { didSet { @@ -148,7 +148,6 @@ class AddParticipantsViewController: BaseVC, AddParticipantsViewProtocol, Naviga var title:String = "" var backBtnImage:UIImage? = nil - var selectAllBtnImage:UIImage? = nil var navHandler:NavigationProtocol? = nil if presenter.participantsMode == .delete { @@ -156,21 +155,18 @@ class AddParticipantsViewController: BaseVC, AddParticipantsViewProtocol, Naviga } else if presenter.participantsMode == .createGroupCall { title = "add_members_to_call".localized.uppercased() backBtnImage = UIImage(named:"ic_close_clear") - selectAllBtnImage = UIImage(named:"ic_unchecked") - navHandler = self + navHandler = presenter self.selectAllButtonVisible = true } else if presenter.participantsMode == .updateGroupCall { title = "add_members_to_call".localized.uppercased() backBtnImage = UIImage(named:"ic_close_clear") - selectAllBtnImage = UIImage(named:"ic_unchecked") - navHandler = self + navHandler = presenter self.selectAllButtonVisible = true } else if presenter.participantsMode == .createConferenceCall { - title = "add_members_to_call".localized.uppercased() title = "add_members_to_call".localized.uppercased() backBtnImage = UIImage(named:"ic_close_clear") - selectAllBtnImage = UIImage(named:"ic_unchecked") - navHandler = self + navHandler = presenter + self.selectAllButtonVisible = true } else if presenter.participantsMode == .admins { title = "admins".localized.uppercased() } else { @@ -203,10 +199,13 @@ class AddParticipantsViewController: BaseVC, AddParticipantsViewProtocol, Naviga doneButton.setTitle("delete".localized.uppercased(), for: .normal) } else if presenter.participantsMode == .createGroupCall { doneButton.setTitle("call".localized.uppercased(), for: .normal) + doneButton.setTitle("call".localized.uppercased(), for: .disabled) } else if presenter.participantsMode == .createConferenceCall { doneButton.setTitle("call".localized.uppercased(), for: .normal) + doneButton.setTitle("call".localized.uppercased(), for: .disabled) } else if presenter.participantsMode == .updateGroupCall { doneButton.setTitle("done".localized.uppercased(), for: .normal) + doneButton.setTitle("done".localized.uppercased(), for: .disabled) } else { doneButton.setTitle("done".localized.uppercased(), for: .normal) } @@ -214,6 +213,8 @@ class AddParticipantsViewController: BaseVC, AddParticipantsViewProtocol, Naviga doneButton.addTarget(self, action: #selector(doneTapped(_:)), for: .touchUpInside) setupTestingKeysInSubviews() + + updateDoneButtonState() } private func configureLists() { @@ -254,6 +255,13 @@ class AddParticipantsViewController: BaseVC, AddParticipantsViewProtocol, Naviga return layout } + + private func updateDoneButtonState() { + + if presenter.participantsMode == .createGroupCall || presenter.participantsMode == .updateGroupCall || presenter.participantsMode == .createConferenceCall { + doneButton.isEnabled = (participantsDataSource.selectedParticipants.count > 0) + } + } // MARK: - Actions @objc private func doneTapped(_ button: UIButton) { @@ -305,7 +313,7 @@ class AddParticipantsViewController: BaseVC, AddParticipantsViewProtocol, Naviga if sender.isSelected { participantsDataSource.selectedParticipants.append(contentsOf: participants) - + } } } @@ -338,6 +346,8 @@ class AddParticipantsViewController: BaseVC, AddParticipantsViewProtocol, Naviga avatarsView.reloadData() tableView.reloadData() + + updateDoneButtonState() } // MARK: - Keyboard @@ -376,12 +386,6 @@ class AddParticipantsViewController: BaseVC, AddParticipantsViewProtocol, Naviga tableView.reloadData() avatarsView.reloadData() } - - // MARK: NavigationProtocol - func back() { - let arr:[Contact] = [] - presenter.hide(with: arr) - } } // MARK: - AddParticipantsActionsDelegate @@ -395,6 +399,8 @@ extension AddParticipantsViewController: ParticipantsActionsDelegate { deselectParticipant(participant) tableView.reloadData() avatarsView.reloadData() + + updateDoneButtonState() } func participantTapped(_ participant: Participant) { @@ -421,6 +427,8 @@ extension AddParticipantsViewController: ParticipantsActionsDelegate { } avatarsView.reloadData() + + updateDoneButtonState() } private func deselectParticipant(_ participant: Participant) { diff --git a/Nynja/Modules/Call/CallInProgressProtocols.swift b/Nynja/Modules/Call/CallInProgressProtocols.swift index e80506a85b5f6efb490f2fb7e4fb3ab0722084f1..a3e92e39ce5d269143c10e41b2d4b1182925191e 100644 --- a/Nynja/Modules/Call/CallInProgressProtocols.swift +++ b/Nynja/Modules/Call/CallInProgressProtocols.swift @@ -20,6 +20,7 @@ protocol CallInProgressWireFrameProtocol: class { func messageActionWith(room:Room, isVideo: Bool) func updateCallParticipants() func showMenuWith(participant: NYNCallParticipant?, delegate: ManageCallInProgressParticipantsProtocol) + func callClosed() } protocol CallInProgressViewProtocol: class { @@ -37,6 +38,9 @@ protocol CallInProgressViewProtocol: class { func updateCallBy(status: CallStatus) func callFailed() func askEndOrLeave() + func didAddRemoteVideoStream() + func didStartLocalCapturer() + func didStopLocalCapturer() } protocol CallInProgressPresenterProtocol: class { @@ -70,6 +74,9 @@ protocol CallInProgressPresenterProtocol: class { func showMenuWith(groupCollectionCell: GroupCollectionViewCell) func endCall() func hangupCall() + func addRemoteVideoRenderer(inView view: UIView) + func attachLocalVideoPreview(inView view: UIView) + func dettachLocalVideoPreview(inView view: UIView) } protocol CallInProgressInteractorOutputProtocol: class { @@ -87,6 +94,9 @@ protocol CallInProgressInteractorOutputProtocol: class { func update(participants: [NYNCallParticipant]) func callFailed() func askEndOrLeave() + func didAddRemoteVideoStream() + func didStartLocalCapturer() + func didStopLocalCapturer() } protocol CallInProgressInteractorInputProtocol: class { @@ -94,6 +104,8 @@ protocol CallInProgressInteractorInputProtocol: class { var presenter: CallInProgressInteractorOutputProtocol! { get set } var call: VICall? { get set } var contact: Contact? { get } + var room: Room? { get } + /** * Add here your methods for communication PRESENTER -> INTERACTOR */ @@ -113,6 +125,9 @@ protocol CallInProgressInteractorInputProtocol: class { func removeCallMember(memberId: String) func endCall() func hangupCall() + func addRemoteVideoRenderer(inView view: UIView) + func attachLocalVideoPreview(inView view: UIView) + func detachLocalVideoPreview(inView view: UIView) } protocol ManageCallInProgressParticipantsProtocol: class { diff --git a/Nynja/Modules/Call/CallProtocols.swift b/Nynja/Modules/Call/CallProtocols.swift deleted file mode 100644 index df276ca62ca61ae62e99aa59cf1a312de3d15d97..0000000000000000000000000000000000000000 --- a/Nynja/Modules/Call/CallProtocols.swift +++ /dev/null @@ -1,118 +0,0 @@ -// -// CallCallProtocols.swift -// Nynja -// -// Created by Bohdan Paliychuk on 26/07/2017. -// Copyright © 2017 TecSynt Solutions. All rights reserved. -// - -import UIKit -import VoxImplant - -protocol CallWireFrameProtocol: class { - - func presentCall(navigation: UINavigationController, callMode: CallMode, contact: Contact, call: VICall?, main: MainWireFrame?) - - /** - * Add here your methods for communication PRESENTER -> WIREFRAME - */ - func messageAction(isVideo: Bool, contact: Contact) - func messageActionWith(room:Room, isVideo: Bool) - func updateCallParticipants() - func showMenuWith(participant: NYNCallParticipant?, delegate: ManageCallParticipantsProtocol) -} - -protocol CallViewProtocol: class { - - var presenter: CallPresenterProtocol! { get set } - - /** - * Add here your methods for communication PRESENTER -> VIEW - */ - func setupUI() - func updateTime(text: String) - func remoteVideoStreamStopped() - func changeUIToIncall() - func update(participants: [NYNCallParticipant]) - func updateCallBy(status: CallStatus) - func callFailed() -} - -protocol CallPresenterProtocol: class { - - var view: CallViewProtocol! { get set } - var interactor: CallInteractorInputProtocol! { get set } - var wireFrame: CallWireFrameProtocol! { get set } - var contact: Contact? { get set } - var room: Room? { get set } - var type: CallMode! { get set } - /** - * Add here your methods for communication VIEW -> PRESENTER - */ - - func willShow() - func setupViews(myView: UIView, remoteView: UIView) - - func acceptCall(withVideo: Bool) - func declineCall() - func speakerAction() - func messageAcion(with roomId:String, isVideo: Bool) - func microphoneAction() - func toggleMicrophone() - func isMuted()->Bool - func switchCamera() - func disableVideo() - func viewShowed() - func rejectCall() - func updateCallParticipants() - func showMenuWith(groupCollectionCell: GroupCollectionViewCell) - func endCall() -} - -protocol CallInteractorOutputProtocol: class { - - /** - * Add here your methods for communication INTERACTOR -> PRESENTER - */ - - func callClosed() - func callConnected(withVideo: Bool) - func setRingingWithoutVideo() - func setRingingStatus() - func remoteVideoStreamStopped() - func updateTime(text: String) - func update(participants: [NYNCallParticipant]) - func callFailed() -} - -protocol CallInteractorInputProtocol: class { - - var presenter: CallInteractorOutputProtocol! { get set } - var call: VICall? { get set } - var contact: Contact? { get } - - /** - * Add here your methods for communication PRESENTER -> INTERACTOR - */ - - func acceptCall(withVideo: Bool) - func declineCall() - func speakerAction() - func microphoneAction() - func toggleMicrophone() - func isMuted()->Bool - func switchCamera() - func setupViews(myView: UIView, remoteView: UIView) - func disableVideo() - func setupDelegate() - func rejectCall() - func updateGroupCall(contacts: [Contact]) - func removeCallMember(memberId: String) - func endCall() -} - -protocol ManageCallParticipantsProtocol: class { - func remove(participant: NYNCallParticipant?) - func mute(participant: NYNCallParticipant?) - func unmute(participant: NYNCallParticipant?) -} diff --git a/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift b/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift index a23be1b3f74a74862ecb4cbbb803741741a9d914..f3a59004d2112ef44b20b04dd75e65325bb17a93 100644 --- a/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift +++ b/Nynja/Modules/Call/CallScreens/CallInProgress/Interactor/CallInProgressInteractor.swift @@ -8,39 +8,74 @@ import VoxImplant -class CallInProgressInteractor: CallInProgressInteractorInputProtocol, VoxServiceDelegate, NynjaCommunicatorServiceDelegate { +class CallInProgressInteractor: CallInProgressInteractorInputProtocol, VoxServiceDelegate, NynjaCallDelegate { weak var presenter: CallInProgressInteractorOutputProtocol! weak var call: VICall? var vox = VoxService.sharedInstance + var callService = NynjaCommunicatorService.sharedInstance var timer: Timer? var contact: Contact? { guard let voxId = call?.voxId else { return nil } return ContactDAO.findContactBy(voxId: voxId) } + + var room: Room? { + guard let roomId = nynCall?.externalInfo else { return nil } + return RoomDAO.findRoom(by: roomId) + } + 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 factory = MessageFactory() + + let dependencies = MessageFactory.Dependencies( + storageService: storageService, + payloadBuilder: payloadBuilder + ) + factory.inject(dependencies: dependencies) + + return factory + }() + + private(set) lazy var messageSendingService: MessageSendingServiceProtocol = { + let service = MessageSendingService() + let dependencies = MessageSendingService.Dependencies( + mqttService: mqttService, + storageService: storageService, + processingManager: processingManager + ) + service.inject(dependencies: dependencies) + + return service + }() + func setupDelegate() { vox.delegate = self - NynjaCommunicatorService.sharedInstance.delegate = self + callService.callDelegate = self } func acceptCall(withVideo: Bool) { if let id = call { vox.answer(call: id, withVideo: withVideo) } else if let ncall = self.nynCall { - NynjaCommunicatorService.sharedInstance.acceptConference(call: ncall) + callService.acceptConference(call: ncall) } } func rejectCall() { if let nc = self.nynCall { - NynjaCommunicatorService.sharedInstance.rejectConference(call: nc) + callService.rejectConference(call: nc) self.presenter.callClosed() } @@ -93,7 +128,11 @@ class CallInProgressInteractor: CallInProgressInteractorInputProtocol, VoxServic } func speakerAction() { - vox.switchSpeaker() + if AudioManager.sharedInstance.speaker == .loud { + AudioManager.sharedInstance.speaker = .soft + } else { + AudioManager.sharedInstance.speaker = .loud + } } func disableVideo() { @@ -140,7 +179,7 @@ class CallInProgressInteractor: CallInProgressInteractorInputProtocol, VoxServic } func switchCamera() { - vox.switchCamera() + callService.switchCamera() } // MARK: - VoxServiceDelegate @@ -190,18 +229,30 @@ class CallInProgressInteractor: CallInProgressInteractorInputProtocol, VoxServic } } - func dialing(call: NYNCall) { - + func didAddVideoStreamForCall(call: NYNCall) { + self.presenter.didAddRemoteVideoStream() } - - func incomingCallRinging(call: NYNCall) { - + + func didStartLocalCapturerForCall(call: NYNCall) { + self.presenter.didStartLocalCapturer() } - func creatingGroupCall(name: String, call: NYNCall) { - + func didStopLocalCapturerForCall(call: NYNCall) { + self.presenter.didStopLocalCapturer() } - + + func addRemoteVideoRenderer(inView view: UIView) { + callService.attachRemoteVideoRenderer(inView: view) + } + + func attachLocalVideoPreview(inView view: UIView) { + callService.attachLocalVideoPreview(inView: view) + } + + func detachLocalVideoPreview(inView view: UIView) { + callService.detachLocalVideoPreview(inView: view) + } + func stopTimer () { if timer != nil { @@ -260,6 +311,19 @@ class CallInProgressInteractor: CallInProgressInteractorInputProtocol, VoxServic 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]) { @@ -268,14 +332,14 @@ class CallInProgressInteractor: CallInProgressInteractorInputProtocol, VoxServic for ctc in contacts { let name = "\(ctc.names ?? "") \(ctc.surnames ?? "")" - NynjaCommunicatorService.sharedInstance.addConferenceMember(conferenceId: ncall.callId, phoneId: ctc.phone_id!, name: name) + callService.addConferenceMember(conferenceId: ncall.callId, phoneId: ctc.phone_id!, name: name) } } } func removeCallMember(memberId: String) { if let ncall = self.nynCall { - NynjaCommunicatorService.sharedInstance.removeConferenceMember(conferenceId: ncall.callId, memberId: memberId) + callService.removeConferenceMember(conferenceId: ncall.callId, memberId: memberId) } } } diff --git a/Nynja/Modules/Call/CallScreens/CallInProgress/Presenter/CallInProgressPresenter.swift b/Nynja/Modules/Call/CallScreens/CallInProgress/Presenter/CallInProgressPresenter.swift index 5d7dd9c0d233217c9ccdf79e4e419fc59c1cb551..a0ff75729a7c30449ecd2951178f68f3a91916e6 100644 --- a/Nynja/Modules/Call/CallScreens/CallInProgress/Presenter/CallInProgressPresenter.swift +++ b/Nynja/Modules/Call/CallScreens/CallInProgress/Presenter/CallInProgressPresenter.swift @@ -83,10 +83,7 @@ class CallInProgressPresenter: CallInProgressPresenterProtocol, CallInProgressIn } func callClosed() { - if let navigation = (self.view as? UIViewController)?.navigationController { - (navigation.parent as? MainViewProtocol)?.presenter.wireFrame.hideReturnToCallView() - navigation.popViewController(animated: true) - } + wireFrame.callClosed() } func callConnected(withVideo: Bool) { @@ -108,6 +105,30 @@ class CallInProgressPresenter: CallInProgressPresenterProtocol, CallInProgressIn self.view.askEndOrLeave() } + func didAddRemoteVideoStream() { + self.view.didAddRemoteVideoStream() + } + + func didStartLocalCapturer() { + self.view.didStartLocalCapturer() + } + + func didStopLocalCapturer() { + self.view.didStopLocalCapturer() + } + + func addRemoteVideoRenderer(inView view: UIView) { + self.interactor.addRemoteVideoRenderer(inView: view) + } + + func attachLocalVideoPreview(inView view: UIView) { + self.interactor.attachLocalVideoPreview(inView: view) + } + + func dettachLocalVideoPreview(inView view: UIView) { + self.interactor.detachLocalVideoPreview(inView: view) + } + func remoteVideoStreamStopped() { //self.view.remoteVideoStreamStopped() self.view.setupUI() @@ -143,7 +164,6 @@ class CallInProgressPresenter: CallInProgressPresenterProtocol, CallInProgressIn } func viewShowed() { - self.interactor.setupDelegate() } // MARK: EditParticpantsDelegate diff --git a/Nynja/Modules/Call/CallScreens/CallInProgress/View/CallInProgressViewController.swift b/Nynja/Modules/Call/CallScreens/CallInProgress/View/CallInProgressViewController.swift index 54439ad56c25d32f5641cc3698fa569ac8470489..1688f4407d6c6e4d3d3d0ceb96d564128f3cd9bf 100644 --- a/Nynja/Modules/Call/CallScreens/CallInProgress/View/CallInProgressViewController.swift +++ b/Nynja/Modules/Call/CallScreens/CallInProgress/View/CallInProgressViewController.swift @@ -6,8 +6,29 @@ // Copyright © 2018 TecSynt Solutions. All rights reserved. // +enum CallMode { + case incamingCall + case incamingGroupCall + case outGoingCall + case outGoingGroupCall + case incamingVideoCall + case incamingVideoGroupCall + case outGoingVideoCall + case outGoingVideoGroupCall +} + +enum CallStatus { + case callStarting + case callIncomingAudio + case callIncomingVideo + case callOutgoingAudio + case callOutgoingVideo + case callConnecting + case callInProgress +} + enum CallInProgressMode { - + case oneToOneAudio case oneToOneVideo case groupAudio @@ -16,7 +37,7 @@ enum CallInProgressMode { import UIKit class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCallViewProtocol, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, GroupCollectionViewCellDelegate, GroupAddParticipantsCollectionViewCellDelegate, SpeakerDelegate { - + var presenter: CallInProgressPresenterProtocol! var contact: Contact? var callInProgressMode: CallInProgressMode! @@ -24,116 +45,119 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa var dataSource: NSMutableArray = [] var moderator: Bool = false var roomId: String = "" - + let bottomViewHeight: Float = 188.0 let labelNameHeight: Float = 40.0 let labelStatusHeight: Float = 30.0 let offset: Float = 10.0 let middleGVHeight: Float = 100.0 let statusBarHeight: Float = Float(UIApplication.shared.statusBarFrame.size.height) - - var collapsed: Bool = false - + var collapsed: Bool = false + var initialized: Bool = false + var needLocalRenderer: Bool = false + var needRemoteRenderer: Bool = false + private struct ConstraintConstants { static let buttonSize: CGFloat = 44.0 - + static let bottomOffset: CGFloat = 16.0 static let labelNameFontSize: CGFloat = 22.0 static let labelStatusFontSize: CGFloat = 16.0 - + static let labelsFontSize: CGFloat = 11.0 static let minSectionHeight: CGFloat = 83.0 - + static let declineButtonSize:CGFloat = 68.0 } - + lazy var expectedRowsInCollectionView: Int = { - + var sections:Int = 0 var topOffset:Float = 165 var bottomOffset = self.bottomViewHeight let screenHeight:Float = Float(UIScreen.main.bounds.size.height) - + let nameFont = UIFont(name: Constants.fonts.medium, size: ConstraintConstants.labelNameFontSize) let statusFont = UIFont(name: Constants.fonts.medium, size: ConstraintConstants.labelStatusFontSize) - + if let nf = nameFont, let sf = statusFont { topOffset = Float(nf.lineHeight) + Float(sf.lineHeight) + Float(8*offset) + Float(UIApplication.shared.statusBarFrame.size.height) } - + let clearSpace:Float = screenHeight - topOffset - bottomOffset - + if 0 > clearSpace { - + sections = 3 - + } else { - + let minSectionHeight:Float = Float(ConstraintConstants.minSectionHeight) - + sections = Int(floor(clearSpace/minSectionHeight)) } - + return sections }() - + lazy var backgroundImage: UIImageView = { - + let img = UIImageView() img.isUserInteractionEnabled = true img.contentMode = .scaleAspectFill img.backgroundColor = .clear self.view.addSubview(img) - + img.snp.makeConstraints({ (make) in make.top.left.right.equalTo(self.view) make.bottom.equalTo(self.bottomView.snp.top).offset(-offset/2) }) return img }() - + lazy var otherVideoView: UIView = { - + let view = UIView() view.isUserInteractionEnabled = true - view.backgroundColor = .yellow + view.backgroundColor = self.view.backgroundColor self.view.addSubview(view) - + view.snp.makeConstraints({ (make) in make.top.left.right.equalTo(self.view) make.bottom.equalTo(self.bottomView.snp.top).offset(-offset/2) }) return view }() - + lazy var myVideoView: UIView = { - + let view = UIView() view.isUserInteractionEnabled = true - view.backgroundColor = .green + view.backgroundColor = .clear self.view.addSubview(view) - + view.snp.makeConstraints({ (make) in make.left.equalTo(self.view).offset(1.5*offset) make.bottom.equalTo(self.otherVideoView.snp.bottom).offset(-1.5*offset) - make.width.equalTo(30) - make.height.equalTo(60) + make.width.equalTo(72.adjustedByWidth) + make.height.equalTo(115.adjustedByHeight) }) return view }() - + lazy var switchCameraButton: UIButton = { - + let btn = UIButton() let img = #imageLiteral(resourceName: "switch_camera") btn.backgroundColor = .clear btn.setImage(img, for: .normal) self.view.addSubview(btn) - btn.addTarget(self, action: #selector(declineButtonPressed), for: .touchUpInside) - + + btn.addTarget(self, action: #selector(switchCameraButtonPressed), for: .touchUpInside) + btn.snp.makeConstraints({ (make) in make.right.equalTo(self.view).offset(-offset) make.bottom.equalTo(self.otherVideoView.snp.bottom).offset(-offset) @@ -142,7 +166,7 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa return btn }() - + lazy var collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .vertical @@ -154,7 +178,7 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa cv.delegate = self cv.dataSource = self cv.backgroundColor = Constants.colors.grayForCallScreenBottom.getColor() - + cv.register(GroupCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: GroupCollectionViewCell.self)) cv.register(GroupAddParticipantsCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: GroupAddParticipantsCollectionViewCell.self)) @@ -162,11 +186,11 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa make.top.equalTo(self.statusLabel.snp.bottom).offset(offset) make.left.right.equalTo(self.view) make.bottom.equalTo(self.openCloseCallsButton.snp.top).offset(-offset/2) - + }) return cv }() - + private lazy var nameLabel: UILabel = { let scwidth = UIScreen.main.bounds.width let lbl = UILabel() @@ -177,16 +201,16 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa lbl.baselineAdjustment = .alignCenters lbl.lineBreakMode = .byTruncatingTail self.view.addSubview(lbl) - + lbl.snp.makeConstraints({ (make) in make.top.equalTo(self.view).offset(6*offset) make.left.right.equalTo(self.view).offset(offset) make.height.equalTo(lbl.font.lineHeight) }) - + return lbl }() - + private lazy var statusLabel: UILabel = { let scwidth = UIScreen.main.bounds.width let lbl = UILabel() @@ -199,31 +223,31 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa lbl.baselineAdjustment = .alignCenters lbl.lineBreakMode = .byClipping self.view.addSubview(lbl) - + lbl.snp.makeConstraints({ (make) in make.top.equalTo(self.nameLabel.snp.bottom).offset(offset) make.left.right.equalTo(self.view).offset(offset) make.height.equalTo(lbl.font.lineHeight) }) - + return lbl }() - + lazy var bottomView : UIView = { - + let view = UIView() view.isUserInteractionEnabled = true view.backgroundColor = .clear self.view.addSubview(view) - + view.snp.makeConstraints({ (make) in make.bottom.left.right.equalTo(self.view) make.height.equalTo(self.bottomViewHeight) }) - + return view }() - + lazy var declineButton : UIButton = { let btn = UIButton() let img = UIImage.init(named:"ic_decline_call") @@ -231,7 +255,7 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa btn.setImage(img, for: .normal) self.bottomView.addSubview(btn) btn.addTarget(self, action: #selector(declineButtonPressed), for: .touchUpInside) - + btn.snp.makeConstraints({ (make) in make.width.height.equalTo(ConstraintConstants.declineButtonSize) make.width.height.equalTo(ConstraintConstants.declineButtonSize) @@ -240,13 +264,13 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa }) return btn }() - + lazy var speakerButton : UIButton = { - + let btn = UIButton() - + AudioManager.sharedInstance.speaker = .soft - + btn.setImage(#imageLiteral(resourceName: "ic_speaker_off"), for: .normal) btn.setImage(#imageLiteral(resourceName: "ic_speaker_on"), for: .selected) btn.isSelected = (AudioManager.sharedInstance.speaker == .loud) @@ -254,10 +278,10 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa btn.layer.masksToBounds = true self.bottomView.addSubview(btn) - + let offsetX = UIScreen.main.bounds.width / 3.0 btn.addTarget(self, action: #selector(speakerButtonPressed), for: .touchUpInside) - + btn.snp.makeConstraints({ (make) in make.width.equalTo(ConstraintConstants.buttonSize) make.height.equalTo(ConstraintConstants.buttonSize) @@ -266,7 +290,7 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa }) return btn }() - + lazy var speakerLabel: UILabel = { let label = UILabel() label.text = "speakerphone".localized @@ -274,15 +298,15 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa label.textAlignment = .center label.font = UIFont(name: Constants.fonts.medium, size: ConstraintConstants.labelsFontSize) self.bottomView.addSubview(label) - + label.snp.makeConstraints({ (make) in make.top.equalTo(self.speakerButton.snp.bottom).offset(0) make.centerX.equalTo(self.speakerButton) }) - + return label }() - + lazy var cameraLabel: UILabel = { let label = UILabel() label.text = "turn_on_video".localized @@ -290,17 +314,17 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa label.textAlignment = .center label.font = UIFont(name: Constants.fonts.medium, size: ConstraintConstants.labelsFontSize) self.bottomView.addSubview(label) - + let offsetX = UIScreen.main.bounds.width / 3.0 label.snp.makeConstraints({ (make) in make.centerX.equalTo(self.view).offset(-offsetX) make.bottom.equalTo(self.declineButton.snp.top).offset(-2*offset) }) - + return label }() - + lazy var cameraButton: UIButton = { let button = UIButton() button.setImage(#imageLiteral(resourceName: "ic_video_on_voice_call"), for: .normal) @@ -308,17 +332,17 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa button.isEnabled = (.oneToOneVideo == self.callInProgressMode) self.bottomView.addSubview(button) let offsetX = UIScreen.main.bounds.width / 3.0 - + button.snp.makeConstraints({ (make) in make.height.equalTo(ConstraintConstants.buttonSize) make.width.equalTo(ConstraintConstants.buttonSize) make.centerX.equalTo(self.bottomView).offset(-offsetX) make.bottom.equalTo(self.cameraLabel.snp.top).offset(0) }) - + return button }() - + lazy var microphoneButton : UIButton = { let btn = UIButton() let muteImage = (self.isMuted()) ? #imageLiteral(resourceName: "ic_mute_voice_call"): #imageLiteral(resourceName: "ic_unmute_voice_call") @@ -326,7 +350,7 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa btn.layer.masksToBounds = true self.bottomView.addSubview(btn) btn.addTarget(self, action: #selector(microphoneButtonPressed), for: .touchUpInside) - + btn.snp.makeConstraints({ (make) in make.width.equalTo(ConstraintConstants.buttonSize) make.height.equalTo(ConstraintConstants.buttonSize) @@ -335,7 +359,7 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa }) return btn }() - + lazy var muteLabel: UILabel = { let label = UILabel() label.text = "mute_call".localized @@ -343,12 +367,12 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa label.textAlignment = .center label.font = UIFont(name: Constants.fonts.medium, size: ConstraintConstants.labelsFontSize) self.bottomView.addSubview(label) - + label.snp.makeConstraints({ (make) in make.centerY.equalTo(self.cameraLabel.snp.centerY).offset(0) make.centerX.equalTo(self.microphoneButton) }) - + return label }() @@ -359,7 +383,7 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa self.bottomView.addSubview(btn) let offsetX = UIScreen.main.bounds.width / 3.0 btn.addTarget(self, action: #selector(messageButtonPressed), for: .touchUpInside) - + btn.snp.makeConstraints({ (make) in make.width.equalTo(ConstraintConstants.buttonSize) make.height.equalTo(ConstraintConstants.buttonSize) @@ -368,7 +392,7 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa }) return btn }() - + lazy var chatLabel: UILabel = { let label = UILabel() label.text = "return_to_chat_from_call".localized @@ -376,16 +400,16 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa label.textAlignment = .center label.font = UIFont(name: Constants.fonts.medium, size: ConstraintConstants.labelsFontSize) self.bottomView.addSubview(label) - + label.snp.makeConstraints({ (make) in make.top.equalTo(self.messageButton.snp.bottom).offset(0) make.centerX.equalTo(self.messageButton) }) - + return label }() - + lazy var moreLabel: UILabel = { let label = UILabel() label.text = "more".localized @@ -393,32 +417,32 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa label.textAlignment = .center label.font = UIFont(name: Constants.fonts.medium, size: ConstraintConstants.labelsFontSize) self.bottomView.addSubview(label) - + let offsetX = UIScreen.main.bounds.width / 3.0 - + label.snp.makeConstraints({ (make) in make.centerX.equalTo(self.bottomView).offset(offsetX) make.bottom.equalTo(self.declineButton.snp.top).offset(-2*offset) }) - + return label }() - + lazy var moreButton: UIButton = { let button = UIButton() button.setImage(#imageLiteral(resourceName: "ic_more_voice_call"), for: .normal) button.addTarget(self, action: #selector(onMoreButtonPressed), for: .touchUpInside) - + self.bottomView.addSubview(button) let offsetX = UIScreen.main.bounds.width / 3.0 - + button.snp.makeConstraints({ (make) in make.height.equalTo(ConstraintConstants.buttonSize) make.width.equalTo(ConstraintConstants.buttonSize) make.centerX.equalTo(self.bottomView).offset(offsetX) make.bottom.equalTo(self.moreLabel.snp.top).offset(0) }) - + return button }() @@ -429,17 +453,17 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa label.textAlignment = .left label.font = UIFont(name: Constants.fonts.regular, size: 13) self.view.addSubview(label) - + let offsetX = UIScreen.main.bounds.width / 3.0 - + label.snp.makeConstraints({ (make) in make.left.equalTo(self.view).offset(offset) - make.bottom.equalTo(self.cameraButton.snp.top).offset(0)//offset(0) + make.bottom.equalTo(self.bottomView.snp.top).offset(0) }) - + return label }() - + lazy var heldCallDescription: UILabel = { let label = UILabel() label.text = "" @@ -447,19 +471,19 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa label.textAlignment = .right label.font = UIFont(name: Constants.fonts.regular, size: 13) self.view.addSubview(label) - + let offsetX = UIScreen.main.bounds.width / 3.0 - + label.snp.makeConstraints({ (make) in make.right.equalTo(self.view).offset(-offset) make.centerY.equalTo(self.heldCallTitle) make.width.lessThanOrEqualTo(UIScreen.main.bounds.width/2 - CGFloat(offset)) make.left.equalTo(self.heldCallTitle.snp.right).offset(offset) }) - + return label }() - + lazy var activeCallTitle: UILabel = { let label = UILabel() label.text = "" @@ -467,17 +491,17 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa label.textAlignment = .left label.font = UIFont(name: Constants.fonts.regular, size: 13) self.view.addSubview(label) - + let offsetX = UIScreen.main.bounds.width / 3.0 - + label.snp.makeConstraints({ (make) in make.left.equalTo(self.view).offset(offset) make.bottom.equalTo(self.heldCallTitle.snp.top).offset(0)//offset(-offset/2) }) - + return label }() - + lazy var activeCallDescription: UILabel = { let label = UILabel() label.text = "" @@ -485,110 +509,108 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa label.textAlignment = .right label.font = UIFont(name: Constants.fonts.regular, size: 13) self.view.addSubview(label) - + let offsetX = UIScreen.main.bounds.width / 3.0 - + label.snp.makeConstraints({ (make) in make.right.equalTo(self.view).offset(-offset) make.centerY.equalTo(self.activeCallTitle) make.width.lessThanOrEqualTo(UIScreen.main.bounds.width/2 - CGFloat(offset)) make.left.equalTo(self.activeCallTitle.snp.right).offset(offset) }) - + return label }() lazy var openCloseCallsButton: UIButton = { let button = UIButton() - + let img = self.collapsed ? UIImage.init(named: "arrow_expand") : UIImage.init(named: "arrow_collapse") button.setImage(img, for: .normal) button.addTarget(self, action: #selector(onOpenCloseCallsButton), for: .touchUpInside) - + self.view.addSubview(button) let offsetX = UIScreen.main.bounds.width / 3.0 - + button.snp.makeConstraints({ (make) in make.height.equalTo(0)//(34) make.width.equalTo(0)//(34) make.centerX.equalTo(self.view) make.bottom.equalTo(self.activeCallTitle.snp.top).offset(0)//offset(-offset/2) }) - + return button }() - - func updateModeVisibility() { - + + func setupVisibility() { + + // for all modes in view self.nameLabel.isHidden = false - self.statusLabel.isHidden = false - self.declineButton.isHidden = false - self.collectionView.isHidden = true + self.heldCallTitle.isHidden = true + self.heldCallDescription.isHidden = true + self.activeCallTitle.isHidden = true + self.activeCallDescription.isHidden = true + self.openCloseCallsButton.isHidden = true + self.openCloseCallsButton.isEnabled = false + + // for all modes in bottom view + self.declineButton.isHidden = false self.speakerButton.isHidden = false self.speakerLabel.isHidden = false - self.cameraButton.isHidden = false self.cameraLabel.isHidden = false - self.microphoneButton.isHidden = false self.muteLabel.isHidden = false - self.messageButton.isHidden = false self.chatLabel.isHidden = false self.messageButton.isEnabled = (nil != self.contact) || (self.roomId.count > 0) - self.moreButton.isHidden = false self.moreLabel.isHidden = false self.moreButton.isEnabled = false - self.heldCallTitle.isHidden = true - self.heldCallDescription.isHidden = true - - self.activeCallTitle.isHidden = true - self.activeCallDescription.isHidden = true - - self.openCloseCallsButton.isHidden = true - self.openCloseCallsButton.isEnabled = false - switch self.callInProgressMode! { - + case .oneToOneAudio: - self.collectionView.isHidden = true self.myVideoView.isHidden = true self.otherVideoView.isHidden = true self.switchCameraButton.isHidden = true self.backgroundImage.isHidden = false self.backgroundImage.setImage(url: self.contact?.avatarUrl, placeHolder: UIImage(named: "ava_placeholder")) + self.view.bringSubview(toFront: self.backgroundImage) case .oneToOneVideo: - self.collectionView.isHidden = true - self.myVideoView.isHidden = false + self.switchCameraButton.isHidden = true + self.myVideoView.isHidden = true self.otherVideoView.isHidden = false - self.switchCameraButton.isHidden = false - self.backgroundImage.isHidden = true - self.view.insertSubview(self.myVideoView, aboveSubview:otherVideoView) - self.view.insertSubview(self.switchCameraButton, aboveSubview:otherVideoView) + self.backgroundImage.isHidden = false + self.backgroundImage.setImage(url: self.contact?.avatarUrl, placeHolder: UIImage(named: "ava_placeholder")) + self.view.bringSubview(toFront: self.backgroundImage) + self.view.bringSubview(toFront: self.otherVideoView) + self.view.bringSubview(toFront: self.myVideoView) + self.view.bringSubview(toFront: self.switchCameraButton) case .groupAudio: self.collectionView.isHidden = false self.myVideoView.isHidden = true self.otherVideoView.isHidden = true self.switchCameraButton.isHidden = true self.backgroundImage.isHidden = true + self.view.bringSubview(toFront: self.collectionView) } - + + self.view.bringSubview(toFront: self.bottomView) self.view.bringSubview(toFront: self.nameLabel) self.view.bringSubview(toFront: self.statusLabel) } - + func updateTitle() { - + var viewTitle:String = "" - + if let ctct = self.contact { - + viewTitle = "\(ctct.names ?? "") \(ctct.surnames ?? "")" - + } else if self.callInProgressMode == .groupAudio { if self.presenter != nil { if let room = RoomDAO.findRoom(by: self.roomId) { @@ -598,159 +620,157 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa } } } - + nameLabel.text = viewTitle } - + func setupUI() { - - updateModeVisibility() + updateTitle() } - + func updateCallBy(status: CallStatus) { - + } - + func callFailed() { } - + func remoteVideoStreamStopped() { - + // backgtoundVideoImage.isHidden = false // backgtoundVideoImage.image = backgtoundImage.image // // partnerVideoView.isHidden = true -// self.contentVideoView.bringSubview(toFront: self.yourVideoView) } - - + + @objc func resizeButtonAction() { presenter.messageAcion(with: roomId, isVideo: true) } - + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - + // Note: need to prevent weird animation which appears when incoming/outcoming call appears. self.view.layoutIfNeeded() self.presenter.viewShowed() -// self.presenter.setupViews(myView: yourVideoView, remoteView: partnerVideoView) -// -// // Note: need to prevent weird animation with remote and local video views. -// self.partnerVideoView.layoutIfNeeded() -// self.yourVideoView.layoutIfNeeded() + + if self.needLocalRenderer { + self.didStartLocalCapturer() + self.needLocalRenderer = false + } + + if self.needRemoteRenderer { + self.didAddRemoteVideoStream() + self.needRemoteRenderer = false + } } - + override func initialize() { super.initialize() - + self.view.backgroundColor = Constants.colors.grayForCallScreenTop.getColor() - + self.presenter.willShow() - + setupVisibility() + + // mark view as initialized + self.initialized = true } - + //MARK: Collection View Delegates public func numberOfSections(in collectionView: UICollectionView) -> Int { - + return 1 } - + //2 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - + var rows:Int = dataSource.count - + if rows > 0 { rows = dataSource.count + 1 } - + return rows } - + //3 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - + let cell:UICollectionViewCell? - + if 0 == indexPath.row { - + let cellPlus:GroupAddParticipantsCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: GroupAddParticipantsCollectionViewCell.self), for: indexPath) as! GroupAddParticipantsCollectionViewCell - + cellPlus.delegate = self - + cell = cellPlus } else { - + let cellPart:GroupCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: GroupCollectionViewCell.self), for: indexPath) as! GroupCollectionViewCell - + let callPart:NYNCallParticipant? = dataSource[indexPath.row - 1] as? NYNCallParticipant - + if let cp = callPart { - + cellPart.callPart = cp cellPart.canRemove = self.moderator cellPart.delegate = self cellPart.updateCell() - + } else { - + print("Illegal cell") } - + cell = cellPart } - + return cell! } - + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { - + let spacing : CGFloat = (collectionViewLayout as? UICollectionViewFlowLayout)?.minimumInteritemSpacing ?? 0.0 let offsetIn:CGFloat = 5.0 let cellHeight = floor((collectionView.bounds.size.height - ((CGFloat(expectedRowsInCollectionView) - 1)*spacing))/CGFloat(expectedRowsInCollectionView)) let cellWidth = floor((0.75*(cellHeight - 3*offsetIn) + 2*offsetIn)) - + return CGSize(width: cellWidth, height: cellHeight) } - + //MARK: Group Add Participants Collection View Cell delegates - + func didPressAddGroupCollectionCell(groupCollectionCell: GroupAddParticipantsCollectionViewCell) { presenter.updateCallParticipants() } - + //MARK: Group Collection View Cell delegates - + func showMenuWith(groupCollectionCell: GroupCollectionViewCell) { presenter.showMenuWith(groupCollectionCell:groupCollectionCell) } - + //MARK: bottom view delegate - + func acceptButtonPressed() { //presenter.acceptCall(withVideo: (self.callMode == .incamingVideoCall) || (self.callMode == .incamingVideoGroupCall)) } - + @objc func declineButtonPressed() { - + presenter.declineCall() } - + @objc func speakerButtonPressed() { - - let state = AudioManager.sharedInstance.speaker - switch state { - case .loud: - AudioManager.sharedInstance.speaker = .soft - case .soft: - AudioManager.sharedInstance.speaker = .loud - } presenter.speakerAction() } @@ -760,34 +780,34 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa } @objc func messageButtonPressed() { - + if let contact = self.contact { presenter.messageAcion(with: contact, isVideo: false) } else { - + presenter.messageAcion(with: roomId, isVideo: false) } - + } - + @objc func microphoneButtonPressed() { - + toggleMicrophone() } - + func toggleMicrophone() { - + let muteImage = (self.isMuted()) ? #imageLiteral(resourceName: "ic_unmute_voice_call") : #imageLiteral(resourceName: "ic_mute_voice_call") microphoneButton.setImage(muteImage, for: .normal) - + presenter.toggleMicrophone() } - + func isMuted()->Bool { - + return presenter.isMuted() } - + func acceptAudioButtonPressed() { // if self.callMode == .incamingVideoCall || self.callMode == .incamingVideoGroupCall { // presenter.acceptCall(withVideo: false) @@ -795,66 +815,71 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa // presenter.disableVideo() // } } - - func switchCameraButtonPressed() { + + @objc func switchCameraButtonPressed() { presenter.switchCamera() } - + func updateTime(text: String) { - statusLabel.text = "voice_call_status".localized + " - \(text)" + + if .oneToOneVideo == self.callInProgressMode { + statusLabel.text = "video_call_status".localized + " - \(text)" + } else { + statusLabel.text = "voice_call_status".localized + " - \(text)" + } } - + func changeUIToIncall() { - + self.updateCallBy(status: .callInProgress) self.setupUI() } - + func update(participants: [NYNCallParticipant]) { - + dataSource.removeAllObjects() - + for mem in participants { - + if let phoneId = mem.address { - + let contact:Contact? = ContactDAO.findContactBy(phoneId: phoneId) - + if let ct = contact { - + if let urlAvatar = ct.avatarUrl { - + mem.avatarUrl = urlAvatar.absoluteString } } } - + dataSource.add(mem) } - + collectionView.reloadData() } - + @objc func onCameraButtonPressed() { - + if cameraButton.imageView?.image == #imageLiteral(resourceName: "ic_video_on_voice_call") { cameraButton.setImage(#imageLiteral(resourceName: "ic_video_off_voice_call"), for: .normal) } else { cameraButton.setImage(#imageLiteral(resourceName: "ic_video_on_voice_call"), for: .normal) } } - + @objc func onMoreButtonPressed() { - - + + } - + @objc func onOpenCloseCallsButton() { - + self.openCloseCallsButton.snp.removeConstraints() UIView.animate(withDuration: 0.2, animations: { - + let alpha = self.collapsed ? 1.0 : 0.0 self.activeCallTitle.alpha = CGFloat(alpha) self.activeCallDescription.alpha = CGFloat(alpha) @@ -862,14 +887,14 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa self.heldCallDescription.alpha = CGFloat(alpha) if self.collapsed { - + self.openCloseCallsButton.snp.makeConstraints({ (make) in make.height.equalTo(34) make.width.equalTo(34) make.centerX.equalTo(self.view) make.bottom.equalTo(self.activeCallTitle.snp.top).offset(-self.offset/2) }) - + } else { self.openCloseCallsButton.snp.makeConstraints({ (make) in @@ -879,7 +904,7 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa make.bottom.equalTo(self.microphoneButton.snp.top).offset(-self.offset/2) }) } - + self.collapsed = !self.collapsed let img = self.collapsed ? UIImage.init(named: "arrow_expand") : UIImage.init(named: "arrow_collapse") self.openCloseCallsButton.setImage(img, for: .normal) @@ -887,20 +912,20 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa self.view.layoutIfNeeded() }, completion: { _ in - + }) } - + func onPortOutButtonPressed() { let alertVC = UIAlertController(title: "voice_call_the_feature_currently_unavailable".localized, message: nil, preferredStyle: .alert) let okAction = UIAlertAction(title: "ok".localized, style: .cancel) { (action) in alertVC.dismiss(animated: true, completion: nil) } alertVC.addAction(okAction) - + self.present(alertVC, animated: true, completion: nil) } - + func askEndOrLeave() { let alertVC = UIAlertController(title: "question_end_call".localized, message: nil, preferredStyle: .alert) let forMeAction = UIAlertAction(title: "end_call_for_me".localized, style: .default) { (action) in @@ -909,10 +934,63 @@ class CallInProgressViewController: BaseVC, CallInProgressViewProtocol, BottomCa let forAllAction = UIAlertAction(title: "end_call_for_all".localized, style: .default) { (action) in self.presenter.endCall() } - + alertVC.addAction(forMeAction) alertVC.addAction(forAllAction) - + self.present(alertVC, animated: true, completion: nil) } + + func didAddRemoteVideoStream() { + if self.initialized { + handleDidAddRemoteVideoStream() + } else { + self.needRemoteRenderer = true + } + } + + func didStartLocalCapturer() { + if self.initialized { + handleDidStartLocalCapturer() + } else { + self.needLocalRenderer = true + } + } + + func didStopLocalCapturer() { + if self.initialized { + handleDidStopLocalCapturer() + } else { + self.needLocalRenderer = false + } + } + + private func handleDidAddRemoteVideoStream() { + + self.otherVideoView.isHidden = false + self.switchCameraButton.isHidden = false + self.backgroundImage.isHidden = true + self.backgroundImage.image = nil + self.view.sendSubview(toBack: self.backgroundImage) + + self.presenter.addRemoteVideoRenderer(inView: self.otherVideoView); + } + + private func handleDidStartLocalCapturer() { + + self.myVideoView.isHidden = false + self.view.insertSubview(self.myVideoView, aboveSubview: self.otherVideoView) + + self.presenter.attachLocalVideoPreview(inView: self.myVideoView); + } + + private func handleDidStopLocalCapturer() { + + self.myVideoView.isHidden = true + self.view.sendSubview(toBack: self.myVideoView) + + self.presenter.dettachLocalVideoPreview(inView: self.myVideoView); + } + + } diff --git a/Nynja/Modules/Call/CallScreens/CallInProgress/WireFrame/CallInProgressWireframe.swift b/Nynja/Modules/Call/CallScreens/CallInProgress/WireFrame/CallInProgressWireframe.swift index 2bc66b6da0e330d389819f47e6b57782f0ac1fb9..53c92b659014f6f527b1b19b12f71b146a5522f8 100644 --- a/Nynja/Modules/Call/CallScreens/CallInProgress/WireFrame/CallInProgressWireframe.swift +++ b/Nynja/Modules/Call/CallScreens/CallInProgress/WireFrame/CallInProgressWireframe.swift @@ -45,6 +45,7 @@ class CallInProgressWireframe: CallInProgressWireFrameProtocol { interactor.presenter = presenter navigation.pushViewController(view as UIViewController, animated: true) + interactor.setupDelegate() } func presentDialInCall(navigation: UINavigationController, callInProgressMode: CallInProgressMode, contact: Contact?, call: NYNCall? = nil, main: MainWireFrame?) { @@ -71,6 +72,7 @@ class CallInProgressWireframe: CallInProgressWireFrameProtocol { interactor.presenter = presenter navigation.pushViewController(view as UIViewController, animated: true) + interactor.setupDelegate() } func presentCreateGroupCall(navigation: UINavigationController, callInProgressMode: CallInProgressMode, main: MainWireFrame?, call: NYNCall) { @@ -100,6 +102,7 @@ class CallInProgressWireframe: CallInProgressWireFrameProtocol { interactor.presenter = presenter navigation.pushViewController(view as UIViewController, animated: true) + interactor.setupDelegate() } func messageActionWith(room: Room, isVideo: Bool) { @@ -134,7 +137,7 @@ class CallInProgressWireframe: CallInProgressWireFrameProtocol { } } - AddParticipantsWireFrame().presentAddParticipants(navigation: navigation!, main: mainWF, selectedContacts: nil, delegate: external, mode: .updateGroupCall, members: members, room:self.view?.presenter.room) + AddParticipantsWireFrame().presentAddParticipants(navigation: navigation!, main: mainWF, selectedContacts: nil, delegate: external, mode: .updateGroupCall, members: members, room:self.view?.presenter.interactor.room) } func showMenuWith(participant: NYNCallParticipant?, delegate: ManageCallInProgressParticipantsProtocol) { @@ -151,20 +154,6 @@ class CallInProgressWireframe: CallInProgressWireFrameProtocol { })) } - // if participant.isMuted { - // actionSheet.addAction(UIAlertAction(title: "mute_call".localized, - // style: .default, - // handler: { (action) in - // delegate.mute(participant: participant) - // })) - // } else { - // actionSheet.addAction(UIAlertAction(title: "unmute".localized, - // style: .default, - // handler: { (action) in - // delegate.unmute(participant: participant) - // })) - // } - actionSheet.addAction(UIAlertAction(title: "cancel".localized, style: .cancel, handler: { (action) in self.navigation?.dismiss(animated: true, completion: nil) @@ -172,7 +161,12 @@ class CallInProgressWireframe: CallInProgressWireFrameProtocol { navigation?.present(actionSheet, animated: true, completion: nil) } - + + func callClosed() { + LogService.log(topic: .callSystem, text: "call view popped to root") + navigation?.popViewController(animated: true) + } + func removeParticipant(participant:NYNCallParticipant?) { } diff --git a/Nynja/Modules/Call/Interactor/CallInteractor.swift b/Nynja/Modules/Call/Interactor/CallInteractor.swift deleted file mode 100644 index 7f93f5a5a121a08b89ae21d3b439a0a5347b0a71..0000000000000000000000000000000000000000 --- a/Nynja/Modules/Call/Interactor/CallInteractor.swift +++ /dev/null @@ -1,300 +0,0 @@ -// -// CallCallInteractor.swift -// Nynja -// -// Created by Bohdan Paliychuk on 26/07/2017. -// Copyright © 2017 TecSynt Solutions. All rights reserved. -// -import VoxImplant - -class CallInteractor: CallInteractorInputProtocol, VoxServiceDelegate, NynjaCommunicatorServiceDelegate { - - weak var presenter: CallInteractorOutputProtocol! - weak var call: VICall? - - var vox = VoxService.sharedInstance - var timer: Timer? - - var contact: Contact? { - guard let voxId = call?.voxId else { return nil } - return ContactDAO.findContactBy(voxId: voxId) - } - weak var nynCall: NYNCall? - - var duration = 0 - - - func setupDelegate() { - vox.delegate = self - NynjaCommunicatorService.sharedInstance.delegate = self - } - - func acceptCall(withVideo: Bool) { - if let id = call { - vox.answer(call: id, withVideo: withVideo) - } else if let ncall = self.nynCall { - NynjaCommunicatorService.sharedInstance.acceptConference(call: ncall) - } - } - - func rejectCall() { - - if let nc = self.nynCall { - NynjaCommunicatorService.sharedInstance.rejectConference(call: nc) - - self.presenter.callClosed() - } - } - - func declineCall() { - if let id = call { - vox.cancelCall(call: id) - } else if let nc = self.nynCall { - if nc.callState == NYNCallState.connected { - nc.hangup() - } else { - self.presenter.callClosed() - } - } else { - self.presenter.callClosed() - } - } - - func speakerAction() { - vox.switchSpeaker() - } - - func disableVideo() { - if let id = call { - vox.disableVideo(call: id) - if id.duration() > 0 { - self.presenter.callConnected(withVideo: false) - } else { - self.presenter.setRingingWithoutVideo() - } - vox.withVideo = false - } - } - - func startRinging() { - presenter.setRingingStatus() - } - - func microphoneAction() { - if let id = call { - vox.switchMicrophone(call: id) - } - if let nc = self.nynCall { - nc.toggleMicrophone() - } - } - - func toggleMicrophone() { - - if let nc = self.nynCall { - nc.toggleMicrophone() - } - } - - func isMuted()->Bool { - - var muted:Bool = false - - if let nc = self.nynCall { - muted = nc.isMuted - } - - return muted - } - - func switchCamera() { - vox.switchCamera() - } - - // MARK: - VoxServiceDelegate - func remoteVideoStreamDeleted () { - presenter.remoteVideoStreamStopped() - } - - func callClosed(call: VICall, isError: Bool) { - self.presenter.callClosed() - } - - func callConnected(call: VICall,withVideo: Bool) { - self.presenter.callConnected(withVideo: withVideo) - self.startTimer() - } - - func setupViews(myView: UIView, remoteView: UIView) { - vox.remoteView = remoteView - vox.myView = myView - } - - func startTimer() { - timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(runTimedCode), userInfo: nil, repeats: true) - } - - @objc func runTimedCode() { - if let call = self.call { - let durationInt = Int(call.duration()) - let minutes = durationInt / 60 - let seconds = durationInt % 60 - - let text = String.localizedStringWithFormat("%u:%02u", minutes,seconds) - if self.presenter != nil { - self.presenter.updateTime(text:text) - } - } else if nil != self.nynCall { - - duration += 1 - let durationInt = Int(duration) - let minutes = durationInt / 60 - let seconds = durationInt % 60 - - let text = String.localizedStringWithFormat("%u:%02u", minutes,seconds) - if self.presenter != nil { - self.presenter.updateTime(text:text) - } - } - } - - func dialing(call: NYNCall) { - - } - - func incomingCallRinging(call: NYNCall) { - - } - - func creatingGroupCall(name: String, call: NYNCall) { - - } - - func stopTimer () { - - if timer != nil { - timer?.invalidate() - timer = nil - duration = 0 - } - } - - func callEnded(call: NYNCall, isError: Bool) { - self.presenter.callClosed() - - stopTimer() - } - - func readyToStart(call:NYNCall) { - - call.start() - - } - - func stateDidChange(call: NYNCall, state: NYNCallState) { - - if let ncall = self.nynCall { - if ncall.callId.elementsEqual(call.callId) { - switch state { - case NYNCallState.new: - break - case NYNCallState.readyToStart: - self.readyToStart(call: ncall) - break; - case NYNCallState.establishing: - break - case NYNCallState.connecting: - break - case NYNCallState.connected: - self.presenter.callConnected(withVideo: false) - self.startTimer() - break - case NYNCallState.failed: - self.presenter.callFailed() - break - case NYNCallState.disconnected: - break - case NYNCallState.closed: - break - case NYNCallState.count: - break - } - } - } - } - - func participantsUpdated(call: NYNCall) { - - if let ncall = self.nynCall, call.callId.elementsEqual(ncall.callId) { - self.presenter.update(participants: ncall.participants) - } - } - - func updateGroupCall(contacts: [Contact]) { - - if let ncall = self.nynCall { - - for ctc in contacts { - let name = "\(ctc.names ?? "") \(ctc.surnames ?? "")" - - NynjaCommunicatorService.sharedInstance.addConferenceMember(conferenceId: ncall.callId, phoneId: ctc.phone_id!, name: name) - } - } - } - - func removeCallMember(memberId: String) { - if let ncall = self.nynCall { - NynjaCommunicatorService.sharedInstance.removeConferenceMember(conferenceId: ncall.callId, memberId: memberId) - } - } - - func endCall() { - if let nc = self.nynCall { - nc.end() - } - } - - //MARK: Should remove to serverside - - let storageService: StorageService = .sharedInstance - let payloadBuilder: MessagePayloadBuilderInput = MessagePayloadBuilder() - private let mqttService: MQTTService = .sharedInstance - let processingManager = DefaultMessagesProcessingManager.shared - - private(set) lazy var messageFactory: MessageFactoryProtocol = { - let factory = MessageFactory() - - let dependencies = MessageFactory.Dependencies( - storageService: storageService, - payloadBuilder: payloadBuilder - ) - factory.inject(dependencies: dependencies) - - return factory - }() - - private(set) lazy var messageSendingService: MessageSendingServiceProtocol = { - let service = MessageSendingService() - let dependencies = MessageSendingService.Dependencies( - mqttService: mqttService, - storageService: storageService, - processingManager: processingManager - ) - service.inject(dependencies: dependencies) - - return service - }() - - 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) - } -} diff --git a/Nynja/Modules/Call/Presenter/CallPresenter.swift b/Nynja/Modules/Call/Presenter/CallPresenter.swift deleted file mode 100644 index 546b0c7d7dbeda37df1b4d1c734861dee7bf2b1e..0000000000000000000000000000000000000000 --- a/Nynja/Modules/Call/Presenter/CallPresenter.swift +++ /dev/null @@ -1,170 +0,0 @@ -// -// CallCallPresenter.swift -// Nynja -// -// Created by Bohdan Paliychuk on 26/07/2017. -// Copyright © 2017 TecSynt Solutions. All rights reserved. -// - -class CallPresenter: CallPresenterProtocol, CallInteractorOutputProtocol, EditParticipantsDelegate, ManageCallParticipantsProtocol { - - weak var view: CallViewProtocol! - var interactor: CallInteractorInputProtocol! - var wireFrame: CallWireFrameProtocol! - var contact: Contact? - var type: CallMode! - var room: Room? - - func acceptCall(withVideo: Bool) { - interactor.acceptCall(withVideo: withVideo) - } - - func disableVideo() { - interactor.disableVideo() - } - - func declineCall() { - interactor.declineCall() - } - - func rejectCall() { - interactor.rejectCall(); - } - - func updateCallParticipants() { - - wireFrame.updateCallParticipants() - } - - func showMenuWith(groupCollectionCell: GroupCollectionViewCell) { - - wireFrame.showMenuWith(participant: groupCollectionCell.callPart, delegate: self) - } - - func endCall() { - interactor.endCall() - } - - func speakerAction() { - interactor.speakerAction() - } - - func messageAcion(with roomId:String, isVideo: Bool) { - guard let room = RoomDAO.findRoom(by: roomId) else {return} - wireFrame.messageActionWith(room:room, isVideo:isVideo) - } - - func microphoneAction() { - interactor.microphoneAction() - } - - func toggleMicrophone() { - - interactor.toggleMicrophone() - } - - func isMuted()->Bool { - - return interactor.isMuted() - } - - func switchCamera() { - interactor.switchCamera() - } - - func callClosed() { - if let navigation = (self.view as? UIViewController)?.navigationController { - (navigation.parent as? MainViewProtocol)?.presenter.wireFrame.hideReturnToCallView() - navigation.popViewController(animated: true) - } - } - - func callConnected(withVideo: Bool) { - if withVideo { - self.view.setupUI() - } else { - self.view.setupUI() - } - - self.view.updateCallBy(status:.callInProgress) - } - - func callFailed() { - - self.view.callFailed() - } - - func remoteVideoStreamStopped() { - //self.view.remoteVideoStreamStopped() - self.view.setupUI() - self.view.updateCallBy(status:.callInProgress) - } - - - func setRingingWithoutVideo() { - self.view.setupUI() - self.view.updateCallBy(status:.callStarting) - } - - func setRingingStatus() { - self.view.setupUI() - self.view.updateCallBy(status:.callOutgoingAudio) - } - - func willShow() { - self.view.setupUI() - } - - func setupViews(myView: UIView, remoteView: UIView) { - self.interactor.setupViews(myView: myView, remoteView: remoteView) - } - - func updateTime(text: String) { - self.view.updateTime(text: text) - } - - func update(participants: [NYNCallParticipant]) { - - self.view.update(participants: participants) - } - - func viewShowed() { - self.interactor.setupDelegate() - } - - // MARK: EditParticpantsDelegate - - func updateGroupCall(contacts: [Contact]) { - - self.interactor.updateGroupCall(contacts:contacts) - } - - func participantsUpdated(contacts: [Contact]) { - - } - - func participantsUpdated(result: ParticipantsResult){ - - switch result { - case let .updateGroupCall(contacts): - updateGroupCall(contacts: contacts) - LogService.log(topic: .callSystem, text: "updateGroupCall") - default: - break - } - } - - // MARK: ManageCallParticipantsProtocol - func remove(participant: NYNCallParticipant?) { - interactor.removeCallMember(memberId: (participant?.memberId)!) - } - - func mute(participant: NYNCallParticipant?) { - - } - - func unmute(participant: NYNCallParticipant?) { - - } - -} diff --git a/Nynja/Modules/Call/View/CallViewController.swift b/Nynja/Modules/Call/View/CallViewController.swift deleted file mode 100644 index 55e62a48820ae829d3baa1535d0d48ae019467b9..0000000000000000000000000000000000000000 --- a/Nynja/Modules/Call/View/CallViewController.swift +++ /dev/null @@ -1,655 +0,0 @@ -// -// CallCallViewController.swift -// Nynja -// -// Created by Bohdan Paliychuk on 26/07/2017. -// Copyright © 2017 TecSynt Solutions. All rights reserved. -// - -enum CallMode { - case incamingCall - case incamingGroupCall - case outGoingCall - case outGoingGroupCall - case incamingVideoCall - case incamingVideoGroupCall - case outGoingVideoCall - case outGoingVideoGroupCall -} - -enum CallStatus { - case callStarting - case callIncomingAudio - case callIncomingVideo - case callOutgoingAudio - case callOutgoingVideo - case callConnecting - case callInProgress -} - -import UIKit - -class CallViewController: BaseVC, CallViewProtocol, BottomCallViewProtocol, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, GroupCollectionViewCellDelegate, GroupAddParticipantsCollectionViewCellDelegate { - - - var presenter: CallPresenterProtocol! - var contact: Contact? - var callMode: CallMode! - var callStatus: CallStatus! - var dataSource: NSMutableArray = [] - var moderator: Bool = false - var roomId: String = "" - - let bottomViewHeight: Float = 200.0 - let labelNameHeight: Float = 40.0 - let labelStatusHeight: Float = 30.0 - let offset: Float = 10.0 - let middleGVHeight: Float = 100.0 - let statusBarHeight: Float = Float(UIApplication.shared.statusBarFrame.size.height) - - lazy var expectedRowsInCollectionView: Int = { - - var sections:Int = 0 - - //Check which iPhone it is - let screenHeight:Float = Float(UIScreen.main.bounds.size.height) - - let clearSpace:Float = screenHeight - (bottomViewHeight + labelNameHeight + labelStatusHeight + statusBarHeight + 5*offset/*top offset + vertical spacing controlls offset*/) - - if 0 > clearSpace { - - sections = 3 - - } else { - - let minSectionHeight:Float = 83.0 - - sections = Int(floor(clearSpace/minSectionHeight)) - } - - return sections - }() - - lazy var contentView: UIView = { - let content = UIView() - - if (self.callMode == .outGoingGroupCall || self.callMode == .outGoingVideoGroupCall || self.callMode == .incamingVideoGroupCall || self.callMode == .incamingGroupCall) { - content.backgroundColor = Constants.colors.grayForCallScreenBottom.getColor() - } else { - content.backgroundColor = .clear - } - - self.view.addSubview(content) - content.snp.makeConstraints({ (make) in - make.top.left.right.bottom.equalTo(self.view) - }) - - return content - }() - - lazy var backgtoundImage: UIImageView = { - - let img = UIImageView() - img.isUserInteractionEnabled = true - img.contentMode = .scaleAspectFill - let height = UIScreen.main.bounds.height * 0.6 - self.contentView.addSubview(img) - - img.snp.makeConstraints({ (make) in - make.top.left.right.equalTo(self.view) - make.bottom.equalTo(self.bottomView).offset(-bottomViewHeight) - }) - return img - }() - - lazy var collectionView: UICollectionView = { - let layout = UICollectionViewFlowLayout() - layout.scrollDirection = .vertical - layout.minimumLineSpacing = 0 - layout.minimumInteritemSpacing = 0 - let cv = GroupCollectionView(frame: .zero, collectionViewLayout: layout) - cv.isUserInteractionEnabled = true - self.contentView.addSubview(cv) - cv.delegate = self - cv.dataSource = self - cv.backgroundColor = Constants.colors.grayForCallScreenBottom.getColor() - cv.register(GroupCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: GroupCollectionViewCell.self)) - cv.register(GroupAddParticipantsCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: GroupAddParticipantsCollectionViewCell.self)) - - cv.snp.makeConstraints({ (make) in - make.top.equalTo(self.statusLabel.snp.bottom).offset(offset) - make.left.right.equalTo(self.contentView) - make.bottom.equalTo(self.bottomView.snp.top) - - }) - return cv - }() - - private lazy var nameLabel: UILabel = { - let scwidth = UIScreen.main.bounds.width - let lbl = UILabel() - lbl.textAlignment = .center - lbl.font = UIFont(name: Constants.fonts.medium, size: 22.0) - lbl.textColor = Constants.colors.white.getColor() - lbl.numberOfLines = 1 -// lbl.adjustsFontSizeToFitWidth = true - lbl.baselineAdjustment = .alignCenters - lbl.lineBreakMode = .byTruncatingTail - self.contentView.addSubview(lbl) - - if (self.callMode == .outGoingGroupCall || self.callMode == .outGoingVideoGroupCall || self.callMode == .incamingVideoGroupCall || self.callMode == .incamingGroupCall) { - - lbl.snp.makeConstraints({ (make) in - make.top.equalTo(self.view).offset(3*offset) - make.centerX.equalTo(self.view) - make.height.equalTo(labelNameHeight) - }) - - } else { - - lbl.snp.makeConstraints({ (make) in - make.centerX.equalTo(self.view) - make.centerY.equalTo(self.view) - make.height.equalTo(40.0) - }) - } - - return lbl - }() - - private lazy var statusLabel: UILabel = { - let scwidth = UIScreen.main.bounds.width - let lbl = UILabel() - lbl.textAlignment = .center - lbl.font = UIFont(name: Constants.fonts.regular, size: 16.0) - lbl.textColor = Constants.colors.white.getColor() - lbl.backgroundColor = .clear - lbl.numberOfLines = 1 - lbl.adjustsFontSizeToFitWidth = true - lbl.baselineAdjustment = .alignCenters - lbl.lineBreakMode = .byClipping - self.contentView.addSubview(lbl) - - lbl.snp.makeConstraints({ (make) in - make.top.equalTo(self.nameLabel.snp.bottom).offset(offset) - make.left.right.equalTo(self.contentView) - make.height.equalTo(labelStatusHeight) - }) - - return lbl - }() - - - lazy var bottomView : BottomCallView = { - let lv = BottomCallView() - lv.backgroundColor = Constants.colors.grayForCallScreenBottom.getColor() - lv.delegate = self - let height = bottomViewHeight//UIScreen.main.bounds.width / 1.4 - - self.contentView.addSubview(lv) - lv.snp.makeConstraints({ (make) in - make.left.right.equalTo(self.contentView) - make.bottom.equalTo(self.contentView) - make.height.equalTo(height) - }) - - return lv - }() - - lazy var resizeVideoViewsButton : UIButton = { - let btn = UIButton() - let img = #imageLiteral(resourceName: "minimaze") - btn.setBackgroundImage(img, for: .normal) - let width = UIScreen.main.bounds.width * 0.088 - let height = UIScreen.main.bounds.width * 0.09 - btn.layer.masksToBounds = true - self.contentView.addSubview(btn) - let topPadding = UIScreen.main.bounds.width * 0.078 - let leftPadding = UIScreen.main.bounds.width * 0.037 - btn.addTarget(self, action: #selector(resizeButtonAction), for: .touchUpInside) - - btn.snp.makeConstraints({ (make) in - make.width.equalTo(width) - make.height.equalTo(height) - make.left.equalTo(self.contentView.snp.left).offset(leftPadding) - make.top.equalTo(self.contentView).offset(topPadding) - }) - return btn - }() - - lazy var yourVideoView: UIView = { - let content = UIView() - content.backgroundColor = .clear - self.contentVideoView.addSubview(content) - - let width = UIScreen.main.bounds.width * 0.256 - let height = UIScreen.main.bounds.width * 0.45 - let topPadding = UIScreen.main.bounds.width * 0.063 - let rightPadding = UIScreen.main.bounds.width * 0.016 - - content.snp.makeConstraints({ (make) in - make.width.equalTo(width) - make.height.equalTo(height) - make.right.equalTo(self.contentVideoView).offset(-rightPadding) - make.top.equalTo(self.contentVideoView).offset(topPadding) - }) - - return content - }() - - lazy var partnerVideoView: UIView = { - let content = UIView() - content.backgroundColor = .clear - self.contentVideoView.addSubview(content) - content.snp.makeConstraints({ (make) in - make.top.left.right.bottom.equalTo(self.contentVideoView) - }) - - return content - }() - - lazy var contentVideoView: UIView = { - let content = UIView() - content.backgroundColor = .clear - self.view.addSubview(content) - content.snp.makeConstraints({ (make) in - make.top.left.right.bottom.equalTo(self.view) - }) - - return content - }() - - lazy var backgtoundVideoImage: UIImageView = { - let img = UIImageView() - img.isUserInteractionEnabled = true - img.contentMode = .scaleAspectFit - self.contentVideoView.addSubview(img) - - img.snp.makeConstraints({ (make) in - make.top.left.right.bottom.equalTo(self.contentVideoView) - }) - return img - }() - - lazy var middleGradientView: GradientView = { - let view = GradientView(colors: [Constants.colors.grayForCallScreenTop.getColor(withAlpha: 0), Constants.colors.grayForCallScreenBottom.getColor()]) - self.bottomView.addSubview(view) - - view.snp.makeConstraints({ (make) in - make.top.equalTo(self.bottomView).offset(-middleGVHeight) - make.trailing.equalTo(self.view) - make.leading.equalTo(self.view) - make.height.equalTo(middleGVHeight) - }) - - return view - }() - - func setupUI() { - - self.contentView.isHidden = false - backImage.isHidden = true - - if (self.callMode == .outGoingGroupCall || self.callMode == .outGoingVideoGroupCall || self.callMode == .incamingVideoGroupCall || self.callMode == .incamingGroupCall) { - - self.middleGradientView.isHidden = true - self.backgtoundImage.isHidden = true - self.collectionView.isHidden = false - - } else { - - self.middleGradientView.isHidden = false - self.backgtoundImage.isHidden = false - self.collectionView.isHidden = true - - self.backgtoundImage.setImage(url: self.contact?.avatarUrl, placeHolder: UIImage(named: "ava_placeholder")) - } - - self.middleGradientView.isHidden = false - - var viewTitle:String = "" - - if let ctct = self.contact { - viewTitle = "\(ctct.names ?? "") \(ctct.surnames ?? "")" - } - - viewTitle = "call_incoming_audio_conference".localized - - if self.callMode == .outGoingVideoGroupCall || self.callMode == .outGoingGroupCall { - if self.presenter != nil { - if let room = RoomDAO.findRoom(by: self.roomId) { - if let rn = room.name { - viewTitle = rn - } - } - } - } - - nameLabel.text = viewTitle - - self.bottomView.backgroundColor = Constants.colors.grayForCallScreenBottom.getColor() - contentVideoView.isHidden = true - partnerVideoView.isHidden = true - switch self.callMode! { - case .incamingCall, .incamingGroupCall: - statusLabel.text = "call_incoming".localized - case .outGoingCall, .outGoingVideoCall, .outGoingGroupCall, .outGoingVideoGroupCall: - statusLabel.text = "call_connecting".localized - case .incamingVideoCall, .incamingVideoGroupCall: - statusLabel.text = "call_incoming_video".localized - } - - bottomView.setupCallView(withMode: self.callMode) - self.presenter.setupViews(myView: yourVideoView, remoteView: partnerVideoView) - } - - func updateCallBy(status: CallStatus) { - - self.callStatus = status - - switch self.callStatus { - case .callStarting: - statusLabel.text = "call_connecting".localized - break - case .callIncomingAudio: - statusLabel.text = "call_incoming".localized - break - case .callIncomingVideo: - self.bottomView.inCallVideo() - self.middleGradientView.isHidden = true - bottomView.backgroundColor = .clear - let hidden:Bool = (self.callMode == .outGoingGroupCall || self.callMode == .outGoingVideoGroupCall || self.callMode == .incamingVideoGroupCall || self.callMode == .incamingGroupCall) - backgtoundImage.isHidden = hidden - middleGradientView.isHidden = hidden - collectionView.isHidden = !hidden - statusLabel.isHidden = true - nameLabel.isHidden = true - resizeVideoViewsButton.isHidden = false - contentVideoView.isHidden = false - partnerVideoView.isHidden = false - contentView.bringSubview(toFront: yourVideoView) - self.view.bringSubview(toFront: contentView) - break - case .callOutgoingAudio: - statusLabel.text = "call_ringing".localized - self.bottomView.outGoingVideoCall() - break - case .callOutgoingVideo: - break - case .callConnecting: - break - case .callInProgress: - self.bottomView.inCall() - statusLabel.text = "voice_call_status".localized + " - 00:00" - let hidden:Bool = (self.callMode == .outGoingGroupCall || self.callMode == .outGoingVideoGroupCall || self.callMode == .incamingVideoGroupCall || self.callMode == .incamingGroupCall) - backgtoundImage.isHidden = hidden - middleGradientView.isHidden = hidden - collectionView.isHidden = !hidden - statusLabel.isHidden = false - nameLabel.isHidden = false - resizeVideoViewsButton.isHidden = true - contentVideoView.isHidden = true - partnerVideoView.isHidden = true - break - - default: break - - } - } - - func callFailed() { - self.bottomView.callFailed() - - statusLabel.text = "call_failed".localized - backgtoundImage.isHidden = true - middleGradientView.isHidden = true - collectionView.isHidden = true - statusLabel.isHidden = false - nameLabel.isHidden = false - } - - func remoteVideoStreamStopped() { - - backgtoundVideoImage.isHidden = false - backgtoundVideoImage.image = backgtoundImage.image - - partnerVideoView.isHidden = true - self.contentVideoView.bringSubview(toFront: self.yourVideoView) - } - - - @objc func resizeButtonAction() { - presenter.messageAcion(with: roomId, isVideo: true) - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - - // Note: need to prevent weird animation which appears when incoming/outcoming call appears. - self.view.layoutIfNeeded() - - self.presenter.viewShowed() - self.presenter.setupViews(myView: yourVideoView, remoteView: partnerVideoView) - - // Note: need to prevent weird animation with remote and local video views. - self.partnerVideoView.layoutIfNeeded() - self.yourVideoView.layoutIfNeeded() - } - - override func initialize() { - super.initialize() - - self.view.backgroundColor = Constants.colors.grayForCallScreenTop.getColor() - - self.presenter.willShow() - } - - //MARK: Collection View Delegates - public func numberOfSections(in collectionView: UICollectionView) -> Int { - - return 1 - } - - //2 - func collectionView(_ collectionView: UICollectionView, - numberOfItemsInSection section: Int) -> Int { - - var rows:Int = dataSource.count - - if rows > 0 { - rows = dataSource.count + 1 - } - - return rows - } - - //3 - func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - - let cell:UICollectionViewCell? - - if 0 == indexPath.row { - - let cellPlus:GroupAddParticipantsCollectionViewCell = - collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: GroupAddParticipantsCollectionViewCell.self), for: indexPath) as! GroupAddParticipantsCollectionViewCell - - cellPlus.delegate = self - - cell = cellPlus - } else { - - let cellPart:GroupCollectionViewCell = - collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: GroupCollectionViewCell.self), for: indexPath) as! GroupCollectionViewCell - - let callPart:NYNCallParticipant? = dataSource[indexPath.row - 1] as? NYNCallParticipant - - if let cp = callPart { - - cellPart.callPart = cp - cellPart.canRemove = self.moderator - cellPart.delegate = self - cellPart.updateCell() - - } else { - LogService.log(topic: .callSystem, text: "Illegal cell") - } - - cell = cellPart - } - - return cell! - } - - func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { - - let spacing : CGFloat = (collectionViewLayout as? UICollectionViewFlowLayout)?.minimumInteritemSpacing ?? 0.0 - let offsetIn:CGFloat = 5.0 - let cellHeight = floor((collectionView.bounds.size.height - ((CGFloat(expectedRowsInCollectionView) - 1)*spacing))/CGFloat(expectedRowsInCollectionView)) - let cellWidth = floor((0.75*(cellHeight - 3*offsetIn) + 2*offsetIn)) - - return CGSize(width: cellWidth, height: cellHeight) - } - - //MARK: Group Add Participants Collection View Cell delegates - - func didPressAddGroupCollectionCell(groupCollectionCell: GroupAddParticipantsCollectionViewCell) { - presenter.updateCallParticipants() - } - - //MARK: Group Collection View Cell delegates - - func showMenuWith(groupCollectionCell: GroupCollectionViewCell) { - presenter.showMenuWith(groupCollectionCell:groupCollectionCell) - } - - //MARK: bottom view delegate - - func acceptButtonPressed() { - presenter.acceptCall(withVideo: (self.callMode == .incamingVideoCall) || (self.callMode == .incamingVideoGroupCall)) - } - - func declineButtonPressed() { - - if self.callMode == .incamingVideoGroupCall || self.callMode == .incamingGroupCall { - if self.callStatus == .callInProgress { - if self.moderator { - askEndOrLeave() - } else { - presenter.declineCall() - } - } else { - presenter.rejectCall() - } - } else { - if self.moderator { - askEndOrLeave() - } else { - presenter.declineCall() - } - } - } - - func speakerButtonPressed() { - presenter.speakerAction() - } - - func messageButtonPressed() { - presenter.messageAcion(with: roomId, isVideo: false) - } - - func microphoneButtonPressed() { - presenter.microphoneAction() - } - - func toggleMicrophone() { - - presenter.toggleMicrophone() - } - - func isMuted()->Bool { - - return presenter.isMuted() - } - - func acceptAudioButtonPressed() { - if self.callMode == .incamingVideoCall || self.callMode == .incamingVideoGroupCall { - presenter.acceptCall(withVideo: false) - } else { - presenter.disableVideo() - } - } - - func switchCameraButtonPressed() { - presenter.switchCamera() - } - - func updateTime(text: String) { - statusLabel.text = "voice_call_status".localized + " - \(text)" - bottomView.timerLabel.text = text - } - - func changeUIToIncall() { - - self.updateCallBy(status: .callInProgress) - self.setupUI() - } - - func update(participants: [NYNCallParticipant]) { - - dataSource.removeAllObjects() - - for mem in participants { - - if let phoneId = mem.address { - - let contact:Contact? = ContactDAO.findContactBy(phoneId: phoneId) - - if let ct = contact { - - if let urlAvatar = ct.avatarUrl { - - mem.avatarUrl = urlAvatar.absoluteString - } - } - } - - dataSource.add(mem) - } - - collectionView.reloadData() - } - - func onCameraButtonPressed() { - - } - - func onMoreButtonPressed() { - - } - - func onPortOutButtonPressed() { - let alertVC = UIAlertController(title: "voice_call_the_feature_currently_unavailable".localized, message: nil, preferredStyle: .alert) - let okAction = UIAlertAction(title: "ok".localized, style: .cancel) { (action) in - alertVC.dismiss(animated: true, completion: nil) - } - alertVC.addAction(okAction) - - self.present(alertVC, animated: true, completion: nil) - } - - func askEndOrLeave() { - let alertVC = UIAlertController(title: "question_end_call".localized, message: nil, preferredStyle: .alert) - let forMeAction = UIAlertAction(title: "end_call_for_me".localized, style: .default) { (action) in - self.presenter.declineCall() - } - let forAllAction = UIAlertAction(title: "end_call_for_all".localized, style: .default) { (action) in - self.presenter.endCall() - } - - alertVC.addAction(forMeAction) - alertVC.addAction(forAllAction) - - self.present(alertVC, animated: true, completion: nil) - } - -} diff --git a/Nynja/Modules/Call/WireFrame/CallWireframe.swift b/Nynja/Modules/Call/WireFrame/CallWireframe.swift deleted file mode 100644 index 6de6c4e3b8e39a84da2ad81973750de850148f88..0000000000000000000000000000000000000000 --- a/Nynja/Modules/Call/WireFrame/CallWireframe.swift +++ /dev/null @@ -1,190 +0,0 @@ -// -// CallCallWireframe.swift -// Nynja -// -// Created by Bohdan Paliychuk on 26/07/2017. -// Copyright © 2017 TecSynt Solutions. All rights reserved. -// - -import UIKit -import VoxImplant - -class CallWireFrame: CallWireFrameProtocol { - - weak var navigation : UINavigationController? - weak var mainWF: MainWireFrame? - weak var call: VICall? - weak var view: CallViewProtocol! - weak var nynCall: NYNCall? - weak var external: EditParticipantsDelegate? - - func presentCall(navigation: UINavigationController, callMode: CallMode, contact: Contact, call: VICall? = nil, main: MainWireFrame?) { - - self.navigation = navigation - self.mainWF = main - - let view = CallViewController() - let presenter = CallPresenter() - let interactor = CallInteractor() - - interactor.call = call - - view.callMode = callMode - - self.view = view - main?.callVC = view - - presenter.type = callMode - presenter.contact = contact - - // Connecting - view.presenter = presenter - presenter.view = view - presenter.wireFrame = self - presenter.interactor = interactor - interactor.presenter = presenter - - navigation.pushViewController(view as UIViewController, animated: true) - } - - func presentDialInCall(navigation: UINavigationController, callMode: CallMode, call: NYNCall? = nil, main: MainWireFrame?) { - - let view = CallViewController() - let presenter = CallPresenter() - let interactor = CallInteractor() - interactor.nynCall = call - self.navigation = navigation - view.callMode = callMode - self.nynCall = call - self.view = view - self.mainWF = main - main?.callVC = view - - presenter.type = callMode - // Connecting - view.presenter = presenter - presenter.view = view - presenter.wireFrame = self - presenter.interactor = interactor - interactor.presenter = presenter - - navigation.pushViewController(view as UIViewController, animated: true) - } - - func presentCreateGroupCall(navigation: UINavigationController, callMode: CallMode, main: MainWireFrame?, call: NYNCall) { - - let view = CallViewController() - let presenter = CallPresenter() - let interactor = CallInteractor() - - self.external = presenter - - interactor.nynCall = call - self.navigation = navigation - view.callMode = callMode - view.moderator = call.isModerator - view.roomId = call.externalInfo - self.nynCall = call - self.view = view - self.mainWF = main - main?.callVC = view - - presenter.type = callMode - // Connecting - view.presenter = presenter - presenter.view = view - presenter.wireFrame = self - presenter.interactor = interactor - interactor.presenter = presenter - - navigation.pushViewController(view as UIViewController, animated: true) - } - - func messageActionWith(room: Room, isVideo: Bool) { - - if self.nynCall != nil { - self.navigation?.popViewController(animated: false) - self.navigation?.view.layoutIfNeeded() - (navigation?.viewControllers.last as? MainViewProtocol)?.presenter.showMessages(room: room, call: self.nynCall!, callVC: self.view!, isVideo: isVideo) - } - } - - func messageAction(isVideo: Bool, contact: Contact) { - self.navigation?.popViewController(animated: false) - self.navigation?.view.layoutIfNeeded() - (navigation?.viewControllers.last as? MainViewProtocol)?.presenter.showMessages(contact: contact, call: self.nynCall!, callVC: self.view!, isVideo: isVideo) - } - - func updateCallParticipants() { - - var members:[Member] = [] - var room:Room? - - if let nc = nynCall { - - for part in nc.participants { - - let member:Member = Member() - member.phone_id = part.address - members.append(member) - } - - if nc.externalInfo.count > 0 { - room = RoomDAO.findRoom(by: nc.externalInfo) - } - } - - AddParticipantsWireFrame().presentAddParticipants(navigation: navigation!, main: mainWF, selectedContacts: nil, delegate: external, mode: .updateGroupCall, members: members, room:room) - } - - func showMenuWith(participant: NYNCallParticipant?, delegate: ManageCallParticipantsProtocol) { - - let actionSheet = UIAlertController(title: nil, - message: nil, - preferredStyle: UIAlertControllerStyle.actionSheet) - - if (false == (participant?.isMe)!) { - actionSheet.addAction(UIAlertAction(title: "remove_participant_from_call".localized, - style: .default, - handler: { (action) in - delegate.remove(participant: participant) - })) - } - -// if participant.isMuted { -// actionSheet.addAction(UIAlertAction(title: "mute_call".localized, -// style: .default, -// handler: { (action) in -// delegate.mute(participant: participant) -// })) -// } else { -// actionSheet.addAction(UIAlertAction(title: "unmute".localized, -// style: .default, -// handler: { (action) in -// delegate.unmute(participant: participant) -// })) -// } - - actionSheet.addAction(UIAlertAction(title: "cancel".localized, style: .cancel, handler: { (action) in - - self.navigation?.dismiss(animated: true, completion: nil) - })) - - navigation?.present(actionSheet, animated: true, completion: nil) - } - - func removeParticipant(participant:NYNCallParticipant?) { - - } - - func muteParticipant(participant:NYNCallParticipant?) { - - - } - - func unmuteParticipant(participant:NYNCallParticipant?) { - - - } - -} diff --git a/Nynja/Modules/Main/Interactor/MainInteractor.swift b/Nynja/Modules/Main/Interactor/MainInteractor.swift index 2458db53eed71ff0437ac9f15a279b0a68c9a73f..f587c50d26852e966560197e8e441f5599a829eb 100644 --- a/Nynja/Modules/Main/Interactor/MainInteractor.swift +++ b/Nynja/Modules/Main/Interactor/MainInteractor.swift @@ -38,7 +38,7 @@ class MainInteractor: MainInteractorInputProtocol, VoxServiceDelegate, EditPhoto } func videoCall(name: String) { - //TODO: Call NynjaCommunicatorService with video true when ready + NynjaCommunicatorService.sharedInstance.call(user: name, withVideo: true) } func dialInGroup(name: String) { NynjaCommunicatorService.sharedInstance.dialInGroup(groupname: name) diff --git a/Nynja/Modules/Main/MainProtocols.swift b/Nynja/Modules/Main/MainProtocols.swift index b922560f97d2af550871ab2369729102ea0c9437..e038bed8e1f76dc3a19de16dc6422f16e4ca5fa3 100644 --- a/Nynja/Modules/Main/MainProtocols.swift +++ b/Nynja/Modules/Main/MainProtocols.swift @@ -33,6 +33,7 @@ protocol MainWireFrameProtocol: class { func showAddContactViaPhoneNumber() func showChatList() func showCreateConferenceCall() + func showNotImplemented() func sendAudio(withURL url: URL) func sendImage(with url: URL) @@ -57,9 +58,7 @@ protocol MainWireFrameProtocol: class { func getContact() -> String? func viewShowed() - func showMessages(contact: Contact, callVC: CallViewProtocol, isVideo: Bool) func showMessages(contact: Contact, callVC: CallInProgressViewProtocol, isVideo: Bool) - func showMessages(room: Room, callVC: CallViewProtocol, isVideo: Bool) func showMessages(room: Room, callVC: CallInProgressViewProtocol, isVideo: Bool) func showNotificationsSettings() func showWheelPositionPicker() @@ -165,8 +164,6 @@ protocol MainPresenterProtocol: class { func isActionEnabled() -> Bool func logout() func showLanguageSettings() - func showMessages(contact: Contact, call: NYNCall, callVC: CallViewProtocol, isVideo: Bool) - func showMessages(room: Room, call: NYNCall, callVC: CallViewProtocol, isVideo: Bool) func showMessages(contact: Contact, call: NYNCall, callVC: CallInProgressViewProtocol, isVideo: Bool) func showMessages(room: Room, call: NYNCall, callVC: CallInProgressViewProtocol, isVideo: Bool) diff --git a/Nynja/Modules/Main/Presenter/MainPresenter.swift b/Nynja/Modules/Main/Presenter/MainPresenter.swift index c10866612f49dc2c6d22adc2c0ac881015873047..374f50643fddad96b0d8a24041bbadd8670e5ecf 100644 --- a/Nynja/Modules/Main/Presenter/MainPresenter.swift +++ b/Nynja/Modules/Main/Presenter/MainPresenter.swift @@ -8,11 +8,11 @@ import VoxImplant class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, ScheduleMessageDelegate, EditParticipantsDelegate { - + func returnToCall() { self.wireFrame.returnToCall() } - + weak var view: MainViewProtocol! var interactor: MainInteractorInputProtocol! var wireFrame: MainWireFrameProtocol! @@ -21,23 +21,23 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu func showQRReader() { wireFrame.showQRReader() } - + func showContacts() { wireFrame.showContacts() } - + func showProfile() { wireFrame.showProfile() } - + func showAddContactViaPhoneNumber() { wireFrame.showAddContactViaPhoneNumber() } - + func showHistory() { wireFrame.showHistory() } - + func showInviteFriends() { PermissionManager().requestContactsPermission { (status) in if status == .authorized { @@ -45,7 +45,7 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu } } } - + func voiceCall() { if let name = wireFrame.getContact() { wireFrame.isVideo = false @@ -53,7 +53,7 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu interactor.call(name: name) } } - + func voiceGroupCall() { if let room = wireFrame.getRoom() { @@ -63,32 +63,32 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu //interactor.dialInGroup(name: room.id!) } } - + func videoCall() { - self.wireFrame.showNotImplementedAlert() + //TODO: To enable video call performVideoCall() } - + func videoGroupCall() { - + self.wireFrame.showNotImplementedAlert() } - + private func performVideoCall() { if let name = wireFrame.getContact() { wireFrame.isVideo = true interactor.videoCall(name: name) } } - + func showChatList() { wireFrame.showChatList() } - + func sendAudio(withURL url: URL) { wireFrame.sendAudio(withURL: url) } - + func sendImage(_ image: UIImage) { guard let url = ResourceManager(permissionManager: PermissionManager()).savePhoto(image: image, setting: .highest) else { LogService.log(topic: .fileSystem, text: "error save image") @@ -97,78 +97,57 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu wireFrame.sendImage(with: url) } - + func sendVideo(with url: URL) { wireFrame.sendVideo(with: url) } - + func getRecentsLocation() -> [LocationType] { return wireFrame.getRecentsLocation() } - + func getStarredLocation() -> [LocationType] { return wireFrame.getStarredLocation() } - + func getRecentsMedia() -> [Media] { return wireFrame.getRecentsMedia() } - + func sendTyping(_ isTyping: Bool) { wireFrame.sendTyping(isTyping) } - + func showMyContacts() { wireFrame.showMyContacts() } - + func viewShowed() { self.wireFrame.viewShowed() } - + func isActionEnabled() -> Bool { return wireFrame.getContact() != nil } - + func logout() { self.interactor.saveLogoutState() self.interactor.logout() self.changeScreenToAuth() } - + func changeScreenToAuth() { self.wireFrame.logout() } - - func showMessages(contact: Contact,call: NYNCall, callVC: CallViewProtocol, isVideo: Bool = false) { - - if isVideo { - if VoxService.sharedInstance.isRemoveVideoStream { - view.showPartnerVideoViewWithPhotoURL(url: contact.avatarUrl) - } else { - let prevView = self.view.showPartnerVideoView() - self.interactor.setVideoView(view: prevView) - } - } else { - self.view.showReturnToCall(call: call) - } - self.wireFrame.showMessages(contact: contact, callVC: callVC,isVideo: isVideo) - } - - func showMessages (room: Room, call: NYNCall, callVC: CallViewProtocol, isVideo: Bool = false) { - - self.view.showReturnToCall(call: call) - self.wireFrame.showMessages(room:room, callVC: callVC, isVideo: isVideo) - } func showMessages (room: Room, call: NYNCall, callVC: CallInProgressViewProtocol, isVideo: Bool = false) { - + self.view.showReturnToCall(call: call) self.wireFrame.showMessages(room:room, callVC: callVC, isVideo: isVideo) } - + func showMessages(contact: Contact, call: NYNCall, callVC: CallInProgressViewProtocol, isVideo: Bool) { - + if isVideo { if VoxService.sharedInstance.isRemoveVideoStream { view.showPartnerVideoViewWithPhotoURL(url: contact.avatarUrl) @@ -179,7 +158,7 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu } else { self.view.showReturnToCall(call: call) } - + self.wireFrame.showMessages(contact: contact, callVC: callVC,isVideo: isVideo) } @@ -187,31 +166,31 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu func openMapView() { self.wireFrame.openMapView() } - + func showLanguageSettings() { self.wireFrame.showLanguageSettings() } - + func about() { self.wireFrame.showSplash() } - + func showNotificationsSettings() { self.wireFrame.showNotificationsSettings() } - + func showWheelPositionPicker() { self.wireFrame.showWheelPositionPicker() } - + func showBuildNumber() { self.wireFrame.showBuildNumber() } - + func showChangeNumber() { self.wireFrame.showChangeNumber() } - + func conferenceVoiceCall() { wireFrame.showAddParticipantsToCreateConferenceCall() } @@ -224,19 +203,19 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu func showThemePicker() { self.wireFrame.showThemePicker() } - + func showSecuritySettings() { self.wireFrame.showSecuritySettings() } - + func showSupport() { self.wireFrame.showSupport() } - + func showPrivacy() { self.wireFrame.showPrivacy() } - + func showContactsToShare() { self.wireFrame.showContactsToShare() } @@ -255,63 +234,63 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu assertionFailure("Contact not found") } } - + func deleteAccount() { self.interactor.deleteAccount() self.wireFrame.logout() } - + func showDataAndStorage() { wireFrame.showDataAndStorage() } - + func showSettingsDataAndStorage(with usageMode: DataDownloadAndUsageMode) { wireFrame.showSettingsDataAndStorage(with: usageMode) } - + func showMySelfChat() { if let contact = self.interactor.contact { self.wireFrame.showMySelfChat(contact: contact) } } - + func showQRGenerator() { self.wireFrame.showQRGenerator() } - + func showAddContactByUserName() { self.wireFrame.showAddContactByUserName() } - + func showEditName() { self.wireFrame.showEditName() } - + func showEditUsername() { - self.wireFrame.showEditUsername() + self.wireFrame.showEditUsername() } - + // MARK: Group func showAddParticipants() { self.wireFrame.showAddParticipants() } - + func showGroupsList() { self.wireFrame.showGroupsList() } - + func showGroupsOptions() { self.wireFrame.showGroupsOptions() } - + func showUILocker() { view?.showUILocker() } - + func hideUILocker() { view?.hideUILocker() } - + // MARK: - ScheduleMessageDelegate func scheduleMessageHasBeenSent() { //TODO: @@ -320,11 +299,11 @@ class MainPresenter: MainPresenterProtocol, MainInteractorOutputProtocol, Schedu // MARK: EditParticpantsDelegate func participantsUpdated(contacts: [Contact]) { - + } - + func participantsUpdated(result: ParticipantsResult){ - + switch result { case let .createGroupCall(contacts, room): interactor.createGroupCall(contacts: contacts, room: room) diff --git a/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift b/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift index 0e98e7d7a20cf63e1299a8f441eaab44240c0627..3f079c41e007916c3d420b8e2a068f015ee14c26 100644 --- a/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift +++ b/Nynja/Modules/Main/View/MainViewController+NavigateProtocol.swift @@ -109,7 +109,6 @@ extension MainViewController: NavigateProtocol { closeWheel(indexPath: indexPath) } - // MARK: - Chat Actions func showMap(indexPath: IndexPath?) { diff --git a/Nynja/Modules/Main/WireFrame/MainWireframe.swift b/Nynja/Modules/Main/WireFrame/MainWireframe.swift index 9dd2be6247bea7216377cf8832b924152eaa890e..cadfc19e38691127e7481afb8837b3e69b653914 100644 --- a/Nynja/Modules/Main/WireFrame/MainWireframe.swift +++ b/Nynja/Modules/Main/WireFrame/MainWireframe.swift @@ -81,6 +81,17 @@ class MainWireFrame: MainWireFrameProtocol, VoxServiceDelegate, NynjaCommunicato AddParticipantsWireFrame().presentAddParticipants(navigation: contentNavigation!, main: self, selectedContacts: [], delegate: self.external, mode: .createConferenceCall, members:[] , room: nil) } + func showNotImplemented() { + + let alertVC = UIAlertController(title: "voice_call_the_feature_currently_unavailable".localized, message: nil, preferredStyle: .alert) + let okAction = UIAlertAction(title: "ok".localized, style: .cancel) { (action) in + alertVC.dismiss(animated: true, completion: nil) + } + alertVC.addAction(okAction) + + self.view?.present(alertVC, animated: true, completion: nil) + } + func showContactsToShare() { ContactsWireFrame().presentContacts(navigation: contentNavigation, contactsViewMode: .shareContact, mainWireFrame: self) @@ -201,31 +212,12 @@ class MainWireFrame: MainWireFrameProtocol, VoxServiceDelegate, NynjaCommunicato } func incomingCall(call: VICall, isVideo: Bool) { - self.view?.view.endEditing(true) - self.call = call - if isVideo { - CallWireFrame().presentCall(navigation: self.navigation!, callMode:self.isGroup ? .incamingVideoGroupCall : .incamingVideoCall, contact: self.getNameFrom(call: call), call: call, main: self) - } else { - CallWireFrame().presentCall(navigation: self.navigation!, callMode:self.isGroup ? .incamingGroupCall : .incamingCall, contact: self.getNameFrom(call: call), call: call, main: self) - } } func ringing(call: VICall) { - self.view?.view.endEditing(true) - self.call = call - let callMode: CallMode = self.isGroup ? (self.isVideo ? .outGoingVideoGroupCall : .outGoingGroupCall) : (self.isVideo ? .outGoingVideoCall : .outGoingCall) - CallWireFrame().presentCall(navigation: navigation!, callMode: callMode, contact: self.getNameFrom(call: call), call: call, main: self) } func callClosed(call: VICall, isError: Bool) { - if !isVideo { - self.hideReturnToCallView() - } - if isVideo { - self.view?.hidePartnerVideoView() - } - navigation?.popViewController(animated: true) - navigation?.dismiss(animated: true, completion: nil) } func getNameFrom(call: VICall) -> Contact { @@ -241,21 +233,10 @@ class MainWireFrame: MainWireFrameProtocol, VoxServiceDelegate, NynjaCommunicato return contact } - var callVC :CallViewProtocol? var callInProgressVC :CallInProgressViewProtocol? var isVideo: Bool = false var isGroup: Bool = false - func showMessages(contact: Contact, callVC: CallViewProtocol, isVideo: Bool = false) { - self.isVideo = isVideo - self.view?.view.endEditing(true) - self.callVC = callVC - - if !isVideo { - self.showReturnToCallView() - } - showChat(contact) - } func showMessages(contact: Contact, callVC: CallInProgressViewProtocol, isVideo: Bool = false) { self.isVideo = isVideo @@ -268,19 +249,6 @@ class MainWireFrame: MainWireFrameProtocol, VoxServiceDelegate, NynjaCommunicato showChat(contact) } - func showMessages(room: Room, callVC: CallViewProtocol, isVideo: Bool = false) { - - self.isVideo = isVideo - self.view?.view.endEditing(true) - self.callVC = callVC - - if !isVideo { - self.showReturnToCallView() - } - - showChat(room) - } - func showMessages(room: Room, callVC: CallInProgressViewProtocol, isVideo: Bool = false) { self.isVideo = isVideo @@ -295,11 +263,7 @@ class MainWireFrame: MainWireFrameProtocol, VoxServiceDelegate, NynjaCommunicato } func callEnded(call: NYNCall, isError: Bool) { - - } - - func stateDidChange(call: NYNCall, state: NYNCallState) { - //TODO: Propagate to call view + self.hideReturnToCallView() } func viewShowed() { @@ -325,7 +289,6 @@ class MainWireFrame: MainWireFrameProtocol, VoxServiceDelegate, NynjaCommunicato func hideReturnToCallView() { updateTopContentNavigationOffset(0) - self.callVC = nil self.view?.hideReturnToCall() } @@ -340,9 +303,6 @@ class MainWireFrame: MainWireFrameProtocol, VoxServiceDelegate, NynjaCommunicato isVideo = false self.showReturnToCallView() self.view?.hidePartnerVideoView() - if let callVC = callVC as? CallViewController { - callVC.changeUIToIncall() - } // if let call = self.call { // self.view?.showReturnToCall(call: call) @@ -351,13 +311,7 @@ class MainWireFrame: MainWireFrameProtocol, VoxServiceDelegate, NynjaCommunicato func returnToCall() { - if callVC != nil { - - self.navigation?.pushViewController(callVC as! UIViewController, animated: true) - if !self.isVideo { - self.hideReturnToCallView() - } - } else if callInProgressVC != nil { + if callInProgressVC != nil { self.navigation?.pushViewController(callInProgressVC as! UIViewController, animated: true) if !self.isVideo { @@ -563,6 +517,7 @@ class MainWireFrame: MainWireFrameProtocol, VoxServiceDelegate, NynjaCommunicato func presentCallInProgressViewForCall(call:NYNCall) { + self.isVideo = call.recvVideo let callMode: CallInProgressMode = self.isVideo ? .oneToOneVideo : call.isConference() ? .groupAudio : .oneToOneAudio if callMode == .groupAudio { diff --git a/Nynja/Modules/Message/View/Views/TableView/MessageTableViewDelegate.swift b/Nynja/Modules/Message/View/Views/TableView/MessageTableViewDelegate.swift index cad450d335e90059a544a7a844029b148d5d036b..478d7105ac7f6c56c96fbcccb3f3e1b4ba2d70b6 100644 --- a/Nynja/Modules/Message/View/Views/TableView/MessageTableViewDelegate.swift +++ b/Nynja/Modules/Message/View/Views/TableView/MessageTableViewDelegate.swift @@ -150,6 +150,14 @@ class MessageTableViewDelegate: NSObject, UITableViewDelegate, CallInfoViewDeleg // MARK: CallInfoVIewDelegate func didPressButtonJoinIn(callInfoView: CallInfoView) { - self.view?.rejoinRunningCall() + + AlertManager.sharedInstance.showAlertWithTwoActions(title: "", + message: "are_u_sure_join_the_call".localized, + firstActionTitle: "no".localized, + secondActionTitle: "yes".localized, + firstAction: nil, + secondAction: { + self.view?.rejoinRunningCall() + }) } } diff --git a/Nynja/Resources/en.lproj/Localizable.strings b/Nynja/Resources/en.lproj/Localizable.strings index 960dd85eb1d49f0851753537e6e3be403155fe8e..4ffac8afe5bf88bca763cc20ed87f5dd07c8c814 100644 --- a/Nynja/Resources/en.lproj/Localizable.strings +++ b/Nynja/Resources/en.lproj/Localizable.strings @@ -396,6 +396,7 @@ "unblock"="Unblock"; "are_u_sure_block"="Are you sure you want to block this user?"; "are_u_sure_unblock"="Are you sure you want to unblock this user?"; +"are_u_sure_join_the_call"="Do you want to join the call?"; "send_message"="Send a message"; "add_contact"="Add to contacts"; "u_are_blocked"="You are blocked"; @@ -595,6 +596,7 @@ // MARK: Call "voice_call_status"="Voice Call"; +"video_call_status"="Video Call"; "voice_call_the_feature_currently_unavailable"="This feature is currently unavailable"; // MARK: Settings group diff --git a/Nynja/Resources/ru.lproj/Localizable.strings b/Nynja/Resources/ru.lproj/Localizable.strings index 6443ea3ae0914f9affff52bc731fbe0a6b248ac7..5babdbb26ebbc766dece34f8bb1e4ecbc5fe894e 100644 --- a/Nynja/Resources/ru.lproj/Localizable.strings +++ b/Nynja/Resources/ru.lproj/Localizable.strings @@ -360,6 +360,7 @@ "unblock"="Разблокировать"; "are_u_sure_block"="Вы уверены, что хотите заблокировать этого пользователя?"; "are_u_sure_unblock"="Вы уверены что хотите разблокировать этого пользователя?"; +"are_u_sure_join_the_call"="Вы хотите присоединиться к вызову?"; "send_message"="Отправить сообщение"; "add_contact"="Добавить в контакты"; "u_are_blocked"="Вы заблокированы"; @@ -556,6 +557,7 @@ // MARK: Call "voice_call_status"="Телефонный звонок"; +"video_call_status"="Видео звонок"; "voice_call_the_feature_currently_unavailable"="Эта функция в данный момент недоступна"; // MARK: Settings group diff --git a/Nynja/Services/NynjaCommunicatorService.swift b/Nynja/Services/NynjaCommunicatorService.swift index 6d503e1114d2648de38465d12526b4ec6ac61906..4579d5a1a9cb5f0003359a49a4635dd2892ce709 100644 --- a/Nynja/Services/NynjaCommunicatorService.swift +++ b/Nynja/Services/NynjaCommunicatorService.swift @@ -12,28 +12,46 @@ import NynjaSDK protocol NynjaCommunicatorServiceDelegate: class { func dialing(call: NYNCall) func creatingGroupCall(name: String, call: NYNCall) - func callEnded(call: NYNCall, isError: Bool) - func stateDidChange(call: NYNCall, state: NYNCallState) - func participantsUpdated(call: NYNCall) func incomingCallRinging(call: NYNCall) - func conferenceCreated(call: NYNCall) + func callEnded(call: NYNCall, isError: Bool) } extension NynjaCommunicatorServiceDelegate { func dialing(call: NYNCall) {} func creatingGroupCall(name: String, call: NYNCall){} + func incomingCallRinging(call: NYNCall){} + func callEnded(call: NYNCall, isError: Bool){} +} + +protocol NynjaCallDelegate: class { + func callEnded(call: NYNCall, isError: 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) + func didStopLocalCapturerForCall(call: NYNCall) +} + +extension NynjaCallDelegate { func callEnded(call: NYNCall, isError: Bool) {} - func stateDidChange(call: NYNCall, state: NYNCallState){} + func stateDidChange(call: NYNCall, state: NYNCallState) {} func participantsUpdated(call: NYNCall){} - func incomingCallRinging(call: NYNCall){} func conferenceCreated(call: NYNCall) {} + func didAddVideoStreamForCall(call: NYNCall) {} + func didRemoveVideoStreamForCall(call: NYNCall) {} + func didStartLocalCapturerForCall(call: NYNCall) {} + func didStopLocalCapturerForCall(call: NYNCall) {} } class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDelegate, NYNCallManagerDelegate { + let nynComm: NynjaCommunicator var isCallInProgress = false weak var delegate : NynjaCommunicatorServiceDelegate? + weak var callDelegate : NynjaCallDelegate? var call:NYNCall? private var creators: [String: CallCreatorMediator] = [String: CallCreatorMediator]() var username: String? @@ -116,7 +134,8 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele self.nynComm.getCallManager().createConference(withRequestId: creator.createId, withExternalId: UUID().uuidString, - withRequestInfo: creator.roomId) + withRequestInfo: creator.roomId, + withSubject: creator.name) } func addConferenceMember(conferenceId:String, phoneId: String, name:String) { @@ -232,7 +251,7 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele func didChangeConferenceState(_ state: NYNCallState) { if let c = self.call { - self.delegate?.stateDidChange(call: c, state: state) + self.callDelegate?.stateDidChange(call: c, state: state) } } @@ -256,6 +275,30 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele }; } + func attachRemoteVideoRenderer(inView view: UIView) { + if let call = self.call { + call.attachRemoteRenderer(to: view) + } + } + + func attachLocalVideoPreview(inView view: UIView) { + if let call = self.call { + call.attachLocalPreview(to: view) + } + } + + func detachLocalVideoPreview(inView view: UIView) { + if let call = self.call { + call.detachLocalPreview(from: view) + } + } + + func switchCamera() { + if let call = self.call { + call.switchCamera() + } + } + //MARK: Helpers func getMySelf() -> Contact? { @@ -347,6 +390,7 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele func callDidEnd(_ call: NYNCall) { isCallInProgress = false if let c = self.call, call.callId.elementsEqual(c.callId) { + self.callDelegate?.callEnded(call: c, isError: false) self.delegate?.callEnded(call: c, isError: false) self.call?.setDelegate(nil) self.call = nil @@ -358,7 +402,7 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele LogService.log(topic: .callSystem, text: log) if let c = self.call, let cid = callid { if c.callId.elementsEqual(cid) { - self.delegate?.stateDidChange(call: c, state: state) + self.callDelegate?.stateDidChange(call: c, state: state) } } } @@ -368,7 +412,43 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele LogService.log(topic: .callSystem, text: log) if let c = self.call, let cid = callid { if cid.elementsEqual(c.callId) { - self.delegate?.participantsUpdated(call: c) + self.callDelegate?.participantsUpdated(call: c) + } + } + } + + func call(_ call: NYNCall, didAddRemoteVideoTrack trackId: String) { + let log = NSString(format: "callWithIdDidAddStream: ", self) as String + LogService.log(topic: .callSystem, text: log) + if let c = self.call{ + if c.callId.elementsEqual(call.callId) { + self.callDelegate?.didAddVideoStreamForCall(call: call) + } + } + } + + func call(_ call: NYNCall, didRemoveRemoteVideoTrack trackId: String) { + let log = NSString(format: "callWithIdDidRemoVeStream: ", self) as String + LogService.log(topic: .callSystem, text: log) + if let c = self.call { + if c.callId.elementsEqual(call.callId) { + self.callDelegate?.didRemoveVideoStreamForCall(call: call) + } + } + } + + func callDidStartLocalCapturer(_ call: NYNCall) { + if let c = self.call{ + if c.callId.elementsEqual(call.callId) { + self.callDelegate?.didStartLocalCapturerForCall(call: call) + } + } + } + + func callDidStopLocalCapturer(_ call: NYNCall) { + if let c = self.call{ + if c.callId.elementsEqual(call.callId) { + self.callDelegate?.didStopLocalCapturerForCall(call: call) } } } @@ -431,7 +511,7 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele self.nynComm.getCallManager().startConference(withRequestId: cr.startId!, withConferenceId: cr.conferenceId!) guard let call = self.call else { return } - self.delegate?.conferenceCreated(call: call) + self.callDelegate?.conferenceCreated(call: call) } } } @@ -469,7 +549,7 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele // clean up call if let c = self.call, c.callId.elementsEqual(cr.conferenceId!) { - self.delegate?.callEnded(call: c, isError: true) + self.callDelegate?.callEnded(call: c, isError: true) self.call?.setDelegate(nil) self.call = nil isCallInProgress = false @@ -495,7 +575,7 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele // clean up call if let c = self.call, call.callId.elementsEqual(cr.conferenceId!) { - self.delegate?.callEnded(call: c, isError: true) + self.callDelegate?.callEnded(call: c, isError: true) self.call?.setDelegate(nil) self.call = nil isCallInProgress = false @@ -550,7 +630,7 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele func didStopRingingIncomingCall(withId conferenceId: String) { // clean up call if let c = self.call, c.callId.elementsEqual(conferenceId) { - self.delegate?.callEnded(call: c, isError: false) + self.callDelegate?.callEnded(call: c, isError: false) self.call?.setDelegate(nil) self.call = nil isCallInProgress = false @@ -583,4 +663,5 @@ class NynjaCommunicatorService: NSObject, NynjaCommunicatorDelegate, NYNCallDele func callStateDidChange(_ call: NYNCall) { self.messageInteractorCallProtocol?.didChangeCallInvitationState(call) } + } diff --git a/Podfile b/Podfile index 03dab61bd237cdc8d9278186270d037064265d08..b198b57c0eb47026a361257e2a1cb7b182297d55 100644 --- a/Podfile +++ b/Podfile @@ -28,19 +28,19 @@ def commonPodsForNynja pod 'CocoaLumberjack', :git => 'https://github.com/CocoaLumberjack/CocoaLumberjack', :commit => '12948ff' pod 'AWSS3', '~> 2.6.1' pod 'SDWebImage', '~> 4.0' - + pod 'GoogleMaps' pod 'GooglePlaces' pod 'Firebase/Storage' pod 'Firebase/Auth' pod 'GRDBCipher', '~> 2.10.0' pod 'SwiftyJSON', '~> 4.0.0' - + pod 'AutoScrollLabel' pod 'MaterialComponents/FlexibleHeader' pod 'JTAppleCalendar', '~> 7.0' - - pod 'NynjaSDK', '~> 1.3.3' + + pod 'NynjaSDK', '~> 1.4.0' pod 'CryptoSwift' end @@ -56,11 +56,11 @@ def commonPodsForNynjaTests pod 'CocoaLumberjack', :git => 'https://github.com/CocoaLumberjack/CocoaLumberjack', :commit => '12948ff' pod 'AWSS3', '~> 2.6.1' pod 'SDWebImage', '~> 4.0' - + pod 'GoogleMaps' pod 'GooglePlaces' pod 'GRDBCipher', '~> 2.10.0' - + pod 'AutoScrollLabel' pod 'MaterialComponents/FlexibleHeader' pod 'JTAppleCalendar', '~> 7.0' @@ -110,7 +110,7 @@ post_install do |installer| config.build_settings['SWIFT_VERSION'] = '4.0' end end - + installer.pods_project.build_configurations.each do |config| config.build_settings['PROVISIONING_PROFILE_SPECIFIER'] = '' end diff --git a/externals/mobile-sdk-s4 b/externals/mobile-sdk-s4 new file mode 160000 index 0000000000000000000000000000000000000000..5bd083a74dcf787903cee307fbf9ab945b326708 --- /dev/null +++ b/externals/mobile-sdk-s4 @@ -0,0 +1 @@ +Subproject commit 5bd083a74dcf787903cee307fbf9ab945b326708