blob: f83f404259cfef3af20d33dfc69cb72942576737 [file] [log] [blame]
Alexandre Lision8521baa2015-03-13 11:08:00 -04001/*
Alexandre Lision9fe374b2016-01-06 10:17:31 -05002 * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
Alexandre Lision8521baa2015-03-13 11:08:00 -04003 * 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 Lision8521baa2015-03-13 11:08:00 -040018 */
Alexandre Lision5855b6a2015-02-03 11:31:05 -050019#import "RingWindowController.h"
Alexandre Lision0f66bd32016-01-18 11:30:45 -050020#import <QuartzCore/QuartzCore.h>
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -040021#include <qrencode.h>
Alexandre Lision0f66bd32016-01-18 11:30:45 -050022
Alexandre Lisionbb5c2462015-07-30 12:55:37 -040023//LRC
Anthony Léonard79597602017-11-13 15:47:09 -050024#import <api/lrc.h>
Anthony Léonard49cb2912017-11-13 16:15:39 -050025#import <api/account.h>
Olivier Soldano994971f2017-12-05 16:30:12 -050026#import <api/newaccountmodel.h>
27#import <api/newcallmodel.h>
28#import <api/behaviorcontroller.h>
29#import <api/conversation.h>
Anthony Léonardd00cd182018-01-17 09:21:27 -050030#import <api/contactmodel.h>
31#import <api/contact.h>
Kateryna Kostiuk67735232018-05-10 15:05:32 -040032#import <api/datatransfermodel.h>
Kateryna Kostiuk00dcbff2019-07-11 15:42:13 -040033#import <api/avmodel.h>
Alexandre Lision5855b6a2015-02-03 11:31:05 -050034
Alexandre Lision624b1a82016-09-11 19:29:01 -040035// Ring
Alexandre Lision745e4d62015-03-22 20:03:10 -040036#import "AppDelegate.h"
Alexandre Lisionc65310c2015-04-23 16:44:23 -040037#import "Constants.h"
Alexandre Lision58cab672015-06-09 15:25:40 -040038#import "CurrentCallVC.h"
Alexandre Lision624b1a82016-09-11 19:29:01 -040039#import "MigrateRingAccountsWC.h"
Alexandre Lision0f66bd32016-01-18 11:30:45 -050040#import "ConversationVC.h"
Alexandre Lisionbfa68f62015-09-10 08:38:42 -040041#import "PreferencesWC.h"
Alexandre Lisiona3a43dc2017-03-30 16:21:30 -040042#import "SmartViewVC.h"
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -040043#import "views/IconButton.h"
Alexandre Lisionbfa68f62015-09-10 08:38:42 -040044#import "views/NSColor+RingTheme.h"
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -040045#import "views/HoverButton.h"
Kateryna Kostiuk74fe20c2018-06-14 12:05:53 -040046#import "utils.h"
Kateryna Kostiukd73f9602018-07-24 13:51:28 -040047#import "RingWizardWC.h"
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -040048#import "AccountSettingsVC.h"
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -040049
50typedef NS_ENUM(NSInteger, ViewState) {
51 SHOW_WELCOME_SCREEN = 0,
52 SHOW_CONVERSATION_SCREEN,
53 SHOW_CALL_SCREEN,
54 SHOW_SETTINGS_SCREEN,
Kateryna Kostiuk9b91d222020-04-29 15:06:55 -040055 HIDE_SETTINGS_SCREEN,
Kateryna Kostiukf6317422018-09-27 17:08:20 -040056 LEAVE_MESSAGE,
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -040057};
Alexandre Lision2db8f472015-07-22 15:05:46 -040058
Kateryna Kostiukef66f972018-11-02 17:10:37 -040059@interface RingWindowController () <MigrateRingAccountsDelegate>
Alexandre Lision624b1a82016-09-11 19:29:01 -040060
61@property (retain) MigrateRingAccountsWC* migrateWC;
Kateryna Kostiukd73f9602018-07-24 13:51:28 -040062@property RingWizardWC* wizard;
Kateryna Kostiuk4db61092019-10-17 16:57:40 -040063@property QMetaObject::Connection callState;
Alexandre Lision624b1a82016-09-11 19:29:01 -040064
65@end
66
Alexandre Lisionbfa68f62015-09-10 08:38:42 -040067@implementation RingWindowController {
Alexandre Lision5855b6a2015-02-03 11:31:05 -050068
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -040069 __unsafe_unretained IBOutlet NSLayoutConstraint* centerYQRCodeConstraint;
70 __unsafe_unretained IBOutlet NSLayoutConstraint* centerYWelcomeContainerConstraint;
Kateryna Kostiukab499f42018-04-16 12:27:33 -040071 IBOutlet NSLayoutConstraint* ringLabelTrailingConstraint;
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -040072 __unsafe_unretained IBOutlet NSView* welcomeContainer;
Alexandre Lision1abdf582016-02-09 14:21:19 -050073 __unsafe_unretained IBOutlet NSView* callView;
74 __unsafe_unretained IBOutlet NSTextField* ringIDLabel;
Kateryna Kostiuk85a334e2018-12-03 15:54:19 -050075 __unsafe_unretained IBOutlet NSTextField* explanationLabel;
Alexandre Lision1abdf582016-02-09 14:21:19 -050076 __unsafe_unretained IBOutlet NSButton* shareButton;
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -040077 __unsafe_unretained IBOutlet NSImageView* qrcodeView;
Alexandre Lision58cab672015-06-09 15:25:40 -040078
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -040079 PreferencesWC* preferencesWC;
Alexandre Lisiona3a43dc2017-03-30 16:21:30 -040080 IBOutlet SmartViewVC* smartViewVC;
Alexandre Lisione77f6f92016-04-17 23:39:39 -040081
Alexandre Lision0f66bd32016-01-18 11:30:45 -050082 CurrentCallVC* currentCallVC;
Andreas Traczykecdc4fa2018-03-22 16:11:47 -040083 ConversationVC* conversationVC;
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -040084 AccountSettingsVC* settingsVC;
Andreas Traczykecdc4fa2018-03-22 16:11:47 -040085
Kateryna Kostiukef66f972018-11-02 17:10:37 -040086 IBOutlet ChooseAccountVC* chooseAccountVC;
Alexandre Lisionbfa68f62015-09-10 08:38:42 -040087}
Alexandre Lision58cab672015-06-09 15:25:40 -040088
Kateryna Kostiukf6317422018-09-27 17:08:20 -040089@synthesize dataTransferModel, accountModel, behaviorController, avModel;
Kateryna Kostiukd73f9602018-07-24 13:51:28 -040090@synthesize wizard;
Kateryna Kostiukecaa3952018-07-13 16:00:34 -040091
Kateryna Kostiukf6317422018-09-27 17:08:20 -040092-(id) initWithWindowNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountModel:( lrc::api::NewAccountModel*)accountModel dataTransferModel:( lrc::api::DataTransferModel*)dataTransferModel behaviourController:( lrc::api::BehaviorController*) behaviorController avModel: (lrc::api::AVModel*)avModel
Kateryna Kostiukecaa3952018-07-13 16:00:34 -040093{
94 if (self = [self initWithWindowNibName:nibNameOrNil])
95 {
96 self.accountModel = accountModel;
97 self.dataTransferModel = dataTransferModel;
98 self.behaviorController = behaviorController;
Kateryna Kostiukf6317422018-09-27 17:08:20 -040099 self.avModel = avModel;
Kateryna Kostiuk5d90c3b2019-07-18 12:03:52 -0400100 self.avModel->useAVFrame(YES);
Kateryna Kostiuk6c892f02020-08-12 10:17:09 -0400101 [NSDistributedNotificationCenter.defaultCenter addObserver:self selector:@selector(themeChanged:) name:@"AppleInterfaceThemeChangedNotification" object: nil];
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400102 }
103 return self;
104}
105
Kateryna Kostiuk6c892f02020-08-12 10:17:09 -0400106-(void) deinit {
107 [NSDistributedNotificationCenter.defaultCenter removeObserver:self];
108
109}
110
Kateryna Kostiukef66f972018-11-02 17:10:37 -0400111- (NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions
112{
113 return (NSApplicationPresentationFullScreen |
114 NSApplicationPresentationAutoHideMenuBar |
115 NSApplicationPresentationAutoHideToolbar);
116}
117
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400118-(void)changeViewTo:(ViewState) state {
119 switch (state) {
120 case SHOW_WELCOME_SCREEN:
121 [self accountSettingsShouldOpen: NO];
122 [conversationVC hideWithAnimation:false];
123 [currentCallVC hideWithAnimation:false];
Kateryna Kostiuk4f37d952018-12-04 13:19:17 -0500124 [currentCallVC cleanUp];
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400125 [currentCallVC.view removeFromSuperview];
126 [welcomeContainer setHidden: NO];
127 [smartViewVC.view setHidden: NO];
128 [settingsVC hide];
129 break;
130 case SHOW_CONVERSATION_SCREEN:
131 [self accountSettingsShouldOpen: NO];
132 [conversationVC showWithAnimation:false];
133 [currentCallVC hideWithAnimation:false];
Kateryna Kostiuk4f37d952018-12-04 13:19:17 -0500134 [currentCallVC cleanUp];
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400135 [currentCallVC.view removeFromSuperview];
136 [welcomeContainer setHidden: YES];
137 [smartViewVC.view setHidden: NO];
138 [settingsVC hide];
139 break;
140 case SHOW_CALL_SCREEN:
Kateryna Kostiuk5d90c3b2019-07-18 12:03:52 -0400141 self.avModel->useAVFrame(YES);
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400142 [self accountSettingsShouldOpen: NO];
143 if (![currentCallVC.view superview]) {
144 [callView addSubview:[currentCallVC view] positioned:NSWindowAbove relativeTo:nil];
145 [currentCallVC initFrame];
146 [currentCallVC showWithAnimation:false];
147 [conversationVC hideWithAnimation:false];
148 [welcomeContainer setHidden: YES];
149 [smartViewVC.view setHidden: NO];
150 [settingsVC hide];
151 }
152 [currentCallVC showWithAnimation:false];
153 break;
154 case SHOW_SETTINGS_SCREEN:
155 @try {
156 [self accountSettingsShouldOpen: YES];
157 }
158 @catch (NSException *ex) {
159 return;
160 }
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400161 [smartViewVC.view setHidden: YES];
162 [settingsVC show];
163 break;
Kateryna Kostiukf6317422018-09-27 17:08:20 -0400164 case LEAVE_MESSAGE:
165 [conversationVC showWithAnimation: false];
166 [currentCallVC hideWithAnimation: false];
167 [conversationVC presentLeaveMessageView];
Kateryna Kostiuk9b91d222020-04-29 15:06:55 -0400168 case HIDE_SETTINGS_SCREEN:
169 [self accountSettingsShouldOpen: NO];
170 [smartViewVC.view setHidden: NO];
171 [settingsVC hide];
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400172 default:
173 break;
174 }
175}
176
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500177- (void)windowDidLoad {
178 [super windowDidLoad];
Alexandre Lision4dfcafc2015-08-20 12:43:23 -0400179 [self.window setMovableByWindowBackground:YES];
Kateryna Kostiuk6c892f02020-08-12 10:17:09 -0400180 [qrcodeView setWantsLayer: YES];
Alexandre Lision58cab672015-06-09 15:25:40 -0400181
Kateryna Kostiuk13b76882017-03-30 09:18:44 -0400182 self.window.titleVisibility = NSWindowTitleHidden;
“Kateryna”a4d72772020-04-08 11:30:27 -0400183 self.window.titlebarAppearsTransparent = true;
Alexandre Lisione77f6f92016-04-17 23:39:39 -0400184
Alexandre Lision0f66bd32016-01-18 11:30:45 -0500185 currentCallVC = [[CurrentCallVC alloc] initWithNibName:@"CurrentCall" bundle:nil];
Kateryna Kostiuk133364b2018-10-31 11:36:08 -0400186 currentCallVC.delegate = self;
Kateryna Kostiukf6317422018-09-27 17:08:20 -0400187 conversationVC = [[ConversationVC alloc] initWithNibName:@"Conversation" bundle:nil delegate:self aVModel:self.avModel];
Kateryna Kostiukef66f972018-11-02 17:10:37 -0400188 [chooseAccountVC updateWithDelegate: self andModel:self.accountModel];
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400189 settingsVC = [[AccountSettingsVC alloc] initWithNibName:@"AccountSettings" bundle:nil accountmodel:self.accountModel];
Alexandre Lision58cab672015-06-09 15:25:40 -0400190 [callView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
Kateryna Kostiukc24e0f92019-10-02 13:37:16 -0400191 [[currentCallVC view] setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
Andreas Traczykecdc4fa2018-03-22 16:11:47 -0400192 [[conversationVC view] setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400193 [[settingsVC view] setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
Alexandre Lision58cab672015-06-09 15:25:40 -0400194
Andreas Traczykecdc4fa2018-03-22 16:11:47 -0400195 [callView addSubview:[conversationVC view] positioned:NSWindowAbove relativeTo:nil];
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400196 [self.window.contentView addSubview:[settingsVC view] positioned:NSWindowAbove relativeTo:nil];
Alexandre Lision16d9c0a2015-08-10 12:05:15 -0400197
Andreas Traczykecdc4fa2018-03-22 16:11:47 -0400198 [conversationVC initFrame];
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400199 [settingsVC initFrame];
Alexandre Lisionbb5c2462015-07-30 12:55:37 -0400200
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -0400201 [self checkAccountsToMigrate];
Anthony Léonard49cb2912017-11-13 16:15:39 -0500202
Kateryna Kostiuk74fe20c2018-06-14 12:05:53 -0400203 // set download folder (default - 'Documents')
Kateryna Kostiuk67735232018-05-10 15:05:32 -0400204 NSString* path = [[NSUserDefaults standardUserDefaults] stringForKey:Preferences::DownloadFolder];
205 if (!path || path.length == 0) {
Kateryna Kostiuk74fe20c2018-06-14 12:05:53 -0400206 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
207 path = [[paths objectAtIndex:0] stringByAppendingString:@"/"];
Kateryna Kostiuk67735232018-05-10 15:05:32 -0400208 }
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400209 self.dataTransferModel->downloadDirectory = QString::fromNSString(path);
Kateryna Kostiuk74fe20c2018-06-14 12:05:53 -0400210 if(appSandboxed()) {
211 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400212 avModel->setRecordPath(QString::fromNSString([paths objectAtIndex:0]));
213 } else if (avModel->getRecordPath().isEmpty()) {
214 avModel->setRecordPath(QString::fromNSString(NSHomeDirectory()));
Kateryna Kostiuk74fe20c2018-06-14 12:05:53 -0400215 }
Kateryna Kostiukef66f972018-11-02 17:10:37 -0400216 NSToolbar *tb = [[self window] toolbar];
217 [tb setAllowsUserCustomization:NO];
Kateryna Kostiukf6317422018-09-27 17:08:20 -0400218
219 //add messages view controller to responders chain
220 NSResponder * viewNextResponder = [self nextResponder];
221 [self setNextResponder: [conversationVC getMessagesView]];
222 [[conversationVC getMessagesView] setNextResponder: viewNextResponder];
Alexandre Lision0f66bd32016-01-18 11:30:45 -0500223}
224
225- (void) connect
226{
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400227 QObject::connect(self.behaviorController,
Olivier Soldano994971f2017-12-05 16:30:12 -0500228 &lrc::api::BehaviorController::showCallView,
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400229 [self](const QString& accountId,
Olivier Soldano994971f2017-12-05 16:30:12 -0500230 const lrc::api::conversation::Info convInfo){
Kateryna Kostiukd5aded72020-11-06 17:03:42 -0500231 AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
232 [appDelegate disableScreenSleep];
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400233 auto* accInfo = &self.accountModel->getAccountInfo(accountId);
234 try {
235 if (accInfo->contactModel->getContact(convInfo.participants[0]).profileInfo.type == lrc::api::profile::Type::PENDING)
236 [smartViewVC selectPendingList];
237 else
238 [smartViewVC selectConversationList];
Anthony Léonardd00cd182018-01-17 09:21:27 -0500239
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400240 [currentCallVC setCurrentCall:convInfo.callId
241 conversation:convInfo.uid
242 account:accInfo
243 avModel: avModel];
244 [self changeViewTo:SHOW_CALL_SCREEN];
245 [conversationVC setConversationUid:convInfo.uid model:accInfo->conversationModel.get()];
246 } catch (std::out_of_range& e) {
247 NSLog(@"contact out of range");
248 }
249 });
Alexandre Lision210fe212016-01-27 11:15:13 -0500250
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400251 QObject::connect(self.behaviorController,
Olivier Soldano994971f2017-12-05 16:30:12 -0500252 &lrc::api::BehaviorController::showIncomingCallView,
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400253 [self](const QString& accountId,
Olivier Soldano994971f2017-12-05 16:30:12 -0500254 const lrc::api::conversation::Info convInfo){
Kateryna Kostiukd5aded72020-11-06 17:03:42 -0500255 AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
256 [appDelegate disableScreenSleep];
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400257 auto* accInfo = &self.accountModel->getAccountInfo(accountId);
Kateryna Kostiuk30202a82020-09-24 10:57:59 -0400258 auto callModel = accInfo->callModel.get();
Kateryna Kostiuk66150982020-09-18 15:14:36 -0400259 lrc::api::account::ConfProperties_t accountProperties = accInfo->accountModel->getAccountConfig(accInfo->id);
Kateryna Kostiuk30202a82020-09-24 10:57:59 -0400260 if (accountProperties.isRendezVous && (!callModel->hasCall(convInfo.callId) || !callModel->getCall(convInfo.callId).isOutgoing)) {
Kateryna Kostiuk66150982020-09-18 15:14:36 -0400261 if ([smartViewVC getSelectedUID] == convInfo.uid) {
262 [smartViewVC deselect];
263 [conversationVC hideWithAnimation:false];
264 [welcomeContainer setHidden:NO];
265 }
266 return;
267 }
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400268 try {
269 if (accInfo->contactModel->getContact(convInfo.participants[0]).profileInfo.type == lrc::api::profile::Type::PENDING)
270 [smartViewVC selectPendingList];
271 else
272 [smartViewVC selectConversationList];
273 [currentCallVC setCurrentCall:convInfo.callId
274 conversation:convInfo.uid
275 account:accInfo
276 avModel: avModel];
277 [smartViewVC selectConversation: convInfo model:accInfo->conversationModel.get()];
278 [self changeViewTo:SHOW_CALL_SCREEN];
279 [conversationVC setConversationUid:convInfo.uid model:accInfo->conversationModel.get()];
280 } catch (std::out_of_range& e) {
281 NSLog(@"contact out of range");
282 }
283 });
Anthony Léonard2382b562017-12-13 15:51:28 -0500284
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400285 QObject::connect(self.behaviorController,
Anthony Léonard2382b562017-12-13 15:51:28 -0500286 &lrc::api::BehaviorController::showChatView,
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400287 [self](const QString& accountId,
Anthony Léonard2382b562017-12-13 15:51:28 -0500288 const lrc::api::conversation::Info& convInfo){
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400289 auto& accInfo = self.accountModel->getAccountInfo(accountId);
Andreas Traczykecdc4fa2018-03-22 16:11:47 -0400290 [conversationVC setConversationUid:convInfo.uid model:accInfo.conversationModel.get()];
Anthony Léonard9bebf1d2017-12-21 14:33:51 -0500291 [smartViewVC selectConversation: convInfo model:accInfo.conversationModel.get()];
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400292 [self changeViewTo:SHOW_CONVERSATION_SCREEN];
Anthony Léonard2382b562017-12-13 15:51:28 -0500293 });
Kateryna Kostiukf6317422018-09-27 17:08:20 -0400294 QObject::connect(self.behaviorController,
295 &lrc::api::BehaviorController::showLeaveMessageView,
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400296 [self](const QString& accountId,
Kateryna Kostiukf6317422018-09-27 17:08:20 -0400297 const lrc::api::conversation::Info& convInfo){
298 auto& accInfo = self.accountModel->getAccountInfo(accountId);
299 [conversationVC setConversationUid:convInfo.uid model:accInfo.conversationModel.get()];
300 [smartViewVC selectConversation: convInfo model:accInfo.conversationModel.get()];
301 [self changeViewTo:LEAVE_MESSAGE];
302 });
Alexandre Lisionbb5c2462015-07-30 12:55:37 -0400303}
304
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -0400305#pragma mark - Ring account migration
306
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400307- (void) migrateRingAccount:(const QString&) acc
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -0400308{
309 self.migrateWC = [[MigrateRingAccountsWC alloc] initWithDelegate:self actionCode:1];
310 self.migrateWC.accountModel = self.accountModel;
311 self.migrateWC.accountToMigrate = acc;
312 [self.window beginSheet:self.migrateWC.window completionHandler:nil];
313}
314
315- (void)checkAccountsToMigrate
316{
317 auto accounts = self.accountModel->getAccountList();
318 for (auto accountId: accounts) {
319 const lrc::api::account::Info& accountInfo = self.accountModel->getAccountInfo(accountId);
320 if (accountInfo.status == lrc::api::account::Status::ERROR_NEED_MIGRATION) {
321 [self migrateRingAccount:accountInfo.id];
322 return;
323 }
324 }
325 @try {
326 [smartViewVC setConversationModel: [chooseAccountVC selectedAccount].conversationModel.get()];
327 }
328 @catch (NSException *ex) {
329 NSLog(@"Caught exception %@: %@", [ex name], [ex reason]);
330 }
331 [shareButton sendActionOn:NSLeftMouseDownMask];
332 [self connect];
333 [self updateRingID];
Kateryna Kostiuk4db61092019-10-17 16:57:40 -0400334 [self connectCallSignalsForAccount];
335}
336
337- (void)connectCallSignalsForAccount
338{
339 @try {
340 auto& account = [chooseAccountVC selectedAccount];
341 QObject::disconnect(self.callState);
342 auto *callModel = account.callModel.get();
343 self.callState = QObject::connect(callModel,
344 &lrc::api::NewCallModel::callStatusChanged,
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400345 [self, callModel](const QString& callId) {
Kateryna Kostiuk4db61092019-10-17 16:57:40 -0400346 if (callModel->hasCall(callId)) {
347 auto call = callModel->getCall(callId);
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400348 [smartViewVC reloadConversationWithURI: call.peerUri.toNSString()];
Kateryna Kostiuk4db61092019-10-17 16:57:40 -0400349 }
350 });
351 } @catch (NSException *ex) {
352 }
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -0400353}
354
355- (void)migrationDidComplete
356{
357 [self checkAccountsToMigrate];
358}
359
360- (void)migrationDidCompleteWithError
361{
362 [self checkAccountsToMigrate];
363}
364
Alexandre Lisionbb5c2462015-07-30 12:55:37 -0400365/**
366 * Implement the necessary logic to choose which Ring ID to display.
367 * This tries to choose the "best" ID to show
368 */
369- (void) updateRingID
370{
Anthony Léonard72128c92017-12-26 16:48:39 -0500371 @try {
372 auto& account = [chooseAccountVC selectedAccount];
Alexandre Lisionbb5c2462015-07-30 12:55:37 -0400373
Anthony Léonard72128c92017-12-26 16:48:39 -0500374 [ringIDLabel setStringValue:@""];
Anthony Léonard49cb2912017-11-13 16:15:39 -0500375
Anthony Léonard72128c92017-12-26 16:48:39 -0500376 if(account.profileInfo.type != lrc::api::profile::Type::RING) {
Kateryna Kostiukab499f42018-04-16 12:27:33 -0400377 self.notRingAccount = YES;
378 self.isSIPAccount = YES;
Anthony Léonard72128c92017-12-26 16:48:39 -0500379 return;
380 }
Kateryna Kostiukab499f42018-04-16 12:27:33 -0400381 self.isSIPAccount = NO;
382 self.notRingAccount = NO;
383 [ringLabelTrailingConstraint setActive:YES];
Anthony Léonard72128c92017-12-26 16:48:39 -0500384 auto& registeredName = account.registeredName;
385 auto& ringID = account.profileInfo.uri;
386 NSString* uriToDisplay = nullptr;
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400387 if (!registeredName.isEmpty()) {
388 uriToDisplay = registeredName.toNSString();
Kateryna Kostiuk85a334e2018-12-03 15:54:19 -0500389 [explanationLabel setStringValue: NSLocalizedString(@"This is your Jami username. \nCopy and share it with your friends!", @"Explanation label when user have Jami username")];
Anthony Léonard72128c92017-12-26 16:48:39 -0500390 } else {
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400391 uriToDisplay = ringID.toNSString();
Kateryna Kostiuk85a334e2018-12-03 15:54:19 -0500392 [explanationLabel setStringValue: NSLocalizedString(@"This is your ID. \nCopy and share it with your friends!", @"Explanation label when user have just ID")];
Anthony Léonard72128c92017-12-26 16:48:39 -0500393 }
394 [ringIDLabel setStringValue:uriToDisplay];
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400395 [self drawQRCode: ringID.toNSString()];
Alexandre Lisionbb5c2462015-07-30 12:55:37 -0400396 }
Anthony Léonard72128c92017-12-26 16:48:39 -0500397 @catch (NSException *ex) {
398 NSLog(@"Caught exception %@: %@", [ex name], [ex reason]);
Kateryna Kostiukab499f42018-04-16 12:27:33 -0400399 self.notRingAccount = YES;
400 self.isSIPAccount = NO;
401 [ringLabelTrailingConstraint setActive:NO];
Anthony Léonard70638f02018-02-05 11:10:19 -0500402 [ringIDLabel setStringValue:NSLocalizedString(@"No account available", @"Displayed as RingID when no accounts are available for selection")];
Alexandre Lision313427f2016-11-24 21:04:04 -0500403 }
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500404}
405
Alexandre Lision1abdf582016-02-09 14:21:19 -0500406- (IBAction)shareRingID:(id)sender {
407 NSSharingServicePicker* sharingServicePicker = [[NSSharingServicePicker alloc] initWithItems:[NSArray arrayWithObject:[ringIDLabel stringValue]]];
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -0400408 [sharingServicePicker setDelegate:self];
Alexandre Lision1abdf582016-02-09 14:21:19 -0500409 [sharingServicePicker showRelativeToRect:[sender bounds]
410 ofView:sender
411 preferredEdge:NSMinYEdge];
412}
413
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -0400414- (IBAction)toggleQRCode:(id)sender {
415 // Toggle pressed state of QRCode button
Kateryna Kostiuk85a334e2018-12-03 15:54:19 -0500416 // [sender setPressed:![sender isPressed]];
417 bool show = qrcodeView.animator.alphaValue == 0.0f ? YES: NO;
418 [self showQRCode: show];
Alexandre Lision313427f2016-11-24 21:04:04 -0500419}
420
421/**
422 * Draw the QRCode in the qrCodeView
423 */
Kateryna Kostiuk65ba43e2017-03-30 15:10:04 -0400424- (void)drawQRCode:(NSString*) uriToDraw
Alexandre Lision313427f2016-11-24 21:04:04 -0500425{
Kateryna Kostiuk65ba43e2017-03-30 15:10:04 -0400426 auto qrCode = QRcode_encodeString(uriToDraw.UTF8String,
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -0400427 0,
428 QR_ECLEVEL_L, // Lowest level of error correction
429 QR_MODE_8, // 8-bit data mode
430 1);
431 if (!qrCode) {
432 return;
433 }
434
Alexandre Lision313427f2016-11-24 21:04:04 -0500435 unsigned char *data = 0;
436 int width;
437 data = qrCode->data;
438 width = qrCode->width;
439 int qr_margin = 3;
440
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -0400441 CGFloat size = qrcodeView.frame.size.width;
442
443 // create context
444 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
445 CGContextRef ctx = CGBitmapContextCreate(0, size, size, 8, size * 4, colorSpace, kCGImageAlphaPremultipliedLast);
446
447 CGAffineTransform translateTransform = CGAffineTransformMakeTranslation(0, -size);
448 CGAffineTransform scaleTransform = CGAffineTransformMakeScale(1, -1);
449 CGContextConcatCTM(ctx, CGAffineTransformConcat(translateTransform, scaleTransform));
450
Alexandre Lision313427f2016-11-24 21:04:04 -0500451 float zoom = ceil((double)size / (qrCode->width + 2.0 * qr_margin));
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -0400452 CGRect rectDraw = CGRectMake(0, 0, zoom, zoom);
453
454 int ran;
455 for(int i = 0; i < width; ++i) {
456 for(int j = 0; j < width; ++j) {
457 if(*data & 1) {
Kateryna Kostiukbf899502019-09-25 11:25:45 -0400458 CGContextSetFillColorWithColor(ctx, [NSColor blackColor].CGColor);
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -0400459 rectDraw.origin = CGPointMake((j + qr_margin) * zoom,(i + qr_margin) * zoom);
460 CGContextAddRect(ctx, rectDraw);
461 CGContextFillPath(ctx);
462 } else {
Kateryna Kostiuke28a0382019-10-25 16:29:08 -0400463 CGContextSetFillColorWithColor(ctx, [NSColor clearColor].CGColor);
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -0400464 rectDraw.origin = CGPointMake((j + qr_margin) * zoom,(i + qr_margin) * zoom);
465 CGContextAddRect(ctx, rectDraw);
466 CGContextFillPath(ctx);
467 }
468 ++data;
469 }
470 }
Alexandre Lision313427f2016-11-24 21:04:04 -0500471
472 // get image
473 auto qrCGImage = CGBitmapContextCreateImage(ctx);
474 auto qrImage = [[NSImage alloc] initWithCGImage:qrCGImage size:qrcodeView.frame.size];
475
476 // some releases
477 CGContextRelease(ctx);
478 CGImageRelease(qrCGImage);
479 CGColorSpaceRelease(colorSpace);
480 QRcode_free(qrCode);
481
482 [qrcodeView setImage:qrImage];
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -0400483}
484
485/**
486 * Start the in/out animation displaying the QRCode
487 * @param show should the QRCode be animated in or out
488 */
489- (void) showQRCode:(BOOL) show
490{
Kateryna Kostiuk6c892f02020-08-12 10:17:09 -0400491 [self updateQRCodeBackground];
Alexandre Lisionfd0d6c82016-03-29 17:06:54 -0400492 static const NSInteger offset = 110;
493 [NSAnimationContext beginGrouping];
494 NSAnimationContext.currentContext.duration = 0.5;
495 [[NSAnimationContext currentContext] setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
496 qrcodeView.animator.alphaValue = show ? 1.0 : 0.0;
497 [centerYQRCodeConstraint.animator setConstant: show ? offset : 0];
498 [centerYWelcomeContainerConstraint.animator setConstant:show ? -offset : 0];
499 [NSAnimationContext endGrouping];
500}
501
Kateryna Kostiuk6c892f02020-08-12 10:17:09 -0400502-(void)themeChanged:(NSNotification *) notification {
503 if (qrcodeView.animator.alphaValue == 1) {
504 [self updateQRCodeBackground];
505 }
506}
507
508-(void)updateQRCodeBackground {
509 if (@available(*, macOS 10.14)) {
510 NSString *interfaceStyle = [NSUserDefaults.standardUserDefaults valueForKey:@"AppleInterfaceStyle"];
511 if ([interfaceStyle isEqualToString:@"Dark"]) {
512 qrcodeView.layer.backgroundColor = [[NSColor whiteColor] CGColor];
513 } else {
514 qrcodeView.layer.backgroundColor = [[NSColor clearColor] CGColor];
515 }
516 }
517}
518
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500519- (IBAction)openPreferences:(id)sender
520{
Kateryna Kostiukbb68a1c2018-06-12 15:16:02 -0400521 if (preferencesWC) {
522 [preferencesWC.window orderFront:preferencesWC.window];
523 return;
524 }
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400525
Kateryna Kostiukc3fc76c2019-01-06 22:12:34 -0500526 preferencesWC = [[PreferencesWC alloc] initWithWindowNibName: @"PreferencesWindow" bundle: nil accountModel:self.accountModel dataTransferModel:self.dataTransferModel behaviourController:self.behaviorController avModel: self.avModel];
Alexandre Lisionbfa68f62015-09-10 08:38:42 -0400527 [preferencesWC.window makeKeyAndOrderFront:preferencesWC.window];
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500528}
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500529
Kateryna Kostiuk882cbac2017-07-05 17:29:00 -0400530- (IBAction)callClickedAtRow:(id)sender
531{
532 NSTabViewItem *selectedTab = [smartViewVC.tabbar selectedTabViewItem];
533 int index = [smartViewVC.tabbar indexOfTabViewItem:selectedTab];
534 switch (index) {
535 case 0:
536 [smartViewVC startCallForRow:sender];
537 break;
Kateryna Kostiuk882cbac2017-07-05 17:29:00 -0400538 default:
539 break;
540 }
541}
Anthony Léonard0a9904c2018-01-11 16:43:47 -0500542
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400543- (void) selectAccount:(const lrc::api::account::Info&)accInfo currentRemoved:(BOOL) removed
Anthony Léonard9bebf1d2017-12-21 14:33:51 -0500544{
545 // If the selected account has been changed, we close any open panel
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400546 [smartViewVC setConversationModel:accInfo.conversationModel.get()];
Anthony Léonard61e3dcf2017-12-27 12:19:52 -0500547 // Welcome view informations are also updated
548 [self updateRingID];
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400549 [settingsVC setSelectedAccount:accInfo.id];
Kateryna Kostiuk9b91d222020-04-29 15:06:55 -0400550 [self changeViewTo: ([settingsVC.view isHidden] || removed) ? SHOW_WELCOME_SCREEN : SHOW_SETTINGS_SCREEN];
Kateryna Kostiuk4db61092019-10-17 16:57:40 -0400551 [self connectCallSignalsForAccount];
Anthony Léonard9bebf1d2017-12-21 14:33:51 -0500552}
553
Kateryna Kostiukab499f42018-04-16 12:27:33 -0400554-(void)allAccountsDeleted
555{
556 [smartViewVC clearConversationModel];
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400557 [self changeViewTo:SHOW_WELCOME_SCREEN];
Kateryna Kostiukab499f42018-04-16 12:27:33 -0400558 [self updateRingID];
Kateryna Kostiukb0db48e2019-01-10 16:03:55 -0500559 qrcodeView.animator.alphaValue = 0.0;
560 [centerYQRCodeConstraint.animator setConstant: 0];
561 [centerYWelcomeContainerConstraint.animator setConstant: 0];
Kateryna Kostiuk4db61092019-10-17 16:57:40 -0400562 QObject::disconnect(self.callState);
Kateryna Kostiukb0db48e2019-01-10 16:03:55 -0500563 [self close];
564 AppDelegate* delegate = (AppDelegate*)[[NSApplication sharedApplication] delegate];
565 [delegate showWizard];
Kateryna Kostiukab499f42018-04-16 12:27:33 -0400566}
567
Anthony Léonard8585cc02017-12-28 14:03:45 -0500568-(void)rightPanelClosed
569{
570 [smartViewVC deselect];
Kateryna Kostiuk394f74c2018-10-05 15:45:26 -0400571 [welcomeContainer setHidden:NO];
Anthony Léonard8585cc02017-12-28 14:03:45 -0500572}
573
Anthony Léonard0a9904c2018-01-11 16:43:47 -0500574-(void)currentConversationTrusted
575{
576 [smartViewVC selectConversationList];
577}
578
Anthony Léonardbee94cc2018-01-16 11:42:40 -0500579-(void) listTypeChanged {
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400580 [self changeViewTo:SHOW_WELCOME_SCREEN];
Anthony Léonardbee94cc2018-01-16 11:42:40 -0500581}
582
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400583- (IBAction)openAccountSettings:(NSButton *)sender
584{
Kateryna Kostiuk9b91d222020-04-29 15:06:55 -0400585 [self changeViewTo: [settingsVC.view isHidden] ? SHOW_SETTINGS_SCREEN : HIDE_SETTINGS_SCREEN];
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400586}
587
Kateryna Kostiukd73f9602018-07-24 13:51:28 -0400588- (void) createNewAccount {
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400589 [self changeViewTo:SHOW_WELCOME_SCREEN];
Kateryna Kostiukd73f9602018-07-24 13:51:28 -0400590 wizard = [[RingWizardWC alloc] initWithNibName:@"RingWizard" bundle: nil accountmodel: self.accountModel];
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400591 [wizard showChooseWithCancelButton: YES];
Kateryna Kostiukd73f9602018-07-24 13:51:28 -0400592 [self.window beginSheet:wizard.window completionHandler:nil];
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400593}
594
Kateryna Kostiuk23222fe2018-11-16 14:28:02 -0500595- (NSRect)window:(NSWindow *)window willPositionSheet:(NSWindow *)sheet
596 usingRect:(NSRect)rect
597{
598 float titleBarHeight = self.window.frame.size.height - [NSWindow contentRectForFrameRect:self.window.frame styleMask:self.window.styleMask].size.height;
599 rect.origin.y = self.window.frame.size.height;
600 return rect;
601}
602
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400603-(void) accountSettingsShouldOpen: (BOOL) open {
604 if (open) {
Kateryna Kostiukc17db8d2018-10-23 09:48:03 -0400605 [settingsVC setSelectedAccount: [chooseAccountVC selectedAccount].id];
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400606 }
Kateryna Kostiukd73f9602018-07-24 13:51:28 -0400607}
608
Kateryna Kostiuk133364b2018-10-31 11:36:08 -0400609#pragma mark - CallViewControllerDelegate
610
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400611-(void) conversationInfoUpdatedFor:(const QString&) conversationID {
612 [smartViewVC reloadConversationWithUid:conversationID.toNSString()];
Kateryna Kostiuk133364b2018-10-31 11:36:08 -0400613}
614
Kateryna Kostiuk1705a5a2020-08-26 09:48:00 -0400615-(void) chooseConversation:(const lrc::api::conversation::Info&)conv model:(lrc::api::ConversationModel*)model{
616 [smartViewVC selectConversation: conv model:model];
617}
618
Kateryna Kostiuk4db61092019-10-17 16:57:40 -0400619-(void) callFinished {
620 [self changeViewTo:SHOW_CONVERSATION_SCREEN];
621}
622
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500623-(void) showConversation:(NSString* )conversationId forAccount:(NSString*)accountId {
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400624 auto& accInfo = self.accountModel->getAccountInfo(QString::fromNSString(accountId));
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500625 [chooseAccountVC selectAccount: accountId];
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400626 [settingsVC setSelectedAccount: QString::fromNSString(accountId)];
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500627 [smartViewVC setConversationModel:accInfo.conversationModel.get()];
628 [smartViewVC selectConversationList];
629 [self updateRingID];
Kateryna Kostiuk3541ae22020-08-17 12:26:14 -0400630 auto convInfo = getConversationFromUid(QString::fromNSString(conversationId), *accInfo.conversationModel.get());
631 if (!conversationExists(convInfo, *accInfo.conversationModel.get())) {
632 convInfo = getSearchResultFromUid(QString::fromNSString(conversationId), *accInfo.conversationModel.get());
633 if (!searchResultExists(convInfo, *accInfo.conversationModel.get())) {
634 return;
635 }
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500636 }
Kateryna Kostiuk3541ae22020-08-17 12:26:14 -0400637 [conversationVC setConversationUid:convInfo->uid model:accInfo.conversationModel.get()];
638 [smartViewVC selectConversation: *convInfo model:accInfo.conversationModel.get()];
639 accInfo.conversationModel.get()->clearUnreadInteractions(QString::fromNSString(conversationId));
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500640 [self changeViewTo:SHOW_CONVERSATION_SCREEN];
641}
642
643-(void) showCall:(NSString* )callId forAccount:(NSString*)accountId forConversation:(NSString*)conversationId {
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400644 auto& accInfo = self.accountModel->getAccountInfo(QString::fromNSString(accountId));
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500645 [chooseAccountVC selectAccount: accountId];
646 [settingsVC setSelectedAccount:accInfo.id];
647 [smartViewVC setConversationModel:accInfo.conversationModel.get()];
648 [self updateRingID];
Kateryna Kostiuk3541ae22020-08-17 12:26:14 -0400649 auto convInfo = getConversationFromUid(QString::fromNSString(conversationId), *accInfo.conversationModel.get());
650 if (!conversationExists(convInfo, *accInfo.conversationModel.get())) {
651 convInfo = getSearchResultFromUid(QString::fromNSString(conversationId), *accInfo.conversationModel.get());
652 if (!searchResultExists(convInfo, *accInfo.conversationModel.get())) {
653 return;
654 }
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500655 }
Kateryna Kostiuk3541ae22020-08-17 12:26:14 -0400656 if (accInfo.contactModel->getContact(convInfo->participants[0]).profileInfo.type == lrc::api::profile::Type::PENDING) {
657 [smartViewVC selectPendingList];
658 }
659 else {
660 [smartViewVC selectConversationList];
661 }
662 [smartViewVC selectConversation: *convInfo model:accInfo.conversationModel.get()];
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400663 [currentCallVC setCurrentCall:QString::fromNSString(callId)
664 conversation:QString::fromNSString(conversationId)
Kateryna Kostiuk5d90c3b2019-07-18 12:03:52 -0400665 account:&accInfo
666 avModel:avModel];
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500667 [self changeViewTo:SHOW_CALL_SCREEN];
668}
669
670-(void) showContactRequestFor:(NSString* )accountId contactUri:(NSString*)uri {
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400671 auto& accInfo = self.accountModel->getAccountInfo(QString::fromNSString(accountId));
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500672 [chooseAccountVC selectAccount: accountId];
673 [settingsVC setSelectedAccount:accInfo.id];
674 [smartViewVC setConversationModel:accInfo.conversationModel.get()];
675 [self updateRingID];
676 [smartViewVC selectPendingList];
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400677 auto convInfo = getConversationFromURI(QString::fromNSString(uri), *accInfo.conversationModel.get());
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500678 auto convQueue = accInfo.conversationModel.get()->allFilteredConversations();
679 if (convInfo != convQueue.end()) {
680 [conversationVC setConversationUid:convInfo->uid model:accInfo.conversationModel.get()];
681 [smartViewVC selectConversation: *convInfo model:accInfo.conversationModel.get()];
682 }
683 [self changeViewTo:SHOW_CONVERSATION_SCREEN];
684}
Kateryna Kostiuk5d90c3b2019-07-18 12:03:52 -0400685
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500686@end