2020-10-14 17:18:58 +03:00
|
|
|
/**
|
|
|
|
* @copyright Copyright (c) 2020 Ivan Sein <ivan@nextcloud.com>
|
|
|
|
*
|
|
|
|
* @author Ivan Sein <ivan@nextcloud.com>
|
|
|
|
*
|
|
|
|
* @license GNU GPL version 3 or any later version
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
2017-07-13 17:56:09 +03:00
|
|
|
|
|
|
|
#import "NCRoom.h"
|
|
|
|
|
2019-06-16 21:21:50 +03:00
|
|
|
#import "NCDatabaseManager.h"
|
2018-08-16 19:08:48 +03:00
|
|
|
|
2018-12-11 14:26:15 +03:00
|
|
|
NSString * const NCRoomObjectTypeFile = @"file";
|
|
|
|
NSString * const NCRoomObjectTypeSharePassword = @"share:password";
|
|
|
|
|
2017-07-13 17:56:09 +03:00
|
|
|
@implementation NCRoom
|
|
|
|
|
|
|
|
+ (instancetype)roomWithDictionary:(NSDictionary *)roomDict
|
|
|
|
{
|
2017-07-13 18:47:40 +03:00
|
|
|
if (!roomDict) {
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2020-06-15 18:40:57 +03:00
|
|
|
NCRoom *room = [[self alloc] init];
|
2017-11-27 16:12:19 +03:00
|
|
|
room.roomId = [[roomDict objectForKey:@"id"] integerValue];
|
2017-07-13 18:47:40 +03:00
|
|
|
room.token = [roomDict objectForKey:@"token"];
|
|
|
|
room.type = (NCRoomType)[[roomDict objectForKey:@"type"] integerValue];
|
2021-07-08 20:04:31 +03:00
|
|
|
room.roomDescription = [roomDict objectForKey:@"description"];
|
2017-07-13 18:47:40 +03:00
|
|
|
room.count = [[roomDict objectForKey:@"count"] integerValue];
|
2017-10-23 18:53:10 +03:00
|
|
|
room.hasPassword = [[roomDict objectForKey:@"hasPassword"] boolValue];
|
|
|
|
room.participantType = (NCParticipantType)[[roomDict objectForKey:@"participantType"] integerValue];
|
2021-07-06 19:03:58 +03:00
|
|
|
room.attendeeId = [[roomDict objectForKey:@"attendeeId"] integerValue];
|
|
|
|
room.attendeePin = [roomDict objectForKey:@"attendeePin"];
|
2017-07-13 18:47:40 +03:00
|
|
|
room.lastPing = [[roomDict objectForKey:@"lastPing"] integerValue];
|
2017-10-23 18:53:10 +03:00
|
|
|
room.numGuests = [[roomDict objectForKey:@"numGuests"] integerValue];
|
2018-05-18 15:41:25 +03:00
|
|
|
room.unreadMessages = [[roomDict objectForKey:@"unreadMessages"] integerValue];
|
2018-08-03 14:12:25 +03:00
|
|
|
room.unreadMention = [[roomDict objectForKey:@"unreadMention"] boolValue];
|
2021-09-24 19:14:51 +03:00
|
|
|
room.unreadMentionDirect = [[roomDict objectForKey:@"unreadMentionDirect"] boolValue];
|
2017-07-13 18:47:40 +03:00
|
|
|
room.guestList = [roomDict objectForKey:@"guestList"];
|
2018-08-01 18:54:34 +03:00
|
|
|
room.lastActivity = [[roomDict objectForKey:@"lastActivity"] integerValue];
|
2018-08-08 15:22:51 +03:00
|
|
|
room.isFavorite = [[roomDict objectForKey:@"isFavorite"] boolValue];
|
2018-10-10 15:40:04 +03:00
|
|
|
room.notificationLevel = (NCRoomNotificationLevel)[[roomDict objectForKey:@"notificationLevel"] integerValue];
|
2021-10-14 17:57:24 +03:00
|
|
|
room.notificationCalls = [[roomDict objectForKey:@"notificationCalls"] boolValue];
|
2018-12-11 13:21:50 +03:00
|
|
|
room.objectType = [roomDict objectForKey:@"objectType"];
|
|
|
|
room.objectId = [roomDict objectForKey:@"objectId"];
|
2019-03-25 19:20:10 +03:00
|
|
|
room.readOnlyState = (NCRoomReadOnlyState)[[roomDict objectForKey:@"readOnly"] integerValue];
|
2022-03-03 19:51:51 +03:00
|
|
|
room.listable = (NCRoomListableScope)[[roomDict objectForKey:@"listable"] integerValue];
|
2022-09-13 20:10:42 +03:00
|
|
|
room.messageExpiration = [[roomDict objectForKey:@"messageExpiration"] integerValue];
|
2019-07-19 18:12:37 +03:00
|
|
|
room.lobbyState = (NCRoomLobbyState)[[roomDict objectForKey:@"lobbyState"] integerValue];
|
2019-07-31 11:02:51 +03:00
|
|
|
room.lobbyTimer = [[roomDict objectForKey:@"lobbyTimer"] integerValue];
|
2021-07-06 19:03:58 +03:00
|
|
|
room.sipEnabled = [[roomDict objectForKey:@"sipEnabled"] boolValue];
|
|
|
|
room.canEnableSIP = [[roomDict objectForKey:@"canEnableSIP"] boolValue];
|
2019-08-29 22:24:21 +03:00
|
|
|
room.lastReadMessage = [[roomDict objectForKey:@"lastReadMessage"] integerValue];
|
2020-12-22 18:23:31 +03:00
|
|
|
room.lastCommonReadMessage = [[roomDict objectForKey:@"lastCommonReadMessage"] integerValue];
|
2019-09-19 23:20:27 +03:00
|
|
|
room.canStartCall = [[roomDict objectForKey:@"canStartCall"] boolValue];
|
2019-09-20 12:49:09 +03:00
|
|
|
room.hasCall = [[roomDict objectForKey:@"hasCall"] boolValue];
|
2021-05-11 17:14:12 +03:00
|
|
|
room.canLeaveConversation = [[roomDict objectForKey:@"canLeaveConversation"] boolValue];
|
|
|
|
room.canDeleteConversation = [[roomDict objectForKey:@"canDeleteConversation"] boolValue];
|
2022-01-04 13:43:21 +03:00
|
|
|
room.permissions = [[roomDict objectForKey:@"permissions"] integerValue];
|
|
|
|
room.attendeePermissions = [[roomDict objectForKey:@"attendeePermissions"] integerValue];
|
|
|
|
room.callPermissions = [[roomDict objectForKey:@"callPermissions"] integerValue];
|
|
|
|
room.defaultPermissions = [[roomDict objectForKey:@"defaultPermissions"] integerValue];
|
2017-07-13 18:47:40 +03:00
|
|
|
|
2020-11-01 17:04:47 +03:00
|
|
|
// Local-only field -> update only if there's actually a value
|
|
|
|
if ([roomDict objectForKey:@"pendingMessage"] != nil) {
|
|
|
|
room.pendingMessage = [roomDict objectForKey:@"pendingMessage"];
|
|
|
|
}
|
|
|
|
|
2018-02-16 12:48:08 +03:00
|
|
|
id name = [roomDict objectForKey:@"name"];
|
|
|
|
if ([name isKindOfClass:[NSString class]]) {
|
|
|
|
room.name = name;
|
|
|
|
} else {
|
|
|
|
room.name = [name stringValue];
|
|
|
|
}
|
|
|
|
|
|
|
|
id displayName = [roomDict objectForKey:@"displayName"];
|
|
|
|
if ([displayName isKindOfClass:[NSString class]]) {
|
|
|
|
room.displayName = displayName;
|
|
|
|
} else {
|
|
|
|
room.displayName = [displayName stringValue];
|
|
|
|
}
|
|
|
|
|
2020-09-17 14:10:18 +03:00
|
|
|
id participants = [roomDict objectForKey:@"participants"];
|
|
|
|
if ([participants isKindOfClass:[NSDictionary class]]) {
|
|
|
|
room.participants = (RLMArray<RLMString> *)[participants allKeys];
|
|
|
|
}
|
|
|
|
|
2021-12-01 22:06:06 +03:00
|
|
|
// Optional attribute
|
|
|
|
id status = [roomDict objectForKey:@"status"];
|
|
|
|
if ([status isKindOfClass:[NSString class]]) {
|
|
|
|
room.status = status;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Optional attribute
|
|
|
|
id statusIcon = [roomDict objectForKey:@"statusIcon"];
|
|
|
|
if ([statusIcon isKindOfClass:[NSString class]]) {
|
|
|
|
room.statusIcon = statusIcon;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Optional attribute
|
|
|
|
id statusMessage = [roomDict objectForKey:@"statusMessage"];
|
|
|
|
if ([statusMessage isKindOfClass:[NSString class]]) {
|
|
|
|
room.statusMessage = statusMessage;
|
|
|
|
}
|
|
|
|
|
2017-07-13 18:47:40 +03:00
|
|
|
return room;
|
2017-07-13 17:56:09 +03:00
|
|
|
}
|
|
|
|
|
2020-02-22 00:40:35 +03:00
|
|
|
+ (instancetype)roomWithDictionary:(NSDictionary *)roomDict andAccountId:(NSString *)accountId
|
|
|
|
{
|
2020-06-15 18:40:57 +03:00
|
|
|
NCRoom *room = [self roomWithDictionary:roomDict];
|
2020-02-22 00:40:35 +03:00
|
|
|
if (room) {
|
|
|
|
room.accountId = accountId;
|
|
|
|
room.internalId = [NSString stringWithFormat:@"%@@%@", room.accountId, room.token];
|
|
|
|
}
|
|
|
|
|
|
|
|
return room;
|
|
|
|
}
|
|
|
|
|
2020-03-04 18:50:29 +03:00
|
|
|
+ (void)updateRoom:(NCRoom *)managedRoom withRoom:(NCRoom *)room
|
|
|
|
{
|
|
|
|
managedRoom.name = room.name;
|
|
|
|
managedRoom.displayName = room.displayName;
|
|
|
|
managedRoom.type = room.type;
|
2021-07-08 20:04:31 +03:00
|
|
|
managedRoom.roomDescription = room.roomDescription;
|
2020-03-04 18:50:29 +03:00
|
|
|
managedRoom.count = room.count;
|
|
|
|
managedRoom.hasPassword = room.hasPassword;
|
|
|
|
managedRoom.participantType = room.participantType;
|
2021-07-06 19:03:58 +03:00
|
|
|
managedRoom.attendeeId = room.attendeeId;
|
|
|
|
managedRoom.attendeePin = room.attendeePin;
|
2020-03-04 18:50:29 +03:00
|
|
|
managedRoom.lastPing = room.lastPing;
|
|
|
|
managedRoom.numGuests = room.numGuests;
|
|
|
|
managedRoom.unreadMessages = room.unreadMessages;
|
|
|
|
managedRoom.unreadMention = room.unreadMention;
|
2021-09-24 19:14:51 +03:00
|
|
|
managedRoom.unreadMentionDirect = room.unreadMentionDirect;
|
2020-03-04 18:50:29 +03:00
|
|
|
managedRoom.guestList = room.guestList;
|
|
|
|
managedRoom.participants = room.participants;
|
|
|
|
managedRoom.lastActivity = room.lastActivity;
|
|
|
|
managedRoom.lastMessageId = room.lastMessageId;
|
|
|
|
managedRoom.isFavorite = room.isFavorite;
|
|
|
|
managedRoom.notificationLevel = room.notificationLevel;
|
2021-10-14 17:57:24 +03:00
|
|
|
managedRoom.notificationCalls = room.notificationCalls;
|
2020-03-04 18:50:29 +03:00
|
|
|
managedRoom.objectType = room.objectType;
|
|
|
|
managedRoom.objectId = room.objectId;
|
|
|
|
managedRoom.readOnlyState = room.readOnlyState;
|
2022-03-03 19:51:51 +03:00
|
|
|
managedRoom.listable = room.listable;
|
2022-09-13 20:10:42 +03:00
|
|
|
managedRoom.messageExpiration = room.messageExpiration;
|
2020-03-04 18:50:29 +03:00
|
|
|
managedRoom.lobbyState = room.lobbyState;
|
|
|
|
managedRoom.lobbyTimer = room.lobbyTimer;
|
2021-07-06 19:03:58 +03:00
|
|
|
managedRoom.sipEnabled = room.sipEnabled;
|
|
|
|
managedRoom.canEnableSIP = room.canEnableSIP;
|
2020-03-04 18:50:29 +03:00
|
|
|
managedRoom.lastReadMessage = room.lastReadMessage;
|
2020-12-22 18:23:31 +03:00
|
|
|
managedRoom.lastCommonReadMessage = room.lastCommonReadMessage;
|
2020-03-04 18:50:29 +03:00
|
|
|
managedRoom.canStartCall = room.canStartCall;
|
|
|
|
managedRoom.hasCall = room.hasCall;
|
|
|
|
managedRoom.lastUpdate = room.lastUpdate;
|
2021-05-11 17:14:12 +03:00
|
|
|
managedRoom.canLeaveConversation = room.canLeaveConversation;
|
|
|
|
managedRoom.canDeleteConversation = room.canDeleteConversation;
|
2021-11-12 14:27:17 +03:00
|
|
|
managedRoom.status = room.status;
|
|
|
|
managedRoom.statusIcon = room.statusIcon;
|
|
|
|
managedRoom.statusMessage = room.statusMessage;
|
2022-01-04 13:43:21 +03:00
|
|
|
managedRoom.permissions = room.permissions;
|
|
|
|
managedRoom.attendeePermissions = room.attendeePermissions;
|
|
|
|
managedRoom.callPermissions = room.callPermissions;
|
|
|
|
managedRoom.defaultPermissions = room.defaultPermissions;
|
2020-03-04 18:50:29 +03:00
|
|
|
}
|
|
|
|
|
2020-02-17 18:27:14 +03:00
|
|
|
+ (NSString *)primaryKey {
|
|
|
|
return @"internalId";
|
|
|
|
}
|
|
|
|
|
2017-10-23 19:22:12 +03:00
|
|
|
- (BOOL)isPublic
|
|
|
|
{
|
2020-02-11 16:44:22 +03:00
|
|
|
return self.type == kNCRoomTypePublic;
|
2017-10-23 19:22:12 +03:00
|
|
|
}
|
|
|
|
|
2022-08-02 13:45:57 +03:00
|
|
|
- (BOOL)isUserOwnerOrModerator
|
|
|
|
{
|
|
|
|
return self.participantType == kNCParticipantTypeOwner || self.participantType == kNCParticipantTypeModerator;
|
|
|
|
}
|
|
|
|
|
2017-10-23 18:53:10 +03:00
|
|
|
- (BOOL)canModerate
|
|
|
|
{
|
2022-08-02 13:45:57 +03:00
|
|
|
return [self isUserOwnerOrModerator] && ![self isLockedOneToOne];
|
2017-10-23 18:53:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isNameEditable
|
|
|
|
{
|
2020-02-11 16:44:22 +03:00
|
|
|
return [self canModerate] && self.type != kNCRoomTypeOneToOne;
|
2019-03-21 12:44:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isLockedOneToOne
|
|
|
|
{
|
2021-05-26 22:58:50 +03:00
|
|
|
return self.type == kNCRoomTypeOneToOne && [[NCDatabaseManager sharedInstance] serverHasTalkCapability:kCapabilityLockedOneToOneRooms];
|
2017-10-23 18:53:10 +03:00
|
|
|
}
|
|
|
|
|
2019-09-19 23:20:27 +03:00
|
|
|
- (BOOL)userCanStartCall
|
|
|
|
{
|
2021-05-26 22:58:50 +03:00
|
|
|
if ([[NCDatabaseManager sharedInstance] serverHasTalkCapability:kCapabilityStartCallFlag] && !self.canStartCall) {
|
2019-09-19 23:20:27 +03:00
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2021-10-05 19:05:02 +03:00
|
|
|
- (BOOL)hasUnreadMention
|
|
|
|
{
|
|
|
|
return self.unreadMention || self.unreadMentionDirect || (self.type == kNCRoomTypeOneToOne && self.unreadMessages > 0);
|
|
|
|
}
|
|
|
|
|
2019-02-27 18:04:17 +03:00
|
|
|
- (BOOL)isLeavable
|
2017-10-23 18:53:10 +03:00
|
|
|
{
|
2019-02-27 19:15:52 +03:00
|
|
|
// Allow users to leave when there are no moderators in the room
|
|
|
|
// (No need to check room type because in one2one rooms users will always be moderators)
|
|
|
|
// or when in a group call and there are other participants.
|
2021-05-11 17:14:12 +03:00
|
|
|
// We can also check "canLeaveConversation" since v2
|
|
|
|
return self.canLeaveConversation || ![self canModerate] || (self.type != kNCRoomTypeOneToOne && [self.participants count] > 1);
|
2017-10-23 18:53:10 +03:00
|
|
|
}
|
|
|
|
|
2019-02-27 20:22:57 +03:00
|
|
|
- (NSString *)deletionMessage
|
|
|
|
{
|
2020-10-13 20:33:09 +03:00
|
|
|
NSString *message = NSLocalizedString(@"Do you really want to delete this conversation?", nil);
|
2020-02-11 16:44:22 +03:00
|
|
|
if (self.type == kNCRoomTypeOneToOne) {
|
2020-10-13 20:33:09 +03:00
|
|
|
message = [NSString stringWithFormat:NSLocalizedString(@"If you delete the conversation, it will also be deleted for %@", nil), self.displayName];
|
2020-02-11 16:44:22 +03:00
|
|
|
} else if ([self.participants count] > 1) {
|
2020-10-13 20:33:09 +03:00
|
|
|
message = NSLocalizedString(@"If you delete the conversation, it will also be deleted for all other participants.", nil);
|
2019-02-27 20:22:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return message;
|
|
|
|
}
|
|
|
|
|
2018-10-10 15:40:04 +03:00
|
|
|
- (NSString *)notificationLevelString
|
|
|
|
{
|
2020-02-11 16:44:22 +03:00
|
|
|
return [self stringForNotificationLevel:self.notificationLevel];
|
2018-10-10 15:40:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *)stringForNotificationLevel:(NCRoomNotificationLevel)level
|
|
|
|
{
|
2020-10-13 20:33:09 +03:00
|
|
|
NSString *levelString = NSLocalizedString(@"Default", nil);
|
2018-10-10 15:40:04 +03:00
|
|
|
switch (level) {
|
|
|
|
case kNCRoomNotificationLevelAlways:
|
2020-10-13 20:33:09 +03:00
|
|
|
levelString = NSLocalizedString(@"All messages", nil);
|
2018-10-10 15:40:04 +03:00
|
|
|
break;
|
|
|
|
case kNCRoomNotificationLevelMention:
|
2020-10-13 20:33:09 +03:00
|
|
|
levelString = NSLocalizedString(@"@-mentions only", nil);
|
2018-10-10 15:40:04 +03:00
|
|
|
break;
|
|
|
|
case kNCRoomNotificationLevelNever:
|
2020-10-13 20:33:09 +03:00
|
|
|
levelString = NSLocalizedString(@"Off", nil);
|
2018-10-10 15:40:04 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return levelString;
|
|
|
|
}
|
|
|
|
|
2020-01-15 15:44:27 +03:00
|
|
|
- (NSString *)lastMessageString
|
2018-08-16 19:08:48 +03:00
|
|
|
{
|
2019-06-16 21:21:50 +03:00
|
|
|
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
|
2020-02-11 16:44:22 +03:00
|
|
|
BOOL ownMessage = [self.lastMessage.actorId isEqualToString:activeAccount.userId];
|
|
|
|
NSString *actorName = [[self.lastMessage.actorDisplayName componentsSeparatedByString:@" "] objectAtIndex:0];
|
2018-12-07 16:08:21 +03:00
|
|
|
// For own messages
|
2020-01-14 23:55:09 +03:00
|
|
|
if (ownMessage) {
|
2020-10-13 20:33:09 +03:00
|
|
|
actorName = NSLocalizedString(@"You", nil);
|
2018-12-07 16:08:21 +03:00
|
|
|
}
|
|
|
|
// For guests
|
2020-02-11 16:44:22 +03:00
|
|
|
if ([self.lastMessage.actorDisplayName isEqualToString:@""]) {
|
2020-10-13 20:33:09 +03:00
|
|
|
actorName = NSLocalizedString(@"Guest", nil);
|
2018-08-16 19:08:48 +03:00
|
|
|
}
|
2020-01-14 23:55:09 +03:00
|
|
|
// No actor name cases
|
2020-02-11 16:44:22 +03:00
|
|
|
if (self.lastMessage.isSystemMessage || (self.type == kNCRoomTypeOneToOne && !ownMessage) || self.type == kNCRoomTypeChangelog) {
|
2020-01-14 23:55:09 +03:00
|
|
|
actorName = @"";
|
|
|
|
}
|
|
|
|
// Use only the first name
|
|
|
|
if (![actorName isEqualToString:@""]) {
|
|
|
|
actorName = [NSString stringWithFormat:@"%@: ", [[actorName componentsSeparatedByString:@" "] objectAtIndex:0]];
|
|
|
|
}
|
2020-01-15 15:44:27 +03:00
|
|
|
// Add the last message
|
2020-02-11 16:44:22 +03:00
|
|
|
NSString *lastMessage = [NSString stringWithFormat:@"%@%@", actorName, self.lastMessage.parsedMessage.string];
|
2018-08-16 19:08:48 +03:00
|
|
|
|
|
|
|
return lastMessage;
|
|
|
|
}
|
|
|
|
|
2020-03-04 18:41:29 +03:00
|
|
|
- (NCChatMessage *)lastMessage
|
|
|
|
{
|
2020-03-04 19:52:02 +03:00
|
|
|
if (self.lastMessageId) {
|
2020-03-04 18:41:29 +03:00
|
|
|
NCChatMessage *unmanagedChatMessage = nil;
|
2020-03-04 19:52:02 +03:00
|
|
|
NCChatMessage *managedChatMessage = [NCChatMessage objectsWhere:@"internalId = %@", self.lastMessageId].firstObject;
|
2020-03-04 18:41:29 +03:00
|
|
|
if (managedChatMessage) {
|
|
|
|
unmanagedChatMessage = [[NCChatMessage alloc] initWithValue:managedChatMessage];
|
|
|
|
}
|
|
|
|
return unmanagedChatMessage;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2017-07-13 17:56:09 +03:00
|
|
|
|
|
|
|
@end
|