blob: f3cce1d84e850c9a9cadc8433ab3c6a5962865d1 [file] [log] [blame]
Olivier Soldanod4311552017-11-20 15:09:53 -05001/*
2 * Copyright (C) 2017 Savoir-faire Linux Inc.
3 * Author: Anthony Léonard <anthony.leonard@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.
18 */
19
Andreas Traczyk77a50d52018-05-08 17:47:31 -040020#import <map>
21
Olivier Soldanod4311552017-11-20 15:09:53 -050022#import <Foundation/Foundation.h>
Andreas Traczyk252a94a2018-04-20 16:36:20 -040023#import "NSString+Extensions.h"
Kateryna Kostiuk9fca5422018-11-19 16:27:46 -050024#import "views/NSColor+RingTheme.h"
25
Andreas Traczyk77a50d52018-05-08 17:47:31 -040026
27// new lrc
Olivier Soldanod4311552017-11-20 15:09:53 -050028#import <api/conversation.h>
29#import <api/conversationmodel.h>
30#import <api/account.h>
31#import <api/contactmodel.h>
32#import <api/contact.h>
Andreas Traczyk77a50d52018-05-08 17:47:31 -040033
34// old lrc
35#import <QSortFilterProxyModel>
36#import <accountmodel.h>
37#import <codecmodel.h>
Olivier Soldanod4311552017-11-20 15:09:53 -050038
39static inline NSString* bestIDForConversation(const lrc::api::conversation::Info& conv, const lrc::api::ConversationModel& model)
40{
Andreas Traczyk4e39aa52018-05-11 17:29:26 -040041 try {
42 auto contact = model.owner.contactModel->getContact(conv.participants[0]);
43 if (!contact.registeredName.empty()) {
44 contact.registeredName.erase(std::remove(contact.registeredName.begin(), contact.registeredName.end(), '\n'), contact.registeredName.end());
45 contact.registeredName.erase(std::remove(contact.registeredName.begin(), contact.registeredName.end(), '\r'), contact.registeredName.end());
46 return [@(contact.registeredName.c_str()) removeEmptyLinesAtBorders];
47 }
48 else {
49 return [@(contact.profileInfo.uri.c_str()) removeEmptyLinesAtBorders];
50 }
51 } catch (std::out_of_range& e) {
52 NSLog(@"bestIDForConversation: getContact - out of range");
Andreas Traczyk252a94a2018-04-20 16:36:20 -040053 }
Olivier Soldanod4311552017-11-20 15:09:53 -050054}
55
Kateryna Kostiukd73f9602018-07-24 13:51:28 -040056static inline NSString* bestIDForAccount(const lrc::api::account::Info& account)
57{
58 if (!account.registeredName.empty()) {
59 return [@(account.registeredName.c_str()) removeEmptyLinesAtBorders];
60 }
61 return [@(account.profileInfo.uri.c_str()) removeEmptyLinesAtBorders];
62}
63
64static inline NSString* bestNameForAccount(const lrc::api::account::Info& account)
65{
66 if (account.profileInfo.alias.empty()) {
67 return bestIDForAccount(account);
68 }
69 return @(account.profileInfo.alias.c_str());
70}
71
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -040072static inline NSString* bestIDForContact(const lrc::api::contact::Info& contact)
73{
74 if (!contact.registeredName.empty()) {
75 return [@(contact.registeredName.c_str()) removeEmptyLinesAtBorders];
76 }
77 return [@(contact.profileInfo.uri.c_str()) removeEmptyLinesAtBorders];
78}
79
80static inline NSString* bestNameForContact(const lrc::api::contact::Info& contact)
81{
82 if (contact.profileInfo.alias.empty()) {
83 return bestIDForContact(contact);
84 }
85 return @(contact.profileInfo.alias.c_str());
86}
87
Olivier Soldanod4311552017-11-20 15:09:53 -050088static inline NSString* bestNameForConversation(const lrc::api::conversation::Info& conv, const lrc::api::ConversationModel& model)
89{
Andreas Traczyk4e39aa52018-05-11 17:29:26 -040090 try {
91 auto contact = model.owner.contactModel->getContact(conv.participants[0]);
92 if (contact.profileInfo.alias.empty()) {
93 return bestIDForConversation(conv, model);
94 }
95 auto alias = contact.profileInfo.alias;
96 alias.erase(std::remove(alias.begin(), alias.end(), '\n'), alias.end());
97 alias.erase(std::remove(alias.begin(), alias.end(), '\r'), alias.end());
98 if(alias.length() == 0) {
99 return bestIDForConversation(conv, model);
100 }
101 return @(alias.c_str());
102 } catch (std::out_of_range& e) {
103 NSLog(@"bestNameForConversation: getContact - out of range");
Andreas Traczyk252a94a2018-04-20 16:36:20 -0400104 }
Andreas Traczyk252a94a2018-04-20 16:36:20 -0400105}
106
107static inline lrc::api::profile::Type profileType(const lrc::api::conversation::Info& conv, const lrc::api::ConversationModel& model)
108{
109 @try {
110 auto contact = model.owner.contactModel->getContact(conv.participants[0]);
111 return contact.profileInfo.type;
112 }
113 @catch (NSException *exception) {
114 lrc::api::profile::Type::INVALID;
115 }
Olivier Soldanod4311552017-11-20 15:09:53 -0500116}
Anthony Léonard6f819752018-01-05 09:53:40 -0500117
118/**
119 * This function return an iterator pointing to a Conversation::Info in ConversationModel given its uid. If not found
120 * the iterator is invalid thus it needs to be checked by caller.
121 * @param uid UID of conversation being searched
122 * @param model ConversationModel in which to do the lookup
123 * @return iterator pointing to corresponding Conversation if any. Points to past-the-end element otherwise.
124 */
125static inline lrc::api::ConversationModel::ConversationQueue::const_iterator getConversationFromUid(const std::string& uid, const lrc::api::ConversationModel& model) {
126 return std::find_if(model.allFilteredConversations().begin(), model.allFilteredConversations().end(),
127 [&] (const lrc::api::conversation::Info& conv) {
128 return uid == conv.uid;
129 });
130}
Andreas Traczyk77a50d52018-05-08 17:47:31 -0400131
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500132/**
133 * This function return an iterator pointing to a Conversation::Info in ConversationModel given its participant uri. Will not work for group chat.
134 * @param uri URI of participant
135 * @param model ConversationModel in which to do the lookup
136 * @return iterator pointing to corresponding Conversation if any. Points to past-the-end element otherwise.
137 */
138static inline lrc::api::ConversationModel::ConversationQueue::const_iterator getConversationFromURI(const std::string& uri, const lrc::api::ConversationModel& model) {
139 return std::find_if(model.allFilteredConversations().begin(), model.allFilteredConversations().end(),
140 [&] (const lrc::api::conversation::Info& conv) {
141 return uri == conv.participants[0];
142 });
143}
144
Andreas Traczyk77a50d52018-05-08 17:47:31 -0400145static inline void
146setVideoAutoQuality(bool autoQuality, std::string accountId)
147{
148 auto thisAccount = AccountModel::instance().getById(QByteArray::fromStdString(accountId));
149 if (const auto& codecModel = thisAccount->codecModel()) {
150 const auto& videoCodecs = codecModel->videoCodecs();
151 for (int i=0; i < videoCodecs->rowCount();i++) {
152 const auto& idx = videoCodecs->index(i,0);
153
154 if (autoQuality) {
155 videoCodecs->setData(idx, "true", CodecModel::Role::AUTO_QUALITY_ENABLED);
156 } else {
157 videoCodecs->setData(idx, "false", CodecModel::Role::AUTO_QUALITY_ENABLED);
158 }
159 }
160 codecModel << CodecModel::EditAction::SAVE;
161 }
162}
Kateryna Kostiuk4138db12018-06-08 15:52:18 -0400163
164static inline bool isUrlAccessibleFromSandbox(NSURL* url)
165{
166 NSFileManager* fileManager = [[NSFileManager alloc] init];
167 NSArray* urlPathsMusic = [fileManager URLsForDirectory:NSMusicDirectory
168 inDomains:NSUserDomainMask];
169 NSArray* urlPathsPictures = [fileManager URLsForDirectory:NSPicturesDirectory
170 inDomains:NSUserDomainMask];
171 NSArray* urlPathsDownloads = [fileManager URLsForDirectory:NSDownloadsDirectory
172 inDomains:NSUserDomainMask];
173 NSArray* urlPathsMovies = [fileManager URLsForDirectory:NSMoviesDirectory
174 inDomains:NSUserDomainMask];
175 NSArray* availablePaths = [[[urlPathsMusic arrayByAddingObjectsFromArray: urlPathsPictures] arrayByAddingObjectsFromArray: urlPathsDownloads] arrayByAddingObjectsFromArray: urlPathsMovies];
176 if([availablePaths containsObject:url]) {
177 return YES;
178 }
179 for (NSURL* availableUrl in availablePaths) {
180 if ([url.path containsString:availableUrl.path]) {
181 return YES;
182 }
183 }
184 return NO;
185}
186
187static inline bool appSandboxed()
188{
189 NSString* bundleID = [[NSBundle mainBundle] bundleIdentifier];
Kateryna Kostiukb88d27f2018-06-14 12:56:52 -0400190 NSString* url = [[NSURL fileURLWithPath:NSHomeDirectory()] path];
191 NSString* appPath = [@"Library/Containers/" stringByAppendingString:bundleID];
192 if ([url containsString: appPath]) {
Kateryna Kostiuk4138db12018-06-08 15:52:18 -0400193 return YES;
194 }
195 return NO;
196}
Kateryna Kostiuk9fca5422018-11-19 16:27:46 -0500197
198static inline NSColor* colorForAccountStatus(const lrc::api::account::Status status)
199{
200 NSColor *accountStatusColor = [NSColor unregisteredColor];
201 switch (status) {
202 case lrc::api::account::Status::REGISTERED:
203 accountStatusColor = [NSColor presenceColor];
204 break;
205 case lrc::api::account::Status::TRYING:
206 accountStatusColor = [NSColor orangeColor];
207 break;
208 default:
209 break;
210 }
211 return accountStatusColor;
212}