From bcb4a9a28c50b7f254bbb12f66a747e916fc83be Mon Sep 17 00:00:00 2001 From: Simon Wiedmer Date: Thu, 25 Nov 2021 18:14:36 +0100 Subject: [PATCH 1/3] Implement call list --- Config/BuildSettings.swift | 1 + Riot/Assets/Base.lproj/Main.storyboard | 32 +++- .../Common/start_call.imageset/Contents.json | 23 +++ .../Common/start_call.imageset/start_call.png | Bin 0 -> 1582 bytes .../start_call.imageset/start_call@2x.png | Bin 0 -> 5061 bytes .../start_call.imageset/start_call@3x.png | Bin 0 -> 6958 bytes .../TabBar/tab_calls.imageset/Contents.json | 26 +++ .../TabBar/tab_calls.imageset/tab_calls.png | Bin 0 -> 519 bytes .../tab_calls.imageset/tab_calls@2x.png | Bin 0 -> 1247 bytes .../tab_calls.imageset/tab_calls@3x.png | Bin 0 -> 1848 bytes Riot/Assets/de.lproj/Vector.strings | 4 + Riot/Assets/en.lproj/Vector.strings | 6 + Riot/Generated/Images.swift | 2 + Riot/Generated/Strings.swift | 16 ++ Riot/Managers/Settings/RiotSettings.swift | 3 + Riot/Modules/Calls/CallsViewController.h | 37 ++++ Riot/Modules/Calls/CallsViewController.m | 171 ++++++++++++++++++ .../Recents/DataSources/RecentsDataSource.h | 9 +- .../Recents/DataSources/RecentsDataSource.m | 98 +++++++++- .../Common/Recents/RecentsViewController.h | 5 + .../MatrixSDK/RecentsListService.swift | 48 ++++- .../Service/Mock/MockRecentsListService.swift | 23 ++- .../Service/Mock/MockRoomSummary.swift | 2 + .../Service/RecentsListServiceProtocol.swift | 8 +- Riot/Modules/Home/HomeViewController.m | 10 +- Riot/Modules/TabBar/MasterTabBarController.h | 8 +- Riot/Modules/TabBar/MasterTabBarController.m | 28 ++- Riot/Modules/TabBar/TabBarCoordinator.swift | 12 ++ 28 files changed, 544 insertions(+), 28 deletions(-) create mode 100644 Riot/Assets/Images.xcassets/Common/start_call.imageset/Contents.json create mode 100644 Riot/Assets/Images.xcassets/Common/start_call.imageset/start_call.png create mode 100644 Riot/Assets/Images.xcassets/Common/start_call.imageset/start_call@2x.png create mode 100644 Riot/Assets/Images.xcassets/Common/start_call.imageset/start_call@3x.png create mode 100644 Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/Contents.json create mode 100644 Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/tab_calls.png create mode 100644 Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/tab_calls@2x.png create mode 100644 Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/tab_calls@3x.png create mode 100644 Riot/Modules/Calls/CallsViewController.h create mode 100644 Riot/Modules/Calls/CallsViewController.m diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index ccdafb43ff..c3b07d57ef 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -242,6 +242,7 @@ final class BuildSettings: NSObject { static let homeScreenShowFavouritesTab: Bool = true static let homeScreenShowPeopleTab: Bool = true static let homeScreenShowRoomsTab: Bool = true + static let homeScreenShowCallsTab: Bool = true static let homeScreenShowCommunitiesTab: Bool = true // MARK: - General Settings Screen diff --git a/Riot/Assets/Base.lproj/Main.storyboard b/Riot/Assets/Base.lproj/Main.storyboard index 0fc069dcce..aebb4917ee 100644 --- a/Riot/Assets/Base.lproj/Main.storyboard +++ b/Riot/Assets/Base.lproj/Main.storyboard @@ -2,8 +2,8 @@ - + @@ -172,7 +172,7 @@ - + @@ -197,6 +197,25 @@ + + + + + + + + + + + + + + + + + + + @@ -281,6 +300,7 @@ + @@ -545,13 +565,14 @@ - + - + + @@ -560,5 +581,8 @@ + + + diff --git a/Riot/Assets/Images.xcassets/Common/start_call.imageset/Contents.json b/Riot/Assets/Images.xcassets/Common/start_call.imageset/Contents.json new file mode 100644 index 0000000000..cf4d858ce9 --- /dev/null +++ b/Riot/Assets/Images.xcassets/Common/start_call.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "start_call.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "start_call@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "start_call@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Riot/Assets/Images.xcassets/Common/start_call.imageset/start_call.png b/Riot/Assets/Images.xcassets/Common/start_call.imageset/start_call.png new file mode 100644 index 0000000000000000000000000000000000000000..a8540b165d21663dc4b1904b582d405c780ff00c GIT binary patch literal 1582 zcmV+}2GRM6P)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91JfH&r1ONa40RR91JOBUy0E^%0TmS$Cm`OxIRA>d=T3u`uRTMsVc5%yA zXltlZ=o*)@vPBb0P#-j!K49a6nyA@CeK0-{(TF6FRMS?QrAdJ_kq}}c7#@rd7VBT+ z1ymkTqluIRO)M;_MH`lyXrm>CUCO#U&Y9giz4JeFXZB~9m-}ljjI77qUHy|C6y!QCVp{ukfJrfW zhn6YGZEduw02_rskii<+t^#Zn0!D*^*2j8T0UY0-Jr*<|JoYMpBl*=&@(2jZ7@DrG z@0+Xue(}r&NG6jYiuzaOTrLL>9B7i(O=XU)MEOpm=_)VViM{jFq0-8=yjq$|^Kj;^ zHbbCVnS>DN+M}NkEnhX-cvB)zw->OVJT(augRPFhA_(;U`2hmD4YC>tH8PvW)7`RO zb`{g`ST;X@IwOa$C6fuUUY_=pP?)duK>!=}0&E#NO}i{h>S;?RhIsguEYsqz3Xp!O ziDx*5CHv64oL&AP+ih7#(4y2BmXcOVNTyGZVVPc?FhiTWlr{KgwkJ5jxzg)#d48ybcq5BjXTd|vFKu18e@o}Disb4S z!fYaaKaZNSq56^N)yG$y(i18@+I>2c$(Zt1gCMViJV(p!Tc_cp*R2VElC!nJa&E_G%y8odThr!ReoyO zFdF>GL#63v6yJ~o|5eCDMri?)iZ9HU{ zZL@|Rrhtt?g3=nfGy{t^TLMM~33Ld{pgeX?vJ7bkr016lMpo6Tc3@GlQ^2y3jhfR| zIjfyr+mL1l;0)5Y4z|CZ^?dWiqgFYqwat}>>ENc%(p&D%47vV9L&y77N)AAWxq9d1 z0!$6A*DIxy--M}++R_tXDy&w(y#S@Q`U02=s}}H!Yu`)Vc>c9dsU9z-uYegt1PT0q zJRj;%hP*J6E5A?mw_0C(GYXwns|8rE|6r6#xJL07*qoM6N<$g4AZ`D*ylh literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Common/start_call.imageset/start_call@2x.png b/Riot/Assets/Images.xcassets/Common/start_call.imageset/start_call@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0281abca30b1770f9826132dbaa641d34271681a GIT binary patch literal 5061 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 bgs1;MjbRUMphUdl00000NkvXXu0mjfVez{T literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Common/start_call.imageset/start_call@3x.png b/Riot/Assets/Images.xcassets/Common/start_call.imageset/start_call@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..920d3f8fa6487e67bf1c8da1f9c15114954f4632 GIT binary patch literal 6958 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 AA^-pY literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/Contents.json b/Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/Contents.json new file mode 100644 index 0000000000..5ce068333f --- /dev/null +++ b/Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "tab_calls.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "tab_calls@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "tab_calls@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/tab_calls.png b/Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/tab_calls.png new file mode 100644 index 0000000000000000000000000000000000000000..53fe67a863de3ffd70accaac31182bd86a5d52c3 GIT binary patch literal 519 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlgftkBcNF~oy+ zZRl-ZW=Ecw00#|u1xLXPOrlTJMHylP1im=&ACOm7_|c@|kY@Jd$?O~D+D%Jqd()4{ zy|?v}+{V3Q|HV4CTSEIZqcW-$qqshb-l}`lpP;t!=zS)KS&I!{pJ2BzRXeKSuF2fD zI{s3CXH-qBK>Q--j(V?>u8TJL%{|{s`}GgEzj^rd;`wEbtx|fC&(@tYpOHPyW@2P{ z3bT~kD_`F!7jyEeOJxgtX7_4qPwaA)eq*N;-{vdvK=Ge7re9o zDCbB;Ez+x2K4Wmw<$u%cy!@J<%N71)F5Q+r;dRJO%ZPQ?tT%p|SpUFe*0OTmMvXK7 nPo6tw{*SX)@-y?zPojF+LXP*RsA(V207ZhQtDnm{r-UW|ADPFe literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/tab_calls@2x.png b/Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/tab_calls@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e286a99a3bf9a62358ea171490358ccad292b88f GIT binary patch literal 1247 zcmV<51R(o~P)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NGNl8RORA>dwnLCVCRTMxUqJkpw zO$a6kSTIy*17;Ybp)f?Cv5*46AJEZ3)I{y1GT10n;v^WUs6em9dUyp6La&aOgT98%k6;1xMO+H| z;SQ8LZ}PhXvlSYZ^;mPgHtA^0mV4y@EQOwB0~TVP^|S60eNXQtf_G?qa}on^aDIf< zP+K<9;x_bigmY~hM6H?FNP~WF)?DWcJ(trGNXo-#T!x}y=;=vOCZyMN*%vAAA3@=G z!g-zg8eWHW;E{I<+L$pHAuZFF2oJBh^Pvy=lj|RWOf&Uotv3yNt;vRK}KI zj&r#>?{_=$a%RV#P%(Lf%C-V9i=AzDsSN%1NdBFf(D;FRN3acXH4GI2tmBK>W=iHK z6ui0Hlodq)Ph|GGD51BK`kaACn8~glT{&*x+)HSC#Plrceumsl*o59CXTY1Zm{Y<>cAN8C^=L~wCTX{^pSKHsr({Ml02 z+m_j&?0oUvAe@QZl%(jl>S=nD3c&h-!oV^{M;+qOY9iODLrR__Azh zgo3&bhx9$2s*c!lpH<&qqaqf-xX~|+Eabyg2su@^%zNT<@RV`=*Ae%?afk)r|0ja7 zo6=arx`C)~FeZRGf%r>QuHD$2XAeED3E91 zD5M6^G$uM2Yf(szLdeNB%1+~3mUuy=MxqUe%YCfR@*bsWaPfZ>ge$`T6x9;fF4!{DzSrVu)8K6C=!2GfVeE8eV002ov JPDHLkV1j=JMjZeE literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/tab_calls@3x.png b/Riot/Assets/Images.xcassets/TabBar/tab_calls.imageset/tab_calls@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..989b1bcca00628195b10646bde924f174120aaf4 GIT binary patch literal 1848 zcmV-82gmq{P)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91NT34%1ONa40RR91NB{r;0FW_8?*IS>qDe$SRCod1n%j$2RUF61M!QU< zO&7D!VMgs@(S@>%t~sOb`w)71jwmg<%2b^Wrzj=o20grVA}c z=gZ>N!k~~h7`Fb*w2cC@l9^a(nj-675^PQt)&8?|-y|F-REik6mxUprDCb?}{v#Xu zg^Pts&cCF@i95iLmLB<%Jv z6r5~Om`PEV+dK)X+9N!3GVeEg(s;p0S#fA$pk(+!NV5Bzj41Fv#WPR1_d|3r{XP@& zj#Ab86Ch)r#QtKUwQ9K6)Y#-c8#%`kUkk{;>@aMzRcxivPtts)FyLwdODp7YPRW6y zdRm|xdxR?QWt1gO#D0S_K1&0~DH10OCZZ;S$472TUVLyWaBmSK>(a-#-QssC3TKP2 z%0c>G_BA~!=@i30!6!K1ihriyN*LiIKP4}NM=52bUbXldbf-~ToPa*5yPPbA^RobjE-#Fp z(Q+}gQgHBRA_2ODtDNNW6nrnIjxxG;5TF?mG_%ZX zL>0f+##FKP<>@=1>lN~Yd4|8UWz!=28zSxL|EyDWMKHb7onP!$) zETSfJIkLPzmcmqW{*aruUu?-KK>LSMD{+q~piwM+y z?A{pJQ2rRuj$jK>|NS8p;aDu0gX}@PJ&j4cxp>GyATyU7j3r)GVgTE&5@JO>le14U zDN0?4nG|vsp6M#``wKQymII^M^nH-peF>*86^0x-o-Upzgxf5N;xAO2LFoiNp62@sM#hN+wy7-9jT`aC-$D`ax*a-___Z_zI$~hp1@&R5U+e01Zq<#vfoRsBnZ$DQ z*^}yR4EfE5-pnpj+tPYvYXSwC6qxQaG7aB-*Bcb+_fr9W4XO{Pq(@P=ewmz#eV_H+ zb(HqvemoiA*J_hF&j$z#4Iatl!-7j$VzSre{w6W`+IXHx@D%~Ve3jSo4@=)C0tGHf zYizn)0{;?fb=s~s*o@fhDbS|Swf!CGCG(DTM#a0nU7o&By<6WAP8QPvPr!{)&rIrux%@i!(*?{309rgyq7hCyMTwXoebg3oKtB`~m1QP&h}Wvn6dT1c~6RiW-?3Va%jfUv78Q_*2Lwdr~WI+&rb`38vgHYOr|x zKPt3Jp2WMqSweCmnIx;N;zo>34B%QJ^(m%Q{!f%8)NYgmRSDD~*|JCArDP?Dbxj4m zStvV5ye?WMlsapq-$)#~Jtw3N6idBV@OghG_VTD(s@DkHgpjitmjH7lvR}e1~)F9m1;uWkR!JTg~|?NlwtfOdOjd%okXa9Fk8HIs}Md m3<&+g=fW1DPoVNnO8)`K8>bDVMj@jB0000 + +#import "CallsViewController.h" + +#import "UIViewController+RiotSearch.h" + +#import "RageShakeManager.h" + +#import "RecentsDataSource.h" +#import "RecentTableViewCell.h" + +#import "Riot-Swift.h" + +@interface CallsViewController () +{ + NSInteger callRoomsSectionNumber; + RecentsDataSource *recentsDataSource; +} + +@property(nonatomic) SpaceMembersCoordinatorBridgePresenter *spaceMembersCoordinatorBridgePresenter; + +@end + +@implementation CallsViewController + ++ (instancetype)instantiate +{ + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; + CallsViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"CallsViewController"]; + return viewController; +} + +- (void)finalizeInit +{ + [super finalizeInit]; + + callRoomsSectionNumber = 0; + + self.screenName = @"Calls"; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. + + self.view.accessibilityIdentifier = @"CallsVCView"; + self.recentsTableView.accessibilityIdentifier = @"CallsVCTableView"; + + // Tag the recents table with the its recents data source mode. + // This will be used by the shared RecentsDataSource instance for sanity checks (see UITableViewDataSource methods). + self.recentsTableView.tag = RecentsDataSourceModeSipCalls; + + // Add the (+) button programmatically + plusButtonImageView = [self vc_addFABWithImage:[UIImage imageNamed:@"start_call"] + target:self + action:@selector(onPlusButtonPressed)]; +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + [AppDelegate theDelegate].masterTabBarController.navigationItem.title = [VectorL10n titleCalls]; + [AppDelegate theDelegate].masterTabBarController.tabBar.tintColor = ThemeService.shared.theme.tintColor; + + if ([self.dataSource isKindOfClass:RecentsDataSource.class]) + { + // Take the lead on the shared data source. + recentsDataSource = (RecentsDataSource*)self.dataSource; + recentsDataSource.areSectionsShrinkable = NO; + [recentsDataSource setDelegate:self andRecentsDataSourceMode:RecentsDataSourceModeSipCalls]; + } +} + +#pragma mark - UITableView delegate + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section +{ + return 0.0; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section +{ + return nil; +} + +#pragma mark - Override RecentsViewController + +- (void)refreshCurrentSelectedCell:(BOOL)forceVisible +{ + // Check whether the recents data source is correctly configured. + if (recentsDataSource.recentsDataSourceMode != RecentsDataSourceModeSipCalls) + { + return; + } + + [super refreshCurrentSelectedCell:forceVisible]; +} + +- (void)onPlusButtonPressed +{ + [super openDialpad]; +} + +#pragma mark - + +- (void)scrollToNextRoomWithMissedNotifications +{ + // Check whether the recents data source is correctly configured. + if (recentsDataSource.recentsDataSourceMode == RecentsDataSourceModeSipCalls) + { + [self scrollToTheTopTheNextRoomWithMissedNotificationsInSection:recentsDataSource.callsSection]; + } +} + +#pragma mark - Empty view management + +- (void)updateEmptyView +{ + [self.emptyView fillWith:[self emptyViewArtwork] + title:[VectorL10n callsEmptyViewTitle] + informationText:[VectorL10n callsEmptyViewInformation]]; +} + +- (UIImage*)emptyViewArtwork +{ + if (ThemeService.shared.isCurrentThemeDark) + { + // TODO: replace with picture calls_empty_screen_artwork_dark + return [UIImage imageNamed:@"rooms_empty_screen_artwork_dark"]; + } + else + { + // TODO: replace with picture calls_empty_screen_artwork + return [UIImage imageNamed:@"rooms_empty_screen_artwork"]; + } +} + +#pragma mark - SpaceMembersCoordinatorBridgePresenterDelegate + +- (void)spaceMembersCoordinatorBridgePresenterDelegateDidComplete:(SpaceMembersCoordinatorBridgePresenter *)coordinatorBridgePresenter +{ + [coordinatorBridgePresenter dismissWithAnimated:YES completion:^{ + self.spaceMembersCoordinatorBridgePresenter = nil; + }]; +} + +@end diff --git a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h index 2dbf20bc5d..b3473a9fbf 100644 --- a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h +++ b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h @@ -33,7 +33,8 @@ typedef NS_ENUM(NSInteger, RecentsDataSourceMode) RecentsDataSourceModeHome = 1, RecentsDataSourceModeFavourites, RecentsDataSourceModePeople, - RecentsDataSourceModeRooms + RecentsDataSourceModeRooms, + RecentsDataSourceModeSipCalls }; /** @@ -77,6 +78,7 @@ extern NSString *const kRecentsDataSourceTapOnDirectoryServerChange; @property (nonatomic) NSInteger lowPrioritySection; @property (nonatomic) NSInteger serverNoticeSection; @property (nonatomic) NSInteger suggestedRoomsSection; +@property (nonatomic) NSInteger callsSection; @property (nonatomic, readonly) NSInteger totalVisibleItemCount; @@ -95,6 +97,11 @@ extern NSString *const kRecentsDataSourceTapOnDirectoryServerChange; */ @property (nonatomic, readonly) DiscussionsCount *groupMissedDiscussionsCount; +/** + Counts for call rooms. + */ +@property (nonatomic, readonly) DiscussionsCount *callsMissedDiscussionsCount; + @property (nonatomic, readonly) SecureBackupBannerDisplay secureBackupBannerDisplay; @property (nonatomic, readonly) CrossSigningBannerDisplay crossSigningBannerDisplay; diff --git a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m index 82b5823b28..73bde57023 100644 --- a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m +++ b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m @@ -36,6 +36,7 @@ #define RECENTSDATASOURCE_SECTION_SERVERNOTICE 0x20 #define RECENTSDATASOURCE_SECTION_PEOPLE 0x40 #define RECENTSDATASOURCE_SECTION_SUGGESTED 0x80 +#define RECENTSDATASOURCE_SECTION_CALLS 0x0100 #define RECENTSDATASOURCE_DEFAULT_SECTION_HEADER_HEIGHT 30.0 @@ -63,7 +64,7 @@ @interface RecentsDataSource() > *)callCellDataArray +{ + return self.recentsListService.callRoomListData.rooms; +} - (NSInteger)totalVisibleItemCount { @@ -165,6 +171,11 @@ - (DiscussionsCount *)groupMissedDiscussionsCount return self.recentsListService.conversationMissedDiscussionsCount; } +- (DiscussionsCount *)callsMissedDiscussionsCount +{ + return self.recentsListService.callsMissedDiscussionsCount; +} + #pragma mark - - (void)setDelegate:(id)delegate andRecentsDataSourceMode:(RecentsDataSourceMode)recentsDataSourceMode @@ -517,6 +528,11 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { suggestedRoomsSection = sectionsCount++; } + + if (self.callCellDataArray.count > 0) + { + callsSection = sectionsCount++; + } } return sectionsCount; @@ -573,7 +589,11 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger { count = self.suggestedRoomCellDataArray.count; } - + else if (section == callsSection && !(shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_CALLS)) + { + count = self.callCellDataArray.count; + } + // Adjust this count according to the potential dragged cell. if ([self isMovingCellSection:section]) { @@ -659,7 +679,12 @@ - (NSAttributedString *)attributedStringForHeaderTitleInSection:(NSInteger)secti count = self.suggestedRoomCellDataArray.count; title = [VectorL10n roomRecentsSuggestedRoomsSection]; } - + else if (section == callsSection) + { + count = self.callCellDataArray.count; + title = [VectorL10n roomRecentsCallsSection]; + } + if (count) { NSString *roomCount = [NSString stringWithFormat:@" %tu", count]; @@ -713,6 +738,10 @@ - (UIView *)badgeViewForHeaderTitleInHomeSection:(NSInteger)section { counts = self.recentsListService.suggestedRoomListData.counts; } + else if (section == callsSection) + { + counts = self.recentsListService.callRoomListData.counts; + } if (counts.numberOfNotifications) { @@ -796,6 +825,10 @@ - (UIView *)viewForHeaderInSection:(NSInteger)section withFrame:(CGRect)frame { sectionBitwise = RECENTSDATASOURCE_SECTION_SUGGESTED; } + else if (section == callsSection) + { + sectionBitwise = RECENTSDATASOURCE_SECTION_CALLS; + } } if (sectionBitwise) @@ -931,7 +964,30 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N return tableViewCell; } - + else if (indexPath.section == callsSection && !self.callCellDataArray.count) + { + MXKTableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier]]; + if (!tableViewCell) + { + tableViewCell = [[MXKTableViewCell alloc] init]; + tableViewCell.textLabel.textColor = ThemeService.shared.theme.textSecondaryColor; + tableViewCell.textLabel.font = [UIFont systemFontOfSize:15.0]; + tableViewCell.selectionStyle = UITableViewCellSelectionStyleNone; + } + + // Check whether a search session is in progress + if (self.searchPatternsList) + { + tableViewCell.textLabel.text = [VectorL10n searchNoResult]; + } + else + { + tableViewCell.textLabel.text = [VectorL10n roomRecentsNoConversation]; + } + + return tableViewCell; + } + return [super tableView:tableView cellForRowAtIndexPath:indexPath]; } @@ -1000,7 +1056,14 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N summary = self.suggestedRoomCellDataArray[cellDataIndex]; } } - + else if (tableSection == callsSection) + { + if (cellDataIndex < self.callCellDataArray.count) + { + summary = self.callCellDataArray[cellDataIndex]; + } + } + if (summary) { return [[MXKRecentCellData alloc] initWithRoomSummary:summary dataSource:self]; @@ -1023,7 +1086,11 @@ - (CGFloat)cellHeightAtIndexPath:(NSIndexPath *)indexPath { return 50.0; } - + if (indexPath.section == callsSection && !self.callCellDataArray.count) + { + return 50.0; + } + // Override this method here to use our own cellDataAtIndexPath id cellData = [self cellDataAtIndexPath:indexPath]; @@ -1172,6 +1239,21 @@ - (NSIndexPath*)cellIndexPathWithRoomId:(NSString*)roomId andMatrixSession:(MXSe indexPath = [NSIndexPath indexPathForRow:index inSection:serverNoticeSection]; } } + + if (!indexPath && (callsSection >= 0)) + { + index = [self cellIndexPosWithRoomId:roomId andMatrixSession:matrixSession within:self.callCellDataArray]; + + if (index != NSNotFound) + { + // Check whether the low priority rooms are shrinked + if (shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_CALLS) + { + return nil; + } + indexPath = [NSIndexPath indexPathForRow:index inSection:callsSection]; + } + } return indexPath; } @@ -1298,6 +1380,10 @@ - (BOOL)isDraggableCellAt:(NSIndexPath*)path { return NO; } + if (_recentsDataSourceMode == RecentsDataSourceModeSipCalls) + { + return NO; + } return (path && ((path.section == favoritesSection) || (path.section == peopleSection) || (path.section == lowPrioritySection) || (path.section == serverNoticeSection) || (path.section == conversationSection))); } diff --git a/Riot/Modules/Common/Recents/RecentsViewController.h b/Riot/Modules/Common/Recents/RecentsViewController.h index 9e9e357a76..8560cc38e4 100644 --- a/Riot/Modules/Common/Recents/RecentsViewController.h +++ b/Riot/Modules/Common/Recents/RecentsViewController.h @@ -156,6 +156,11 @@ FOUNDATION_EXPORT NSString *const RecentsViewControllerDataReadyNotification; */ - (void)leaveEditedRoom; +/** + Make this function accessible to subclass + */ +- (void)openDialpad; + /** Update the selected room tag. */ diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift index 32d06807f6..7093c459fe 100644 --- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift @@ -61,14 +61,16 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { private var conversationRoomListDataFetcherForRooms: MXRoomListDataFetcher? private var directRoomListDataFetcherForHome: MXRoomListDataFetcher? private var directRoomListDataFetcherForPeople: MXRoomListDataFetcher? - + private var directRoomListDataFetcherForCalls: MXRoomListDataFetcher? + // MARK: - Private private var fetcherTypesForMode: [RecentsDataSourceMode: FetcherTypes] = [ .home: [.invited, .favorited, .directHome, .conversationHome, .lowPriority, .serverNotice, .suggested], .favourites: [.favorited], .people: [.directPeople], - .rooms: [.conversationRooms, .suggested] + .rooms: [.conversationRooms, .suggested], + .sipCalls: [.sipCalls] ] private var allFetchers: [MXRoomListDataFetcher] { @@ -85,6 +87,9 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { if let fetcher = directRoomListDataFetcherForPeople { result.append(fetcher) } + if let fetcher = directRoomListDataFetcherForCalls { + result.append(fetcher) + } if let fetcher = conversationRoomListDataFetcherForHome { result.append(fetcher) } @@ -120,6 +125,9 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { if let fetcher = directRoomListDataFetcherForPeople, fetcherTypes.contains(.directPeople) { result.append(fetcher) } + if let fetcher = directRoomListDataFetcherForCalls, fetcherTypes.contains(.sipCalls) { + result.append(fetcher) + } if let fetcher = conversationRoomListDataFetcherForHome, fetcherTypes.contains(.conversationHome) { result.append(fetcher) } @@ -216,7 +224,11 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { guard shouldShowSuggested else { return nil } return suggestedRoomListDataFetcher?.data } - + public var callRoomListData: MXRoomListData? { + guard shouldShowCalls else { return nil } + return directRoomListDataFetcherForCalls?.data + } + public var favoritedMissedDiscussionsCount: DiscussionsCount { guard let data = favoritedRoomListDataFetcher?.data else { return .zero @@ -238,6 +250,13 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { return DiscussionsCount(withRoomListDataCounts: data.counts) } + public var callsMissedDiscussionsCount: DiscussionsCount { + guard let data = directRoomListDataFetcherForCalls?.data else { + return .zero + } + return DiscussionsCount(withRoomListDataCounts: data.counts) + } + public var totalVisibleItemCount: Int { return visibleFetchers.reduce(0, { $0 + ($1.data?.counts.numberOfRooms ?? 0) }) } @@ -360,6 +379,10 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { return fetcherTypesForMode[mode]?.contains(.suggested) ?? false } + private var shouldShowCalls: Bool { + return fetcherTypesForMode[mode]?.contains(.sipCalls) ?? false + } + private func createCommonRoomListDataFetcher(withDataTypes dataTypes: MXRoomSummaryDataTypes = [], onlySuggested: Bool = false, paginate: Bool = true) -> MXRoomListDataFetcher { @@ -399,6 +422,14 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { return fetcher } + private func createDirectRoomListDataFetcherForCalls() -> MXRoomListDataFetcher { + let fetcher = createCommonRoomListDataFetcher(withDataTypes: [.sipCall], paginate: false) + updateDirectFetcher(fetcher, for: .sipCalls) + fetcher.addDelegate(self) + fetcher.paginate() + return fetcher + } + private func createConversationRoomListDataFetcherForHome() -> MXRoomListDataFetcher { let fetcher = createCommonRoomListDataFetcher(withDataTypes: [], paginate: false) updateConversationFetcher(fetcher, for: .home) @@ -422,6 +453,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { favoritedRoomListDataFetcher = createCommonRoomListDataFetcher(withDataTypes: [.favorited]) directRoomListDataFetcherForHome = createDirectRoomListDataFetcherForHome() directRoomListDataFetcherForPeople = createDirectRoomListDataFetcherForPeople() + directRoomListDataFetcherForCalls = createDirectRoomListDataFetcherForCalls() conversationRoomListDataFetcherForHome = createConversationRoomListDataFetcherForHome() conversationRoomListDataFetcherForRooms = createConversationRoomListDataFetcherForRooms() lowPriorityRoomListDataFetcher = createCommonRoomListDataFetcher(withDataTypes: [.lowPriority]) @@ -433,9 +465,12 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { var notDataTypes: MXRoomSummaryDataTypes = [.hidden, .conferenceUser, .space] switch mode { case .home: - notDataTypes.insert([.invited, .favorited, .lowPriority]) + notDataTypes.insert([.invited, .favorited, .lowPriority, .sipCall]) fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes case .people: + notDataTypes.insert([.lowPriority, .sipCall]) + fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes + case .sipCalls: notDataTypes.insert([.lowPriority]) fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes default: @@ -511,8 +546,9 @@ 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 sipCalls = FetcherTypes(rawValue: 1 << 9) + static let none: FetcherTypes = [] static let all: FetcherTypes = [ - .invited, .favorited, .directHome, .directPeople, .conversationHome, .conversationRooms, .lowPriority, .serverNotice, .suggested] + .invited, .favorited, .directHome, .directPeople, .sipCalls, .conversationHome, .conversationRooms, .lowPriority, .serverNotice, .suggested] } diff --git a/Riot/Modules/Common/Recents/Service/Mock/MockRecentsListService.swift b/Riot/Modules/Common/Recents/Service/Mock/MockRecentsListService.swift index 6be38a6761..0b85a3c110 100644 --- a/Riot/Modules/Common/Recents/Service/Mock/MockRecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/Mock/MockRecentsListService.swift @@ -27,7 +27,8 @@ public class MockRecentsListService: NSObject, RecentsListServiceProtocol { private var _conversationRoomListData: MXRoomListData? private var _lowPriorityRoomListData: MXRoomListData? private var _serverNoticeRoomListData: MXRoomListData? - + private var _callRoomListData: MXRoomListData? + // swiftlint:disable weak_delegate private let multicastDelegate: MXMulticastDelegate = MXMulticastDelegate() // swiftlint:enable weak_delegate @@ -41,7 +42,8 @@ public class MockRecentsListService: NSObject, RecentsListServiceProtocol { var conversation: [MockRoomSummary] = [] var lowPriority: [MockRoomSummary] = [] var serverNotice: [MockRoomSummary] = [] - + var calls: [MockRoomSummary] = [] + rooms.forEach { summary in if summary.isTyped(.invited) { invited.append(summary) @@ -72,7 +74,8 @@ public class MockRecentsListService: NSObject, RecentsListServiceProtocol { _conversationRoomListData = MockRoomListData(withRooms: conversation) _lowPriorityRoomListData = MockRoomListData(withRooms: lowPriority) _serverNoticeRoomListData = MockRoomListData(withRooms: serverNotice) - + _callRoomListData = MockRoomListData(withRooms: calls) + super.init() } @@ -90,6 +93,8 @@ public class MockRecentsListService: NSObject, RecentsListServiceProtocol { room.dataTypes = .invited } else if i % 11 == 0 { room.dataTypes = .serverNotice + } else if i % 13 == 0 { + room.dataTypes = .sipCall } room.displayname = "Room \(i+1)" if let event = MXEvent(fromJSON: [ @@ -147,6 +152,11 @@ public class MockRecentsListService: NSObject, RecentsListServiceProtocol { return _serverNoticeRoomListData } + public var callRoomListData: MXRoomListData? { + guard mode == .sipCalls else { return nil } + return _callRoomListData + } + public var suggestedRoomListData: MXRoomListData? public var favoritedMissedDiscussionsCount: DiscussionsCount = .zero @@ -154,7 +164,9 @@ public class MockRecentsListService: NSObject, RecentsListServiceProtocol { public var peopleMissedDiscussionsCount: DiscussionsCount = .zero public var conversationMissedDiscussionsCount: DiscussionsCount = .zero - + + public var callsMissedDiscussionsCount: DiscussionsCount = .zero + public var totalVisibleItemCount: Int { switch mode { case .home: @@ -165,6 +177,8 @@ public class MockRecentsListService: NSObject, RecentsListServiceProtocol { return peopleRoomListData?.counts.numberOfRooms ?? 0 case .rooms: return conversationRoomListData?.counts.numberOfRooms ?? 0 + case .sipCalls: + return callRoomListData?.counts.numberOfRooms ?? 0 @unknown default: return 0 } @@ -194,6 +208,7 @@ public class MockRecentsListService: NSObject, RecentsListServiceProtocol { _conversationRoomListData = nil _lowPriorityRoomListData = nil _serverNoticeRoomListData = nil + _callRoomListData = nil removeAllDelegates() } diff --git a/Riot/Modules/Common/Recents/Service/Mock/MockRoomSummary.swift b/Riot/Modules/Common/Recents/Service/Mock/MockRoomSummary.swift index c211db025b..8dc2242882 100644 --- a/Riot/Modules/Common/Recents/Service/Mock/MockRoomSummary.swift +++ b/Riot/Modules/Common/Recents/Service/Mock/MockRoomSummary.swift @@ -44,6 +44,8 @@ public class MockRoomSummary: NSObject, MXRoomSummaryProtocol { public var isConferenceUserRoom: Bool = false + public var isSipCallRoom: Bool = false + public var hiddenFromUser: Bool = false public var storedHash: UInt = 0 diff --git a/Riot/Modules/Common/Recents/Service/RecentsListServiceProtocol.swift b/Riot/Modules/Common/Recents/Service/RecentsListServiceProtocol.swift index 154cf2e211..d4648fa92c 100644 --- a/Riot/Modules/Common/Recents/Service/RecentsListServiceProtocol.swift +++ b/Riot/Modules/Common/Recents/Service/RecentsListServiceProtocol.swift @@ -53,6 +53,9 @@ public protocol RecentsListServiceProtocol { /// Suggested rooms for current mode var suggestedRoomListData: MXRoomListData? { get } + /// Call list + var callRoomListData: MXRoomListData? { get } + // MARK: Discussion counts /// Counts for favorite screen @@ -63,7 +66,10 @@ public protocol RecentsListServiceProtocol { /// Counts for rooms screen var conversationMissedDiscussionsCount: DiscussionsCount { get } - + + /// Counts for rooms screen + var callsMissedDiscussionsCount: DiscussionsCount { get } + /// Total number of rooms visible in one screen. Can be used to display an empty view var totalVisibleItemCount: Int { get } diff --git a/Riot/Modules/Home/HomeViewController.m b/Riot/Modules/Home/HomeViewController.m index 2c2f702d76..fcecc668b7 100644 --- a/Riot/Modules/Home/HomeViewController.m +++ b/Riot/Modules/Home/HomeViewController.m @@ -386,7 +386,11 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { return [recentsDataSource tableView:tableView cellForRowAtIndexPath:indexPath]; } - + if (indexPath.section == recentsDataSource.callsSection && !recentsDataSource.recentsListService.callRoomListData.counts.numberOfRooms) + { + return [recentsDataSource tableView:tableView cellForRowAtIndexPath:indexPath]; + } + TableViewCellWithCollectionView *tableViewCell = [tableView dequeueReusableCellWithIdentifier:TableViewCellWithCollectionView.defaultReuseIdentifier forIndexPath:indexPath]; tableViewCell.collectionView.tag = indexPath.section; [tableViewCell.collectionView registerClass:RoomCollectionViewCell.class forCellWithReuseIdentifier:RoomCollectionViewCell.defaultReuseIdentifier]; @@ -475,6 +479,10 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa { return [recentsDataSource cellHeightAtIndexPath:indexPath]; } + else if (indexPath.section == recentsDataSource.callsSection && !recentsDataSource.recentsListService.callRoomListData.counts.numberOfRooms) + { + return [recentsDataSource cellHeightAtIndexPath:indexPath]; + } else if (indexPath.section == recentsDataSource.secureBackupBannerSection || indexPath.section == recentsDataSource.crossSigningBannerSection) { CGFloat height = 0.0; diff --git a/Riot/Modules/TabBar/MasterTabBarController.h b/Riot/Modules/TabBar/MasterTabBarController.h index b607c0ea9f..0ae4c406fa 100644 --- a/Riot/Modules/TabBar/MasterTabBarController.h +++ b/Riot/Modules/TabBar/MasterTabBarController.h @@ -23,20 +23,23 @@ #import "PeopleViewController.h" #import "RoomsViewController.h" #import "GroupsViewController.h" +#import "CallsViewController.h" #define TABBAR_HOME_INDEX 0 #define TABBAR_FAVOURITES_INDEX 1 #define TABBAR_PEOPLE_INDEX 2 #define TABBAR_ROOMS_INDEX 3 #define TABBAR_GROUPS_INDEX 4 -#define TABBAR_COUNT 5 +#define TABBAR_CALLS_INDEX 5 +#define TABBAR_COUNT 6 typedef NS_ENUM(NSUInteger, MasterTabBarIndex) { MasterTabBarIndexHome = TABBAR_HOME_INDEX, MasterTabBarIndexFavourites = TABBAR_FAVOURITES_INDEX, MasterTabBarIndexPeople = TABBAR_PEOPLE_INDEX, MasterTabBarIndexRooms = TABBAR_ROOMS_INDEX, - MasterTabBarIndexGroups = TABBAR_GROUPS_INDEX + MasterTabBarIndexGroups = TABBAR_GROUPS_INDEX, + MasterTabBarIndexCalls = TABBAR_CALLS_INDEX }; @protocol MasterTabBarControllerDelegate; @@ -157,6 +160,7 @@ typedef NS_ENUM(NSUInteger, MasterTabBarIndex) { @property (nonatomic, readonly) PeopleViewController *peopleViewController; @property (nonatomic, readonly) RoomsViewController *roomsViewController; @property (nonatomic, readonly) GroupsViewController *groupsViewController; +@property (nonatomic, readonly) CallsViewController *callsViewController; // References on the currently selected room diff --git a/Riot/Modules/TabBar/MasterTabBarController.m b/Riot/Modules/TabBar/MasterTabBarController.m index 6d4e175b8a..6b5afc763c 100644 --- a/Riot/Modules/TabBar/MasterTabBarController.m +++ b/Riot/Modules/TabBar/MasterTabBarController.m @@ -107,6 +107,11 @@ - (GroupsViewController *)groupsViewController return (GroupsViewController*)[self viewControllerForClass:GroupsViewController.class]; } +- (CallsViewController *)callsViewController +{ + return (CallsViewController*)[self viewControllerForClass:CallsViewController.class]; +} + #pragma mark - Life cycle - (void)viewDidLoad @@ -359,7 +364,8 @@ - (void)initializeDataSources [self.favouritesViewController displayList:recentsDataSource]; [self.peopleViewController displayList:recentsDataSource]; [self.roomsViewController displayList:recentsDataSource]; - + [self.callsViewController displayList:recentsDataSource]; + // Restore the right delegate of the shared recent data source. id recentsDataSourceDelegate = self.homeViewController; RecentsDataSourceMode recentsDataSourceMode = RecentsDataSourceModeHome; @@ -382,7 +388,11 @@ - (void)initializeDataSources recentsDataSourceDelegate = self.roomsViewController; recentsDataSourceMode = RecentsDataSourceModeRooms; break; - + case TABBAR_CALLS_INDEX: + recentsDataSourceDelegate = self.callsViewController; + recentsDataSourceMode = RecentsDataSourceModeSipCalls; + break; + default: break; } @@ -479,7 +489,8 @@ - (void)removeMatrixSession:(MXSession *)mxSession [self.favouritesViewController displayList:nil]; [self.peopleViewController displayList:nil]; [self.roomsViewController displayList:nil]; - + [self.callsViewController displayList:nil]; + [recentsDataSource destroy]; recentsDataSource = nil; } @@ -854,6 +865,13 @@ - (void)refreshTabBarBadges withBadgeColor:(recentsDataSource.groupMissedDiscussionsCount.hasHighlight ? ThemeService.shared.theme.noticeColor : ThemeService.shared.theme.noticeSecondaryColor)]; } } + + if (RiotSettings.shared.homeScreenShowCallsTab) + { + [self setMissedDiscussionsCount:recentsDataSource.callsMissedDiscussionsCount.numberOfNotified + onTabBarItem:TABBAR_CALLS_INDEX + withBadgeColor:ThemeService.shared.theme.noticeSecondaryColor]; + } } - (void)setMissedDiscussionsCount:(NSUInteger)count onTabBarItem:(NSUInteger)index withBadgeColor:(UIColor*)badgeColor @@ -1093,6 +1111,10 @@ - (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item { [self.favouritesViewController scrollToNextRoomWithMissedNotifications]; } + else if (item.tag == TABBAR_CALLS_INDEX) + { + [self.callsViewController scrollToNextRoomWithMissedNotifications]; + } } } diff --git a/Riot/Modules/TabBar/TabBarCoordinator.swift b/Riot/Modules/TabBar/TabBarCoordinator.swift index 37342d973b..5e14d67b9c 100644 --- a/Riot/Modules/TabBar/TabBarCoordinator.swift +++ b/Riot/Modules/TabBar/TabBarCoordinator.swift @@ -257,6 +257,13 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType { return groupsViewController } + private func createCallsViewController() -> CallsViewController { + let callsViewController: CallsViewController = CallsViewController.instantiate() + callsViewController.tabBarItem.tag = Int(TABBAR_CALLS_INDEX) + callsViewController.accessibilityLabel = VectorL10n.titleCalls + return callsViewController + } + private func createUnifiedSearchController() -> UnifiedSearchViewController { let viewController: UnifiedSearchViewController = UnifiedSearchViewController.instantiate() @@ -329,6 +336,11 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType { viewControllers.append(groupsViewController) } + if RiotSettings.shared.homeScreenShowCallsTab { + let callsViewController = self.createCallsViewController() + viewControllers.append(callsViewController) + } + tabBarController.updateViewControllers(viewControllers) } From 50b14c0341733aec0d02bdf97d635adbb95e9dc5 Mon Sep 17 00:00:00 2001 From: Simon Wiedmer Date: Mon, 21 Mar 2022 09:26:28 +0100 Subject: [PATCH 2/3] Implementation changes from merge --- .../MatrixSDK/RecentsListService.swift | 39 +++++++++++++++---- .../Service/RecentsListServiceSection.swift | 1 + 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift index 79185273e7..357368fc65 100644 --- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift @@ -40,6 +40,8 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { return invitedRoomListDataFetcherForPeople case .rooms: return invitedRoomListDataFetcherForRooms + case .sipCalls: + return invitedRoomListDataFetcherForCalls default: return nil } @@ -51,6 +53,8 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { return directRoomListDataFetcherForHome case .people: return directRoomListDataFetcherForPeople + case .sipCalls: + return directRoomListDataFetcherForCalls default: return nil } @@ -77,6 +81,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { private var invitedRoomListDataFetcherForHome: MXRoomListDataFetcher? private var invitedRoomListDataFetcherForPeople: MXRoomListDataFetcher? private var invitedRoomListDataFetcherForRooms: MXRoomListDataFetcher? + private var invitedRoomListDataFetcherForCalls: MXRoomListDataFetcher? // MARK: - Private @@ -85,7 +90,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { .favourites: [.favorited], .people: [.invited, .directPeople], .rooms: [.invited, .conversationRooms, .suggested], - .sipCalls: [.sipCalls] + .sipCalls: [.invited, .sipCalls] ] private var allFetchers: [MXRoomListDataFetcher] { @@ -93,9 +98,11 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { invitedRoomListDataFetcherForHome, invitedRoomListDataFetcherForPeople, invitedRoomListDataFetcherForRooms, + invitedRoomListDataFetcherForCalls, favoritedRoomListDataFetcher, directRoomListDataFetcherForHome, directRoomListDataFetcherForPeople, + directRoomListDataFetcherForCalls, conversationRoomListDataFetcherForHome, conversationRoomListDataFetcherForRooms, lowPriorityRoomListDataFetcher, @@ -245,12 +252,12 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { let totalCounts = [invitesCount, conversationCount].compactMap { $0 } return DiscussionsCount(withRoomListDataCounts: totalCounts) } - + public var callsMissedDiscussionsCount: DiscussionsCount { - guard let data = directRoomListDataFetcherForCalls?.data else { - return .zero - } - return DiscussionsCount(withRoomListDataCounts: data.counts) + let invitesCount = invitedRoomListDataFetcherForCalls?.data?.counts.total + let callsCount = directRoomListDataFetcherForCalls?.data?.counts.total + let totalCounts = [invitesCount, callsCount].compactMap { $0 } + return DiscussionsCount(withRoomListDataCounts: totalCounts) } public var totalVisibleItemCount: Int { @@ -304,9 +311,11 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { invitedRoomListDataFetcherForHome = nil invitedRoomListDataFetcherForPeople = nil invitedRoomListDataFetcherForRooms = nil + invitedRoomListDataFetcherForCalls = nil favoritedRoomListDataFetcher = nil directRoomListDataFetcherForHome = nil directRoomListDataFetcherForPeople = nil + directRoomListDataFetcherForCalls = nil conversationRoomListDataFetcherForHome = nil conversationRoomListDataFetcherForRooms = nil lowPriorityRoomListDataFetcher = nil @@ -441,6 +450,8 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { return favoritedRoomListDataFetcher case .people: return directRoomListDataFetcher + case .sipCalls: + return directRoomListDataFetcherForCalls case .conversation: return conversationRoomListDataFetcher case .lowPriority: @@ -459,6 +470,8 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { return .favorited } else if fetcher === directRoomListDataFetcher { return .people + } else if fetcher === directRoomListDataFetcherForCalls { + return .sipCalls } else if fetcher === conversationRoomListDataFetcher { return .conversation } else if fetcher === lowPriorityRoomListDataFetcher { @@ -512,6 +525,14 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { return fetcher } + private func createInvitedRoomListDataFetcherForCalls() -> MXRoomListDataFetcher { + let fetcher = createCommonRoomListDataFetcher(withDataTypes: [.invited, .sipCall], paginate: false, strictMatches: true) + updateInvitedFetcher(fetcher, for: .sipCalls) + fetcher.addDelegate(self) + fetcher.paginate() + return fetcher + } + private func createDirectRoomListDataFetcherForHome() -> MXRoomListDataFetcher { let fetcher = createCommonRoomListDataFetcher(withDataTypes: [.direct], paginate: false) updateDirectFetcher(fetcher, for: .home) @@ -567,6 +588,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { invitedRoomListDataFetcherForHome = createCommonRoomListDataFetcher(withDataTypes: [.invited]) invitedRoomListDataFetcherForPeople = createInvitedRoomListDataFetcherForPeople() invitedRoomListDataFetcherForRooms = createInvitedRoomListDataFetcherForRooms() + invitedRoomListDataFetcherForCalls = createInvitedRoomListDataFetcherForCalls() } favoritedRoomListDataFetcher = createCommonRoomListDataFetcher(withDataTypes: [.favorited]) directRoomListDataFetcherForHome = createDirectRoomListDataFetcherForHome() @@ -602,9 +624,12 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { var notDataTypes: MXRoomSummaryDataTypes = [.hidden, .conferenceUser, .lowPriority, .serverNotice, .space] switch mode { case .people: + notDataTypes.insert([.sipCall]) fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes case .rooms: - notDataTypes.insert([.direct]) + notDataTypes.insert([.direct, .sipCall]) + fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes + case .sipCalls: fetcher.fetchOptions.filterOptions.notDataTypes = notDataTypes default: break diff --git a/Riot/Modules/Common/Recents/Service/RecentsListServiceSection.swift b/Riot/Modules/Common/Recents/Service/RecentsListServiceSection.swift index 99ef113532..c6567a64e3 100644 --- a/Riot/Modules/Common/Recents/Service/RecentsListServiceSection.swift +++ b/Riot/Modules/Common/Recents/Service/RecentsListServiceSection.swift @@ -21,6 +21,7 @@ public enum RecentsListServiceSection: Int { case invited case favorited case people + case sipCalls case conversation case lowPriority case serverNotice From e08dcefe53879e91ef08594cea1c75b0efbdefd4 Mon Sep 17 00:00:00 2001 From: Simon Wiedmer Date: Mon, 21 Mar 2022 09:37:21 +0100 Subject: [PATCH 3/3] Add changelog --- changelog.d/5782.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5782.feature diff --git a/changelog.d/5782.feature b/changelog.d/5782.feature new file mode 100644 index 0000000000..e2139887af --- /dev/null +++ b/changelog.d/5782.feature @@ -0,0 +1 @@ +HomeViewController: Tab for list of calls with bridged users. \ No newline at end of file