Merge branch 'develop' into gil/SP1_space_creation

This commit is contained in:
Gil Eluard
2022-03-01 10:15:13 +01:00
164 changed files with 3643 additions and 1650 deletions
@@ -133,10 +133,15 @@ extern NSString *const kRecentsDataSourceTapOnDirectoryServerChange;
- (void)forceRefresh;
/**
Tell whether the sections are shrinkable. NO by default.
Tell whether the sections are shrinkable. YES by default.
*/
@property (nonatomic) BOOL areSectionsShrinkable;
/**
Return true if the given section is currently shrinked.
*/
- (BOOL)isSectionShrinkedAt:(NSInteger)section;
/**
Get the sticky header view for the specified section.
@@ -78,7 +78,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
[self resetSectionIndexes];
_areSectionsShrinkable = NO;
_areSectionsShrinkable = YES;
shrinkedSectionsBitMask = 0;
roomTagsListenerByUserId = [[NSMutableDictionary alloc] init];
@@ -661,7 +661,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
title = [VectorL10n roomRecentsSuggestedRoomsSection];
}
if (count)
if (count && !(section == invitesSection))
{
NSString *roomCount = [NSString stringWithFormat:@" %tu", count];
@@ -684,12 +684,16 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
return sectionTitle;
}
- (UIView *)badgeViewForHeaderTitleInHomeSection:(NSInteger)section
- (UIView *)badgeViewForHeaderTitleInSection:(NSInteger)section
{
// Prepare a badge to display the total of missed notifications in this section.
id<MXRoomListDataCounts> counts = nil;
UIView *missedNotifAndUnreadBadgeBgView = nil;
if (section == invitesSection)
{
counts = self.recentsListService.invitedRoomListData.counts;
}
if (section == favoritesSection)
{
counts = self.recentsListService.favoritedRoomListData.counts;
@@ -715,8 +719,9 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
counts = self.recentsListService.suggestedRoomListData.counts;
}
NSUInteger numberOfNotifications = counts.total.numberOfNotifications;
NSUInteger numberOfHighlights = counts.total.numberOfHighlights;
// Invites are counted as highlights for the badge view display.
NSUInteger numberOfNotifications = counts.total.numberOfNotifications + counts.total.numberOfInvitedRooms;
NSUInteger numberOfHighlights = counts.total.numberOfHighlights + counts.total.numberOfInvitedRooms;
if (numberOfNotifications)
{
@@ -833,14 +838,16 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
chevronView.contentMode = UIViewContentModeCenter;
sectionHeader.accessoryView = chevronView;
}
else if (_recentsDataSourceMode == RecentsDataSourceModeHome)
if (_recentsDataSourceMode == RecentsDataSourceModeHome
|| _recentsDataSourceMode == RecentsDataSourceModePeople
|| _recentsDataSourceMode == RecentsDataSourceModeRooms)
{
// Add a badge to display the total of missed notifications by section.
UIView *badgeView = [self badgeViewForHeaderTitleInHomeSection:section];
UIView *badgeView = [self badgeViewForHeaderTitleInSection:section];
if (badgeView)
{
sectionHeader.accessoryView = badgeView;
sectionHeader.rightAccessoryView = badgeView;
}
}
@@ -1510,4 +1517,55 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
[self.delegate dataSource:self didCellChange:update];
}
#pragma mark - Shrinkable
- (BOOL)isSectionShrinkedAt:(NSInteger)section
{
if (_areSectionsShrinkable == NO)
{
return NO;
}
if (section == favoritesSection && (shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_FAVORITES))
{
return YES;
}
if (section == peopleSection && (shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_PEOPLE))
{
return YES;
}
if (section == conversationSection && (shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_CONVERSATIONS))
{
return YES;
}
if (section == directorySection && (shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_DIRECTORY))
{
return YES;
}
if (section == lowPrioritySection && (shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_LOWPRIORITY))
{
return YES;
}
if (section == serverNoticeSection && (shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_SERVERNOTICE))
{
return YES;
}
if (section == invitesSection && (shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_INVITES))
{
return YES;
}
if (section == suggestedRoomsSection && (shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_SUGGESTED))
{
return YES;
}
return NO;
}
@end
@@ -51,10 +51,10 @@ public class DiscussionsCount: NSObject {
super.init()
}
public init(withRoomListDataCounts counts: MXRoomListDataCounts) {
self.numberOfNotified = counts.numberOfNotifiedRooms
self.numberOfHighlighted = counts.numberOfHighlightedRooms + counts.numberOfInvitedRooms
self.numberOfUnsent = counts.numberOfUnsentRooms
public init(withRoomListDataCounts counts: [MXRoomListDataCounts]) {
self.numberOfNotified = counts.reduce(0, { $0 + $1.numberOfNotifiedRooms })
self.numberOfHighlighted = counts.reduce(0, { $0 + $1.numberOfHighlightedRooms + $1.numberOfInvitedRooms })
self.numberOfUnsent = counts.reduce(0, { $0 + $1.numberOfUnsentRooms })
super.init()
}
}
@@ -19,7 +19,7 @@
@class RootTabEmptyView;
@class AnalyticsScreenTimer;
@class AppActivityIndicatorPresenter;
@class AppUserIndicatorPresenter;
/**
Notification to be posted when recents data is ready. Notification object will be the RecentsViewController instance.
@@ -98,9 +98,9 @@ FOUNDATION_EXPORT NSString *const RecentsViewControllerDataReadyNotification;
@property (nonatomic) AnalyticsScreenTimer *screenTimer;
/**
Presenter for displaying app-wide activity / loading indicators. If not set, the view controller will use legacy activity indicators
Presenter for displaying app-wide user indicators. If not set, the view controller will use legacy activity indicators
*/
@property (nonatomic, strong) AppActivityIndicatorPresenter *activityPresenter;
@property (nonatomic, strong) AppUserIndicatorPresenter *userIndicatorPresenter;
/**
Return the sticky header for the specified section of the table view
@@ -314,6 +314,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
[[NSNotificationCenter defaultCenter] removeObserver:kMXNotificationCenterDidUpdateRulesObserver];
kMXNotificationCenterDidUpdateRulesObserver = nil;
}
[self stopActivityIndicator];
}
- (void)viewDidAppear:(BOOL)animated
@@ -1040,6 +1042,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
SectionHeaderView *updatedSectionHeaderView = (SectionHeaderView *)updatedHeaderView;
sectionHeaderView.headerLabel = updatedSectionHeaderView.headerLabel;
sectionHeaderView.accessoryView = updatedSectionHeaderView.accessoryView;
sectionHeaderView.rightAccessoryView = updatedSectionHeaderView.rightAccessoryView;
}
}
}
@@ -1280,8 +1283,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
MXRoom *room = [self.mainSession roomWithRoomId:currentRoomId];
if (room)
{
[self startActivityIndicator];
[self startActivityIndicatorWithLabel:[VectorL10n roomParticipantsLeaveProcessing]];
// cancel pending uploads/downloads
// they are useless by now
[MXMediaManager cancelDownloadsInCacheFolder:room.roomId];
@@ -1296,6 +1298,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
{
typeof(self) self = weakSelf;
[self stopActivityIndicator];
[self.userIndicatorPresenter presentSuccessWithLabel:[VectorL10n roomParticipantsLeaveSuccess]];
// Force table refresh
[self cancelEditionMode:YES];
}
@@ -2421,20 +2424,28 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
#pragma mark - Activity Indicator
- (BOOL)providesCustomActivityIndicator {
return self.activityPresenter != nil;
return self.userIndicatorPresenter != nil;
}
- (void)startActivityIndicatorWithLabel:(NSString *)label {
if (self.userIndicatorPresenter) {
[self.userIndicatorPresenter presentActivityIndicatorWithLabel:label];
} else {
[super startActivityIndicator];
}
}
- (void)startActivityIndicator {
if (self.activityPresenter) {
[self.activityPresenter presentActivityIndicator];
if (self.userIndicatorPresenter) {
[self.userIndicatorPresenter presentActivityIndicator];
} else {
[super startActivityIndicator];
}
}
- (void)stopActivityIndicator {
if (self.activityPresenter) {
[self.activityPresenter removeCurrentActivityIndicatorWithAnimated:YES completion:nil];
if (self.userIndicatorPresenter) {
[self.userIndicatorPresenter removeCurrentActivityIndicatorWithAnimated:YES completion:nil];
} else {
[super stopActivityIndicator];
}
@@ -32,7 +32,18 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
// MARK: - Fetchers
private var invitedRoomListDataFetcher: MXRoomListDataFetcher?
private var invitedRoomListDataFetcher: MXRoomListDataFetcher? {
switch mode {
case .home:
return invitedRoomListDataFetcherForHome
case .people:
return invitedRoomListDataFetcherForPeople
case .rooms:
return invitedRoomListDataFetcherForRooms
default:
return nil
}
}
private var favoritedRoomListDataFetcher: MXRoomListDataFetcher?
private var directRoomListDataFetcher: MXRoomListDataFetcher? {
switch mode {
@@ -62,19 +73,24 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
private var conversationRoomListDataFetcherForRooms: MXRoomListDataFetcher?
private var directRoomListDataFetcherForHome: MXRoomListDataFetcher?
private var directRoomListDataFetcherForPeople: MXRoomListDataFetcher?
private var invitedRoomListDataFetcherForHome: MXRoomListDataFetcher?
private var invitedRoomListDataFetcherForPeople: MXRoomListDataFetcher?
private var invitedRoomListDataFetcherForRooms: MXRoomListDataFetcher?
// MARK: - Private
private var fetcherTypesForMode: [RecentsDataSourceMode: FetcherTypes] = [
.home: [.invited, .favorited, .directHome, .conversationHome, .lowPriority, .serverNotice, .suggested],
.favourites: [.favorited],
.people: [.directPeople],
.rooms: [.conversationRooms, .suggested]
.people: [.invited, .directPeople],
.rooms: [.invited, .conversationRooms, .suggested]
]
private var allFetchers: [MXRoomListDataFetcher] {
return [
invitedRoomListDataFetcher,
invitedRoomListDataFetcherForHome,
invitedRoomListDataFetcherForPeople,
invitedRoomListDataFetcherForRooms,
favoritedRoomListDataFetcher,
directRoomListDataFetcherForHome,
directRoomListDataFetcherForPeople,
@@ -120,7 +136,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
}
return result
}
private var hideInvitedSection: Bool {
return MXSDKOptions.sharedInstance().autoAcceptRoomInvites
}
@@ -204,20 +220,20 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
guard let totalCounts = favoritedRoomListDataFetcher?.data?.counts.total else {
return .zero
}
return DiscussionsCount(withRoomListDataCounts: totalCounts)
return DiscussionsCount(withRoomListDataCounts: [totalCounts])
}
public var peopleMissedDiscussionsCount: DiscussionsCount {
guard let totalCounts = directRoomListDataFetcherForPeople?.data?.counts.total else {
return .zero
}
let invitesCount = invitedRoomListDataFetcherForPeople?.data?.counts.total
let directCount = directRoomListDataFetcherForPeople?.data?.counts.total
let totalCounts = [invitesCount, directCount].compactMap { $0 }
return DiscussionsCount(withRoomListDataCounts: totalCounts)
}
public var conversationMissedDiscussionsCount: DiscussionsCount {
guard let totalCounts = conversationRoomListDataFetcherForRooms?.data?.counts.total else {
return .zero
}
let invitesCount = invitedRoomListDataFetcherForRooms?.data?.counts.total
let conversationCount = conversationRoomListDataFetcherForRooms?.data?.counts.total
let totalCounts = [invitesCount, conversationCount].compactMap { $0 }
return DiscussionsCount(withRoomListDataCounts: totalCounts)
}
@@ -269,7 +285,9 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
removeAllDelegates()
allFetchers.forEach({ $0.stop() })
invitedRoomListDataFetcher = nil
invitedRoomListDataFetcherForHome = nil
invitedRoomListDataFetcherForPeople = nil
invitedRoomListDataFetcherForRooms = nil
favoritedRoomListDataFetcher = nil
directRoomListDataFetcherForHome = nil
directRoomListDataFetcherForPeople = nil
@@ -435,7 +453,8 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
private func createCommonRoomListDataFetcher(withDataTypes dataTypes: MXRoomSummaryDataTypes = [],
onlySuggested: Bool = false,
paginate: Bool = true) -> MXRoomListDataFetcher {
paginate: Bool = true,
strictMatches: Bool = false) -> MXRoomListDataFetcher {
guard let session = session else {
fatalError("Session deallocated")
}
@@ -443,7 +462,8 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
onlySuggested: onlySuggested,
query: query,
space: space,
showAllRoomsInHomeSpace: showAllRoomsInHomeSpace)
showAllRoomsInHomeSpace: showAllRoomsInHomeSpace,
strictMatches: strictMatches)
let fetchOptions = MXRoomListDataFetchOptions(filterOptions: filterOptions,
sortOptions: sortOptions,
@@ -455,6 +475,22 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
}
return fetcher
}
private func createInvitedRoomListDataFetcherForPeople() -> MXRoomListDataFetcher {
let fetcher = createCommonRoomListDataFetcher(withDataTypes: [.invited, .direct], paginate: false, strictMatches: true)
updateInvitedFetcher(fetcher, for: .people)
fetcher.addDelegate(self)
fetcher.paginate()
return fetcher
}
private func createInvitedRoomListDataFetcherForRooms() -> MXRoomListDataFetcher {
let fetcher = createCommonRoomListDataFetcher(withDataTypes: [.invited], paginate: false)
updateInvitedFetcher(fetcher, for: .rooms)
fetcher.addDelegate(self)
fetcher.paginate()
return fetcher
}
private func createDirectRoomListDataFetcherForHome() -> MXRoomListDataFetcher {
let fetcher = createCommonRoomListDataFetcher(withDataTypes: [.direct], paginate: false)
@@ -500,7 +536,9 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
return
}
if !hideInvitedSection {
invitedRoomListDataFetcher = createCommonRoomListDataFetcher(withDataTypes: [.invited])
invitedRoomListDataFetcherForHome = createCommonRoomListDataFetcher(withDataTypes: [.invited])
invitedRoomListDataFetcherForPeople = createInvitedRoomListDataFetcherForPeople()
invitedRoomListDataFetcherForRooms = createInvitedRoomListDataFetcherForRooms()
}
favoritedRoomListDataFetcher = createCommonRoomListDataFetcher(withDataTypes: [.favorited])
directRoomListDataFetcherForHome = createDirectRoomListDataFetcherForHome()
@@ -516,18 +554,30 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
}
private func updateDirectFetcher(_ fetcher: MXRoomListDataFetcher, for mode: RecentsDataSourceMode) {
var notDataTypes: MXRoomSummaryDataTypes = [.hidden, .conferenceUser, .space]
var notDataTypes: MXRoomSummaryDataTypes = [.hidden, .conferenceUser, .space, .invited, .lowPriority]
switch mode {
case .home:
notDataTypes.insert([.invited, .favorited, .lowPriority])
notDataTypes.insert(.favorited)
fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes
case .people:
notDataTypes.insert([.lowPriority])
fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes
default:
break
}
}
private func updateInvitedFetcher(_ fetcher: MXRoomListDataFetcher, for mode: RecentsDataSourceMode) {
var notDataTypes: MXRoomSummaryDataTypes = [.hidden, .conferenceUser, .lowPriority, .serverNotice, .space]
switch mode {
case .people:
fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes
case .rooms:
notDataTypes.insert([.direct])
fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes
default:
break
}
}
private func updateFavoritedFetcher(_ fetcher: MXRoomListDataFetcher, for mode: RecentsDataSourceMode) {
switch mode {
@@ -543,15 +593,12 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
}
private func updateConversationFetcher(_ fetcher: MXRoomListDataFetcher, for mode: RecentsDataSourceMode) {
var notDataTypes: MXRoomSummaryDataTypes = [.hidden, .conferenceUser, .direct, .lowPriority, .serverNotice, .space]
var notDataTypes: MXRoomSummaryDataTypes = [.hidden, .conferenceUser, .direct, .invited, .lowPriority, .serverNotice, .space]
switch mode {
case .home:
notDataTypes.insert([.invited, .favorited])
notDataTypes.insert(.favorited)
fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes
case .rooms:
if hideInvitedSection {
notDataTypes.insert(.invited)
}
fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes
default:
break
@@ -603,7 +650,7 @@ private struct FetcherTypes: OptionSet {
static let lowPriority = FetcherTypes(rawValue: 1 << 6)
static let serverNotice = FetcherTypes(rawValue: 1 << 7)
static let suggested = FetcherTypes(rawValue: 1 << 8)
static let none: FetcherTypes = []
static let all: FetcherTypes = [
.invited, .favorited, .directHome, .directPeople, .conversationHome, .conversationRooms, .lowPriority, .serverNotice, .suggested]