Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 1 | /* |
Alexandre Lision | 9fe374b | 2016-01-06 10:17:31 -0500 | [diff] [blame] | 2 | * Copyright (C) 2015-2016 Savoir-faire Linux Inc. |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 3 | * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com> |
| 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation; either version 3 of the License, or |
| 8 | * (at your option) any later version. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software |
| 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 18 | */ |
| 19 | #import "CurrentCallVC.h" |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 20 | extern "C" { |
| 21 | #import "libavutil/frame.h" |
| 22 | #import "libavutil/display.h" |
| 23 | } |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 24 | |
| 25 | #import <QuartzCore/QuartzCore.h> |
| 26 | |
Alexandre Lision | 210fe21 | 2016-01-27 11:15:13 -0500 | [diff] [blame] | 27 | ///Qt |
| 28 | #import <QMimeData> |
| 29 | #import <QtMacExtras/qmacfunctions.h> |
| 30 | #import <QtCore/qabstractitemmodel.h> |
Alexandre Lision | 210fe21 | 2016-01-27 11:15:13 -0500 | [diff] [blame] | 31 | #import <QPixmap> |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 32 | #import <QUrl> |
Alexandre Lision | 210fe21 | 2016-01-27 11:15:13 -0500 | [diff] [blame] | 33 | |
| 34 | ///LRC |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 35 | #import <video/renderer.h> |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 36 | #import <api/newcallmodel.h> |
| 37 | #import <api/call.h> |
| 38 | #import <api/conversationmodel.h> |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 39 | #import <api/avmodel.h> |
Alexandre Lision | 210fe21 | 2016-01-27 11:15:13 -0500 | [diff] [blame] | 40 | #import <globalinstances.h> |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 41 | |
Alexandre Lision | 6200531 | 2016-01-28 15:55:16 -0500 | [diff] [blame] | 42 | #import "AppDelegate.h" |
Alexandre Lision | f47a256 | 2015-06-15 15:48:29 -0400 | [diff] [blame] | 43 | #import "views/ITProgressIndicator.h" |
Alexandre Lision | 74dd47f | 2015-04-14 13:47:42 -0400 | [diff] [blame] | 44 | #import "views/CallView.h" |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 45 | #import "views/NSColor+RingTheme.h" |
Alexandre Lision | 210fe21 | 2016-01-27 11:15:13 -0500 | [diff] [blame] | 46 | #import "delegates/ImageManipulationDelegate.h" |
Alexandre Lision | 16d9c0a | 2015-08-10 12:05:15 -0400 | [diff] [blame] | 47 | #import "ChatVC.h" |
Alexandre Lision | 4baba4c | 2016-02-11 13:00:57 -0500 | [diff] [blame] | 48 | #import "views/IconButton.h" |
Anthony Léonard | 6f81975 | 2018-01-05 09:53:40 -0500 | [diff] [blame] | 49 | #import "utils.h" |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 50 | #import "views/CallMTKView.h" |
Kateryna Kostiuk | c5fd3b9 | 2019-07-24 10:12:44 -0400 | [diff] [blame] | 51 | #import "VideoCommon.h" |
Kateryna Kostiuk | 88a6ee8 | 2019-09-10 17:55:08 -0400 | [diff] [blame] | 52 | #import "views/GradientView.h" |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 53 | #import "views/MovableView.h" |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 54 | #import "views/RenderingView.h" |
Alexandre Lision | 74dd47f | 2015-04-14 13:47:42 -0400 | [diff] [blame] | 55 | |
Kateryna Kostiuk | 1ba5a01 | 2018-12-12 17:07:38 -0500 | [diff] [blame] | 56 | @interface CurrentCallVC () <NSPopoverDelegate> { |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 57 | QString convUid_; |
| 58 | QString callUid_; |
| 59 | QString confUid_; |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 60 | const lrc::api::account::Info *accountInfo_; |
Anthony Léonard | 66a050c | 2018-01-03 16:32:34 -0500 | [diff] [blame] | 61 | NSTimer* refreshDurationTimer; |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 62 | } |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 63 | |
Alexandre Lision | 210fe21 | 2016-01-27 11:15:13 -0500 | [diff] [blame] | 64 | // Main container |
| 65 | @property (unsafe_unretained) IBOutlet NSSplitView* splitView; |
Kateryna Kostiuk | 89398b6 | 2018-11-20 16:45:04 -0500 | [diff] [blame] | 66 | @property (unsafe_unretained) IBOutlet NSView* backgroundImage; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 67 | @property (unsafe_unretained) IBOutlet NSBox* bluerBackgroundEffect; |
Alexandre Lision | 210fe21 | 2016-01-27 11:15:13 -0500 | [diff] [blame] | 68 | |
Alexandre Lision | 89edc6a | 2015-11-09 11:30:47 -0500 | [diff] [blame] | 69 | // Header info |
| 70 | @property (unsafe_unretained) IBOutlet NSView* headerContainer; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 71 | @property (unsafe_unretained) IBOutlet NSView* headerGradientView; |
Alexandre Lision | 89edc6a | 2015-11-09 11:30:47 -0500 | [diff] [blame] | 72 | @property (unsafe_unretained) IBOutlet NSTextField* timeSpentLabel; |
| 73 | |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 74 | // info |
| 75 | @property (unsafe_unretained) IBOutlet NSStackView* infoContainer; |
| 76 | @property (unsafe_unretained) IBOutlet NSImageView* contactPhoto; |
| 77 | @property (unsafe_unretained) IBOutlet NSTextField* contactNameLabel; |
| 78 | @property (unsafe_unretained) IBOutlet NSTextField* callStateLabel; |
| 79 | @property (unsafe_unretained) IBOutlet NSTextField* contactIdLabel; |
| 80 | @property (unsafe_unretained) IBOutlet IconButton* cancelCallButton; |
| 81 | @property (unsafe_unretained) IBOutlet IconButton* pickUpButton; |
| 82 | @property (unsafe_unretained) IBOutlet ITProgressIndicator *loadingIndicator; |
Andreas Traczyk | 77a50d5 | 2018-05-08 17:47:31 -0400 | [diff] [blame] | 83 | |
Alexandre Lision | 89edc6a | 2015-11-09 11:30:47 -0500 | [diff] [blame] | 84 | // Call Controls |
Kateryna Kostiuk | 88a6ee8 | 2019-09-10 17:55:08 -0400 | [diff] [blame] | 85 | @property (unsafe_unretained) IBOutlet GradientView* controlsPanel; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 86 | @property (unsafe_unretained) IBOutlet NSStackView* controlsStackView; |
Alexandre Lision | 6200531 | 2016-01-28 15:55:16 -0500 | [diff] [blame] | 87 | |
Alexandre Lision | 4baba4c | 2016-02-11 13:00:57 -0500 | [diff] [blame] | 88 | @property (unsafe_unretained) IBOutlet IconButton* holdOnOffButton; |
| 89 | @property (unsafe_unretained) IBOutlet IconButton* hangUpButton; |
| 90 | @property (unsafe_unretained) IBOutlet IconButton* recordOnOffButton; |
Alexandre Lision | 4baba4c | 2016-02-11 13:00:57 -0500 | [diff] [blame] | 91 | @property (unsafe_unretained) IBOutlet IconButton* muteAudioButton; |
| 92 | @property (unsafe_unretained) IBOutlet IconButton* muteVideoButton; |
Alexandre Lision | 4baba4c | 2016-02-11 13:00:57 -0500 | [diff] [blame] | 93 | @property (unsafe_unretained) IBOutlet IconButton* transferButton; |
| 94 | @property (unsafe_unretained) IBOutlet IconButton* addParticipantButton; |
| 95 | @property (unsafe_unretained) IBOutlet IconButton* chatButton; |
Andreas Traczyk | 77a50d5 | 2018-05-08 17:47:31 -0400 | [diff] [blame] | 96 | @property (unsafe_unretained) IBOutlet IconButton* qualityButton; |
Alexandre Lision | d18fa27 | 2015-06-15 11:18:03 -0400 | [diff] [blame] | 97 | |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 98 | // Video |
Alexandre Lision | 58cab67 | 2015-06-09 15:25:40 -0400 | [diff] [blame] | 99 | @property (unsafe_unretained) IBOutlet CallView *videoView; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 100 | @property (unsafe_unretained) IBOutlet RenderingView *previewView; |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 101 | @property (unsafe_unretained) IBOutlet MovableView *movableBaseForView; |
| 102 | @property (unsafe_unretained) IBOutlet NSView* hidePreviewBackground; |
| 103 | @property (unsafe_unretained) IBOutlet NSButton* hidePreviewButton; |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 104 | |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 105 | @property (unsafe_unretained) IBOutlet RenderingView *distantView; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 106 | |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 107 | @property RendererConnectionsHolder* renderConnections; |
Alexandre Lision | ef6333a | 2015-03-24 12:30:31 -0400 | [diff] [blame] | 108 | @property QMetaObject::Connection videoStarted; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 109 | @property QMetaObject::Connection callStateChanged; |
Alexandre Lision | b65c027 | 2015-07-22 15:51:29 -0400 | [diff] [blame] | 110 | @property QMetaObject::Connection messageConnection; |
Kateryna Kostiuk | 133364b | 2018-10-31 11:36:08 -0400 | [diff] [blame] | 111 | @property QMetaObject::Connection profileUpdatedConnection; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 112 | |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 113 | //conference |
| 114 | @property (unsafe_unretained) IBOutlet NSStackView *callingWidgetsContainer; |
| 115 | |
| 116 | @property (strong) NSPopover* brokerPopoverVC; |
| 117 | |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 118 | @property (strong) IBOutlet ChatVC* chatVC; |
| 119 | |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 120 | @end |
| 121 | |
| 122 | @implementation CurrentCallVC |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 123 | lrc::api::AVModel* mediaModel; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 124 | NSMutableDictionary *connectingCalls; |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 125 | |
| 126 | NSInteger const PREVIEW_WIDTH = 185; |
| 127 | NSInteger const PREVIEW_HEIGHT = 130; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 128 | NSInteger const HIDE_PREVIEW_BUTTON_SIZE = 25; |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 129 | NSInteger const PREVIEW_MARGIN = 20; |
| 130 | |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 131 | @synthesize holdOnOffButton, hangUpButton, recordOnOffButton, pickUpButton, chatButton, transferButton, addParticipantButton, timeSpentLabel, muteVideoButton, muteAudioButton, controlsPanel, headerContainer, videoView, previewView, splitView, loadingIndicator, backgroundImage, bluerBackgroundEffect, hidePreviewButton, hidePreviewBackground, movableBaseForView, infoContainer, contactPhoto, contactNameLabel, callStateLabel, contactIdLabel, cancelCallButton, headerGradientView, controlsStackView, callingWidgetsContainer, brokerPopoverVC; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 132 | |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 133 | @synthesize renderConnections; |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 134 | CVPixelBufferPoolRef pixelBufferPoolDistantView; |
| 135 | CVPixelBufferRef pixelBufferDistantView; |
| 136 | CVPixelBufferPoolRef pixelBufferPoolPreview; |
| 137 | CVPixelBufferRef pixelBufferPreview; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 138 | |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 139 | /* update call and conversation info |
| 140 | * set info for chat view |
| 141 | * connect signals |
| 142 | */ |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 143 | -(void) setCurrentCall:(const QString&)callUid |
| 144 | conversation:(const QString&)convUid |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 145 | account:(const lrc::api::account::Info*)account |
| 146 | avModel:(lrc::api::AVModel *)avModel; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 147 | { |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 148 | if(account == nil) |
| 149 | return; |
Alexandre Lision | ef6333a | 2015-03-24 12:30:31 -0400 | [diff] [blame] | 150 | |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 151 | mediaModel = avModel; |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 152 | auto* callModel = account->callModel.get(); |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 153 | |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 154 | if (not callModel->hasCall(callUid)){ |
| 155 | callUid_.clear(); |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 156 | confUid_.clear(); |
Alexandre Lision | 2db8f47 | 2015-07-22 15:05:46 -0400 | [diff] [blame] | 157 | return; |
| 158 | } |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 159 | callUid_ = callUid; |
| 160 | convUid_ = convUid; |
| 161 | accountInfo_ = account; |
Kateryna Kostiuk | 3541ae2 | 2020-08-17 12:26:14 -0400 | [diff] [blame] | 162 | auto convIt = getConversationFromUid(convUid_, *accountInfo_->conversationModel); |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 163 | confUid_ = convIt->confId; |
Anthony Léonard | 4b0935f | 2017-12-26 12:05:22 -0500 | [diff] [blame] | 164 | [self.chatVC setConversationUid:convUid model:account->conversationModel.get()]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 165 | [self connectSignals]; |
| 166 | } |
| 167 | |
| 168 | -(void) connectSignals { |
| 169 | auto* callModel = accountInfo_->callModel.get(); |
| 170 | auto* convModel = accountInfo_->conversationModel.get(); |
| 171 | //monitor for updated call state |
| 172 | QObject::disconnect(self.callStateChanged); |
| 173 | self.callStateChanged = QObject::connect(callModel, |
| 174 | &lrc::api::NewCallModel::callStatusChanged, |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 175 | [self](const QString& callId) { |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 176 | if ([self isCurrentCall: callId]) { |
| 177 | [self updateCall]; |
| 178 | } |
| 179 | }); |
| 180 | /* monitor media for messaging text messaging */ |
| 181 | QObject::disconnect(self.messageConnection); |
| 182 | self.messageConnection = QObject::connect(convModel, |
| 183 | &lrc::api::ConversationModel::interactionStatusUpdated, |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 184 | [self] (const QString& convUid, |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 185 | uint64_t msgId, |
| 186 | lrc::api::interaction::Info msg) { |
| 187 | if (msg.type == lrc::api::interaction::Type::TEXT) { |
| 188 | if(not [[self splitView] isSubviewCollapsed:[[[self splitView] subviews] objectAtIndex: 1]]){ |
| 189 | return; |
| 190 | } |
| 191 | [self uncollapseRightView]; |
| 192 | } |
| 193 | }); |
| 194 | //monitor for updated profile |
| 195 | QObject::disconnect(self.profileUpdatedConnection); |
| 196 | self.profileUpdatedConnection = |
| 197 | QObject::connect(accountInfo_->contactModel.get(), |
| 198 | &lrc::api::ContactModel::contactAdded, |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 199 | [self](const QString &contactUri) { |
Kateryna Kostiuk | 3541ae2 | 2020-08-17 12:26:14 -0400 | [diff] [blame] | 200 | auto convIt = getConversationFromUid(convUid_, *accountInfo_->conversationModel.get()); |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 201 | if (convIt == accountInfo_->conversationModel->allFilteredConversations().end()) { |
| 202 | return; |
| 203 | } |
| 204 | if (convIt->participants.empty()) { |
| 205 | return; |
| 206 | |
| 207 | } |
| 208 | auto& contact = accountInfo_->contactModel->getContact(convIt->participants[0]); |
| 209 | if (contact.profileInfo.type == lrc::api::profile::Type::RING && contact.profileInfo.uri == contactUri) |
| 210 | accountInfo_->conversationModel->makePermanent(convUid_); |
| 211 | [contactPhoto setImage: [self getContactImageOfSize:120.0 withDefaultAvatar:YES]]; |
| 212 | [self.delegate conversationInfoUpdatedFor:convUid_]; |
| 213 | [self setBackground]; |
| 214 | }); |
| 215 | [self connectVideoSignals]; |
| 216 | } |
| 217 | |
| 218 | -(void) updatePendingCalls { |
| 219 | for (NSView *view in callingWidgetsContainer.subviews) { |
| 220 | view.removeFromSuperview; |
| 221 | } |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 222 | NSDictionary * calls = connectingCalls[callUid_.toNSString()]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 223 | for (NSViewController * callView in calls.allValues) { |
| 224 | [self.callingWidgetsContainer addView: callView.view inGravity:NSStackViewGravityBottom]; |
| 225 | } |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 226 | } |
| 227 | |
Kateryna Kostiuk | 88a6ee8 | 2019-09-10 17:55:08 -0400 | [diff] [blame] | 228 | -(void) setUpButtons:(lrc::api::call::Info&)callInfo isRecording:(BOOL) isRecording { |
| 229 | muteAudioButton.image = callInfo.audioMuted ? [NSImage imageNamed:@"ic_action_mute_audio.png"] : |
| 230 | [NSImage imageNamed:@"ic_action_audio.png"]; |
| 231 | muteVideoButton.image = callInfo.videoMuted ? [NSImage imageNamed:@"ic_action_mute_video.png"] : |
| 232 | [NSImage imageNamed:@"ic_action_video.png"]; |
| 233 | [muteVideoButton setHidden: callInfo.isAudioOnly ? YES: NO]; |
| 234 | if (isRecording) { |
| 235 | [recordOnOffButton startBlinkAnimationfrom:[NSColor buttonBlinkColorColor] to:[NSColor whiteColor] scaleFactor: 1 duration: 1.5]; |
| 236 | } else { |
| 237 | [recordOnOffButton stopBlinkAnimation]; |
| 238 | } |
| 239 | } |
| 240 | |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 241 | - (void) setUpPreviewFrame { |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 242 | CGPoint previewOrigin = CGPointMake(self.videoView.frame.size.width - PREVIEW_WIDTH - PREVIEW_MARGIN, PREVIEW_MARGIN); |
| 243 | movableBaseForView.frame = CGRectMake(previewOrigin.x, previewOrigin.y, PREVIEW_WIDTH, PREVIEW_HEIGHT); |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 244 | self.movableBaseForView.movable = true; |
| 245 | previewView.frame = movableBaseForView.bounds; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 246 | hidePreviewBackground.frame = [self frameForExpendPreviewButton]; |
Kateryna Kostiuk | e9eb38b | 2020-03-23 14:33:08 -0400 | [diff] [blame] | 247 | if ([hidePreviewButton respondsToSelector:@selector(contentTintColor)]) { |
| 248 | hidePreviewButton.contentTintColor = [NSColor blackColor]; |
| 249 | } |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 250 | } |
| 251 | |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 252 | - (void)awakeFromNib |
| 253 | { |
Alexandre Lision | ef6333a | 2015-03-24 12:30:31 -0400 | [diff] [blame] | 254 | [self.view setWantsLayer:YES]; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 255 | |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 256 | renderConnections = [[RendererConnectionsHolder alloc] init]; |
Alexandre Lision | ef6333a | 2015-03-24 12:30:31 -0400 | [diff] [blame] | 257 | |
Alexandre Lision | f47a256 | 2015-06-15 15:48:29 -0400 | [diff] [blame] | 258 | [loadingIndicator setColor:[NSColor whiteColor]]; |
Andreas Traczyk | 77a50d5 | 2018-05-08 17:47:31 -0400 | [diff] [blame] | 259 | [loadingIndicator setNumberOfLines:200]; |
| 260 | [loadingIndicator setWidthOfLine:4]; |
| 261 | [loadingIndicator setLengthOfLine:4]; |
| 262 | [loadingIndicator setInnerMargin:59]; |
Alexandre Lision | f47a256 | 2015-06-15 15:48:29 -0400 | [diff] [blame] | 263 | |
Alexandre Lision | a1eee3c | 2015-08-10 13:44:51 -0400 | [diff] [blame] | 264 | [self.videoView setCallDelegate:self]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 265 | [bluerBackgroundEffect setWantsLayer:YES]; |
Kateryna Kostiuk | 89398b6 | 2018-11-20 16:45:04 -0500 | [diff] [blame] | 266 | [backgroundImage setWantsLayer: YES]; |
| 267 | backgroundImage.layer.contentsGravity = kCAGravityResizeAspectFill; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 268 | movableBaseForView.wantsLayer = YES; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 269 | movableBaseForView.shadow = [[NSShadow alloc] init]; |
| 270 | movableBaseForView.layer.shadowOpacity = 0.6; |
| 271 | movableBaseForView.layer.shadowColor = [[NSColor blackColor] CGColor]; |
| 272 | movableBaseForView.layer.shadowOffset = NSMakeSize(0, -3); |
| 273 | movableBaseForView.layer.shadowRadius = 10; |
| 274 | previewView.wantsLayer = YES; |
| 275 | previewView.layer.cornerRadius = 5; |
| 276 | previewView.layer.masksToBounds = true; |
| 277 | hidePreviewBackground.wantsLayer = YES; |
| 278 | hidePreviewBackground.layer.cornerRadius = 5; |
| 279 | hidePreviewBackground.layer.maskedCorners = kCALayerMinXMinYCorner; |
| 280 | hidePreviewBackground.layer.masksToBounds = true; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 281 | movableBaseForView.hostingView = self.videoView; |
| 282 | [movableBaseForView setAutoresizingMask: NSViewNotSizable | NSViewMaxXMargin | NSViewMaxYMargin | NSViewMinXMargin | NSViewMinYMargin]; |
| 283 | [previewView setAutoresizingMask: NSViewNotSizable | NSViewMaxXMargin | NSViewMaxYMargin | NSViewMinXMargin | NSViewMinYMargin]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 284 | connectingCalls = [[NSMutableDictionary alloc] init]; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 285 | } |
| 286 | |
Anthony Léonard | 66a050c | 2018-01-03 16:32:34 -0500 | [diff] [blame] | 287 | -(void) updateDurationLabel |
| 288 | { |
| 289 | if (accountInfo_ != nil) { |
| 290 | auto* callModel = accountInfo_->callModel.get(); |
| 291 | if (callModel->hasCall(callUid_)) { |
| 292 | auto& callStatus = callModel->getCall(callUid_).status; |
| 293 | if (callStatus != lrc::api::call::Status::ENDED && |
| 294 | callStatus != lrc::api::call::Status::TERMINATING && |
| 295 | callStatus != lrc::api::call::Status::INVALID) { |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 296 | [timeSpentLabel setStringValue:callModel->getFormattedCallDuration(callUid_).toNSString()]; |
Anthony Léonard | 66a050c | 2018-01-03 16:32:34 -0500 | [diff] [blame] | 297 | return; |
| 298 | } |
| 299 | } |
| 300 | } |
| 301 | |
| 302 | // If call is not running anymore or accountInfo_ is not set for any reason |
| 303 | // we stop the refresh loop |
| 304 | [refreshDurationTimer invalidate]; |
| 305 | refreshDurationTimer = nil; |
Anthony Léonard | 66a050c | 2018-01-03 16:32:34 -0500 | [diff] [blame] | 306 | } |
| 307 | |
Andreas Traczyk | 77a50d5 | 2018-05-08 17:47:31 -0400 | [diff] [blame] | 308 | -(void) updateCall |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 309 | { |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 310 | if (accountInfo_ == nil) |
| 311 | return; |
Alexandre Lision | bb5dbcd | 2015-07-09 16:36:47 -0400 | [diff] [blame] | 312 | |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 313 | auto* callModel = accountInfo_->callModel.get(); |
| 314 | if (not callModel->hasCall(callUid_)) { |
| 315 | return; |
| 316 | } |
Alexandre Lision | 89edc6a | 2015-11-09 11:30:47 -0500 | [diff] [blame] | 317 | |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 318 | auto currentCall = callModel->getCall(callUid_); |
Kateryna Kostiuk | 3541ae2 | 2020-08-17 12:26:14 -0400 | [diff] [blame] | 319 | auto convIt = getConversationFromUid(convUid_, *accountInfo_->conversationModel); |
| 320 | if (conversationExists(convIt, *accountInfo_->conversationModel)) { |
Andreas Traczyk | 77a50d5 | 2018-05-08 17:47:31 -0400 | [diff] [blame] | 321 | NSString* bestName = bestNameForConversation(*convIt, *accountInfo_->conversationModel); |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 322 | [contactNameLabel setStringValue:bestName]; |
Andreas Traczyk | 77a50d5 | 2018-05-08 17:47:31 -0400 | [diff] [blame] | 323 | NSString* ringID = bestIDForConversation(*convIt, *accountInfo_->conversationModel); |
| 324 | if([bestName isEqualToString:ringID]) { |
| 325 | ringID = @""; |
| 326 | } |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 327 | [contactIdLabel setStringValue:ringID]; |
Andreas Traczyk | 77a50d5 | 2018-05-08 17:47:31 -0400 | [diff] [blame] | 328 | } |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 329 | [self setupContactInfo:contactPhoto]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 330 | confUid_ = convIt->confId; |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 331 | [muteAudioButton setHidden:!confUid_.isEmpty()]; |
| 332 | [muteVideoButton setHidden:!confUid_.isEmpty()]; |
| 333 | [recordOnOffButton setHidden:!confUid_.isEmpty()]; |
| 334 | [holdOnOffButton setHidden:!confUid_.isEmpty()]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 335 | |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 336 | [timeSpentLabel setStringValue:callModel->getFormattedCallDuration(callUid_).toNSString()]; |
Anthony Léonard | 66a050c | 2018-01-03 16:32:34 -0500 | [diff] [blame] | 337 | if (refreshDurationTimer == nil) |
| 338 | refreshDurationTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 |
| 339 | target:self |
| 340 | selector:@selector(updateDurationLabel) |
| 341 | userInfo:nil |
| 342 | repeats:YES]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 343 | [self setBackground]; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 344 | |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 345 | using Status = lrc::api::call::Status; |
Kateryna Kostiuk | 88a6ee8 | 2019-09-10 17:55:08 -0400 | [diff] [blame] | 346 | if (currentCall.status == Status::PAUSED) { |
| 347 | [holdOnOffButton startBlinkAnimationfrom:[NSColor buttonBlinkColorColor] to:[NSColor whiteColor] scaleFactor: 1.0 duration: 1.5]; |
| 348 | } else { |
| 349 | [holdOnOffButton stopBlinkAnimation]; |
| 350 | } |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 351 | |
Kateryna Kostiuk | a740481 | 2019-10-28 12:24:46 -0400 | [diff] [blame] | 352 | [self setUpButtons: currentCall isRecording: (callModel->isRecording([self getcallID]) || mediaModel->getAlwaysRecord())]; |
| 353 | |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 354 | [videoView setShouldAcceptInteractions: currentCall.status == Status::IN_PROGRESS]; |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 355 | callStateLabel.stringValue = currentCall.status == Status::INCOMING_RINGING ? @"wants to talk to you" : to_string(currentCall.status).toNSString(); |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 356 | loadingIndicator.hidden = (currentCall.status == Status::SEARCHING || |
| 357 | currentCall.status == Status::CONNECTING || |
| 358 | currentCall.status == Status::OUTGOING_RINGING) ? NO : YES; |
| 359 | pickUpButton.hidden = (currentCall.status == Status::INCOMING_RINGING) ? NO : YES; |
| 360 | callStateLabel.hidden = (currentCall.status == Status::IN_PROGRESS) ? YES : NO; |
| 361 | cancelCallButton.hidden = (currentCall.status == Status::IN_PROGRESS || |
| 362 | currentCall.status == Status::PAUSED) ? YES : NO; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 363 | callingWidgetsContainer.hidden = (currentCall.status == Status::IN_PROGRESS) ? NO : YES; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 364 | |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 365 | switch (currentCall.status) { |
| 366 | case Status::SEARCHING: |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 367 | case Status::CONNECTING: |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 368 | case Status::OUTGOING_RINGING: |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 369 | case Status::INCOMING_RINGING: |
| 370 | [infoContainer setHidden: NO]; |
Andreas Traczyk | 77a50d5 | 2018-05-08 17:47:31 -0400 | [diff] [blame] | 371 | [headerContainer setHidden:YES]; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 372 | [headerGradientView setHidden:YES]; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 373 | [controlsPanel setHidden:YES]; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 374 | [controlsStackView setHidden:YES]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 375 | [self.distantView fillWithBlack]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 376 | [self.previewView fillWithBlack]; |
| 377 | [hidePreviewBackground setHidden:YES]; |
| 378 | [self.previewView setHidden: YES]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 379 | [self.distantView setHidden: YES]; |
| 380 | self.previewView.videoRunning = NO; |
| 381 | self.distantView.videoRunning = NO; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 382 | [backgroundImage setHidden:NO]; |
| 383 | [bluerBackgroundEffect setHidden:NO]; |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 384 | break; |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 385 | case Status::PAUSED: |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 386 | [infoContainer setHidden: NO]; |
| 387 | [headerContainer setHidden:NO]; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 388 | [headerGradientView setHidden:NO]; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 389 | [controlsPanel setHidden:NO]; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 390 | [controlsStackView setHidden:NO]; |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 391 | [backgroundImage setHidden:NO]; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 392 | [bluerBackgroundEffect setHidden:NO]; |
| 393 | if(!currentCall.isAudioOnly) { |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 394 | [self.distantView fillWithBlack]; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 395 | [self.previewView fillWithBlack]; |
| 396 | [hidePreviewBackground setHidden:YES]; |
| 397 | [self.previewView setHidden: YES]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 398 | [self.distantView setHidden: YES]; |
| 399 | self.previewView.videoRunning = NO; |
| 400 | self.distantView.videoRunning = NO; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 401 | } |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 402 | break; |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 403 | case Status::INACTIVE: |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 404 | if(currentCall.isAudioOnly) { |
| 405 | [self setUpAudioOnlyView]; |
| 406 | } else { |
| 407 | [self setUpVideoCallView]; |
| 408 | } |
| 409 | break; |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 410 | case Status::IN_PROGRESS: |
“Kateryna” | 414738e | 2020-04-07 11:44:35 -0400 | [diff] [blame] | 411 | callModel->setCurrentCall([self getcallID]); |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 412 | [headerContainer setHidden:NO]; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 413 | [headerGradientView setHidden:NO]; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 414 | [controlsPanel setHidden:NO]; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 415 | [controlsStackView setHidden:NO]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 416 | if(currentCall.isAudioOnly) { |
| 417 | [self setUpAudioOnlyView]; |
| 418 | } else { |
| 419 | [self setUpVideoCallView]; |
| 420 | } |
Andreas Traczyk | 77a50d5 | 2018-05-08 17:47:31 -0400 | [diff] [blame] | 421 | break; |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 422 | case Status::CONNECTED: |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 423 | break; |
| 424 | case Status::ENDED: |
| 425 | case Status::TERMINATING: |
| 426 | case Status::INVALID: |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 427 | case Status::PEER_BUSY: |
| 428 | case Status::TIMEOUT: |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 429 | connectingCalls[callUid_.toNSString()] = nil; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 430 | //[self cleanUp]; |
| 431 | [self.delegate callFinished]; |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 432 | break; |
| 433 | } |
Alexandre Lision | 4d9905e | 2016-01-22 12:01:36 -0500 | [diff] [blame] | 434 | } |
| 435 | |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 436 | -(void) setUpVideoCallView { |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 437 | [previewView fillWithBlack]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 438 | [self.distantView fillWithBlack]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 439 | [previewView setHidden: NO]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 440 | [self.distantView setHidden:NO]; |
| 441 | [hidePreviewBackground setHidden: !self.previewView.videoRunning]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 442 | [bluerBackgroundEffect setHidden:YES]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 443 | [backgroundImage setHidden:YES]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 444 | self.previewView.videoRunning = true; |
| 445 | self.distantView.videoRunning = true; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 446 | } |
| 447 | |
| 448 | -(void) setUpAudioOnlyView { |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 449 | [self.previewView setHidden: YES]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 450 | [self.distantView setHidden: YES]; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 451 | [hidePreviewBackground setHidden: YES]; |
| 452 | [bluerBackgroundEffect setHidden:NO]; |
| 453 | [backgroundImage setHidden:NO]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 454 | } |
| 455 | |
| 456 | -(void) setBackground { |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 457 | NSImage *image= [self getContactImageOfSize:120.0 withDefaultAvatar:NO]; |
| 458 | if(image) { |
Kateryna Kostiuk | 89398b6 | 2018-11-20 16:45:04 -0500 | [diff] [blame] | 459 | CIImage * ciImage = [[CIImage alloc] initWithData:[image TIFFRepresentation]]; |
| 460 | CIContext *context = [[CIContext alloc] init]; |
| 461 | CIFilter *clamp = [CIFilter filterWithName:@"CIAffineClamp"]; |
| 462 | [clamp setValue:[NSAffineTransform transform] forKey:@"inputTransform"]; |
| 463 | [clamp setValue:ciImage forKey: kCIInputImageKey]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 464 | CIFilter* bluerFilter = [CIFilter filterWithName:@"CIGaussianBlur"]; |
| 465 | [bluerFilter setDefaults]; |
Kateryna Kostiuk | 89398b6 | 2018-11-20 16:45:04 -0500 | [diff] [blame] | 466 | [bluerFilter setValue:[NSNumber numberWithFloat: 9] forKey:@"inputRadius"]; |
| 467 | [bluerFilter setValue:[clamp valueForKey:kCIOutputImageKey] forKey: kCIInputImageKey]; |
| 468 | CIImage *result = [bluerFilter valueForKey:kCIOutputImageKey]; |
| 469 | CGRect extent = [result extent]; |
| 470 | CGImageRef cgImage = [context createCGImage:result fromRect: [ciImage extent]]; |
| 471 | NSImage *bluredImage = [[NSImage alloc] initWithCGImage:cgImage size:NSSizeFromCGSize(CGSizeMake(image.size.width, image.size.height))]; |
| 472 | backgroundImage.layer.contents = bluredImage; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 473 | [backgroundImage setHidden:NO]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 474 | [bluerBackgroundEffect setFillColor:[NSColor darkGrayColor]]; |
| 475 | [bluerBackgroundEffect setAlphaValue:0.6]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 476 | } else { |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 477 | contactNameLabel.textColor = [NSColor textColor]; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 478 | contactIdLabel.textColor = [NSColor textColor]; |
| 479 | callStateLabel.textColor = [NSColor textColor]; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 480 | backgroundImage.layer.contents = nil; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 481 | [bluerBackgroundEffect setFillColor:[NSColor windowBackgroundColor]]; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 482 | [bluerBackgroundEffect setAlphaValue:1]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 483 | [backgroundImage setHidden:YES]; |
Andreas Traczyk | 77a50d5 | 2018-05-08 17:47:31 -0400 | [diff] [blame] | 484 | } |
| 485 | } |
| 486 | |
Kateryna Kostiuk | 133364b | 2018-10-31 11:36:08 -0400 | [diff] [blame] | 487 | -(NSImage *) getContactImageOfSize: (double) size withDefaultAvatar:(BOOL) shouldDrawDefault { |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 488 | auto* convModel = accountInfo_->conversationModel.get(); |
Kateryna Kostiuk | 3541ae2 | 2020-08-17 12:26:14 -0400 | [diff] [blame] | 489 | auto convIt = getConversationFromUid(convUid_, *convModel); |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 490 | if (convIt == convModel->allFilteredConversations().end()) { |
| 491 | return nil; |
| 492 | } |
| 493 | if(shouldDrawDefault) { |
| 494 | auto& imgManip = reinterpret_cast<Interfaces::ImageManipulationDelegate&>(GlobalInstances::pixmapManipulator()); |
| 495 | QVariant photo = imgManip.conversationPhoto(*convIt, *accountInfo_, QSize(size, size), NO); |
| 496 | return QtMac::toNSImage(qvariant_cast<QPixmap>(photo)); |
| 497 | } |
| 498 | auto contact = accountInfo_->contactModel->getContact(convIt->participants[0]); |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 499 | NSData *imageData = [[NSData alloc] initWithBase64EncodedString:contact.profileInfo.avatar.toNSString() options:NSDataBase64DecodingIgnoreUnknownCharacters]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 500 | return [[NSImage alloc] initWithData:imageData]; |
| 501 | } |
| 502 | |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 503 | -(void) setupContactInfo:(NSImageView*)imageView |
| 504 | { |
| 505 | [imageView setImage: [self getContactImageOfSize:120.0 withDefaultAvatar:YES]]; |
| 506 | } |
| 507 | |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 508 | -(void)collapseRightView |
| 509 | { |
| 510 | NSView *right = [[splitView subviews] objectAtIndex:1]; |
| 511 | NSView *left = [[splitView subviews] objectAtIndex:0]; |
| 512 | NSRect leftFrame = [left frame]; |
| 513 | [right setHidden:YES]; |
| 514 | [splitView display]; |
| 515 | } |
| 516 | |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 517 | -(void) connectVideoSignals |
| 518 | { |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 519 | if (accountInfo_ == nil) |
| 520 | return; |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 521 | [self connectRenderer]; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 522 | } |
| 523 | |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 524 | -(void) connectRenderer |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 525 | { |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 526 | QObject::disconnect(renderConnections.frameUpdated); |
| 527 | QObject::disconnect(renderConnections.stopped); |
| 528 | QObject::disconnect(renderConnections.started); |
| 529 | renderConnections.started = |
| 530 | QObject::connect(mediaModel, |
| 531 | &lrc::api::AVModel::rendererStarted, |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 532 | [=](const QString& id) { |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 533 | if (id == lrc::api::video::PREVIEW_RENDERER_ID) { |
| 534 | [self.previewView setHidden:NO]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 535 | [hidePreviewBackground setHidden: NO]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 536 | self.previewView.videoRunning = true; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 537 | } else if ([self isCurrentCall: id]) { |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 538 | [self mouseIsMoving: NO]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 539 | self.distantView.videoRunning = true; |
| 540 | [self.distantView setHidden:NO]; |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 541 | [bluerBackgroundEffect setHidden:YES]; |
| 542 | [backgroundImage setHidden:YES]; |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 543 | } |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 544 | }); |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 545 | renderConnections.stopped = |
| 546 | QObject::connect(mediaModel, |
| 547 | &lrc::api::AVModel::rendererStopped, |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 548 | [=](const QString& id) { |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 549 | if (id == lrc::api::video::PREVIEW_RENDERER_ID) { |
| 550 | [self.previewView setHidden:YES]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 551 | self.previewView.videoRunning = false; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 552 | } else if ([self isCurrentCall: id]) { |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 553 | [self mouseIsMoving: YES]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 554 | self.distantView.videoRunning = false; |
| 555 | [self.distantView setHidden:YES]; |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 556 | [bluerBackgroundEffect setHidden:NO]; |
| 557 | [backgroundImage setHidden:NO]; |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 558 | } |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 559 | }); |
| 560 | renderConnections.frameUpdated = |
| 561 | QObject::connect(mediaModel, |
| 562 | &lrc::api::AVModel::frameUpdated, |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 563 | [=](const QString& id) { |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 564 | if (id == lrc::api::video::PREVIEW_RENDERER_ID) { |
| 565 | auto renderer = &mediaModel->getRenderer(lrc::api::video::PREVIEW_RENDERER_ID); |
| 566 | if(!renderer->isRendering()) { |
| 567 | return; |
| 568 | } |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 569 | [hidePreviewBackground setHidden: !self.previewView.videoRunning]; |
| 570 | [self rendererPreview: renderer]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 571 | } else if ([self isCurrentCall: id]) { |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 572 | auto renderer = &mediaModel->getRenderer(id); |
| 573 | if(!renderer->isRendering()) { |
| 574 | return; |
| 575 | } |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 576 | [self rendererDistantView: renderer]; |
Kateryna Kostiuk | 732b406 | 2018-11-28 09:59:28 -0500 | [diff] [blame] | 577 | } |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 578 | }); |
| 579 | } |
| 580 | |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 581 | -(void) rendererDistantView: (const lrc::api::video::Renderer*)renderer { |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 582 | @autoreleasepool { |
| 583 | auto framePtr = renderer->currentAVFrame(); |
| 584 | auto frame = framePtr.get(); |
| 585 | if(!frame || !frame->width || !frame->height) { |
| 586 | return; |
| 587 | } |
| 588 | auto frameSize = CGSizeMake(frame->width, frame->height); |
| 589 | auto rotation = 0; |
| 590 | if (auto matrix = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX)) { |
| 591 | const int32_t* data = reinterpret_cast<int32_t*>(matrix->data); |
| 592 | rotation = av_display_rotation_get(data); |
| 593 | } |
| 594 | if (frame->data[3] != NULL && (CVPixelBufferRef)frame->data[3]) { |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 595 | [self.distantView renderWithPixelBuffer: (CVPixelBufferRef)frame->data[3] |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 596 | size: frameSize |
| 597 | rotation: rotation |
| 598 | fillFrame: false]; |
| 599 | } |
| 600 | if (CVPixelBufferRef pixelBuffer = [self getBufferForDistantViewFromFrame:frame]) { |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 601 | [self.distantView renderWithPixelBuffer: pixelBuffer |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 602 | size: frameSize |
| 603 | rotation: rotation |
| 604 | fillFrame: false]; |
| 605 | } |
Kateryna Kostiuk | bcf24e9 | 2018-11-20 10:09:06 -0500 | [diff] [blame] | 606 | } |
Anthony Léonard | 14e7bf3 | 2017-06-08 08:13:16 -0400 | [diff] [blame] | 607 | } |
| 608 | |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 609 | -(void) rendererPreview: (const lrc::api::video::Renderer*)renderer { |
| 610 | @autoreleasepool { |
| 611 | auto framePtr = renderer->currentAVFrame(); |
| 612 | auto frame = framePtr.get(); |
| 613 | if(!frame || !frame->width || !frame->height) { |
| 614 | return; |
| 615 | } |
| 616 | auto frameSize = CGSizeMake(frame->width, frame->height); |
| 617 | auto rotation = 0; |
| 618 | if (auto matrix = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX)) { |
| 619 | const int32_t* data = reinterpret_cast<int32_t*>(matrix->data); |
| 620 | rotation = av_display_rotation_get(data); |
| 621 | } |
| 622 | if (frame->data[3] != NULL && (CVPixelBufferRef)frame->data[3]) { |
| 623 | [self.previewView renderWithPixelBuffer: (CVPixelBufferRef)frame->data[3] |
| 624 | size: frameSize |
| 625 | rotation: rotation |
| 626 | fillFrame: false]; |
| 627 | } |
| 628 | if (CVPixelBufferRef pixelBuffer = [self getBufferForPreviewFromFrame:frame]) { |
| 629 | [self.previewView renderWithPixelBuffer: pixelBuffer |
| 630 | size: frameSize |
| 631 | rotation: rotation |
| 632 | fillFrame: true]; |
| 633 | } |
| 634 | } |
| 635 | } |
| 636 | |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 637 | -(CVPixelBufferRef) getBufferForPreviewFromFrame:(const AVFrame*)frame { |
Kateryna Kostiuk | c5fd3b9 | 2019-07-24 10:12:44 -0400 | [diff] [blame] | 638 | [VideoCommon fillPixelBuffr:&pixelBufferPreview fromFrame:frame bufferPool:&pixelBufferPoolPreview]; |
| 639 | CVPixelBufferRef buffer = pixelBufferPreview; |
| 640 | return buffer; |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 641 | } |
| 642 | |
| 643 | -(CVPixelBufferRef) getBufferForDistantViewFromFrame:(const AVFrame*)frame { |
Kateryna Kostiuk | c5fd3b9 | 2019-07-24 10:12:44 -0400 | [diff] [blame] | 644 | [VideoCommon fillPixelBuffr:&pixelBufferDistantView fromFrame:frame bufferPool:&pixelBufferPoolDistantView]; |
| 645 | CVPixelBufferRef buffer = pixelBufferDistantView; |
| 646 | return buffer; |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 647 | } |
| 648 | |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 649 | - (void) initFrame |
| 650 | { |
| 651 | [self.view setFrame:self.view.superview.bounds]; |
| 652 | [self.view setHidden:YES]; |
| 653 | self.view.layer.position = self.view.frame.origin; |
Alexandre Lision | bb5dbcd | 2015-07-09 16:36:47 -0400 | [diff] [blame] | 654 | [self collapseRightView]; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 655 | } |
| 656 | |
| 657 | # pragma private IN/OUT animations |
| 658 | |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 659 | -(void)uncollapseRightView |
| 660 | { |
| 661 | NSView *left = [[splitView subviews] objectAtIndex:0]; |
| 662 | NSView *right = [[splitView subviews] objectAtIndex:1]; |
| 663 | [right setHidden:NO]; |
| 664 | |
| 665 | CGFloat dividerThickness = [splitView dividerThickness]; |
| 666 | |
| 667 | // get the different frames |
| 668 | NSRect leftFrame = [left frame]; |
| 669 | NSRect rightFrame = [right frame]; |
| 670 | |
| 671 | leftFrame.size.width = (leftFrame.size.width - rightFrame.size.width - dividerThickness); |
| 672 | rightFrame.origin.x = leftFrame.size.width + dividerThickness; |
| 673 | [left setFrameSize:leftFrame.size]; |
| 674 | [right setFrame:rightFrame]; |
| 675 | [splitView display]; |
| 676 | |
| 677 | [self.chatVC takeFocus]; |
| 678 | } |
| 679 | |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 680 | -(void) cleanUp |
| 681 | { |
Anthony Léonard | 5c28764 | 2018-02-21 15:54:19 -0500 | [diff] [blame] | 682 | if(self.splitView.isInFullScreenMode) |
| 683 | [self.splitView exitFullScreenModeWithOptions:nil]; |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 684 | QObject::disconnect(renderConnections.frameUpdated); |
| 685 | QObject::disconnect(renderConnections.started); |
| 686 | QObject::disconnect(renderConnections.stopped); |
Anthony Léonard | c0013bb | 2018-02-20 16:23:02 -0500 | [diff] [blame] | 687 | QObject::disconnect(self.messageConnection); |
Alexandre Lision | 883719f | 2015-10-22 17:37:45 -0400 | [diff] [blame] | 688 | |
Alexandre Lision | 4baba4c | 2016-02-11 13:00:57 -0500 | [diff] [blame] | 689 | [self.chatButton setPressed:NO]; |
Alexandre Lision | 883719f | 2015-10-22 17:37:45 -0400 | [diff] [blame] | 690 | [self collapseRightView]; |
Alexandre Lision | 5722777 | 2016-01-15 17:19:36 -0500 | [diff] [blame] | 691 | |
Alexandre Lision | 5722777 | 2016-01-15 17:19:36 -0500 | [diff] [blame] | 692 | [timeSpentLabel setStringValue:@""]; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 693 | [contactIdLabel setStringValue:@""]; |
| 694 | [contactNameLabel setStringValue:@""]; |
| 695 | [contactPhoto setImage:nil]; |
Kateryna Kostiuk | 81afce7 | 2018-10-30 16:40:50 -0400 | [diff] [blame] | 696 | //background view |
| 697 | [bluerBackgroundEffect setHidden:NO]; |
| 698 | [backgroundImage setHidden:NO]; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 699 | backgroundImage.layer.contents = nil; |
Kateryna Kostiuk | 00dcbff | 2019-07-11 15:42:13 -0400 | [diff] [blame] | 700 | [self.previewView setHidden:YES]; |
Kateryna Kostiuk | 0668168 | 2020-05-07 20:50:56 -0400 | [diff] [blame] | 701 | [self.distantView setHidden:YES]; |
Kateryna Kostiuk | 9e9f782 | 2019-09-27 11:29:45 -0400 | [diff] [blame] | 702 | |
| 703 | contactNameLabel.textColor = [NSColor highlightColor]; |
| 704 | contactNameLabel.textColor = [NSColor highlightColor]; |
| 705 | contactIdLabel.textColor = [NSColor highlightColor]; |
| 706 | callStateLabel.textColor = [NSColor highlightColor]; |
Kateryna Kostiuk | 5acaefd | 2020-03-25 11:14:25 -0400 | [diff] [blame] | 707 | [self.chatVC clearData]; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 708 | } |
| 709 | |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 710 | /* |
| 711 | * update ui |
| 712 | */ |
| 713 | |
Andreas Traczyk | ecdc4fa | 2018-03-22 16:11:47 -0400 | [diff] [blame] | 714 | -(void) setupCallView |
| 715 | { |
| 716 | if (accountInfo_ == nil) |
| 717 | return; |
| 718 | |
| 719 | auto* callModel = accountInfo_->callModel.get(); |
Andreas Traczyk | ecdc4fa | 2018-03-22 16:11:47 -0400 | [diff] [blame] | 720 | |
Andreas Traczyk | ecdc4fa | 2018-03-22 16:11:47 -0400 | [diff] [blame] | 721 | /* check if text media is already present */ |
| 722 | if(not callModel->hasCall(callUid_)) |
| 723 | return; |
| 724 | |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 725 | // when call comes in we want to show the controls/header |
| 726 | [self mouseIsMoving: YES]; |
Andreas Traczyk | ecdc4fa | 2018-03-22 16:11:47 -0400 | [diff] [blame] | 727 | [loadingIndicator setAnimates:YES]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 728 | auto currentCall = callModel->getCall([self getcallID]); |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 729 | [previewView setHidden: YES]; |
| 730 | [self setUpPreviewFrame]; |
| 731 | [self updatePendingCalls]; |
Andreas Traczyk | 77a50d5 | 2018-05-08 17:47:31 -0400 | [diff] [blame] | 732 | [self updateCall]; |
Andreas Traczyk | ecdc4fa | 2018-03-22 16:11:47 -0400 | [diff] [blame] | 733 | } |
| 734 | |
| 735 | -(void) showWithAnimation:(BOOL)animate |
| 736 | { |
| 737 | if (!animate) { |
| 738 | [self.view setHidden:NO]; |
| 739 | [self setupCallView]; |
| 740 | return; |
| 741 | } |
| 742 | |
| 743 | CGRect frame = CGRectOffset(self.view.superview.bounds, -self.view.superview.bounds.size.width, 0); |
| 744 | [self.view setHidden:NO]; |
| 745 | |
| 746 | [CATransaction begin]; |
| 747 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"]; |
| 748 | [animation setFromValue:[NSValue valueWithPoint:frame.origin]]; |
| 749 | [animation setToValue:[NSValue valueWithPoint:self.view.superview.bounds.origin]]; |
| 750 | [animation setDuration:0.2f]; |
| 751 | [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]]; |
| 752 | [CATransaction setCompletionBlock:^{ |
| 753 | [self setupCallView]; |
| 754 | }]; |
| 755 | |
| 756 | [self.view.layer addAnimation:animation forKey:animation.keyPath]; |
| 757 | [CATransaction commit]; |
| 758 | } |
| 759 | |
| 760 | -(void) hideWithAnimation:(BOOL)animate |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 761 | { |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 762 | if(self.view.frame.origin.x < 0) { |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 763 | return; |
| 764 | } |
| 765 | |
Andreas Traczyk | ecdc4fa | 2018-03-22 16:11:47 -0400 | [diff] [blame] | 766 | if (!animate) { |
| 767 | [self.view setHidden:YES]; |
| 768 | return; |
| 769 | } |
| 770 | |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 771 | CGRect frame = CGRectOffset(self.view.frame, -self.view.frame.size.width, 0); |
| 772 | [CATransaction begin]; |
| 773 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"]; |
| 774 | [animation setFromValue:[NSValue valueWithPoint:self.view.frame.origin]]; |
| 775 | [animation setToValue:[NSValue valueWithPoint:frame.origin]]; |
| 776 | [animation setDuration:0.2f]; |
Alexandre Lision | 22d615b | 2016-01-25 12:54:34 -0500 | [diff] [blame] | 777 | [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 778 | |
| 779 | [CATransaction setCompletionBlock:^{ |
| 780 | [self.view setHidden:YES]; |
Alexandre Lision | ef6333a | 2015-03-24 12:30:31 -0400 | [diff] [blame] | 781 | // first make sure everything is disconnected |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 782 | [self cleanUp]; |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 783 | // if (currentCall_) { |
| 784 | // [self animateIn]; |
| 785 | // } |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 786 | }]; |
| 787 | [self.view.layer addAnimation:animation forKey:animation.keyPath]; |
Alexandre Lision | a1c6d75 | 2015-06-23 12:27:38 -0400 | [diff] [blame] | 788 | |
| 789 | [self.view.layer setPosition:frame.origin]; |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 790 | [CATransaction commit]; |
| 791 | } |
| 792 | |
| 793 | /** |
| 794 | * Debug purpose |
| 795 | */ |
| 796 | -(void) dumpFrame:(CGRect) frame WithName:(NSString*) name |
| 797 | { |
| 798 | NSLog(@"frame %@ : %f %f %f %f \n\n",name ,frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); |
| 799 | } |
| 800 | |
Alexandre Lision | 58cab67 | 2015-06-09 15:25:40 -0400 | [diff] [blame] | 801 | #pragma mark - Button methods |
| 802 | |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 803 | - (IBAction)hangUp:(id)sender { |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 804 | if (accountInfo_ == nil) |
| 805 | return; |
| 806 | |
| 807 | auto* callModel = accountInfo_->callModel.get(); |
Kateryna Kostiuk | 28b99be | 2019-11-18 14:54:08 -0500 | [diff] [blame] | 808 | callModel->hangUp(callUid_); |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 809 | } |
| 810 | |
| 811 | - (IBAction)accept:(id)sender { |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 812 | if (accountInfo_ == nil) |
| 813 | return; |
| 814 | |
Anthony Léonard | f584cc5 | 2018-01-19 12:00:19 -0500 | [diff] [blame] | 815 | // If we accept a conversation with a non trusted contact, we first accept it |
Kateryna Kostiuk | 3541ae2 | 2020-08-17 12:26:14 -0400 | [diff] [blame] | 816 | auto convIt = getConversationFromUid(convUid_, *accountInfo_->conversationModel.get()); |
| 817 | if (convIt != accountInfo_->conversationModel->allFilteredConversations().end()) { |
Anthony Léonard | f584cc5 | 2018-01-19 12:00:19 -0500 | [diff] [blame] | 818 | auto& contact = accountInfo_->contactModel->getContact(convIt->participants[0]); |
| 819 | if (contact.profileInfo.type == lrc::api::profile::Type::PENDING) |
| 820 | accountInfo_->conversationModel->makePermanent(convUid_); |
| 821 | } |
| 822 | |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 823 | auto* callModel = accountInfo_->callModel.get(); |
| 824 | |
| 825 | callModel->accept(callUid_); |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 826 | } |
| 827 | |
| 828 | - (IBAction)toggleRecording:(id)sender { |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 829 | if (accountInfo_ == nil) |
| 830 | return; |
| 831 | |
| 832 | auto* callModel = accountInfo_->callModel.get(); |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 833 | callModel->toggleAudioRecord(callUid_); |
Kateryna Kostiuk | 88a6ee8 | 2019-09-10 17:55:08 -0400 | [diff] [blame] | 834 | if (callModel->isRecording(callUid_)) { |
| 835 | [recordOnOffButton startBlinkAnimationfrom:[NSColor buttonBlinkColorColor] to:[NSColor whiteColor] scaleFactor: 1 duration: 1.5]; |
| 836 | } else { |
| 837 | [recordOnOffButton stopBlinkAnimation]; |
| 838 | } |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 839 | } |
| 840 | |
| 841 | - (IBAction)toggleHold:(id)sender { |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 842 | if (accountInfo_ == nil) |
| 843 | return; |
| 844 | |
| 845 | auto* callModel = accountInfo_->callModel.get(); |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 846 | callModel->togglePause([self getcallID]); |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 847 | } |
| 848 | |
Alexandre Lision | 6200531 | 2016-01-28 15:55:16 -0500 | [diff] [blame] | 849 | - (IBAction)showDialpad:(id)sender { |
| 850 | AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate]; |
| 851 | [appDelegate showDialpad]; |
| 852 | } |
| 853 | |
Alexandre Lision | 58cab67 | 2015-06-09 15:25:40 -0400 | [diff] [blame] | 854 | -(IBAction)toggleChat:(id)sender; |
| 855 | { |
| 856 | BOOL rightViewCollapsed = [[self splitView] isSubviewCollapsed:[[[self splitView] subviews] objectAtIndex: 1]]; |
| 857 | if (rightViewCollapsed) { |
| 858 | [self uncollapseRightView]; |
Alexandre Lision | 58cab67 | 2015-06-09 15:25:40 -0400 | [diff] [blame] | 859 | } else { |
| 860 | [self collapseRightView]; |
| 861 | } |
Alexandre Lision | 6200531 | 2016-01-28 15:55:16 -0500 | [diff] [blame] | 862 | [chatButton setPressed:rightViewCollapsed]; |
Alexandre Lision | 58cab67 | 2015-06-09 15:25:40 -0400 | [diff] [blame] | 863 | } |
| 864 | |
Alexandre Lision | d18fa27 | 2015-06-15 11:18:03 -0400 | [diff] [blame] | 865 | - (IBAction)muteAudio:(id)sender |
| 866 | { |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 867 | if (accountInfo_ == nil) |
| 868 | return; |
| 869 | |
| 870 | auto* callModel = accountInfo_->callModel.get(); |
Kateryna Kostiuk | 54d7697 | 2018-06-07 15:45:07 -0400 | [diff] [blame] | 871 | auto currentCall = callModel->getCall(callUid_); |
| 872 | if (currentCall.audioMuted) { |
| 873 | muteAudioButton.image = [NSImage imageNamed:@"ic_action_audio.png"]; |
| 874 | } else { |
| 875 | muteAudioButton.image = [NSImage imageNamed:@"ic_action_mute_audio.png"]; |
| 876 | } |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 877 | callModel->toggleMedia(callUid_, lrc::api::NewCallModel::Media::AUDIO); |
Alexandre Lision | d18fa27 | 2015-06-15 11:18:03 -0400 | [diff] [blame] | 878 | } |
| 879 | |
| 880 | - (IBAction)muteVideo:(id)sender |
| 881 | { |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 882 | if (accountInfo_ == nil) |
| 883 | return; |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 884 | auto* callModel = accountInfo_->callModel.get(); |
Kateryna Kostiuk | 54d7697 | 2018-06-07 15:45:07 -0400 | [diff] [blame] | 885 | auto currentCall = callModel->getCall(callUid_); |
| 886 | if(!currentCall.isAudioOnly) { |
| 887 | if (currentCall.videoMuted) { |
| 888 | muteVideoButton.image = [NSImage imageNamed:@"ic_action_video.png"]; |
| 889 | } else { |
| 890 | muteVideoButton.image = [NSImage imageNamed:@"ic_action_mute_video.png"]; |
| 891 | } |
| 892 | } |
Olivier Soldano | 994971f | 2017-12-05 16:30:12 -0500 | [diff] [blame] | 893 | callModel->toggleMedia(callUid_, lrc::api::NewCallModel::Media::VIDEO); |
Alexandre Lision | d18fa27 | 2015-06-15 11:18:03 -0400 | [diff] [blame] | 894 | } |
Alexandre Lision | 883719f | 2015-10-22 17:37:45 -0400 | [diff] [blame] | 895 | |
| 896 | - (IBAction)toggleTransferView:(id)sender { |
Kateryna Kostiuk | 1ba5a01 | 2018-12-12 17:07:38 -0500 | [diff] [blame] | 897 | |
Alexandre Lision | f23ec5a | 2015-07-16 11:24:06 -0400 | [diff] [blame] | 898 | } |
Alexandre Lision | d18fa27 | 2015-06-15 11:18:03 -0400 | [diff] [blame] | 899 | |
Alexandre Lision | 89edc6a | 2015-11-09 11:30:47 -0500 | [diff] [blame] | 900 | - (IBAction)toggleAddParticipantView:(id)sender { |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 901 | if (brokerPopoverVC != nullptr) { |
| 902 | [brokerPopoverVC performClose:self]; |
| 903 | brokerPopoverVC = NULL; |
| 904 | } else { |
| 905 | auto* contactSelectorVC = [[ChooseContactVC alloc] initWithNibName:@"ChooseContactVC" bundle:nil]; |
| 906 | auto* convModel = accountInfo_->conversationModel.get(); |
| 907 | [contactSelectorVC setConversationModel:convModel andCurrentConversation: convUid_]; |
| 908 | contactSelectorVC.delegate = self; |
| 909 | brokerPopoverVC = [[NSPopover alloc] init]; |
| 910 | [brokerPopoverVC setContentSize:contactSelectorVC.view.frame.size]; |
| 911 | [brokerPopoverVC setContentViewController:contactSelectorVC]; |
| 912 | [brokerPopoverVC setAnimates:YES]; |
| 913 | [brokerPopoverVC setBehavior:NSPopoverBehaviorTransient]; |
| 914 | [brokerPopoverVC setDelegate:self]; |
| 915 | [brokerPopoverVC showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMinYEdge]; |
| 916 | } |
Alexandre Lision | 89edc6a | 2015-11-09 11:30:47 -0500 | [diff] [blame] | 917 | } |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 918 | |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 919 | - (IBAction)hidePreview:(id)sender { |
| 920 | CGRect previewFrame = previewView.frame; |
Kateryna Kostiuk | 28b99be | 2019-11-18 14:54:08 -0500 | [diff] [blame] | 921 | CGRect newPreviewFrame; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 922 | if (previewFrame.size.width > HIDE_PREVIEW_BUTTON_SIZE) { |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 923 | self.movableBaseForView.movable = false; |
| 924 | newPreviewFrame = self.getVideoPreviewCollapsedSize; |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 925 | hidePreviewButton.image = [NSImage imageNamed: NSImageNameTouchBarEnterFullScreenTemplate]; |
| 926 | } else { |
| 927 | self.movableBaseForView.movable = true; |
| 928 | newPreviewFrame = CGRectMake(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT); |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 929 | hidePreviewButton.image = [NSImage imageNamed: NSImageNameTouchBarExitFullScreenTemplate]; |
| 930 | } |
| 931 | [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) { |
| 932 | context.duration = 0.2f; |
| 933 | context.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseOut]; |
| 934 | previewView.animator.frame = newPreviewFrame; |
| 935 | } completionHandler: nil]; |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 936 | } |
Alexandre Lision | 89edc6a | 2015-11-09 11:30:47 -0500 | [diff] [blame] | 937 | |
Alexandre Lision | 58cab67 | 2015-06-09 15:25:40 -0400 | [diff] [blame] | 938 | #pragma mark - NSSplitViewDelegate |
| 939 | |
| 940 | /* Return YES if the subview should be collapsed because the user has double-clicked on an adjacent divider. If a split view has a delegate, and the delegate responds to this message, it will be sent once for the subview before a divider when the user double-clicks on that divider, and again for the subview after the divider, but only if the delegate returned YES when sent -splitView:canCollapseSubview: for the subview in question. When the delegate indicates that both subviews should be collapsed NSSplitView's behavior is undefined. |
| 941 | */ |
| 942 | - (BOOL)splitView:(NSSplitView *)splitView shouldCollapseSubview:(NSView *)subview forDoubleClickOnDividerAtIndex:(NSInteger)dividerIndex; |
| 943 | { |
| 944 | NSView* rightView = [[splitView subviews] objectAtIndex:1]; |
| 945 | return ([subview isEqual:rightView]); |
| 946 | } |
| 947 | |
| 948 | |
| 949 | - (BOOL)splitView:(NSSplitView *)splitView canCollapseSubview:(NSView *)subview; |
| 950 | { |
| 951 | NSView* rightView = [[splitView subviews] objectAtIndex:1]; |
| 952 | return ([subview isEqual:rightView]); |
| 953 | } |
| 954 | |
| 955 | |
Alexandre Lision | a1eee3c | 2015-08-10 13:44:51 -0400 | [diff] [blame] | 956 | # pragma mark - CallnDelegate |
Alexandre Lision | 58cab67 | 2015-06-09 15:25:40 -0400 | [diff] [blame] | 957 | |
| 958 | - (void) callShouldToggleFullScreen |
| 959 | { |
| 960 | if(self.splitView.isInFullScreenMode) |
| 961 | [self.splitView exitFullScreenModeWithOptions:nil]; |
| 962 | else { |
| 963 | NSApplicationPresentationOptions options = NSApplicationPresentationDefault +NSApplicationPresentationAutoHideDock + |
| 964 | NSApplicationPresentationAutoHideMenuBar + NSApplicationPresentationAutoHideToolbar; |
| 965 | NSDictionary *opts = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:options], |
| 966 | NSFullScreenModeApplicationPresentationOptions, nil]; |
| 967 | |
| 968 | [self.splitView enterFullScreenMode:[NSScreen mainScreen] withOptions:opts]; |
| 969 | } |
| 970 | } |
| 971 | |
Alexandre Lision | a1eee3c | 2015-08-10 13:44:51 -0400 | [diff] [blame] | 972 | -(void) mouseIsMoving:(BOOL) move |
| 973 | { |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 974 | [[controlsPanel animator] setAlphaValue:move];// fade out |
| 975 | [[controlsStackView animator] setAlphaValue:move]; |
Alexandre Lision | a1eee3c | 2015-08-10 13:44:51 -0400 | [diff] [blame] | 976 | [[headerContainer animator] setAlphaValue:move]; |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 977 | [[headerGradientView animator] setAlphaValue:move]; |
Alexandre Lision | a1eee3c | 2015-08-10 13:44:51 -0400 | [diff] [blame] | 978 | } |
| 979 | |
Kateryna Kostiuk | 89398b6 | 2018-11-20 16:45:04 -0500 | [diff] [blame] | 980 | - (BOOL)splitView:(NSSplitView *)splitView shouldHideDividerAtIndex:(NSInteger)dividerIndex |
| 981 | { |
| 982 | return YES; |
| 983 | } |
| 984 | |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 985 | -(void) screenShare { |
| 986 | NSScreen *mainScreen = [NSScreen mainScreen]; |
| 987 | NSRect screenFrame = mainScreen.frame; |
| 988 | QRect captureRect = QRect(screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height); |
| 989 | mediaModel->setDisplay(0, screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height); |
| 990 | } |
| 991 | -(void) switchToDevice:(int)deviceID { |
| 992 | auto devices = mediaModel->getDevices(); |
| 993 | auto device = devices[deviceID]; |
| 994 | mediaModel->switchInputTo(device); |
| 995 | } |
| 996 | |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 997 | -(QVector<QString>) getDeviceList { |
| 998 | QVector<QString> devicesVector; |
Kateryna Kostiuk | 6453310 | 2019-10-29 15:34:29 -0400 | [diff] [blame] | 999 | for (auto device : mediaModel->getDevices()) { |
| 1000 | try { |
| 1001 | auto settings = mediaModel->getDeviceSettings(device); |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1002 | devicesVector.append(settings.name); |
Kateryna Kostiuk | 6453310 | 2019-10-29 15:34:29 -0400 | [diff] [blame] | 1003 | } catch (...) {} |
| 1004 | } |
| 1005 | return devicesVector; |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 1006 | } |
| 1007 | |
Kateryna Kostiuk | 32cf6be | 2019-10-28 12:22:45 -0400 | [diff] [blame] | 1008 | -(NSString*) getDefaultDeviceName { |
| 1009 | auto type = mediaModel->getCurrentRenderedDevice(callUid_).type; |
| 1010 | switch (type) { |
| 1011 | case lrc::api::video::DeviceType::CAMERA: |
Kateryna Kostiuk | 6453310 | 2019-10-29 15:34:29 -0400 | [diff] [blame] | 1012 | try { |
| 1013 | auto device = mediaModel->getCurrentRenderedDevice(callUid_).name; |
| 1014 | auto settings = mediaModel->getDeviceSettings(device); |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1015 | return settings.name.toNSString(); |
Kateryna Kostiuk | 6453310 | 2019-10-29 15:34:29 -0400 | [diff] [blame] | 1016 | } catch (...) {} |
Kateryna Kostiuk | 32cf6be | 2019-10-28 12:22:45 -0400 | [diff] [blame] | 1017 | case lrc::api::video::DeviceType::DISPLAY: |
| 1018 | return NSLocalizedString(@"Share screen", @"Contextual menu entry"); |
| 1019 | default: |
| 1020 | return @""; |
| 1021 | } |
| 1022 | } |
| 1023 | |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1024 | -(void) switchToFile:(QString)uri { |
| 1025 | mediaModel->setInputFile(uri); |
Kateryna Kostiuk | 5d90c3b | 2019-07-18 12:03:52 -0400 | [diff] [blame] | 1026 | } |
| 1027 | |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 1028 | -(CGRect) getVideoPreviewCollapsedSize { |
| 1029 | CGPoint origin; |
| 1030 | switch (movableBaseForView.closestCorner) { |
| 1031 | case TOP_LEFT: |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 1032 | origin = CGPointMake(0, movableBaseForView.frame.size.height - HIDE_PREVIEW_BUTTON_SIZE); |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 1033 | break; |
| 1034 | case BOTTOM_LEFT: |
| 1035 | origin = CGPointMake(0, 0); |
| 1036 | break; |
| 1037 | case TOP_RIGHT: |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 1038 | origin = CGPointMake(movableBaseForView.frame.size.width - HIDE_PREVIEW_BUTTON_SIZE, movableBaseForView.frame.size.height - HIDE_PREVIEW_BUTTON_SIZE); |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 1039 | break; |
| 1040 | case BOTTOM_RIGHT: |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 1041 | origin = CGPointMake(movableBaseForView.frame.size.width - HIDE_PREVIEW_BUTTON_SIZE, 0); |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 1042 | break; |
| 1043 | } |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 1044 | return CGRectMake(origin.x, origin.y, HIDE_PREVIEW_BUTTON_SIZE, HIDE_PREVIEW_BUTTON_SIZE); |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 1045 | } |
| 1046 | |
Kateryna Kostiuk | 2aa3923 | 2019-10-10 11:55:11 -0400 | [diff] [blame] | 1047 | -(CGRect) frameForExpendPreviewButton { |
| 1048 | CGPoint origin = CGPointMake(self.previewView.frame.size.width - HIDE_PREVIEW_BUTTON_SIZE, |
| 1049 | self.previewView.frame.size.height - HIDE_PREVIEW_BUTTON_SIZE); |
| 1050 | return CGRectMake(origin.x, origin.y, HIDE_PREVIEW_BUTTON_SIZE, HIDE_PREVIEW_BUTTON_SIZE); |
Kateryna Kostiuk | 6891d4f | 2019-09-19 17:44:33 -0400 | [diff] [blame] | 1051 | } |
| 1052 | |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1053 | # pragma mark -ChooseContactVCDelegate |
| 1054 | |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1055 | -(void)callToContact:(const QString&)contactUri convUID:(const QString&)convID { |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1056 | if (brokerPopoverVC != nullptr) { |
| 1057 | [brokerPopoverVC performClose:self]; |
| 1058 | brokerPopoverVC = NULL; |
| 1059 | } |
| 1060 | auto* callModel = accountInfo_->callModel.get(); |
| 1061 | auto currentCall = callModel->getCall([self getcallID]); |
| 1062 | auto* convModel = accountInfo_->conversationModel.get(); |
| 1063 | auto newCall = callModel->callAndAddParticipant(contactUri, |
| 1064 | [self getcallID], |
| 1065 | currentCall.isAudioOnly); |
| 1066 | [self addPreviewForContactUri:contactUri call: newCall]; |
| 1067 | } |
| 1068 | |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1069 | -(void)joinCall:(const QString&)callId { |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1070 | if (brokerPopoverVC != nullptr) { |
| 1071 | [brokerPopoverVC performClose:self]; |
| 1072 | brokerPopoverVC = NULL; |
| 1073 | } |
| 1074 | auto* callModel = accountInfo_->callModel.get(); |
| 1075 | callModel->joinCalls([self getcallID], callId); |
| 1076 | } |
| 1077 | |
| 1078 | # pragma mark -CallInConferenceVCDelegate |
| 1079 | |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1080 | -(void)removePreviewForContactUri:(const QString&)uri forCall:(const QString&) callId { |
| 1081 | NSMutableDictionary * calls = connectingCalls[callId.toNSString()]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1082 | if (!calls) { |
| 1083 | return; |
| 1084 | } |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1085 | NSViewController *callView = calls[uri.toNSString()]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1086 | if (!callView) { |
| 1087 | return; |
| 1088 | } |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1089 | calls[uri.toNSString()] = nil; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1090 | [self.callingWidgetsContainer removeView:callView.view]; |
| 1091 | } |
| 1092 | |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1093 | -(void)addPreviewForContactUri:(const QString&)uri call:(const QString&)callId { |
| 1094 | NSMutableDictionary *calls = connectingCalls[callUid_.toNSString()]; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1095 | if (!calls) { |
| 1096 | calls = [[NSMutableDictionary alloc] init]; |
| 1097 | } |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1098 | if (calls[uri.toNSString()]) { |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1099 | return; |
| 1100 | } |
| 1101 | CallInConferenceVC *callingView = [self callingViewForCallId: callId]; |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1102 | calls[uri.toNSString()] = callingView; |
| 1103 | connectingCalls[callUid_.toNSString()] = calls; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1104 | [self.callingWidgetsContainer addView:callingView.view inGravity:NSStackViewGravityBottom]; |
| 1105 | [self.callingWidgetsContainer updateConstraints]; |
| 1106 | [self.callingWidgetsContainer updateLayer]; |
| 1107 | [self.callingWidgetsContainer setNeedsDisplay:YES]; |
| 1108 | } |
| 1109 | |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1110 | -(CallInConferenceVC*) callingViewForCallId:(const QString&)callId { |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1111 | CallInConferenceVC *callView = [[CallInConferenceVC alloc] |
| 1112 | initWithNibName:@"CallInConferenceVC" |
| 1113 | bundle:nil |
| 1114 | callId:callId |
| 1115 | accountInfo:accountInfo_]; |
| 1116 | callView.delegate = self; |
| 1117 | callView.initiatorCallId = callUid_; |
| 1118 | return callView; |
| 1119 | } |
| 1120 | |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1121 | -(const QString&)getcallID { |
| 1122 | return confUid_.isEmpty() ? callUid_ : confUid_; |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1123 | } |
| 1124 | |
Kateryna Kostiuk | c867eb9 | 2020-03-08 13:15:17 -0400 | [diff] [blame] | 1125 | -(bool)isCurrentCall:(const QString&)callId { |
Kateryna Kostiuk | 4db6109 | 2019-10-17 16:57:40 -0400 | [diff] [blame] | 1126 | return (callId == confUid_ || callId == callUid_); |
| 1127 | } |
| 1128 | |
| 1129 | #pragma mark Popover delegate |
| 1130 | |
| 1131 | - (void)popoverWillClose:(NSNotification *)notification |
| 1132 | { |
| 1133 | if (brokerPopoverVC != nullptr) { |
| 1134 | [brokerPopoverVC performClose:self]; |
| 1135 | brokerPopoverVC = NULL; |
| 1136 | } |
| 1137 | } |
Alexandre Lision | c514805 | 2015-03-04 15:10:35 -0500 | [diff] [blame] | 1138 | @end |