diff --git a/Riot/Managers/Activities/UserActivities.h b/Riot/Managers/Activities/UserActivities.h deleted file mode 100644 index f283af7e1f..0000000000 --- a/Riot/Managers/Activities/UserActivities.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright 2021 New Vector Ltd -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#ifndef UserActivities_h -#define UserActivities_h - -#import - -/** - NSUserActivity types for rooms - */ -FOUNDATION_EXPORT NSString *const kUserActivityTypeMatrixRoom; - -/** - UserInfo field for the room id - */ -FOUNDATION_EXPORT NSString *const kUserActivityInfoRoomId; - -/** - UserInfo field for the user id - */ -FOUNDATION_EXPORT NSString *const kUserActivityInfoUserId; - -#endif /* UserActivities_h */ diff --git a/Riot/Managers/Activities/UserActivities.m b/Riot/Managers/Activities/UserActivities.m deleted file mode 100644 index 1c86f8b5d1..0000000000 --- a/Riot/Managers/Activities/UserActivities.m +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright 2021 New Vector Ltd -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import "UserActivities.h" - -NSString *const kUserActivityTypeMatrixRoom = @"org.matrix.room"; -NSString *const kUserActivityInfoRoomId = @"roomID"; -NSString *const kUserActivityInfoUserId = @"userID"; diff --git a/Riot/Managers/Activities/UserActivityService.swift b/Riot/Managers/Activities/UserActivityService.swift index f90443d77d..a3af97ca0d 100644 --- a/Riot/Managers/Activities/UserActivityService.swift +++ b/Riot/Managers/Activities/UserActivityService.swift @@ -15,14 +15,28 @@ // import Foundation +import CoreSpotlight import MatrixSDK @objcMembers class UserActivityService: NSObject { // MARK: - Constants + /// The NSUserActivity type for rooms + public static let roomActivityType = "org.matrix.room" - // TODO: Move constants in here from UserActivities.m + /// Keys to use inside the userInfo dict + public enum UserInfoKeys: String, RawRepresentable { + /// Key for a room id usually the internal id prefix with `!` + case roomId = "roomID" + + /// Key to store a user id + case userId = "userID" + } + + // objc reexport + public static let userInfoKeyRoomId = UserInfoKeys.roomId.rawValue + public static let userInfoKeyUserId = UserInfoKeys.userId.rawValue // MARK: - Properties @@ -39,12 +53,46 @@ class UserActivityService: NSObject { // MARK: - Public - func update(_ activity: NSUserActivity, from room: MXRoom) { + func update(_ userActivity: NSUserActivity, from room: MXRoom) { // TODO: Convert objc code into here. + userActivity.title = room.summary.displayname + + userActivity.requiredUserInfoKeys = [ UserInfoKeys.roomId.rawValue ] + var userInfo = [UserInfoKeys: Any]() + userInfo[UserInfoKeys.roomId] = room.roomId + if room.isDirect { + userInfo[UserInfoKeys.userId] = room.directUserId + } + userActivity.userInfo = userInfo + + // TODO: if we add more userActivities, a `org.matrix.room` prefix should probably be added + userActivity.persistentIdentifier = room.roomId + + userActivity.isEligibleForHandoff = true + userActivity.isEligibleForSearch = true + userActivity.isEligibleForPrediction = true + + var contentAttributes: CSSearchableItemAttributeSet + if #available(iOS 14.0, *) { + contentAttributes = CSSearchableItemAttributeSet(contentType: UTType.item) + } else { + contentAttributes = CSSearchableItemAttributeSet(itemContentType: "public.item") + } + + contentAttributes.title = room.summary.displayname + contentAttributes.displayName = room.summary.displayname + contentAttributes.contentDescription = room.summary.lastMessage.text + // TODO: contentAttributes.thumbnailURL + contentAttributes.domainIdentifier = room.roomId + // TODO: contentAttributes.weakRelatedUniqueIdentifier (is this needed? does it break anything else?) + contentAttributes.instantMessageAddresses = [ room.roomId ] + + userActivity.contentAttributeSet = contentAttributes } func didLeaveRoom(_ notification: Notification) { guard let roomId = notification.userInfo?[kMXSessionNotificationRoomIdKey] as? String else { return } // TODO: Remove the room from spotlight + NSUserActivity.deleteSavedUserActivities(withPersistentIdentifiers: [roomId], completionHandler: { }) } } diff --git a/Riot/Modules/Application/LegacyAppDelegate.m b/Riot/Modules/Application/LegacyAppDelegate.m index 0611923b26..2e1650162b 100644 --- a/Riot/Modules/Application/LegacyAppDelegate.m +++ b/Riot/Modules/Application/LegacyAppDelegate.m @@ -58,8 +58,6 @@ #import "Riot-Swift.h" #import "PushNotificationService.h" -#import "UserActivities.h" - //#define MX_CALL_STACK_OPENWEBRTC #ifdef MX_CALL_STACK_OPENWEBRTC #import @@ -751,9 +749,9 @@ - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserAct { continueUserActivity = [self handleUniversalLink:userActivity]; } - else if ([userActivity.activityType isEqualToString:kUserActivityTypeMatrixRoom]) + else if ([userActivity.activityType isEqualToString:[UserActivityService roomActivityType]]) { - NSString *roomID = userActivity.userInfo[kUserActivityInfoRoomId]; + NSString *roomID = userActivity.userInfo[[UserActivityService userInfoKeyRoomId]]; if (!roomID) return continueUserActivity; @@ -766,7 +764,7 @@ - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserAct INInteraction *interaction = userActivity.interaction; // roomID provided by Siri intent - NSString *roomID = userActivity.userInfo[kUserActivityInfoRoomId]; + NSString *roomID = userActivity.userInfo[[UserActivityService userInfoKeyRoomId]]; // We've launched from calls history list if (!roomID) diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 8a2eff5245..c473840e3d 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -130,8 +130,6 @@ #import "MXSDKOptions.h" -#import "UserActivities.h" - #import "Riot-Swift.h" NSNotificationName const RoomCallTileTappedNotification = @"RoomCallTileTappedNotification"; @@ -595,7 +593,7 @@ - (void)viewWillAppear:(BOOL)animated category:AnalyticsNoficationsCategory]; } - [self becomeCurrentActivity]; + [self updateUserActivity]; } - (void)viewWillDisappear:(BOOL)animated @@ -2001,51 +1999,18 @@ - (void)setupActions { roomInputView.actionsBar.actionItems = actionItems; } -- (void)becomeCurrentActivity +- (void)updateUserActivity { if (!self.userActivity) { - self.userActivity = [[NSUserActivity alloc] initWithActivityType:kUserActivityTypeMatrixRoom]; + self.userActivity = [[NSUserActivity alloc] initWithActivityType:[UserActivityService roomActivityType]]; } // TODO: Move everything else into the method called below [UserActivityService.shared update:self.userActivity from:self.roomDataSource.room]; - self.userActivity.title = self.roomDataSource.room.summary.displayname; - self.userActivity.requiredUserInfoKeys = [[NSSet alloc] initWithObjects:kUserActivityInfoRoomId, nil]; - - // user info - NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; - [userInfo setObject:self.roomDataSource.roomId forKey:kUserActivityInfoRoomId]; - if ([self.roomDataSource.room isDirect]) { - [userInfo setObject:self.roomDataSource.room.directUserId forKey:kUserActivityInfoUserId]; - } - self.userActivity.userInfo = userInfo; - // TODO: add a NSUserActivityDelegate to save the current text in the userinfo of the activity // self.userActivity.delegate = self; // self.userActivity.needsSave = true; - self.userActivity.persistentIdentifier = self.roomDataSource.roomId; - - self.userActivity.eligibleForHandoff = true; - self.userActivity.eligibleForSearch = true; - self.userActivity.eligibleForPrediction = true; - - CSSearchableItemAttributeSet *contentAttribute; - if (@available(iOS 14.0, *)) { - contentAttribute = [[CSSearchableItemAttributeSet alloc] initWithContentType:UTTypeItem]; - } else { - contentAttribute = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:@"public.item"]; - } - - contentAttribute.title = self.roomDataSource.room.summary.displayname; - contentAttribute.displayName = self.roomDataSource.room.summary.displayname; - contentAttribute.contentDescription = self.roomDataSource.room.summary.lastMessage.text; - - // TODO: contentAttribute.thumbnailURL = - // TODO: accountHandles of everyone in the room - contentAttribute.instantMessageAddresses = [[NSArray alloc] initWithObjects:self.roomDataSource.roomId, nil]; - - self.userActivity.contentAttributeSet = contentAttribute; } - (void)roomInputToolbarViewPresentStickerPicker