talk-ios/NextcloudTalk/NCRoom.m

344 строки
13 KiB
Objective-C

/**
* @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/>.
*
*/
#import "NCRoom.h"
#import "NCDatabaseManager.h"
NSString * const NCRoomObjectTypeFile = @"file";
NSString * const NCRoomObjectTypeSharePassword = @"share:password";
@implementation NCRoom
+ (instancetype)roomWithDictionary:(NSDictionary *)roomDict
{
if (!roomDict) {
return nil;
}
NCRoom *room = [[self alloc] init];
room.roomId = [[roomDict objectForKey:@"id"] integerValue];
room.token = [roomDict objectForKey:@"token"];
room.type = (NCRoomType)[[roomDict objectForKey:@"type"] integerValue];
room.roomDescription = [roomDict objectForKey:@"description"];
room.count = [[roomDict objectForKey:@"count"] integerValue];
room.hasPassword = [[roomDict objectForKey:@"hasPassword"] boolValue];
room.participantType = (NCParticipantType)[[roomDict objectForKey:@"participantType"] integerValue];
room.attendeeId = [[roomDict objectForKey:@"attendeeId"] integerValue];
room.attendeePin = [roomDict objectForKey:@"attendeePin"];
room.lastPing = [[roomDict objectForKey:@"lastPing"] integerValue];
room.numGuests = [[roomDict objectForKey:@"numGuests"] integerValue];
room.unreadMessages = [[roomDict objectForKey:@"unreadMessages"] integerValue];
room.unreadMention = [[roomDict objectForKey:@"unreadMention"] boolValue];
room.unreadMentionDirect = [[roomDict objectForKey:@"unreadMentionDirect"] boolValue];
room.guestList = [roomDict objectForKey:@"guestList"];
room.lastActivity = [[roomDict objectForKey:@"lastActivity"] integerValue];
room.isFavorite = [[roomDict objectForKey:@"isFavorite"] boolValue];
room.notificationLevel = (NCRoomNotificationLevel)[[roomDict objectForKey:@"notificationLevel"] integerValue];
room.notificationCalls = [[roomDict objectForKey:@"notificationCalls"] boolValue];
room.objectType = [roomDict objectForKey:@"objectType"];
room.objectId = [roomDict objectForKey:@"objectId"];
room.readOnlyState = (NCRoomReadOnlyState)[[roomDict objectForKey:@"readOnly"] integerValue];
room.listable = (NCRoomListableScope)[[roomDict objectForKey:@"listable"] integerValue];
room.messageExpiration = [[roomDict objectForKey:@"messageExpiration"] integerValue];
room.lobbyState = (NCRoomLobbyState)[[roomDict objectForKey:@"lobbyState"] integerValue];
room.lobbyTimer = [[roomDict objectForKey:@"lobbyTimer"] integerValue];
room.sipState = (NCRoomSIPState)[[roomDict objectForKey:@"sipEnabled"] integerValue];
room.canEnableSIP = [[roomDict objectForKey:@"canEnableSIP"] boolValue];
room.lastReadMessage = [[roomDict objectForKey:@"lastReadMessage"] integerValue];
room.lastCommonReadMessage = [[roomDict objectForKey:@"lastCommonReadMessage"] integerValue];
room.canStartCall = [[roomDict objectForKey:@"canStartCall"] boolValue];
room.hasCall = [[roomDict objectForKey:@"hasCall"] boolValue];
room.canLeaveConversation = [[roomDict objectForKey:@"canLeaveConversation"] boolValue];
room.canDeleteConversation = [[roomDict objectForKey:@"canDeleteConversation"] boolValue];
room.participantFlags = [[roomDict objectForKey:@"participantFlags"] integerValue];
room.permissions = [[roomDict objectForKey:@"permissions"] integerValue];
room.attendeePermissions = [[roomDict objectForKey:@"attendeePermissions"] integerValue];
room.callPermissions = [[roomDict objectForKey:@"callPermissions"] integerValue];
room.defaultPermissions = [[roomDict objectForKey:@"defaultPermissions"] integerValue];
// Local-only field -> update only if there's actually a value
if ([roomDict objectForKey:@"pendingMessage"] != nil) {
room.pendingMessage = [roomDict objectForKey:@"pendingMessage"];
}
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];
}
id participants = [roomDict objectForKey:@"participants"];
if ([participants isKindOfClass:[NSDictionary class]]) {
room.participants = (RLMArray<RLMString> *)[participants allKeys];
}
// 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;
}
return room;
}
+ (instancetype)roomWithDictionary:(NSDictionary *)roomDict andAccountId:(NSString *)accountId
{
NCRoom *room = [self roomWithDictionary:roomDict];
if (room) {
room.accountId = accountId;
room.internalId = [NSString stringWithFormat:@"%@@%@", room.accountId, room.token];
}
return room;
}
+ (void)updateRoom:(NCRoom *)managedRoom withRoom:(NCRoom *)room
{
managedRoom.name = room.name;
managedRoom.displayName = room.displayName;
managedRoom.type = room.type;
managedRoom.roomDescription = room.roomDescription;
managedRoom.count = room.count;
managedRoom.hasPassword = room.hasPassword;
managedRoom.participantType = room.participantType;
managedRoom.attendeeId = room.attendeeId;
managedRoom.attendeePin = room.attendeePin;
managedRoom.lastPing = room.lastPing;
managedRoom.numGuests = room.numGuests;
managedRoom.unreadMessages = room.unreadMessages;
managedRoom.unreadMention = room.unreadMention;
managedRoom.unreadMentionDirect = room.unreadMentionDirect;
managedRoom.guestList = room.guestList;
managedRoom.participants = room.participants;
managedRoom.lastActivity = room.lastActivity;
managedRoom.lastMessageId = room.lastMessageId;
managedRoom.isFavorite = room.isFavorite;
managedRoom.notificationLevel = room.notificationLevel;
managedRoom.notificationCalls = room.notificationCalls;
managedRoom.objectType = room.objectType;
managedRoom.objectId = room.objectId;
managedRoom.readOnlyState = room.readOnlyState;
managedRoom.listable = room.listable;
managedRoom.messageExpiration = room.messageExpiration;
managedRoom.lobbyState = room.lobbyState;
managedRoom.lobbyTimer = room.lobbyTimer;
managedRoom.sipState = room.sipState;
managedRoom.canEnableSIP = room.canEnableSIP;
managedRoom.lastReadMessage = room.lastReadMessage;
managedRoom.lastCommonReadMessage = room.lastCommonReadMessage;
managedRoom.canStartCall = room.canStartCall;
managedRoom.hasCall = room.hasCall;
managedRoom.lastUpdate = room.lastUpdate;
managedRoom.canLeaveConversation = room.canLeaveConversation;
managedRoom.canDeleteConversation = room.canDeleteConversation;
managedRoom.status = room.status;
managedRoom.statusIcon = room.statusIcon;
managedRoom.statusMessage = room.statusMessage;
managedRoom.participantFlags = room.participantFlags;
managedRoom.permissions = room.permissions;
managedRoom.attendeePermissions = room.attendeePermissions;
managedRoom.callPermissions = room.callPermissions;
managedRoom.defaultPermissions = room.defaultPermissions;
}
+ (NSString *)primaryKey {
return @"internalId";
}
- (BOOL)isPublic
{
return self.type == kNCRoomTypePublic;
}
- (BOOL)isUserOwnerOrModerator
{
return self.participantType == kNCParticipantTypeOwner || self.participantType == kNCParticipantTypeModerator;
}
- (BOOL)canModerate
{
return [self isUserOwnerOrModerator] && ![self isLockedOneToOne];
}
- (BOOL)isNameEditable
{
return [self canModerate] && self.type != kNCRoomTypeOneToOne;
}
- (BOOL)isLockedOneToOne
{
return self.type == kNCRoomTypeOneToOne && [[NCDatabaseManager sharedInstance] serverHasTalkCapability:kCapabilityLockedOneToOneRooms];
}
- (BOOL)userCanStartCall
{
if ([[NCDatabaseManager sharedInstance] serverHasTalkCapability:kCapabilityStartCallFlag] && !self.canStartCall) {
return NO;
}
return YES;
}
- (BOOL)hasUnreadMention
{
return self.unreadMention || self.unreadMentionDirect || (self.type == kNCRoomTypeOneToOne && self.unreadMessages > 0);
}
- (BOOL)isLeavable
{
// 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.
// We can also check "canLeaveConversation" since v2
return self.canLeaveConversation || ![self canModerate] || (self.type != kNCRoomTypeOneToOne && [self.participants count] > 1);
}
- (NSString *)deletionMessage
{
NSString *message = NSLocalizedString(@"Do you really want to delete this conversation?", nil);
if (self.type == kNCRoomTypeOneToOne) {
message = [NSString stringWithFormat:NSLocalizedString(@"If you delete the conversation, it will also be deleted for %@", nil), self.displayName];
} else if ([self.participants count] > 1) {
message = NSLocalizedString(@"If you delete the conversation, it will also be deleted for all other participants.", nil);
}
return message;
}
- (NSString *)notificationLevelString
{
return [self stringForNotificationLevel:self.notificationLevel];
}
- (NSString *)stringForNotificationLevel:(NCRoomNotificationLevel)level
{
NSString *levelString = NSLocalizedString(@"Default", nil);
switch (level) {
case kNCRoomNotificationLevelAlways:
levelString = NSLocalizedString(@"All messages", nil);
break;
case kNCRoomNotificationLevelMention:
levelString = NSLocalizedString(@"@-mentions only", nil);
break;
case kNCRoomNotificationLevelNever:
levelString = NSLocalizedString(@"Off", nil);
break;
default:
break;
}
return levelString;
}
- (NSString *)messageExpirationString
{
return [self stringForMessageExpiration:self.messageExpiration];
}
- (NSString *)stringForMessageExpiration:(NSInteger)messageExpiration
{
NSString *levelString = NSLocalizedString(@"Off", nil);
switch (messageExpiration) {
case NCMessageExpiration4Weeks:
levelString = NSLocalizedString(@"4 weeks", nil);
break;
case NCMessageExpiration1Week:
levelString = NSLocalizedString(@"1 week", nil);
break;
case NCMessageExpiration1Day:
levelString = NSLocalizedString(@"1 day", nil);
break;
case NCMessageExpiration8Hours:
levelString = NSLocalizedString(@"8 hours", nil);
break;
case NCMessageExpiration1Hour:
levelString = NSLocalizedString(@"1 hour", nil);
break;
default:
break;
}
return levelString;
}
- (NSString *)lastMessageString
{
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
BOOL ownMessage = [self.lastMessage.actorId isEqualToString:activeAccount.userId];
NSString *actorName = [[self.lastMessage.actorDisplayName componentsSeparatedByString:@" "] objectAtIndex:0];
// For own messages
if (ownMessage) {
actorName = NSLocalizedString(@"You", nil);
}
// For guests
if ([self.lastMessage.actorDisplayName isEqualToString:@""]) {
actorName = NSLocalizedString(@"Guest", nil);
}
// No actor name cases
if (self.lastMessage.isSystemMessage || (self.type == kNCRoomTypeOneToOne && !ownMessage) || self.type == kNCRoomTypeChangelog) {
actorName = @"";
}
// Use only the first name
if (![actorName isEqualToString:@""]) {
actorName = [NSString stringWithFormat:@"%@: ", [[actorName componentsSeparatedByString:@" "] objectAtIndex:0]];
}
// Add the last message
NSString *lastMessage = [NSString stringWithFormat:@"%@%@", actorName, self.lastMessage.parsedMessage.string];
return lastMessage;
}
- (NCChatMessage *)lastMessage
{
if (self.lastMessageId) {
NCChatMessage *unmanagedChatMessage = nil;
NCChatMessage *managedChatMessage = [NCChatMessage objectsWhere:@"internalId = %@", self.lastMessageId].firstObject;
if (managedChatMessage) {
unmanagedChatMessage = [[NCChatMessage alloc] initWithValue:managedChatMessage];
}
return unmanagedChatMessage;
}
return nil;
}
@end