Setup custom URL to open conversations from another app.

Signed-off-by: Ivan Sein <ivan@nextcloud.com>
This commit is contained in:
Ivan Sein 2021-10-28 16:45:07 +02:00
Родитель ca640f2322
Коммит 7bf8c3d7a5
9 изменённых файлов: 97 добавлений и 9 удалений

Просмотреть файл

@ -144,6 +144,21 @@
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSString *scheme = urlComponents.scheme;
if ([scheme isEqualToString:@"nextcloudtalk"]) {
NSString *action = urlComponents.host;
if ([action isEqualToString:@"open-conversation"]) {
[[NCUserInterfaceController sharedInstance] presentChatForURL:urlComponents];
return YES;
}
}
return NO;
}
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (_shouldLockInterfaceOrientation) {

Просмотреть файл

@ -23,6 +23,19 @@
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>com.nextcloud.Talk</string>
<key>CFBundleURLSchemes</key>
<array>
<string>nextcloudtalk</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSApplicationQueriesSchemes</key>

Просмотреть файл

@ -34,7 +34,9 @@
#import "NCExternalSignalingController.h"
#import "NCSettingsController.h"
#import "NCUserInterfaceController.h"
#import "NCUtils.h"
#import "NewRoomTableViewController.h"
#import "NotificationCenterNotifications.h"
#import "RoomCreation2TableViewController.h"
NSString * const NCRoomsManagerDidJoinRoomNotification = @"NCRoomsManagerDidJoinRoomNotification";
@ -91,6 +93,7 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(joinOrCreateChat:) name:NCChatViewControllerReplyPrivatelyNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(joinChatOfForwardedMessage:) name:NCChatViewControllerForwardNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(joinOrCreateChat:) name:NCChatViewControllerTalkToUserNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(joinOrCreateChatWithURL:) name:NCURLWantsToOpenConversationNotification object:nil];
}
return self;
@ -761,17 +764,14 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
[self startChatWithRoomToken:pushNotification.roomToken];
}
- (void)joinOrCreateChat:(NSNotification *)notification
- (void)joinOrCreateChatWithUser:(NSString *)userId usingAccountId:(NSString *)accountId
{
NSString *actorId = [notification.userInfo objectForKey:@"actorId"];
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
NSArray *accountRooms = [[NCRoomsManager sharedInstance] roomsForAccountId:activeAccount.accountId witRealm:nil];
NSArray *accountRooms = [[NCRoomsManager sharedInstance] roomsForAccountId:accountId witRealm:nil];
for (NCRoom *room in accountRooms) {
NSArray *participantsInRoom = [room.participants valueForKey:@"self"];
if (room.type == kNCRoomTypeOneToOne && [participantsInRoom containsObject:actorId]) {
if (room.type == kNCRoomTypeOneToOne && [participantsInRoom containsObject:userId]) {
// Room already exists -> join the room
[self startChatWithRoomToken:room.token];
@ -780,18 +780,39 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
}
// Did not find a one-to-one room for this user -> create a new one
[[NCAPIController sharedInstance] createRoomForAccount:[[NCDatabaseManager sharedInstance] activeAccount] with:actorId
[[NCAPIController sharedInstance] createRoomForAccount:[[NCDatabaseManager sharedInstance] activeAccount] with:userId
ofType:kNCRoomTypeOneToOne
andName:nil
withCompletionBlock:^(NSString *token, NSError *error) {
if (!error) {
[self startChatWithRoomToken:token];
NSLog(@"Room %@ with %@ created", token, actorId);
NSLog(@"Room %@ with %@ created", token, userId);
} else {
NSLog(@"Failed creating a room with %@", actorId);
NSLog(@"Failed creating a room with %@", userId);
}
}];
}
- (void)joinOrCreateChat:(NSNotification *)notification
{
NSString *actorId = [notification.userInfo objectForKey:@"actorId"];
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
[self joinOrCreateChatWithUser:actorId usingAccountId:activeAccount.accountId];
}
- (void)joinOrCreateChatWithURL:(NSNotification *)notification
{
NSURLComponents *urlComponents = [notification.userInfo objectForKey:@"url"];
NSArray *queryItems = urlComponents.queryItems;
NSString *server = [NCUtils valueForKey:@"server" fromQueryItems:queryItems];
NSString *user = [NCUtils valueForKey:@"user" fromQueryItems:queryItems];
NSString *withUser = [NCUtils valueForKey:@"withUser" fromQueryItems:queryItems];
NSString *accountId = [[NCDatabaseManager sharedInstance] accountIdForUser:user inServer:server];
TalkAccount *account = [[NCDatabaseManager sharedInstance] talkAccountForAccountId:accountId];
[self checkForAccountChange:accountId];
[self joinOrCreateChatWithUser:withUser usingAccountId:account.accountId];
}
- (void)joinChatOfForwardedMessage:(NSNotification *)notification

Просмотреть файл

@ -44,5 +44,6 @@
- (void)presentChatViewController:(NCChatViewController *)chatViewController;
- (void)presentCallViewController:(CallViewController *)callViewController;
- (void)presentCallKitCallInRoom:(NSString *)token withVideoEnabled:(BOOL)video;
- (void)presentChatForURL:(NSURLComponents *)urlComponents;
@end

Просмотреть файл

@ -33,6 +33,7 @@
#import "NCDatabaseManager.h"
#import "NCRoomsManager.h"
#import "NCSettingsController.h"
#import "NCUtils.h"
#import "NotificationCenterNotifications.h"
@interface NCUserInterfaceController () <LoginViewControllerDelegate, AuthenticationViewControllerDelegate>
@ -42,6 +43,7 @@
NCPushNotification *_pendingPushNotification;
NSMutableDictionary *_pendingCallKitCall;
NSDictionary *_pendingLocalNotification;
NSURLComponents *_pendingURL;
BOOL _waitingForServerCapabilities;
}
@ -307,6 +309,28 @@
[[NCRoomsManager sharedInstance] joinCallWithCallToken:roomToken withVideo:video];
}
- (void)presentChatForURL:(NSURLComponents *)urlComponents
{
if ([NCConnectionController sharedInstance].appState != kAppStateReady) {
_waitingForServerCapabilities = YES;
_pendingURL = urlComponents;
return;
}
NSArray *queryItems = urlComponents.queryItems;
NSString *server = [NCUtils valueForKey:@"server" fromQueryItems:queryItems];
NSString *user = [NCUtils valueForKey:@"user" fromQueryItems:queryItems];
NSString *accountId = [[NCDatabaseManager sharedInstance] accountIdForUser:user inServer:server];
TalkAccount *account = [[NCDatabaseManager sharedInstance] talkAccountForAccountId:accountId];
if (account) {
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:urlComponents forKey:@"url"];
[[NSNotificationCenter defaultCenter] postNotificationName:NCURLWantsToOpenConversationNotification
object:self
userInfo:userInfo];
}
}
#pragma mark - Notifications
- (void)appStateHasChanged:(NSNotification *)notification
@ -322,6 +346,8 @@
}
} else if (_pendingCallKitCall) {
[self startCallKitCall:_pendingCallKitCall];
} else if (_pendingURL) {
[self presentChatForURL:_pendingURL];
}
}
}

Просмотреть файл

@ -51,6 +51,8 @@ NS_ASSUME_NONNULL_BEGIN
+ (BOOL)isValidIndexPath:(NSIndexPath *)indexPath forTableView:(UITableView *)tableView;
+ (NSString *)valueForKey:(NSString *)key fromQueryItems:(NSArray *)queryItems;
@end
NS_ASSUME_NONNULL_END

Просмотреть файл

@ -220,4 +220,12 @@ static NSString *const nextcloudScheme = @"nextcloud:";
return indexPath.section < tableView.numberOfSections && indexPath.row < [tableView numberOfRowsInSection:indexPath.section];
}
+ (NSString *)valueForKey:(NSString *)key fromQueryItems:(NSArray *)queryItems
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@", key];
NSURLQueryItem *queryItem = [[queryItems filteredArrayUsingPredicate:predicate] firstObject];
return queryItem.value;
}
@end

Просмотреть файл

@ -29,5 +29,6 @@ extern NSString * const NCOutdatedTalkVersionNotification;
extern NSString * const NCServerCapabilitiesUpdatedNotification;
extern NSString * const NCUserProfileImageUpdatedNotification;
extern NSString * const NCTokenRevokedResponseReceivedNotification;
extern NSString * const NCURLWantsToOpenConversationNotification;
NS_ASSUME_NONNULL_END

Просмотреть файл

@ -27,4 +27,5 @@ NSString * const NCOutdatedTalkVersionNotification = @"NCOutdatedTalkVersionNoti
NSString * const NCServerCapabilitiesUpdatedNotification = @"NCServerCapabilitiesUpdatedNotification";
NSString * const NCUserProfileImageUpdatedNotification = @"NCUserProfileImageUpdatedNotification";
NSString * const NCTokenRevokedResponseReceivedNotification = @"NCTokenRevokedResponseReceivedNotification";
NSString * const NCURLWantsToOpenConversationNotification = @"NCURLWantsToOpenConversationNotification";