Merge pull request #4658 from vector-im/gil/4501_show_suggested_in_room_lists

[Spaces] M10.5 Show suggested in room lists #4501
This commit is contained in:
Gil Eluard
2021-08-16 12:10:57 +02:00
committed by GitHub
14 changed files with 222 additions and 16 deletions
+1
View File
@@ -189,6 +189,7 @@
"room_recents_low_priority_section" = "LOW PRIORITY";
"room_recents_server_notice_section" = "SYSTEM ALERTS";
"room_recents_invites_section" = "INVITES";
"room_recents_suggested_rooms_section" = "SUGGESTED ROOMS";
"room_recents_start_chat_with" = "Start chat";
"room_recents_create_empty_room" = "Create room";
"room_recents_join_room" = "Join room";
+32
View File
@@ -0,0 +1,32 @@
//
// 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 Foundation
extension MXKImageView {
@objc func vc_setRoomAvatarImage(with url: String?, displayName: String, mediaManager: MXMediaManager) {
// Use the display name to prepare the default avatar image.
let avatarImage = AvatarGenerator.generateAvatar(forText: displayName)
if let avatarUrl = url {
self.enableInMemoryCache = true
self.setImageURI(avatarUrl, withType: nil, andImageOrientation: .up, toFitViewSize: self.frame.size, with: MXThumbnailingMethodCrop, previewImage: avatarImage, mediaManager: mediaManager)
} else {
self.image = avatarImage
}
self.contentMode = .scaleAspectFill
}
}
+4
View File
@@ -3402,6 +3402,10 @@ internal enum VectorL10n {
internal static var roomRecentsStartChatWith: String {
return VectorL10n.tr("Vector", "room_recents_start_chat_with")
}
/// SUGGESTED ROOMS
internal static var roomRecentsSuggestedRoomsSection: String {
return VectorL10n.tr("Vector", "room_recents_suggested_rooms_section")
}
/// Can't find this room. Make sure it exists
internal static var roomRecentsUnknownRoomErrorMessage: String {
return VectorL10n.tr("Vector", "room_recents_unknown_room_error_message")
+8
View File
@@ -97,6 +97,14 @@
*/
- (instancetype)initWithPublicRoom:(MXPublicRoom*)publicRoom andSession:(MXSession*)mxSession;
/**
Contructors.
@param childInfo MXSpaceChildInfo instance that describes the child.
@param mxSession the session to open the room preview with.
*/
- (instancetype)initWithSpaceChildInfo:(MXSpaceChildInfo*)childInfo andSession:(MXSession*)mxSession;
/**
Attempt to peek into the room to get room data (state, messages history, etc).
+16
View File
@@ -16,6 +16,7 @@
*/
#import "RoomPreviewData.h"
#import <MatrixSDK-Swift.h>
@implementation RoomPreviewData
@@ -79,6 +80,21 @@
return self;
}
- (instancetype)initWithSpaceChildInfo:(MXSpaceChildInfo*)childInfo andSession:(MXSession*)mxSession
{
self = [self init];
if (self)
{
_roomId = childInfo.childRoomId;
_roomName = childInfo.name;
_roomAvatarUrl = childInfo.avatarUrl;
_roomTopic = childInfo.topic;
_numJoinedMembers = childInfo.activeMemberCount;
_mxSession = mxSession;
}
return self;
}
- (void)dealloc
{
if (_roomDataSource)
@@ -18,6 +18,7 @@
#import "RecentCellData.h"
#import "MXRoom+Riot.h"
#import "MatrixSDK-Swift.h"
@implementation RecentCellData
// trick to hide the mother class property as it is readonly one.
@@ -57,7 +58,7 @@
- (void)update
{
[super update];
roomDisplayname = self.roomSummary.displayname;
roomDisplayname = self.spaceChildInfo ? self.spaceChildInfo.name: self.roomSummary.displayname;
if (!roomDisplayname.length)
{
roomDisplayname = [NSBundle mxk_localizedStringForKey:@"room_displayname_empty_room"];
@@ -74,6 +74,7 @@ extern NSString *const kRecentsDataSourceTapOnDirectoryServerChange;
@property (nonatomic) NSInteger conversationSection;
@property (nonatomic) NSInteger lowPrioritySection;
@property (nonatomic) NSInteger serverNoticeSection;
@property (nonatomic) NSInteger suggestedRoomsSection;
@property (nonatomic, readonly) NSArray* invitesCellDataArray;
@property (nonatomic, readonly) NSArray* favoriteCellDataArray;
@@ -81,6 +82,7 @@ extern NSString *const kRecentsDataSourceTapOnDirectoryServerChange;
@property (nonatomic, readonly) NSArray* conversationCellDataArray;
@property (nonatomic, readonly) NSArray* lowPriorityCellDataArray;
@property (nonatomic, readonly) NSArray* serverNoticeCellDataArray;
@property (nonatomic, readonly) NSArray* suggestedRoomCellDataArray;
@property (nonatomic, readonly) SecureBackupBannerDisplay secureBackupBannerDisplay;
@property (nonatomic, readonly) CrossSigningBannerDisplay crossSigningBannerDisplay;
@@ -34,6 +34,7 @@
#define RECENTSDATASOURCE_SECTION_LOWPRIORITY 0x10
#define RECENTSDATASOURCE_SECTION_SERVERNOTICE 0x20
#define RECENTSDATASOURCE_SECTION_PEOPLE 0x40
#define RECENTSDATASOURCE_SECTION_SUGGESTED 0x80
#define RECENTSDATASOURCE_DEFAULT_SECTION_HEADER_HEIGHT 30.0
@@ -60,7 +61,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
@end
@implementation RecentsDataSource
@synthesize directorySection, invitesSection, favoritesSection, peopleSection, conversationSection, lowPrioritySection, serverNoticeSection, secureBackupBannerSection, crossSigningBannerSection;
@synthesize directorySection, invitesSection, favoritesSection, peopleSection, conversationSection, lowPrioritySection, serverNoticeSection, suggestedRoomsSection, secureBackupBannerSection, crossSigningBannerSection;
@synthesize hiddenCellIndexPath, droppingCellIndexPath, droppingCellBackGroundView;
- (instancetype)init
@@ -106,6 +107,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
conversationSection = -1;
lowPrioritySection = -1;
serverNoticeSection = -1;
suggestedRoomsSection = -1;
}
#pragma mark - Properties
@@ -134,6 +136,10 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
{
return state.serverNoticeCellDataArray;
}
- (NSArray *)suggestedRoomCellDataArray
{
return state.suggestedRoomCellDataArray;
}
- (NSUInteger)missedFavouriteDiscussionsCount
{
@@ -513,6 +519,11 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
{
serverNoticeSection = sectionsCount++;
}
if (self.suggestedRoomCellDataArray.count > 0)
{
suggestedRoomsSection = sectionsCount++;
}
}
return sectionsCount;
@@ -565,6 +576,10 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
{
count = self.invitesCellDataArray.count;
}
else if (section == suggestedRoomsSection && !(shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_SUGGESTED))
{
count = self.suggestedRoomCellDataArray.count;
}
// Adjust this count according to the potential dragged cell.
if ([self isMovingCellSection:section])
@@ -646,6 +661,11 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
title = NSLocalizedStringFromTable(@"room_recents_invites_section", @"Vector", nil);
}
}
else if (section == suggestedRoomsSection)
{
count = self.suggestedRoomCellDataArray.count;
title = NSLocalizedStringFromTable(@"room_recents_suggested_rooms_section", @"Vector", nil);
}
if (count)
{
@@ -697,6 +717,10 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
{
sectionArray = self.serverNoticeCellDataArray;
}
else if (section == suggestedRoomsSection)
{
sectionArray = self.suggestedRoomCellDataArray;
}
BOOL highlight = NO;
for (id<MXKRecentCellDataStoring> cellData in sectionArray)
@@ -782,6 +806,10 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
{
sectionBitwise = RECENTSDATASOURCE_SECTION_INVITES;
}
else if (section == suggestedRoomsSection)
{
sectionBitwise = RECENTSDATASOURCE_SECTION_SUGGESTED;
}
}
if (sectionBitwise)
@@ -979,6 +1007,13 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
cellData = self.invitesCellDataArray[cellDataIndex];
}
}
else if (tableSection == suggestedRoomsSection)
{
if (cellDataIndex < self.suggestedRoomCellDataArray.count)
{
cellData = self.suggestedRoomCellDataArray[cellDataIndex];
}
}
return cellData;
}
@@ -1035,9 +1070,19 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
{
id<MXKRecentCellDataStoring> cellDataStoring = cellDataArray[index];
if ([roomId isEqualToString:cellDataStoring.roomSummary.roomId] && (matrixSession == cellDataStoring.roomSummary.room.mxSession))
if (cellDataStoring.roomSummary)
{
return index;
if ([roomId isEqualToString:cellDataStoring.roomSummary.roomId] && (matrixSession == cellDataStoring.roomSummary.room.mxSession))
{
return index;
}
}
else if (cellDataStoring.spaceChildInfo)
{
if ([roomId isEqualToString:cellDataStoring.spaceChildInfo.name])
{
return index;
}
}
}
}
@@ -1139,7 +1184,22 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
indexPath = [NSIndexPath indexPathForRow:index inSection:serverNoticeSection];
}
}
if (!indexPath && (suggestedRoomsSection >= 0))
{
index = [self cellIndexPosWithRoomId:roomId andMatrixSession:matrixSession within:self.serverNoticeCellDataArray];
if (index != NSNotFound)
{
// Check whether the low priority rooms are shrinked
if (shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_SUGGESTED)
{
return nil;
}
indexPath = [NSIndexPath indexPathForRow:index inSection:serverNoticeSection];
}
}
return indexPath;
}
@@ -1201,7 +1261,8 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
NSMutableArray<id<MXKRecentCellDataStoring>> *conversationCellDataArray = [NSMutableArray new];
NSMutableArray<id<MXKRecentCellDataStoring>> *lowPriorityCellDataArray = [NSMutableArray new];
NSMutableArray<id<MXKRecentCellDataStoring>> *serverNoticeCellDataArray = [NSMutableArray new];
NSMutableArray<id<MXKRecentCellDataStoring>> *suggestedRoomCellDataArray = [NSMutableArray new];
MissedDiscussionsCount *favouriteMissedDiscussionsCount = [MissedDiscussionsCount new];
MissedDiscussionsCount *directMissedDiscussionsCount = [MissedDiscussionsCount new];
MissedDiscussionsCount *groupMissedDiscussionsCount = [MissedDiscussionsCount new];
@@ -1237,6 +1298,15 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
{
[peopleCellDataArray addObject:recentCellDataStoring];
}
else if (recentCellDataStoring.isSuggestedRoom)
{
MXRoomSummary *roomSummary = [mxSession roomSummaryWithRoomId:recentCellDataStoring.spaceChildInfo.childRoomId];
BOOL isJoined = roomSummary.membership == MXMembershipJoin || roomSummary.membershipTransitionState == MXMembershipTransitionStateJoined;
if (!isJoined)
{
[suggestedRoomCellDataArray addObject:recentCellDataStoring];
}
}
else
{
// Hide spaces from home (keep space invites)
@@ -1275,8 +1345,17 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
}
else if (recentsDataSourceMode == RecentsDataSourceModeRooms)
{
if (recentCellDataStoring.isSuggestedRoom)
{
MXRoomSummary *roomSummary = [mxSession roomSummaryWithRoomId:recentCellDataStoring.spaceChildInfo.childRoomId];
BOOL isJoined = roomSummary.membership == MXMembershipJoin || roomSummary.membershipTransitionState == MXMembershipTransitionStateJoined;
if (!isJoined)
{
[suggestedRoomCellDataArray addObject:recentCellDataStoring];
}
}
// Consider only non direct rooms.
if (!room.isDirect)
else if (!room.isDirect)
{
// Keep only the invites, the favourites and the rooms without tag and room type different from space
if (room.summary.membership == MXMembershipInvite)
@@ -1370,6 +1449,15 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
// Sort each rooms collection by considering first the rooms with some missed notifs, the rooms with unread, then the others.
comparator = ^NSComparisonResult(id<MXKRecentCellDataStoring> recentCellData1, id<MXKRecentCellDataStoring> recentCellData2) {
if (recentCellData1.spaceChildInfo && !recentCellData2.spaceChildInfo)
{
return NSOrderedDescending;
}
if (recentCellData2.spaceChildInfo && !recentCellData1.spaceChildInfo)
{
return NSOrderedAscending;
}
if (recentCellData1.roomSummary.room.sentStatus != RoomSentStatusOk
&& recentCellData2.roomSummary.room.sentStatus == RoomSentStatusOk)
{
@@ -1439,6 +1527,15 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
// Sort each rooms collection by considering first the rooms with some unread messages then the others.
comparator = ^NSComparisonResult(id<MXKRecentCellDataStoring> recentCellData1, id<MXKRecentCellDataStoring> recentCellData2) {
if (recentCellData1.spaceChildInfo && !recentCellData2.spaceChildInfo)
{
return NSOrderedDescending;
}
if (recentCellData2.spaceChildInfo && !recentCellData1.spaceChildInfo)
{
return NSOrderedAscending;
}
if (recentCellData1.roomSummary.room.sentStatus != RoomSentStatusOk
&& recentCellData2.roomSummary.room.sentStatus == RoomSentStatusOk)
{
@@ -1511,6 +1608,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
}
MXLogDebug(@"[RecentsDataSource] refreshRoomsSections: Done in %.0fms", [[NSDate date] timeIntervalSinceDate:startDate] * 1000);
MXLogDebug(@"[Spaces] refreshRoomsSections with %ld suggested room", suggestedRoomCellDataArray.count);
return [[RecentsDataSourceState alloc]
initWithInvitesCellDataArray:invitesCellDataArray
@@ -1519,6 +1617,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
conversationCellDataArray:conversationCellDataArray
lowPriorityCellDataArray:lowPriorityCellDataArray
serverNoticeCellDataArray:serverNoticeCellDataArray
suggestedRoomCellDataArray:suggestedRoomCellDataArray
favouriteMissedDiscussionsCount:favouriteMissedDiscussionsCount
directMissedDiscussionsCount:directMissedDiscussionsCount
groupMissedDiscussionsCount:groupMissedDiscussionsCount
@@ -29,6 +29,7 @@ class RecentsDataSourceState: NSObject {
let conversationCellDataArray: [MXKRecentCellDataStoring]
let lowPriorityCellDataArray: [MXKRecentCellDataStoring]
let serverNoticeCellDataArray: [MXKRecentCellDataStoring]
let suggestedRoomCellDataArray: [MXKRecentCellDataStoring]
// MARK: Notifications counts
let favouriteMissedDiscussionsCount: MissedDiscussionsCount
@@ -47,6 +48,7 @@ class RecentsDataSourceState: NSObject {
conversationCellDataArray: [MXKRecentCellDataStoring],
lowPriorityCellDataArray: [MXKRecentCellDataStoring],
serverNoticeCellDataArray: [MXKRecentCellDataStoring],
suggestedRoomCellDataArray: [MXKRecentCellDataStoring],
favouriteMissedDiscussionsCount: MissedDiscussionsCount,
directMissedDiscussionsCount: MissedDiscussionsCount,
groupMissedDiscussionsCount: MissedDiscussionsCount,
@@ -58,6 +60,7 @@ class RecentsDataSourceState: NSObject {
self.conversationCellDataArray = conversationCellDataArray
self.lowPriorityCellDataArray = lowPriorityCellDataArray
self.serverNoticeCellDataArray = serverNoticeCellDataArray
self.suggestedRoomCellDataArray = suggestedRoomCellDataArray
self.favouriteMissedDiscussionsCount = favouriteMissedDiscussionsCount
self.directMissedDiscussionsCount = directMissedDiscussionsCount
self.groupMissedDiscussionsCount = groupMissedDiscussionsCount
@@ -2051,6 +2051,18 @@
[self dispayRoomWithRoomId:roomId inMatrixSession:matrixSession];
}
- (void)recentListViewController:(MXKRecentListViewController *)recentListViewController didSelectSuggestedRoom:(MXSpaceChildInfo *)childInfo
{
RoomPreviewData *previewData = [[RoomPreviewData alloc] initWithSpaceChildInfo:childInfo andSession:self.mainSession];
[self startActivityIndicator];
MXWeakify(self);
[previewData peekInRoom:^(BOOL succeeded) {
MXStrongifyAndReturnIfNil(self);
[self stopActivityIndicator];
[[AppDelegate theDelegate].masterTabBarController showRoomPreview:previewData];
}];
}
#pragma mark - UISearchBarDelegate
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
@@ -91,7 +91,7 @@ static const CGFloat kDirectRoomBorderWidth = 3.0;
self.lastEventDate.text = roomCellData.lastEventDate;
// Manage lastEventAttributedTextMessage optional property
if ([roomCellData respondsToSelector:@selector(lastEventAttributedTextMessage)])
if (!roomCellData.spaceChildInfo && [roomCellData respondsToSelector:@selector(lastEventAttributedTextMessage)])
{
// Force the default text color for the last message (cancel highlighted message color)
NSMutableAttributedString *lastEventDescription = [[NSMutableAttributedString alloc] initWithAttributedString:roomCellData.lastEventAttributedTextMessage];
@@ -141,7 +141,14 @@ static const CGFloat kDirectRoomBorderWidth = 3.0;
self.directRoomBorderView.hidden = !roomCellData.roomSummary.room.isDirect;
[roomCellData.roomSummary setRoomAvatarImageIn:self.roomAvatar];
if (roomCellData.spaceChildInfo)
{
[self.roomAvatar vc_setRoomAvatarImageWith:roomCellData.spaceChildInfo.avatarUrl displayName:roomCellData.spaceChildInfo.name mediaManager:roomCellData.recentsDataSource.mxSession.mediaManager];
}
else
{
[self.roomAvatar vc_setRoomAvatarImageWith:roomCellData.roomSummary.avatar displayName:roomCellData.roomSummary.displayname mediaManager:roomCellData.roomSummary.mxSession.mediaManager];
}
}
else
{
+10 -2
View File
@@ -557,7 +557,14 @@
id<MXKRecentCellDataStoring> renderedCellData = (id<MXKRecentCellDataStoring>)roomCollectionViewCell.renderedCellData;
[self.delegate recentListViewController:self didSelectRoom:renderedCellData.roomSummary.roomId inMatrixSession:renderedCellData.roomSummary.room.mxSession];
if (renderedCellData.isSuggestedRoom)
{
[self.delegate recentListViewController:self didSelectSuggestedRoom:renderedCellData.spaceChildInfo];
}
else
{
[self.delegate recentListViewController:self didSelectRoom:renderedCellData.roomSummary.roomId inMatrixSession:renderedCellData.roomSummary.room.mxSession];
}
}
// Hide the keyboard when user select a room
@@ -856,7 +863,8 @@
+ recentsDataSource.peopleCellDataArray.count
+ recentsDataSource.conversationCellDataArray.count
+ recentsDataSource.lowPriorityCellDataArray.count
+ recentsDataSource.serverNoticeCellDataArray.count;
+ recentsDataSource.serverNoticeCellDataArray.count
+ recentsDataSource.suggestedRoomCellDataArray.count;
}
@end
@@ -147,7 +147,14 @@ static const CGFloat kDirectRoomBorderWidth = 3.0;
self.directRoomBorderView.hidden = !roomCellData.roomSummary.room.isDirect;
[roomCellData.roomSummary setRoomAvatarImageIn:self.roomAvatar];
if (roomCellData.roomSummary)
{
[self.roomAvatar vc_setRoomAvatarImageWith:roomCellData.roomSummary.avatar displayName:roomCellData.roomSummary.displayname mediaManager:roomCellData.roomSummary.mxSession.mediaManager];
}
else
{
[self.roomAvatar vc_setRoomAvatarImageWith:roomCellData.spaceChildInfo.avatarUrl displayName:roomCellData.spaceChildInfo.name mediaManager:roomCellData.recentsDataSource.mxSession.mediaManager];
}
}
}
@@ -188,7 +195,7 @@ static const CGFloat kDirectRoomBorderWidth = 3.0;
{
if (roomCellData)
{
return roomCellData.roomSummary.roomId;
return roomCellData.spaceChildInfo ? roomCellData.spaceChildInfo.childRoomId : roomCellData.roomSummary.roomId;
}
return nil;
}
+9 -3
View File
@@ -103,8 +103,13 @@
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
// Hide the header to merge Invites and Rooms into a single list.
return 0.0;
if ([tableView numberOfSections] <= 1)
{
// Hide the header to merge Invites and Rooms into a single list.
return 0.0;
}
return [super tableView:tableView heightForHeaderInSection:section];
}
#pragma mark -
@@ -155,7 +160,8 @@
- (NSUInteger)totalItemCounts
{
return recentsDataSource.conversationCellDataArray.count
+ recentsDataSource.invitesCellDataArray.count;
+ recentsDataSource.invitesCellDataArray.count
+ recentsDataSource.suggestedRoomCellDataArray.count;
}
@end