diff --git a/Application/Resources/Data/parsePlayUrl.js b/Application/Resources/Data/parsePlayUrl.js index df9ac4f7c..8eceb557f 100644 --- a/Application/Resources/Data/parsePlayUrl.js +++ b/Application/Resources/Data/parsePlayUrl.js @@ -1,6 +1,6 @@ // parsePlayUrl -var parsePlayUrlVersion = 22; +var parsePlayUrlVersion = 24; var parsePlayUrlBuild = "mmf"; if(! console) { @@ -95,13 +95,19 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { } // Returns default TV homepage - return openTvHomePage(server,bu); + return openTvHomePage(server, bu); } if (hostname.includes("play-mmf") && ! pathname.startsWith("/mmf/")) { pathname = pathname.substring(4); } + if (hostname.includes("play-web")) { + pathname = pathname.substring(4); + pathname = pathname.replace("/stage/play", "/play"); + pathname = pathname.replace("/test/play", "/play"); + } + /** * Catch special case: shared RTS media urls built by RTS MAM. * @@ -123,7 +129,7 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { } else if (pathname.startsWith("/video")) { // Returns default TV homepage - return openTvHomePage(server,bu); + return openTvHomePage(server, bu); } else { var channelId = null; @@ -159,6 +165,7 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { * Catch classic media urls * * Ex: https://www.rts.ch/play/tv/faut-pas-croire/video/exportations-darmes--la-suisse-vend-t-elle-la-guerre-ou-la-paix-?id=9938530 + * Ex: https://www.srf.ch/play/tv/_/video/_?urn=urn:srf:scheduled_livestream:video:6d49170d-16e9-45ef-a8aa-00873333a610 (strange) */ var mediaType = null; switch (true) { @@ -171,9 +178,13 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { } if (mediaType) { + var mediaUrn = queryParams["urn"]; var mediaId = queryParams["id"]; - if (mediaId) { - var startTime = queryParams["startTime"]; + var startTime = queryParams["startTime"]; + if (mediaUrn) { + return openMediaURN(server, bu, mediaUrn, startTime); + } + else if (mediaId) { return openMedia(server, bu, mediaType, mediaId, startTime); } else { @@ -210,15 +221,16 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { * Catch live TV urls * * Ex: https://www.srf.ch/play/tv/live?tvLiveId=c49c1d73-2f70-0001-138a-15e0c4ccd3d0 + * Ex: https://www.srf.ch/play/tv/live/?tvLiveId=c49c1d73-2f70-0001-138a-15e0c4ccd3d0 */ - if (pathname.endsWith("/tv/live") || pathname.endsWith("/tv/direct")) { + if (pathname.endsWith("/tv/live") || pathname.endsWith("/tv/live/") || pathname.endsWith("/tv/direct") || pathname.endsWith("/tv/direct/")) { var mediaId = queryParams["tvLiveId"]; if (mediaId) { return openMedia(server, bu, "video", mediaId, null); } else { // Returns default TV homepage - return openTvHomePage(server,bu); + return openTvHomePage(server, bu); } } @@ -226,8 +238,9 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { * Catch live radio urls * * Ex: https://www.rsi.ch/play/radio/livepopup/rete-uno + * Ex: https://www.rsi.ch/play/radio/legacy-livepopup/rete-uno */ - if (pathname.includes("/radio/livepopup/")) { + if (pathname.includes("/radio/livepopup/") || pathname.includes("/radio/legacy-livepopup/")) { var mediaBu = null; var mediaId = null; switch (pathname.substr(pathname.lastIndexOf('/') + 1)) { @@ -299,7 +312,7 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { } /** - * Catch live tv popup urls + * Catch tv video popup urls * * Ex: https://www.srf.ch/play/tv/popupvideoplayer?id=b833a5af-63c6-4310-bb80-05341310a4f5 */ @@ -310,7 +323,23 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { } else { // Returns default TV homepage - return openTvHomePage(server,bu); + return openTvHomePage(server, bu); + } + } + + /** + * Catch radio audio popup urls + * + * Ex: https://www.srf.ch/play/radio/popupaudioplayer?id=dc5e9465-ac64-409a-9878-ee47de3d1346 + */ + if (pathname.includes("/radio/popupaudioplayer")) { + var mediaId = queryParams["id"]; + if (mediaId) { + return openMedia(server, bu, "audio", mediaId, null); + } + else { + // Returns default radio homepage + return openRadioHomePage(server, bu, null); } } @@ -340,15 +369,18 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { } /** - * Catch redirect show urls + * Catch redirect and simple show urls * * Ex: https://www.rts.ch/play/tv/quicklink/6176 + * Ex: https://www.rts.ch/play/tv/show/9674517 */ switch (true) { case pathname.includes("/tv/quicklink/"): + case pathname.includes("/tv/show/"): showTransmission = "tv"; break; case pathname.includes("/radio/quicklink/"): + case pathname.includes("/radio/show/"): showTransmission = "radio"; break; } @@ -369,7 +401,7 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { * Ex: https://www.srf.ch/play/tv */ if (pathname.endsWith("/tv")) { - return openTvHomePage(server,bu); + return openTvHomePage(server, bu); } /** @@ -379,7 +411,7 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { */ if (pathname.endsWith("/radio")) { var channelId = queryParams["station"]; - return openRadioHomePage(server, bu,channelId); + return openRadioHomePage(server, bu, channelId); } /** @@ -476,7 +508,7 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { * Ex: https://www.rts.ch/play/tv/categories/info */ if (pathname.endsWith("/tv/themen") || pathname.endsWith("/tv/categories") || pathname.endsWith("/tv/categorie") || pathname.endsWith("/tv/tematicas") || pathname.endsWith("/tv/topics")) { - return openTvHomePage(server,bu); + return openTvHomePage(server, bu); } else if (pathname.includes("/tv/themen") || pathname.includes("/tv/categories") || pathname.includes("/tv/categorie") || pathname.includes("/tv/tematicas") || pathname.includes("/tv/topics")) { var lastPathComponent = pathname.split("/").slice(-1)[0]; @@ -493,7 +525,7 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { return openTopic(server, bu, "tv", topicId); } else { - return openTvHomePage(server,bu); + return openTvHomePage(server, bu); } } @@ -504,7 +536,7 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { *. Ex: https://www.rsi.ch/play/tv/event/event-playrsi-8858482 */ if (pathname.endsWith("/tv/event")) { - return openTvHomePage(server,bu); + return openTvHomePage(server, bu); } else if (pathname.includes("/tv/event")) { var lastPathComponent = pathname.split("/").slice(-1)[0]; @@ -521,7 +553,7 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { return openModule(server, bu, "event", eventId); } else { - return openTvHomePage(server,bu); + return openTvHomePage(server, bu); } } @@ -532,19 +564,20 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { *. Ex: https://www.rsi.ch/play */ if (pathname.endsWith("/play/") || pathname.endsWith("/play")) { - return openTvHomePage(server,bu); + return openTvHomePage(server, bu); } /** * Catch play help urls * * Ex: https://www.srf.ch/play/tv/hilfe + * Ex: https://www.srf.ch/play/tv/hilfe/geoblock * Ex: https://www.rts.ch/play/tv/aide * Ex: https://www.rsi.ch/play/tv/guida * Ex: https://www.rtr.ch/play/tv/agid * Ex: https://play.swissinfo.ch/play/tv/help */ - if (pathname.endsWith("/hilfe") || pathname.endsWith("/aide") || pathname.endsWith("/guida") || pathname.endsWith("/agid") || pathname.endsWith("/help")) { + if (pathname.endsWith("/hilfe") || pathname.includes("/hilfe/") || pathname.endsWith("/aide") || pathname.includes("/aide/") || pathname.endsWith("/guida") || pathname.includes("/guida/") || pathname.endsWith("/agid") || pathname.includes("/agid/") || pathname.endsWith("/help") || pathname.includes("/help/")) { return openURL(server, bu, scheme, hostname, pathname, queryParams, anchor); } @@ -557,7 +590,7 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { function openMedia(server, bu, mediaType, mediaId, startTime) { var urn="urn:" + bu + ":" + mediaType + ":" + mediaId; - return openMediaURN(server,bu,urn,startTime); + return openMediaURN(server, bu, urn, startTime); } function openMediaURN(server, bu, mediaURN, startTime) { @@ -777,6 +810,14 @@ function serverForUrl(hostname, pathname, queryParams) { } } } + else if (hostname.includes("play-web")) { + if (pathname.includes("/stage/play")) { + server = "stage"; + } + else if (pathname.includes("/test/play")) { + server = "test"; + } + } return server; } @@ -784,15 +825,15 @@ function getBuFromHostname(hostname, pathname) { switch (true) { case hostname.endsWith("tp.srgssr.ch") || hostname.endsWith("player.rts.ch") || hostname.endsWith("player.rsi.ch") || hostname.endsWith("player.rtr.ch") || hostname.endsWith("player.swissinfo.ch") || hostname.endsWith("player.srf.ch"): return "tp"; - case hostname.includes("rts.ch") || hostname.includes("srgplayer-rts") || (hostname.includes("play-mmf") && pathname.startsWith("/rts/")): + case hostname.includes("rts.ch") || hostname.includes("srgplayer-rts") || (hostname.includes("play-mmf") && pathname.startsWith("/rts/")) || (hostname.includes("play-web") && pathname.startsWith("/rts/")): return "rts"; - case hostname.includes("rsi.ch") || hostname.includes("srgplayer-rsi") || (hostname.includes("play-mmf") && pathname.startsWith("/rsi/")): + case hostname.includes("rsi.ch") || hostname.includes("srgplayer-rsi") || (hostname.includes("play-mmf") && pathname.startsWith("/rsi/")) || (hostname.includes("play-web") && pathname.startsWith("/rsi/")): return "rsi"; - case hostname.includes("rtr.ch") || hostname.includes("srgplayer-rtr") || (hostname.includes("play-mmf") && pathname.startsWith("/rtr/")): + case hostname.includes("rtr.ch") || hostname.includes("srgplayer-rtr") || (hostname.includes("play-mmf") && pathname.startsWith("/rtr/")) || (hostname.includes("play-web") && pathname.startsWith("/rtr/")): return "rtr"; - case hostname.includes("swissinfo.ch") || hostname.includes("srgplayer-swi") || (hostname.includes("play-mmf") && pathname.startsWith("/swi/")): + case hostname.includes("swissinfo.ch") || hostname.includes("srgplayer-swi") || (hostname.includes("play-mmf") && pathname.startsWith("/swi/")) || (hostname.includes("play-web") && pathname.startsWith("/swi/")): return "swi"; - case hostname.includes("srf.ch") || hostname.includes("srgplayer-srf") || (hostname.includes("play-mmf") && pathname.startsWith("/srf/")): + case hostname.includes("srf.ch") || hostname.includes("srgplayer-srf") || (hostname.includes("play-mmf") && pathname.startsWith("/srf/")) || (hostname.includes("play-web") && pathname.startsWith("/srf/")): return "srf"; case hostname.includes("play-mmf") && pathname.startsWith("/mmf/"): return "mmf"; diff --git a/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.latest_result.txt b/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.latest_result.txt index 5cb34f75d..a2571e7af 100755 --- a/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.latest_result.txt +++ b/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.latest_result.txt @@ -448,7 +448,7 @@ name: UrbanAirship-iOS-SDK, nameSpecified: body: Copyright 2017 Urban… version: 9.4.0 -name: appcenter-sdk-apple, nameSpecified: , owner: microsoft, version: 2.5.3 +name: appcenter-sdk-apple, nameSpecified: , owner: microsoft, version: 3.1.1 name: CoconutKit, nameSpecified: , owner: defagos, version: 3.4 @@ -466,19 +466,19 @@ name: Mantle, nameSpecified: , owner: Mantle, version: 2.1.0 name: Masonry, nameSpecified: , owner: SRGSSR, version: v1.1.0_srg1 -name: srganalytics-apple, nameSpecified: , owner: SRGSSR, version: 4.1.0 +name: srganalytics-apple, nameSpecified: , owner: SRGSSR, version: 4.1.1 -name: srgappearance-apple, nameSpecified: , owner: SRGSSR, version: 2.0.0 +name: srgappearance-apple, nameSpecified: , owner: SRGSSR, version: 2.1.0 name: srgcontentprotection-apple, nameSpecified: , owner: SRGSSR, version: 2.0.1 -name: srgdataprovider-apple, nameSpecified: , owner: SRGSSR, version: 7.0.1 +name: srgdataprovider-apple, nameSpecified: , owner: SRGSSR, version: 7.1.0 name: srgdiagnostics-apple, nameSpecified: , owner: SRGSSR, version: 2.0.1 -name: srgidentity-apple, nameSpecified: , owner: SRGSSR, version: 2.0.1 +name: srgidentity-apple, nameSpecified: , owner: SRGSSR, version: 2.0.2 -name: srgletterbox-apple, nameSpecified: , owner: SRGSSR, version: 3.0.1 +name: srgletterbox-apple, nameSpecified: , owner: SRGSSR, version: 4.0.0 name: srglogger-apple, nameSpecified: , owner: SRGSSR, version: 2.0.0 @@ -486,7 +486,7 @@ name: srgmediaplayer-apple, nameSpecified: , owner: SRGSSR, version: 4.0.0 name: srgnetwork-apple, nameSpecified: , owner: SRGSSR, version: 2.0.1 -name: srguserdata-apple, nameSpecified: , owner: SRGSSR, version: 2.0.1 +name: srguserdata-apple, nameSpecified: , owner: SRGSSR, version: 2.0.2 name: tagcommander-apple, nameSpecified: , owner: SRGSSR, version: 4.5.4_4.4.1_srg3 diff --git a/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.plist b/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.plist index ea10e50fd..c5b3f9799 100755 --- a/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.plist +++ b/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.plist @@ -8,7 +8,7 @@ File com.mono0926.LicensePlist/appcenter-sdk-apple Title - appcenter-sdk-apple (2.5.3) + appcenter-sdk-apple (3.1.1) Type PSChildPaneSpecifier @@ -232,7 +232,7 @@ File com.mono0926.LicensePlist/srganalytics-apple Title - srganalytics-apple (4.1.0) + srganalytics-apple (4.1.1) Type PSChildPaneSpecifier @@ -240,7 +240,7 @@ File com.mono0926.LicensePlist/srgappearance-apple Title - srgappearance-apple (2.0.0) + srgappearance-apple (2.1.0) Type PSChildPaneSpecifier @@ -256,7 +256,7 @@ File com.mono0926.LicensePlist/srgdataprovider-apple Title - srgdataprovider-apple (7.0.1) + srgdataprovider-apple (7.1.0) Type PSChildPaneSpecifier @@ -272,7 +272,7 @@ File com.mono0926.LicensePlist/srgidentity-apple Title - srgidentity-apple (2.0.1) + srgidentity-apple (2.0.2) Type PSChildPaneSpecifier @@ -280,7 +280,7 @@ File com.mono0926.LicensePlist/srgletterbox-apple Title - srgletterbox-apple (3.0.1) + srgletterbox-apple (4.0.0) Type PSChildPaneSpecifier @@ -312,7 +312,7 @@ File com.mono0926.LicensePlist/srguserdata-apple Title - srguserdata-apple (2.0.1) + srguserdata-apple (2.0.2) Type PSChildPaneSpecifier diff --git a/Application/Sources/Application/PlayAppDelegate.m b/Application/Sources/Application/PlayAppDelegate.m index d8f9ffcfa..8d0692ef6 100755 --- a/Application/Sources/Application/PlayAppDelegate.m +++ b/Application/Sources/Application/PlayAppDelegate.m @@ -596,6 +596,9 @@ - (void)setupAppCenter return YES; }]; + + MSDistribute.updateTrack = MSUpdateTrackPrivate; + [MSAppCenter start:appCenterSecret withServices:@[ MSCrashes.class, MSDistribute.class ]]; } diff --git a/Application/Sources/Downloads/DownloadsViewController.m b/Application/Sources/Downloads/DownloadsViewController.m index cb49eb6ef..9fa67c5cb 100755 --- a/Application/Sources/Downloads/DownloadsViewController.m +++ b/Application/Sources/Downloads/DownloadsViewController.m @@ -15,6 +15,8 @@ #import "Layout.h" #import "NSBundle+PlaySRG.h" #import "PlayErrors.h" +#import "RefreshControl.h" +#import "TableView.h" #import "UIColor+PlaySRG.h" #import "UIViewController+PlaySRG.h" @@ -26,8 +28,8 @@ @interface DownloadsViewController () @property (nonatomic) NSArray *downloads; -@property (nonatomic, weak) UITableView *tableView; -@property (nonatomic, weak) UIRefreshControl *refreshControl; +@property (nonatomic, weak) TableView *tableView; +@property (nonatomic, weak) RefreshControl *refreshControl; @property (nonatomic) UIBarButtonItem *defaultLeftBarButtonItem; @@ -59,18 +61,14 @@ - (void)loadView UIView *view = [[UIView alloc] initWithFrame:UIScreen.mainScreen.bounds]; view.backgroundColor = UIColor.play_blackColor; - UITableView *tableView = [[UITableView alloc] initWithFrame:view.bounds]; - tableView.backgroundColor = UIColor.clearColor; - tableView.indicatorStyle = UIScrollViewIndicatorStyleWhite; - tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + TableView *tableView = [[TableView alloc] initWithFrame:view.bounds]; tableView.allowsSelectionDuringEditing = YES; tableView.allowsMultipleSelectionDuringEditing = YES; tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [view addSubview:tableView]; self.tableView = tableView; - UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; - refreshControl.tintColor = UIColor.whiteColor; + RefreshControl *refreshControl = [[RefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged]; [tableView insertSubview:refreshControl atIndex:0]; self.refreshControl = refreshControl; diff --git a/Application/Sources/Favorites/FavoritesViewController.m b/Application/Sources/Favorites/FavoritesViewController.m index 8cc43bbb1..e55572ac0 100755 --- a/Application/Sources/Favorites/FavoritesViewController.m +++ b/Application/Sources/Favorites/FavoritesViewController.m @@ -14,6 +14,8 @@ #import "FavoriteTableViewCell.h" #import "Favorites.h" #import "Layout.h" +#import "RefreshControl.h" +#import "TableView.h" #import "UIColor+PlaySRG.h" #import "UIImageView+PlaySRG.h" #import "UIViewController+PlaySRG.h" @@ -27,8 +29,8 @@ @interface FavoritesViewController () @property (nonatomic) NSArray *shows; -@property (nonatomic, weak) IBOutlet UITableView *tableView; -@property (nonatomic, weak) UIRefreshControl *refreshControl; +@property (nonatomic, weak) TableView *tableView; +@property (nonatomic, weak) RefreshControl *refreshControl; @property (nonatomic) UIImageView *loadingImageView; // strong @@ -55,18 +57,14 @@ - (void)loadView UIView *view = [[UIView alloc] initWithFrame:UIScreen.mainScreen.bounds]; view.backgroundColor = UIColor.play_blackColor; - UITableView *tableView = [[UITableView alloc] initWithFrame:view.bounds]; - tableView.backgroundColor = UIColor.clearColor; - tableView.indicatorStyle = UIScrollViewIndicatorStyleWhite; - tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + TableView *tableView = [[TableView alloc] initWithFrame:view.bounds]; tableView.allowsSelectionDuringEditing = YES; tableView.allowsMultipleSelectionDuringEditing = YES; tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [view addSubview:tableView]; self.tableView = tableView; - UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; - refreshControl.tintColor = UIColor.whiteColor; + RefreshControl *refreshControl = [[RefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged]; [tableView insertSubview:refreshControl atIndex:0]; self.refreshControl = refreshControl; diff --git a/Application/Sources/Helpers/Categories/SRGModule+PlaySRG.h b/Application/Sources/Helpers/Categories/SRGModule+PlaySRG.h index 08bf97d32..f7f0651e5 100755 --- a/Application/Sources/Helpers/Categories/SRGModule+PlaySRG.h +++ b/Application/Sources/Helpers/Categories/SRGModule+PlaySRG.h @@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN /** * The play background color to use for the module. */ -@property (nonatomic, readonly) UIColor *play_backgroundColor; +@property (nonatomic, readonly, nullable) UIColor *play_backgroundColor; @end diff --git a/Application/Sources/Helpers/Categories/SRGModule+PlaySRG.m b/Application/Sources/Helpers/Categories/SRGModule+PlaySRG.m index 5c86329f0..f1789fd9e 100755 --- a/Application/Sources/Helpers/Categories/SRGModule+PlaySRG.m +++ b/Application/Sources/Helpers/Categories/SRGModule+PlaySRG.m @@ -16,9 +16,9 @@ - (UIColor *)play_backgroundColor { UIColor *backgroundColor = self.backgroundColor; - // TODO: Remove when Play apps and web portal will use the same black background color - if ([backgroundColor isEqual:[UIColor srg_colorFromHexadecimalString:@"#1A1A1A"]]) { - backgroundColor = UIColor.play_blackColor; + // TODO: Remove #1A1A1A" test when Play apps and web portal will use the same black background color + if ([backgroundColor isEqual:[UIColor srg_colorFromHexadecimalString:@"#1A1A1A"]] || [backgroundColor isEqual:UIColor.play_blackColor]) { + backgroundColor = nil; } return [backgroundColor colorWithAlphaComponent:.3f]; diff --git a/Application/Sources/Helpers/Layout.h b/Application/Sources/Helpers/Layout.h index 69357e629..43e24775b 100644 --- a/Application/Sources/Helpers/Layout.h +++ b/Application/Sources/Helpers/Layout.h @@ -21,14 +21,14 @@ static const CGFloat LayoutCollectionViewCellStandardWidth = 210.f; static const CGFloat LayoutTableViewCellStandardHeight = 84.f; /** - * Standard table view padding. + * Standard margin. */ -static const UIEdgeInsets LayoutStandardTableViewPaddingInsets = { 10.f, 0.f, 5.f, 0.f }; +static const CGFloat LayoutStandardMargin = 10.f; /** - * Standard margin. + * Standard table view padding. */ -static const CGFloat LayoutStandardMargin = 10.f; +static const UIEdgeInsets LayoutStandardTableViewPaddingInsets = { LayoutStandardMargin, 0.f, 0.f, 0.f }; /** * Calculate the width to apply to items within a collection so that they approach some desired size, ensuring constant diff --git a/Application/Sources/Helpers/Layout.m b/Application/Sources/Helpers/Layout.m index 94ffd7631..668673111 100644 --- a/Application/Sources/Helpers/Layout.m +++ b/Application/Sources/Helpers/Layout.m @@ -39,15 +39,15 @@ CGFloat LayoutStandardTableSectionHeaderHeight(BOOL hasBackgroundColor) s_headerHeights = @{ UIContentSizeCategoryExtraSmall : @25, UIContentSizeCategorySmall : @30, UIContentSizeCategoryMedium : @35, - UIContentSizeCategoryLarge : @40, - UIContentSizeCategoryExtraLarge : @40, - UIContentSizeCategoryExtraExtraLarge : @40, - UIContentSizeCategoryExtraExtraExtraLarge : @45, - UIContentSizeCategoryAccessibilityMedium : @45, - UIContentSizeCategoryAccessibilityLarge : @45, - UIContentSizeCategoryAccessibilityExtraLarge : @45, - UIContentSizeCategoryAccessibilityExtraExtraLarge : @45, - UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @45 }; + UIContentSizeCategoryLarge : @35, + UIContentSizeCategoryExtraLarge : @35, + UIContentSizeCategoryExtraExtraLarge : @35, + UIContentSizeCategoryExtraExtraExtraLarge : @40, + UIContentSizeCategoryAccessibilityMedium : @40, + UIContentSizeCategoryAccessibilityLarge : @40, + UIContentSizeCategoryAccessibilityExtraLarge : @40, + UIContentSizeCategoryAccessibilityExtraExtraLarge : @40, + UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @40 }; }); NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; diff --git a/Application/Sources/History/HistoryViewController.m b/Application/Sources/History/HistoryViewController.m index cedcfef16..5022dbb7a 100755 --- a/Application/Sources/History/HistoryViewController.m +++ b/Application/Sources/History/HistoryViewController.m @@ -14,6 +14,7 @@ #import "NSBundle+PlaySRG.h" #import "PlayErrors.h" #import "PlayLogger.h" +#import "TableView.h" #import "UIColor+PlaySRG.h" #import "UIViewController+PlaySRG.h" @@ -45,10 +46,7 @@ - (void)loadView UIView *view = [[UIView alloc] initWithFrame:UIScreen.mainScreen.bounds]; view.backgroundColor = UIColor.play_blackColor; - UITableView *tableView = [[UITableView alloc] initWithFrame:view.bounds]; - tableView.backgroundColor = UIColor.clearColor; - tableView.indicatorStyle = UIScrollViewIndicatorStyleWhite; - tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + TableView *tableView = [[TableView alloc] initWithFrame:view.bounds]; tableView.allowsSelectionDuringEditing = YES; tableView.allowsMultipleSelectionDuringEditing = YES; tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; diff --git a/Application/Sources/Home/HomeMediaCollectionHeaderView.m b/Application/Sources/Home/HomeMediaCollectionHeaderView.m index d85461a69..996d57918 100755 --- a/Application/Sources/Home/HomeMediaCollectionHeaderView.m +++ b/Application/Sources/Home/HomeMediaCollectionHeaderView.m @@ -149,11 +149,12 @@ - (void)reloadData self.headerView.hidden = NO; self.placeholderView.hidden = YES; + id object = self.homeSectionInfo.module ?: self.homeSectionInfo.topic; + self.titleLabel.font = [UIFont srg_mediumFontWithTextStyle:self.featured ? SRGAppearanceFontTextStyleTitle : SRGAppearanceFontTextStyleBody]; - self.titleLabel.text = NSLocalizedString(@"All content", @"Title of the first cell of a media list on homepage."); + self.titleLabel.text = object.lead ?: NSLocalizedString(@"All content", @"Title of the first cell of a media list on homepage."); ImageScale imageScale = self.featured ? ImageScaleMedium : ImageScaleSmall; - id object = self.homeSectionInfo.module ?: self.homeSectionInfo.topic; [self.thumbnailImageView play_requestImageForObject:object withScale:imageScale type:SRGImageTypeDefault placeholder:ImagePlaceholderMediaList]; } diff --git a/Application/Sources/Home/HomeMediaListTableViewCell.m b/Application/Sources/Home/HomeMediaListTableViewCell.m index f5853e562..1fd1bb70d 100755 --- a/Application/Sources/Home/HomeMediaListTableViewCell.m +++ b/Application/Sources/Home/HomeMediaListTableViewCell.m @@ -126,19 +126,18 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr #pragma mark Overrides -- (void)prepareForReuse +- (void)layoutSubviews { - [super prepareForReuse]; + [super layoutSubviews]; - // Clear the collection - [self.collectionView reloadData]; + [self.collectionView.collectionViewLayout invalidateLayout]; } -- (void)layoutSubviews +- (void)reloadData { - [super layoutSubviews]; + [super reloadData]; - [self.collectionView.collectionViewLayout invalidateLayout]; + [self.collectionView reloadData]; } #pragma mark Getters and setters @@ -149,8 +148,6 @@ - (void)setHomeSectionInfo:(HomeSectionInfo *)homeSectionInfo featured:(BOOL)fea self.moduleBackgroundView.backgroundColor = homeSectionInfo.module.play_backgroundColor; - [self.collectionView reloadData]; - dispatch_async(dispatch_get_main_queue(), ^{ if (homeSectionInfo) { // Restore position in rows when scrolling vertically and returning to a previously scrolled row @@ -256,11 +253,7 @@ - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UIColl - (void)scrollViewDidScroll:(UIScrollView *)scrollView { - // Delay content offset recording so that we don't record a content offset before restoring a content offset - // (which also is made with a slight delay) - dispatch_async(dispatch_get_main_queue(), ^{ - self.homeSectionInfo.contentOffset = scrollView.contentOffset; - }); + self.homeSectionInfo.contentOffset = scrollView.contentOffset; } @end diff --git a/Application/Sources/Home/HomeShowListTableViewCell.m b/Application/Sources/Home/HomeShowListTableViewCell.m index bb2b6f0e6..641d7b7f5 100755 --- a/Application/Sources/Home/HomeShowListTableViewCell.m +++ b/Application/Sources/Home/HomeShowListTableViewCell.m @@ -9,6 +9,7 @@ #import "HomeShowCollectionViewCell.h" #import "Layout.h" #import "ShowViewController.h" +#import "UICollectionView+PlaySRG.h" #import #import @@ -91,19 +92,18 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr #pragma mark Overrides -- (void)prepareForReuse +- (void)layoutSubviews { - [super prepareForReuse]; + [super layoutSubviews]; - // Clear the collection - [self.collectionView reloadData]; + [self.collectionView.collectionViewLayout invalidateLayout]; } -- (void)layoutSubviews +- (void)reloadData { - [super layoutSubviews]; + [super reloadData]; - [self.collectionView.collectionViewLayout invalidateLayout]; + [self.collectionView reloadData]; } #pragma mark Getters and setters @@ -112,7 +112,16 @@ - (void)setHomeSectionInfo:(HomeSectionInfo *)homeSectionInfo featured:(BOOL)fea { [super setHomeSectionInfo:homeSectionInfo featured:featured]; - [self.collectionView reloadData]; + dispatch_async(dispatch_get_main_queue(), ^{ + if (homeSectionInfo) { + // Restore position in rows when scrolling vertically and returning to a previously scrolled row + CGPoint maxContentOffset = self.collectionView.play_maximumContentOffset; + CGPoint contentOffset = CGPointMake(fmaxf(fminf(homeSectionInfo.contentOffset.x, maxContentOffset.x), 0.f), + homeSectionInfo.contentOffset.y); + [self.collectionView setContentOffset:contentOffset animated:NO]; + } + self.collectionView.scrollEnabled = (homeSectionInfo.items.count != 0); + }); } #pragma mark UICollectionViewDataSource protocol @@ -168,11 +177,7 @@ - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UIColl - (void)scrollViewDidScroll:(UIScrollView *)scrollView { - // Delay content offset recording so that we don't record a content offset before restoring a content offset - // (which also is made with a slight delay) - dispatch_async(dispatch_get_main_queue(), ^{ - self.homeSectionInfo.contentOffset = scrollView.contentOffset; - }); + self.homeSectionInfo.contentOffset = scrollView.contentOffset; } @end diff --git a/Application/Sources/Home/HomeShowVerticalListTableViewCell.m b/Application/Sources/Home/HomeShowVerticalListTableViewCell.m index 4b3cf00fb..ae259426c 100755 --- a/Application/Sources/Home/HomeShowVerticalListTableViewCell.m +++ b/Application/Sources/Home/HomeShowVerticalListTableViewCell.m @@ -80,6 +80,8 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr return self; } +#pragma mark Overrides + - (void)layoutSubviews { [super layoutSubviews]; @@ -87,11 +89,9 @@ - (void)layoutSubviews [self.collectionView.collectionViewLayout invalidateLayout]; } -#pragma mark Getters and setters - -- (void)setHomeSectionInfo:(HomeSectionInfo *)homeSectionInfo featured:(BOOL)featured +- (void)reloadData { - [super setHomeSectionInfo:homeSectionInfo featured:featured]; + [super reloadData]; [self.collectionView reloadData]; } diff --git a/Application/Sources/Home/HomeShowsAccessTableViewCell.m b/Application/Sources/Home/HomeShowsAccessTableViewCell.m index cc6e36fb8..847253f0f 100755 --- a/Application/Sources/Home/HomeShowsAccessTableViewCell.m +++ b/Application/Sources/Home/HomeShowsAccessTableViewCell.m @@ -72,8 +72,23 @@ - (void)awakeFromNib self.showsByDateButton.layer.masksToBounds = YES; [self.showsByDateButton setTitle:NSLocalizedString(@"By date", @"Short title displayed in home page shows section.") forState:UIControlStateNormal]; self.showsByDateButton.accessibilityLabel = PlaySRGAccessibilityLocalizedString(@"Programmes by date", @"Title displayed in home page shows section."); +} + +- (void)reloadData +{ + [super reloadData]; + + if (! self.dataAvailable) { + self.mainView.hidden = YES; + self.placeholderView.hidden = NO; + return; + } - [self reloadData]; + self.mainView.hidden = NO; + self.placeholderView.hidden = YES; + + self.showsAtoZButton.titleLabel.font = [UIFont srg_mediumFontWithTextStyle:SRGAppearanceFontTextStyleBody]; + self.showsByDateButton.titleLabel.font = [UIFont srg_mediumFontWithTextStyle:SRGAppearanceFontTextStyleBody]; } #pragma mark Accessibility @@ -88,15 +103,6 @@ - (NSArray *)accessibilityElements return self.dataAvailable ? @[self.showsAtoZButton, self.showsByDateButton] : nil; } -#pragma mark Getters and setters - -- (void)setHomeSectionInfo:(HomeSectionInfo *)homeSectionInfo featured:(BOOL)featured -{ - [super setHomeSectionInfo:homeSectionInfo featured:featured]; - - [self reloadData]; -} - #pragma mark UI - (BOOL)isDataAvailable @@ -109,21 +115,6 @@ - (BOOL)isDataAvailable } } -- (void)reloadData -{ - if (! self.dataAvailable) { - self.mainView.hidden = YES; - self.placeholderView.hidden = NO; - return; - } - - self.mainView.hidden = NO; - self.placeholderView.hidden = YES; - - self.showsAtoZButton.titleLabel.font = [UIFont srg_mediumFontWithTextStyle:SRGAppearanceFontTextStyleBody]; - self.showsByDateButton.titleLabel.font = [UIFont srg_mediumFontWithTextStyle:SRGAppearanceFontTextStyleBody]; -} - #pragma mark Actions - (IBAction)openShowsAZ:(id)sender diff --git a/Application/Sources/Home/HomeStatusHeaderView.m b/Application/Sources/Home/HomeStatusHeaderView.m index b0e167917..f50cfd656 100755 --- a/Application/Sources/Home/HomeStatusHeaderView.m +++ b/Application/Sources/Home/HomeStatusHeaderView.m @@ -18,6 +18,10 @@ @interface HomeStatusHeaderView () @property (nonatomic, weak) IBOutlet UIView *backgroundView; @property (nonatomic, weak) IBOutlet UILabel *messageLabel; +@property (nonatomic, weak) IBOutlet NSLayoutConstraint *backgroundViewLeadingLayoutConstraint; +@property (nonatomic, weak) IBOutlet NSLayoutConstraint *backgroundViewTrailingLayoutConstraint; +@property (nonatomic, weak) IBOutlet NSLayoutConstraint *backgroundViewBottomLayoutConstraint; + @end @implementation HomeStatusHeaderView @@ -54,6 +58,10 @@ - (void)awakeFromNib self.backgroundView.backgroundColor = UIColor.play_redColor; self.backgroundView.layer.cornerRadius = LayoutStandardViewCornerRadius; + + self.backgroundViewLeadingLayoutConstraint.constant = LayoutStandardMargin; + self.backgroundViewTrailingLayoutConstraint.constant = LayoutStandardMargin; + self.backgroundViewBottomLayoutConstraint.constant = LayoutStandardMargin; } #pragma mark Getters and setters diff --git a/Application/Sources/Home/HomeStatusHeaderView.xib b/Application/Sources/Home/HomeStatusHeaderView.xib index 386341956..eca4f6b74 100755 --- a/Application/Sources/Home/HomeStatusHeaderView.xib +++ b/Application/Sources/Home/HomeStatusHeaderView.xib @@ -1,31 +1,29 @@ - - - - + + - + - + - + - + @@ -47,16 +45,19 @@ - + - + + + + - + diff --git a/Application/Sources/Home/HomeTableViewCell.h b/Application/Sources/Home/HomeTableViewCell.h index ba4e438d1..d0cf9b445 100755 --- a/Application/Sources/Home/HomeTableViewCell.h +++ b/Application/Sources/Home/HomeTableViewCell.h @@ -20,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)setHomeSectionInfo:(nullable HomeSectionInfo *)homeSectionInfo featured:(BOOL)featured; +- (void)reloadData NS_REQUIRES_SUPER; - (BOOL)isEmpty; @end diff --git a/Application/Sources/Home/HomeTableViewCell.m b/Application/Sources/Home/HomeTableViewCell.m index d21abb876..e1b4be909 100755 --- a/Application/Sources/Home/HomeTableViewCell.m +++ b/Application/Sources/Home/HomeTableViewCell.m @@ -31,10 +31,15 @@ - (void)prepareForReuse self.homeSectionInfo = nil; self.featured = NO; + + [self reloadData]; } #pragma mark Getters and setters +- (void)reloadData +{} + - (BOOL)isEmpty { return self.homeSectionInfo.items.count == 0; @@ -44,6 +49,7 @@ - (void)setHomeSectionInfo:(HomeSectionInfo *)homeSectionInfo featured:(BOOL)fea { self.featured = featured; self.homeSectionInfo = homeSectionInfo; + [self reloadData]; } @end diff --git a/Application/Sources/Home/HomeViewController.m b/Application/Sources/Home/HomeViewController.m index 169b5301d..3e2ea7003 100755 --- a/Application/Sources/Home/HomeViewController.m +++ b/Application/Sources/Home/HomeViewController.m @@ -22,7 +22,10 @@ #import "HomeStatusHeaderView.h" #import "NavigationController.h" #import "NSBundle+PlaySRG.h" +#import "RefreshControl.h" #import "ShowsViewController.h" +#import "SRGModule+PlaySRG.h" +#import "TableView.h" #import "UIColor+PlaySRG.h" #import "UIScrollView+PlaySRG.h" #import "UIViewController+PlaySRG.h" @@ -35,7 +38,6 @@ typedef NS_ENUM(NSInteger, HomeHeaderType) { HomeHeaderTypeNone, // No header - HomeHeaderTypeSpace, // A space, no header view HomeHeaderTypeView // A header with underlying view }; @@ -52,8 +54,8 @@ @interface HomeViewController () @property (nonatomic) NSError *lastRequestError; -@property (nonatomic, weak) UIRefreshControl *refreshControl; -@property (nonatomic, weak) IBOutlet UITableView *tableView; +@property (nonatomic, weak) RefreshControl *refreshControl; +@property (nonatomic, weak) TableView *tableView; @property (nonatomic, getter=isTopicsLoaded) BOOL topicsLoaded; @property (nonatomic, getter=isEventsLoaded) BOOL eventsLoaded; @@ -89,16 +91,12 @@ - (void)loadView UIView *view = [[UIView alloc] initWithFrame:UIScreen.mainScreen.bounds]; view.backgroundColor = UIColor.play_blackColor; - UITableView *tableView = [[UITableView alloc] initWithFrame:view.bounds style:UITableViewStyleGrouped]; - tableView.backgroundColor = UIColor.clearColor; - tableView.indicatorStyle = UIScrollViewIndicatorStyleWhite; - tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + TableView *tableView = [[TableView alloc] initWithFrame:view.bounds style:UITableViewStyleGrouped]; tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [view addSubview:tableView]; self.tableView = tableView; - UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; - refreshControl.tintColor = UIColor.whiteColor; + RefreshControl *refreshControl = [[RefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged]; [tableView insertSubview:refreshControl atIndex:0]; self.refreshControl = refreshControl; @@ -320,10 +318,10 @@ - (void)refreshHomeSection:(HomeSection)homeSection withRequestQueue:(SRGRequest NSArray *homeSectionInfos = [self.homeSectionInfos filteredArrayUsingPredicate:predicate]; for (HomeSectionInfo *homeSectionInfo in homeSectionInfos) { [homeSectionInfo refreshWithRequestQueue:requestQueue page:nil /* only the first page */ completionBlock:^(NSArray * _Nullable items, SRGPage * _Nonnull page, SRGPage * _Nullable nextPage, NSHTTPURLResponse * _Nullable HTTPResponse, NSError * _Nullable error) { - // Refresh as data becomes available for better perceived loading times - if (! error) { - [self.tableView reloadData]; - } + NSUInteger index = [self.homeSectionInfos indexOfObject:homeSectionInfo]; + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:index]; + HomeTableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; + [cell reloadData]; }]; } } @@ -407,7 +405,7 @@ - (HomeHeaderType)headerTypeForHomeSectionInfo:(HomeSectionInfo *)homeSectionInf BOOL isRadioChannel = ([applicationConfiguration radioChannelForUid:homeSectionInfo.identifier] != nil); BOOL isFeaturedHeaderHidden = isRadioChannel ? applicationConfiguration.radioFeaturedHomeSectionHeaderHidden : applicationConfiguration.tvFeaturedHomeSectionHeaderHidden; if (! UIAccessibilityIsVoiceOverRunning() && isFeaturedHeaderHidden) { - return HomeHeaderTypeSpace; + return HomeHeaderTypeNone; } else { return HomeHeaderTypeView; @@ -428,7 +426,7 @@ - (HomeHeaderType)headerTypeForHomeSectionInfo:(HomeSectionInfo *)homeSectionInf - (UIEdgeInsets)play_paddingContentInsets { - return UIEdgeInsetsZero; + return LayoutStandardTableViewPaddingInsets; } #pragma mark DZNEmptyDataSetSource protocol @@ -596,15 +594,9 @@ - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSIntege } HomeHeaderType headerType = [self headerTypeForHomeSectionInfo:homeSectionInfo tableView:tableView inSection:section]; - switch (headerType) { - case HomeHeaderTypeSpace: { - return LayoutStandardMargin; - break; - } - + switch (headerType) { case HomeHeaderTypeView: { - BOOL hasBackgroundColor = (homeSectionInfo.module && ! [homeSectionInfo.module.backgroundColor isEqual:UIColor.play_blackColor]); - return LayoutStandardTableSectionHeaderHeight(hasBackgroundColor); + return LayoutStandardTableSectionHeaderHeight(homeSectionInfo.module.play_backgroundColor != nil); break; } diff --git a/Application/Sources/Notifications/NotificationsViewController.m b/Application/Sources/Notifications/NotificationsViewController.m index 5a9ee1715..ecbb725e9 100755 --- a/Application/Sources/Notifications/NotificationsViewController.m +++ b/Application/Sources/Notifications/NotificationsViewController.m @@ -15,7 +15,9 @@ #import "Notification.h" #import "PlayErrors.h" #import "PushService.h" +#import "RefreshControl.h" #import "ShowViewController.h" +#import "TableView.h" #import "UIColor+PlaySRG.h" #import "UIViewController+PlaySRG.h" @@ -25,8 +27,8 @@ @interface NotificationsViewController () @property (nonatomic) NSArray *notifications; -@property (nonatomic, weak) IBOutlet UITableView *tableView; -@property (nonatomic, weak) UIRefreshControl *refreshControl; +@property (nonatomic, weak) TableView *tableView; +@property (nonatomic, weak) RefreshControl *refreshControl; @end @@ -104,18 +106,14 @@ - (void)loadView UIView *view = [[UIView alloc] initWithFrame:UIScreen.mainScreen.bounds]; view.backgroundColor = UIColor.play_blackColor; - UITableView *tableView = [[UITableView alloc] initWithFrame:view.bounds]; - tableView.backgroundColor = UIColor.clearColor; - tableView.indicatorStyle = UIScrollViewIndicatorStyleWhite; - tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + TableView *tableView = [[TableView alloc] initWithFrame:view.bounds]; tableView.allowsSelectionDuringEditing = YES; tableView.allowsMultipleSelectionDuringEditing = YES; tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [view addSubview:tableView]; self.tableView = tableView; - UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; - refreshControl.tintColor = UIColor.whiteColor; + RefreshControl *refreshControl = [[RefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged]; [tableView insertSubview:refreshControl atIndex:0]; self.refreshControl = refreshControl; diff --git a/Application/Sources/Player/MediaPlayerViewController.m b/Application/Sources/Player/MediaPlayerViewController.m index 05747c6d1..9854b6655 100755 --- a/Application/Sources/Player/MediaPlayerViewController.m +++ b/Application/Sources/Player/MediaPlayerViewController.m @@ -156,14 +156,16 @@ @interface MediaPlayerViewController () @property (nonatomic, weak) IBOutlet UILabel *relatedContentsTitleLabel; @property (nonatomic, weak) IBOutlet UIStackView *relatedContentsStackView; -// Switching to and from full-screen is made by adjusting the priority of a constraint at the bottom of the player view +// Switching to and from full-screen is made by adjusting the priority of constraints at the top and bottom of the player view +@property (nonatomic, weak) IBOutlet NSLayoutConstraint *playerTopConstraint; @property (nonatomic, weak) IBOutlet NSLayoutConstraint *playerBottomConstraint; // Showing details is made by disabling the following height constraint property @property (nonatomic, weak) IBOutlet NSLayoutConstraint *collapsedDetailsLabelsHeightConstraint; -// Displaying segments (if any) is achieved by adding a small offset to the player aspect ratio constraint -@property (nonatomic, weak) IBOutlet NSLayoutConstraint *playerAspectRatio16_9Constraint; +// The aspect ratio constant is used to display the player with the best possible aspect ratio, taking into account +// other frame changes into account (e.g. timeline display) +@property (nonatomic, weak) IBOutlet NSLayoutConstraint *playerAspectRatioStandardConstraint; @property (nonatomic, weak) IBOutlet NSLayoutConstraint *playerAspectRatioBigLandscapeScreenConstraint; @property (nonatomic, weak) IBOutlet UIGestureRecognizer *detailsGestureRecognizer; @@ -622,11 +624,11 @@ - (void)userActivityWillSave:(NSUserActivity *)userActivity - (void)synchronizeUserActivity:(NSUserActivity *)userActivity { - SRGMedia *mainMedia = [self.letterboxController.mediaComposition mediaForSubdivision:self.letterboxController.mediaComposition.mainChapter]; - if (mainMedia) { - userActivity.title = mainMedia.title; - if (mainMedia.endDate) { - userActivity.expirationDate = mainMedia.endDate; + SRGMedia *mainChapterMedia = [self mainChapterMedia]; + if (mainChapterMedia) { + userActivity.title = mainChapterMedia.title; + if (mainChapterMedia.endDate) { + userActivity.expirationDate = mainChapterMedia.endDate; } NSNumber *position = nil; @@ -640,12 +642,12 @@ - (void)synchronizeUserActivity:(NSUserActivity *)userActivity else { currentTime = kCMTimeZero; } - [userActivity addUserInfoEntriesFromDictionary:@{ @"URNString" : mainMedia.URN, - @"SRGMediaData" : [NSKeyedArchiver archivedDataWithRootObject:mainMedia], + [userActivity addUserInfoEntriesFromDictionary:@{ @"URNString" : mainChapterMedia.URN, + @"SRGMediaData" : [NSKeyedArchiver archivedDataWithRootObject:mainChapterMedia], @"position" : position ?: [NSNull null], @"applicationVersion" : [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"] }]; userActivity.requiredUserInfoKeys = [NSSet setWithArray:userActivity.userInfo.allKeys]; - userActivity.webpageURL = [ApplicationConfiguration.sharedApplicationConfiguration sharingURLForMediaMetadata:mainMedia atTime:currentTime]; + userActivity.webpageURL = [ApplicationConfiguration.sharedApplicationConfiguration sharingURLForMediaMetadata:mainChapterMedia atTime:currentTime]; } else { [userActivity resignCurrent]; @@ -713,7 +715,8 @@ - (void)reloadDetailsWithMedia:(SRGMedia *)media mainChapterMedia:(SRGMedia *)ma [self.availabilityLabel play_displayAvailabilityLabelForMediaMetadata:mainChapterMedia]; // Livestream: Display channel information when available - if (media.contentType == SRGContentTypeLivestream) { + SRGMedia *mainMedia = mainChapterMedia ?: media; + if (mainMedia.contentType == SRGContentTypeLivestream) { [self.mediaInfoStackView play_setHidden:YES]; SRGLetterboxController *letterboxController = self.letterboxController; @@ -929,7 +932,10 @@ - (void)setUserInterfaceBehaviorForMedia:(SRGMedia *)media animated:(BOOL)animat - (void)setFullScreen:(BOOL)fullScreen { self.pullDownGestureRecognizer.enabled = ! fullScreen; - self.playerBottomConstraint.priority = fullScreen ? MediaPlayerBottomConstraintFullScreenPriority : MediaPlayerBottomConstraintNormalPriority; + + UILayoutPriority priority = fullScreen ? MediaPlayerBottomConstraintFullScreenPriority : MediaPlayerBottomConstraintNormalPriority; + self.playerTopConstraint.priority = priority; + self.playerBottomConstraint.priority = priority; [self setNeedsStatusBarAppearanceUpdate]; } @@ -982,11 +988,11 @@ - (void)updatePlayerViewAspectRatioWithSize:(CGSize)size if (self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassRegular && self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular && isLandscape) { - self.playerAspectRatio16_9Constraint.priority = MediaPlayerViewAspectRatioConstraintLowPriority; + self.playerAspectRatioStandardConstraint.priority = MediaPlayerViewAspectRatioConstraintLowPriority; self.playerAspectRatioBigLandscapeScreenConstraint.priority = MediaPlayerViewAspectRatioConstraintNormalPriority; } else { - self.playerAspectRatio16_9Constraint.priority = MediaPlayerViewAspectRatioConstraintNormalPriority; + self.playerAspectRatioStandardConstraint.priority = MediaPlayerViewAspectRatioConstraintNormalPriority; self.playerAspectRatioBigLandscapeScreenConstraint.priority = MediaPlayerViewAspectRatioConstraintLowPriority; } } @@ -1037,6 +1043,16 @@ - (SRGMedia *)mainChapterMedia return nil; } +- (SRGMedia *)mainMedia +{ + if (self.letterboxController.mediaComposition) { + return [self.letterboxController.mediaComposition mediaForSubdivision:self.letterboxController.mediaComposition.mainChapter]; + } + else { + return self.letterboxController.media; + } +} + - (SRGShow *)mainShow { SRGMedia *mainChapterMedia = [self mainChapterMedia]; @@ -1171,13 +1187,13 @@ - (void)updateGoogleCastButton - (BOOL)isLivestreamButtonHidden { - SRGMedia *media = self.letterboxController.media; + SRGMedia *media = [self mainMedia]; return ! media || ! [self.livestreamMedias containsObject:media] || self.livestreamMedias.count < 2; } - (void)updateLivestreamButton { - SRGMedia *media = self.letterboxController.media; + SRGMedia *media = [self mainMedia]; if (! media || media.contentType != SRGContentTypeLivestream || media.channel.transmission != SRGTransmissionRadio) { self.livestreamMedias = nil; @@ -1251,10 +1267,24 @@ - (BOOL)srg_isOpenedFromPushNotification - (void)letterboxViewWillAnimateUserInterface:(SRGLetterboxView *)letterboxView { [self.view layoutIfNeeded]; - [letterboxView animateAlongsideUserInterfaceWithAnimations:^(BOOL hidden, BOOL minimal, CGFloat timelineHeight) { + [letterboxView animateAlongsideUserInterfaceWithAnimations:^(BOOL hidden, BOOL minimal, CGFloat aspectRatio, CGFloat heightOffset) { self.topBarView.alpha = (minimal || ! hidden) ? 1.f : 0.f; - self.playerAspectRatio16_9Constraint.constant = timelineHeight; - self.playerAspectRatioBigLandscapeScreenConstraint.constant = timelineHeight; + + // Calculate the minimum possible aspect ratio so that only a fraction of the vertical height is occupied by the player at most. + // Use it as limit value if needed + static CGFloat kVerticalFillRatio = 0.6f; + CGFloat minAspectRatio = CGRectGetWidth(self.view.frame) / (kVerticalFillRatio * CGRectGetHeight(self.view.frame)); + CGFloat multiplier = 1.f / fmaxf(aspectRatio, minAspectRatio); + + if (@available(iOS 10, *)) { + self.playerAspectRatioStandardConstraint = [self.playerAspectRatioStandardConstraint srg_replacementConstraintWithMultiplier:multiplier constant:heightOffset]; + self.playerAspectRatioBigLandscapeScreenConstraint = [self.playerAspectRatioBigLandscapeScreenConstraint srg_replacementConstraintWithMultiplier:multiplier constant:heightOffset]; + } + else { + self.playerAspectRatioStandardConstraint.constant = heightOffset; + self.playerAspectRatioBigLandscapeScreenConstraint.constant = heightOffset; + } + [self.view layoutIfNeeded]; } completion:^(BOOL finished) { [self play_setNeedsUpdateOfHomeIndicatorAutoHidden]; @@ -1262,20 +1292,27 @@ - (void)letterboxViewWillAnimateUserInterface:(SRGLetterboxView *)letterboxView } - (void)letterboxView:(SRGLetterboxView *)letterboxView toggleFullScreen:(BOOL)fullScreen animated:(BOOL)animated withCompletionHandler:(nonnull void (^)(BOOL))completionHandler -{ - // On iPhones, full-screen transitions are always trigerred by rotation. Even when tapping on the full-screen button, - // we force a rotation, which itself will perform the appropriate transition from or to full-screen - if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone && ! self.transitioning) { +{ + void (^rotate)(UIDeviceOrientation) = ^(UIDeviceOrientation orientation) { // We interrupt the rotation attempt and trigger a rotation (which itself will toggle the expected full-screen display) completionHandler(NO); - + [UIDevice.currentDevice setValue:@(orientation) forKey:@keypath(UIDevice.new, orientation)]; + }; + + // On iPhones, full-screen transitions can be triggered by rotation. In such cases, when tapping on the full-screen button, + // we force a rotation, which itself will perform the appropriate transition from or to full-screen + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone && ! self.transitioning) { if (UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation)) { - [UIDevice.currentDevice setValue:@(UIInterfaceOrientationPortrait) forKey:@keypath(UIDevice.new, orientation)]; + rotate(UIDeviceOrientationPortrait); + return; } else { - [UIDevice.currentDevice setValue:@(s_previouslyUsedLandscapeDeviceOrientation) forKey:@keypath(UIDevice.new, orientation)]; + // Only force rotation from portrait to landscape orientation if the content is better watched in landscape orientation + if (letterboxView.aspectRatio > 1.f) { + rotate(s_previouslyUsedLandscapeDeviceOrientation); + return; + } } - return; } self.statusBarHidden = fullScreen; @@ -1834,22 +1871,23 @@ - (void)mediaMetadataDidChange:(NSNotification *)notification - (void)playbackStateDidChange:(NSNotification *)notification { - if (self.letterboxController.media.mediaType == SRGMediaTypeAudio && [notification.userInfo[SRGMediaPlayerPlaybackStateKey] integerValue] == SRGMediaPlayerPlaybackStatePlaying) { + SRGMediaType mediaType = self.letterboxController.media.mediaType; + SRGMediaPlayerPlaybackState playbackState = [notification.userInfo[SRGMediaPlayerPlaybackStateKey] integerValue]; + + if (mediaType == SRGMediaTypeAudio && playbackState == SRGMediaPlayerPlaybackStatePlaying) { self.closeButton.accessibilityHint = PlaySRGAccessibilityLocalizedString(@"Closes the player and continue playing audio.", @"Player close button hint"); } - if (self.letterboxController.media.mediaType == SRGMediaTypeVideo && AVAudioSession.srg_isAirPlayActive && [notification.userInfo[SRGMediaPlayerPlaybackStateKey] integerValue] == SRGMediaPlayerPlaybackStatePlaying) { + else if (mediaType == SRGMediaTypeVideo && AVAudioSession.srg_isAirPlayActive && playbackState == SRGMediaPlayerPlaybackStatePlaying) { self.closeButton.accessibilityHint = PlaySRGAccessibilityLocalizedString(@"Closes the player and continue playing video with AirPlay.", @"Player close button hint"); } - if (self.letterboxController.media.mediaType == SRGMediaTypeVideo && ApplicationSettingBackgroundVideoPlaybackEnabled() && [notification.userInfo[SRGMediaPlayerPlaybackStateKey] integerValue] == SRGMediaPlayerPlaybackStatePlaying) { + else if (mediaType == SRGMediaTypeVideo && ApplicationSettingBackgroundVideoPlaybackEnabled() && playbackState == SRGMediaPlayerPlaybackStatePlaying) { self.closeButton.accessibilityHint = PlaySRGAccessibilityLocalizedString(@"Closes the player and continue playing in the background.", @"Player close button hint"); } else { self.closeButton.accessibilityHint = nil; } - if ([notification.userInfo[SRGMediaPlayerPlaybackStateKey] integerValue] == SRGMediaPlayerPlaybackStatePreparing) { - [self reloadDataOverriddenWithMedia:nil mainChapterMedia:nil]; - } + [self reloadDataOverriddenWithMedia:nil mainChapterMedia:nil]; } - (void)playbackDidFail:(NSNotification *)notification diff --git a/Application/Sources/Player/MediaPlayerViewController.storyboard b/Application/Sources/Player/MediaPlayerViewController.storyboard index 47509ddd7..78954a4ca 100755 --- a/Application/Sources/Player/MediaPlayerViewController.storyboard +++ b/Application/Sources/Player/MediaPlayerViewController.storyboard @@ -509,7 +509,8 @@ - + + @@ -551,9 +552,10 @@ - + + diff --git a/Application/Sources/Player/MediaPreviewViewController.h b/Application/Sources/Player/MediaPreviewViewController.h index bc5dd16dd..94958a0f4 100755 --- a/Application/Sources/Player/MediaPreviewViewController.h +++ b/Application/Sources/Player/MediaPreviewViewController.h @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface MediaPreviewViewController : HLSViewController +@interface MediaPreviewViewController : HLSViewController - (instancetype)initWithMedia:(SRGMedia *)media; diff --git a/Application/Sources/Player/MediaPreviewViewController.m b/Application/Sources/Player/MediaPreviewViewController.m index 2c2c26f7b..4a5435989 100755 --- a/Application/Sources/Player/MediaPreviewViewController.m +++ b/Application/Sources/Player/MediaPreviewViewController.m @@ -51,6 +51,8 @@ @interface MediaPreviewViewController () @property (nonatomic, weak) IBOutlet UILabel *programTimeLabel; @property (nonatomic, weak) IBOutlet UILabel *channelLabel; +@property (nonatomic, weak) IBOutlet NSLayoutConstraint *playerAspectRatioConstraint; + @property (nonatomic) BOOL shouldRestoreServicePlayback; @property (nonatomic, copy) NSString *previousAudioSessionCategory; @@ -353,6 +355,22 @@ - (NSString *)srg_pageViewTitle return @[ AnalyticsPageLevelPlay, AnalyticsPageLevelPreview ]; } +#pragma mark SRGLetterboxViewDelegate protocol + +- (void)letterboxViewWillAnimateUserInterface:(SRGLetterboxView *)letterboxView +{ + [self.view layoutIfNeeded]; + [letterboxView animateAlongsideUserInterfaceWithAnimations:^(BOOL hidden, BOOL minimal, CGFloat aspecRatio, CGFloat heightOffset) { + if (@available(iOS 10, *)) { + self.playerAspectRatioConstraint = [self.playerAspectRatioConstraint srg_replacementConstraintWithMultiplier:fminf(1.f / aspecRatio, 1.f) constant:heightOffset]; + } + else { + self.playerAspectRatioConstraint.constant = heightOffset; + } + [self.view layoutIfNeeded]; + } completion:nil]; +} + #pragma mark Notifications - (void)mediaMetadataDidChange:(NSNotification *)notification diff --git a/Application/Sources/Player/MediaPreviewViewController.storyboard b/Application/Sources/Player/MediaPreviewViewController.storyboard index ab96b7f22..040c5e657 100755 --- a/Application/Sources/Player/MediaPreviewViewController.storyboard +++ b/Application/Sources/Player/MediaPreviewViewController.storyboard @@ -7,7 +7,7 @@ - + @@ -23,10 +23,11 @@ - + + @@ -122,6 +123,7 @@ + diff --git a/Application/Sources/Search/SearchLoadingCollectionViewCell.m b/Application/Sources/Search/SearchLoadingCollectionViewCell.m index 2f8ecd700..b2bcf4d0f 100755 --- a/Application/Sources/Search/SearchLoadingCollectionViewCell.m +++ b/Application/Sources/Search/SearchLoadingCollectionViewCell.m @@ -20,6 +20,13 @@ @implementation SearchLoadingCollectionViewCell #pragma mark Overrides +- (void)awakeFromNib +{ + [super awakeFromNib]; + + self.backgroundColor = UIColor.clearColor; +} + - (void)prepareForReuse { [super prepareForReuse]; diff --git a/Application/Sources/Settings/SettingsBaseViewController.m b/Application/Sources/Settings/SettingsBaseViewController.m index a2df3d426..3abbdba3e 100755 --- a/Application/Sources/Settings/SettingsBaseViewController.m +++ b/Application/Sources/Settings/SettingsBaseViewController.m @@ -22,6 +22,10 @@ - (void)viewDidLoad { [super viewDidLoad]; + self.tableView.estimatedRowHeight = 0.f; + self.tableView.estimatedSectionHeaderHeight = 0.f; + self.tableView.estimatedSectionFooterHeight = 0.f; + self.view.backgroundColor = UIColor.play_blackColor; self.tableView.separatorColor = UIColor.play_grayColor; diff --git a/Application/Sources/Settings/SettingsViewController.m b/Application/Sources/Settings/SettingsViewController.m index f77b3bc50..62b41773f 100755 --- a/Application/Sources/Settings/SettingsViewController.m +++ b/Application/Sources/Settings/SettingsViewController.m @@ -72,16 +72,6 @@ static NSString * const SettingsDeveloperGroup = @"Group_Developer"; static NSString * const SettingsFLEXButton = @"Button_FLEX"; -/** - * Private App Center implementation details. - */ -@interface MSDistribute (Private) - -+ (id)sharedInstance; -- (void)startUpdate; - -@end - @interface SettingsViewController () @property (nonatomic) SRGRequestQueue *requestQueue; @@ -355,7 +345,7 @@ - (void)settingsViewController:(IASKAppSettingsViewController *)sender buttonTap else if ([specifier.key isEqualToString:SettingsVersionsAndReleaseNotes]) { // Clear internal App Center timestamp to force a new update request [NSUserDefaults.standardUserDefaults removeObjectForKey:@"MSPostponedTimestamp"]; - [[MSDistribute sharedInstance] startUpdate]; + [MSDistribute checkForUpdate]; // Display version history NSString *appCenterURLString = [NSBundle.mainBundle.infoDictionary objectForKey:@"AppCenterURL"]; diff --git a/Application/Sources/UI/Controllers/CollectionRequestViewController.m b/Application/Sources/UI/Controllers/CollectionRequestViewController.m index ab998ee11..6c4c6b599 100755 --- a/Application/Sources/UI/Controllers/CollectionRequestViewController.m +++ b/Application/Sources/UI/Controllers/CollectionRequestViewController.m @@ -8,6 +8,7 @@ #import "Banner.h" #import "CollectionLoadMoreFooterView.h" +#import "RefreshControl.h" #import "UIColor+PlaySRG.h" #import "UIImageView+PlaySRG.h" #import "UIScrollView+PlaySRG.h" @@ -64,9 +65,7 @@ - (void)viewDidLoad UINib *footerNib = [UINib nibWithNibName:footerIdentifier bundle:nil]; [self.collectionView registerNib:footerNib forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:footerIdentifier]; - UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; - refreshControl.tintColor = UIColor.whiteColor; - refreshControl.layer.zPosition = -1.f; // Ensure the refresh control appears behind the cells, see http://stackoverflow.com/a/25829016/760435 + RefreshControl *refreshControl = [[RefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(collectionRequestViewController_refresh:) forControlEvents:UIControlEventValueChanged]; [self.collectionView insertSubview:refreshControl atIndex:0]; self.refreshControl = refreshControl; diff --git a/Application/Sources/UI/Controllers/TableRequestViewController.m b/Application/Sources/UI/Controllers/TableRequestViewController.m index 9c60ce491..a03a7b2fb 100755 --- a/Application/Sources/UI/Controllers/TableRequestViewController.m +++ b/Application/Sources/UI/Controllers/TableRequestViewController.m @@ -7,6 +7,7 @@ #import "TableRequestViewController.h" #import "Banner.h" +#import "RefreshControl.h" #import "TableLoadMoreFooterView.h" #import "UIColor+PlaySRG.h" #import "UIImageView+PlaySRG.h" @@ -18,7 +19,7 @@ @interface TableRequestViewController () @property (nonatomic) NSError *lastRequestError; -@property (nonatomic, weak) UIRefreshControl *refreshControl; +@property (nonatomic, weak) RefreshControl *refreshControl; @property (nonatomic) UIImageView *loadingImageView; // strong @@ -64,9 +65,7 @@ - (void)viewDidLoad UINib *footerNib = [UINib nibWithNibName:footerIdentifier bundle:nil]; [self.tableView registerNib:footerNib forHeaderFooterViewReuseIdentifier:footerIdentifier]; - UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; - refreshControl.tintColor = UIColor.whiteColor; - refreshControl.layer.zPosition = -1.f; // Ensure the refresh control appears behind the cells, see http://stackoverflow.com/a/25829016/760435 + RefreshControl *refreshControl = [[RefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(tableRequestViewController_refresh:) forControlEvents:UIControlEventValueChanged]; [self.tableView insertSubview:refreshControl atIndex:0]; self.refreshControl = refreshControl; diff --git a/Application/Sources/UI/Views/RefreshControl.h b/Application/Sources/UI/Views/RefreshControl.h new file mode 100644 index 000000000..8db7a588e --- /dev/null +++ b/Application/Sources/UI/Views/RefreshControl.h @@ -0,0 +1,18 @@ +// +// Copyright (c) SRG SSR. All rights reserved. +// +// License information is available from the LICENSE file. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Common Play design for the refresh control. + */ +@interface RefreshControl : UIRefreshControl + +@end + +NS_ASSUME_NONNULL_END diff --git a/Application/Sources/UI/Views/RefreshControl.m b/Application/Sources/UI/Views/RefreshControl.m new file mode 100644 index 000000000..8737511e3 --- /dev/null +++ b/Application/Sources/UI/Views/RefreshControl.m @@ -0,0 +1,23 @@ +// +// Copyright (c) SRG SSR. All rights reserved. +// +// License information is available from the LICENSE file. +// + +#import "RefreshControl.h" + +@implementation RefreshControl + +#pragma mark Object lifecycle + +- (instancetype)init +{ + if (self = [super init]) { + self.tintColor = UIColor.whiteColor; + self.layer.zPosition = -1.f; // Ensure the refresh control appears behind the cells, see http://stackoverflow.com/a/25829016/760435 + self.userInteractionEnabled = NO; // Avoid conflicts with table view cell interactions when using VoiceOver + } + return self; +} + +@end diff --git a/Application/Sources/UI/Views/TableView.h b/Application/Sources/UI/Views/TableView.h new file mode 100644 index 000000000..c019eb109 --- /dev/null +++ b/Application/Sources/UI/Views/TableView.h @@ -0,0 +1,18 @@ +// +// Copyright (c) SRG SSR. All rights reserved. +// +// License information is available from the LICENSE file. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Common Play design for table views instantiated in code (with manual cell height). + */ +@interface TableView : UITableView + +@end + +NS_ASSUME_NONNULL_END diff --git a/Application/Sources/UI/Views/TableView.m b/Application/Sources/UI/Views/TableView.m new file mode 100644 index 000000000..996d3b85f --- /dev/null +++ b/Application/Sources/UI/Views/TableView.m @@ -0,0 +1,43 @@ +// +// Copyright (c) SRG SSR. All rights reserved. +// +// License information is available from the LICENSE file. +// + +#import "TableView.h" + +static void commonInit(TableView *self) +{ + self.backgroundColor = UIColor.clearColor; + self.indicatorStyle = UIScrollViewIndicatorStyleWhite; + self.separatorStyle = UITableViewCellSeparatorStyleNone; + + // The default when instantiated in a xib or storyboard. Avoid unreliable content size calculations + // when row heights are specified. We do not use automatic cell sizing, so this is best avoided by + // default. + self.estimatedRowHeight = 0.f; + self.estimatedSectionFooterHeight = 0.f; + self.estimatedSectionHeaderHeight = 0.f; +} + +@implementation TableView + +#pragma mark Object lifecycle + +- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style +{ + if (self = [super initWithFrame:frame style:style]) { + commonInit(self); + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)coder +{ + if (self = [super initWithCoder:coder]) { + commonInit(self); + } + return self; +} + +@end diff --git a/Application/Sources/WatchLater/WatchLaterViewController.m b/Application/Sources/WatchLater/WatchLaterViewController.m index a8d400912..4c7227a50 100755 --- a/Application/Sources/WatchLater/WatchLaterViewController.m +++ b/Application/Sources/WatchLater/WatchLaterViewController.m @@ -12,6 +12,7 @@ #import "NSBundle+PlaySRG.h" #import "PlayErrors.h" #import "PlayLogger.h" +#import "TableView.h" #import "UIColor+PlaySRG.h" #import "UIViewController+PlaySRG.h" #import "WatchLater.h" @@ -45,10 +46,7 @@ - (void)loadView UIView *view = [[UIView alloc] initWithFrame:UIScreen.mainScreen.bounds]; view.backgroundColor = UIColor.play_blackColor; - UITableView *tableView = [[UITableView alloc] initWithFrame:view.bounds]; - tableView.backgroundColor = UIColor.clearColor; - tableView.indicatorStyle = UIScrollViewIndicatorStyleWhite; - tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + TableView *tableView = [[TableView alloc] initWithFrame:view.bounds]; tableView.allowsSelectionDuringEditing = YES; tableView.allowsMultipleSelectionDuringEditing = YES; tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; diff --git a/Cartfile b/Cartfile index a56ff95b4..610cb1cdd 100755 --- a/Cartfile +++ b/Cartfile @@ -1,8 +1,8 @@ github "defagos/CoconutKit" "3.4" github "Flipboard/FLEX" "6d489e72c52401839386ee41aeefe1f5105c212e" github "mapbox/Fingertips" "cdffabac5506103a2c7cc5aedeed4021df2501da" -github "microsoft/appcenter-sdk-apple" ~> 2.5.0 +github "microsoft/appcenter-sdk-apple" ~> 3.1.0 github "SRGSSR/DZNEmptyDataSet" "v1.8.1_srg1" github "SRGSSR/Masonry" "v1.1.0_srg1" -github "SRGSSR/srgletterbox-apple" "3.0.1" -github "SRGSSR/srguserdata-apple" "2.0.1" \ No newline at end of file +github "SRGSSR/srgletterbox-apple" "4.0.0" +github "SRGSSR/srguserdata-apple" "2.0.2" \ No newline at end of file diff --git a/Cartfile.resolved.proprietary b/Cartfile.resolved.proprietary index 2379923a9..0dd947123 100755 --- a/Cartfile.resolved.proprietary +++ b/Cartfile.resolved.proprietary @@ -8,18 +8,18 @@ github "SRGSSR/Masonry" "v1.1.0_srg1" github "SRGSSR/UICKeyChainStore" "v2.1.2_srg1" github "SRGSSR/YYWebImage" "1.0.5_srg2" github "SRGSSR/libextobjc" "0.6_srg2" -github "SRGSSR/srganalytics-apple" "4.1.0" -github "SRGSSR/srgappearance-apple" "2.0.0" +github "SRGSSR/srganalytics-apple" "4.1.1" +github "SRGSSR/srgappearance-apple" "2.1.0" github "SRGSSR/srgcontentprotection-apple" "2.0.1" -github "SRGSSR/srgdataprovider-apple" "7.0.1" +github "SRGSSR/srgdataprovider-apple" "7.1.0" github "SRGSSR/srgdiagnostics-apple" "2.0.1" -github "SRGSSR/srgidentity-apple" "2.0.1" -github "SRGSSR/srgletterbox-apple" "3.0.1" +github "SRGSSR/srgidentity-apple" "2.0.2" +github "SRGSSR/srgletterbox-apple" "4.0.0" github "SRGSSR/srglogger-apple" "2.0.0" github "SRGSSR/srgmediaplayer-apple" "4.0.0" github "SRGSSR/srgnetwork-apple" "2.0.1" -github "SRGSSR/srguserdata-apple" "2.0.1" +github "SRGSSR/srguserdata-apple" "2.0.2" github "SRGSSR/tagcommander-apple" "4.5.4_4.4.1_srg3" github "defagos/CoconutKit" "3.4" github "mapbox/Fingertips" "cdffabac5506103a2c7cc5aedeed4021df2501da" -github "microsoft/appcenter-sdk-apple" "2.5.3" +github "microsoft/appcenter-sdk-apple" "3.1.1" diff --git a/Cartfile.resolved.public b/Cartfile.resolved.public index c877c44ef..7823b1214 100755 --- a/Cartfile.resolved.public +++ b/Cartfile.resolved.public @@ -8,18 +8,18 @@ github "SRGSSR/Masonry" "v1.1.0_srg1" github "SRGSSR/UICKeyChainStore" "v2.1.2_srg1" github "SRGSSR/YYWebImage" "1.0.5_srg2" github "SRGSSR/libextobjc" "0.6_srg2" -github "SRGSSR/srganalytics-apple" "4.1.0" -github "SRGSSR/srgappearance-apple" "2.0.0" +github "SRGSSR/srganalytics-apple" "4.1.1" +github "SRGSSR/srgappearance-apple" "2.1.0" github "SRGSSR/srgcontentprotection-fake-apple" "2.0.1" -github "SRGSSR/srgdataprovider-apple" "7.0.1" +github "SRGSSR/srgdataprovider-apple" "7.1.0" github "SRGSSR/srgdiagnostics-apple" "2.0.1" -github "SRGSSR/srgidentity-apple" "2.0.1" -github "SRGSSR/srgletterbox-apple" "3.0.1" +github "SRGSSR/srgidentity-apple" "2.0.2" +github "SRGSSR/srgletterbox-apple" "4.0.0" github "SRGSSR/srglogger-apple" "2.0.0" github "SRGSSR/srgmediaplayer-apple" "4.0.0" github "SRGSSR/srgnetwork-apple" "2.0.1" -github "SRGSSR/srguserdata-apple" "2.0.1" +github "SRGSSR/srguserdata-apple" "2.0.2" github "SRGSSR/tagcommander-apple" "4.5.4_4.4.1_srg3" github "defagos/CoconutKit" "3.4" github "mapbox/Fingertips" "cdffabac5506103a2c7cc5aedeed4021df2501da" -github "microsoft/appcenter-sdk-apple" "2.5.3" +github "microsoft/appcenter-sdk-apple" "3.1.1" diff --git a/Gemfile.lock b/Gemfile.lock index c23c6f397..39ec20527 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,6 +5,22 @@ GEM addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) atomos (0.1.3) + aws-eventstream (1.1.0) + aws-partitions (1.298.0) + aws-sdk-core (3.94.0) + aws-eventstream (~> 1, >= 1.0.2) + aws-partitions (~> 1, >= 1.239.0) + aws-sigv4 (~> 1.1) + jmespath (~> 1.0) + aws-sdk-kms (1.30.0) + aws-sdk-core (~> 3, >= 3.71.0) + aws-sigv4 (~> 1.1) + aws-sdk-s3 (1.61.2) + aws-sdk-core (~> 3, >= 3.83.0) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.1) + aws-sigv4 (1.1.2) + aws-eventstream (~> 1.0, >= 1.0.2) babosa (1.0.3) claide (1.0.3) colored (1.2) @@ -13,12 +29,12 @@ GEM highline (~> 1.7.2) declarative (0.0.10) declarative-option (0.1.0) - digest-crc (0.4.1) + digest-crc (0.5.1) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) dotenv (2.7.5) emoji_regex (1.0.1) - excon (0.72.0) + excon (0.73.0) faraday (0.17.3) multipart-post (>= 1.2, < 3) faraday-cookie_jar (0.0.6) @@ -27,9 +43,10 @@ GEM faraday_middleware (0.13.1) faraday (>= 0.7.4, < 1.0) fastimage (2.1.7) - fastlane (2.141.0) + fastlane (2.145.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) + aws-sdk-s3 (~> 1.0) babosa (>= 1.0.2, < 2.0.0) bundler (>= 1.12.0, < 3.0.0) colored @@ -77,27 +94,28 @@ GEM google-cloud-core (1.5.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) - google-cloud-env (1.3.0) - faraday (~> 0.11) + google-cloud-env (1.3.1) + faraday (>= 0.17.3, < 2.0) google-cloud-errors (1.0.0) - google-cloud-storage (1.25.1) + google-cloud-storage (1.26.0) addressable (~> 2.5) digest-crc (~> 0.4) google-api-client (~> 0.33) google-cloud-core (~> 1.2) googleauth (~> 0.9) mini_mime (~> 1.0) - googleauth (0.10.0) - faraday (~> 0.12) + googleauth (0.12.0) + faraday (>= 0.17.3, < 2.0) jwt (>= 1.4, < 3.0) memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) - signet (~> 0.12) + signet (~> 0.14) highline (1.7.10) http-cookie (1.0.3) domain_name (~> 0.5) httpclient (2.8.3) + jmespath (1.4.0) json (2.3.0) jwt (2.1.0) memoist (0.16.2) @@ -108,7 +126,7 @@ GEM multipart-post (2.0.0) nanaimo (0.2.6) naturally (2.2.0) - os (1.0.1) + os (1.1.0) plist (3.5.0) public_suffix (2.0.5) representable (3.0.4) @@ -119,9 +137,9 @@ GEM rouge (2.0.7) rubyzip (1.3.0) security (0.1.3) - signet (0.12.0) + signet (0.14.0) addressable (~> 2.3) - faraday (~> 0.9) + faraday (>= 0.17.3, < 2.0) jwt (>= 1.5, < 3.0) multi_json (~> 1.10) simctl (1.6.8) @@ -138,10 +156,10 @@ GEM uber (0.1.0) unf (0.1.4) unf_ext - unf_ext (0.0.7.6) - unicode-display_width (1.6.1) + unf_ext (0.0.7.7) + unicode-display_width (1.7.0) word_wrap (1.0.0) - xcodeproj (1.15.0) + xcodeproj (1.16.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) diff --git a/PlaySRG.xcodeproj/project.pbxproj b/PlaySRG.xcodeproj/project.pbxproj index e507b5a30..048f6a479 100644 --- a/PlaySRG.xcodeproj/project.pbxproj +++ b/PlaySRG.xcodeproj/project.pbxproj @@ -640,6 +640,11 @@ 6F0E8D9A1F14F62F002014C3 /* SRGChannel+PlaySRG.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F0E8D971F14F62F002014C3 /* SRGChannel+PlaySRG.m */; }; 6F0E8D9B1F14F62F002014C3 /* SRGChannel+PlaySRG.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F0E8D971F14F62F002014C3 /* SRGChannel+PlaySRG.m */; }; 6F0E8D9C1F14F62F002014C3 /* SRGChannel+PlaySRG.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F0E8D971F14F62F002014C3 /* SRGChannel+PlaySRG.m */; }; + 6F0EDA652448B0D800F0FED2 /* RefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F0EDA632448B0D700F0FED2 /* RefreshControl.m */; }; + 6F0EDA662448B0D800F0FED2 /* RefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F0EDA632448B0D700F0FED2 /* RefreshControl.m */; }; + 6F0EDA672448B0D800F0FED2 /* RefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F0EDA632448B0D700F0FED2 /* RefreshControl.m */; }; + 6F0EDA682448B0D800F0FED2 /* RefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F0EDA632448B0D700F0FED2 /* RefreshControl.m */; }; + 6F0EDA692448B0D800F0FED2 /* RefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F0EDA632448B0D700F0FED2 /* RefreshControl.m */; }; 6F0F88361ECEE7800060A893 /* override_default_la1.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 6F0F88201ECEE69F0060A893 /* override_default_la1.pdf */; }; 6F0F88371ECEE7800060A893 /* override_default_la2.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 6F0F88211ECEE69F0060A893 /* override_default_la2.pdf */; }; 6F0F883D1ECEE78C0060A893 /* override_artwork_radio_rtr.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 6FCB574F1EC204900015CAB7 /* override_artwork_radio_rtr.pdf */; }; @@ -1105,6 +1110,11 @@ 6F93DE1C20AE9BE600B71572 /* OnboardingTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F93DE1920AE9BE600B71572 /* OnboardingTableViewCell.m */; }; 6F93DE1D20AE9BE600B71572 /* OnboardingTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F93DE1920AE9BE600B71572 /* OnboardingTableViewCell.m */; }; 6F93DE1E20AE9BE600B71572 /* OnboardingTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F93DE1920AE9BE600B71572 /* OnboardingTableViewCell.m */; }; + 6F982B93244F1E1200C0386E /* TableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F982B92244F1E1200C0386E /* TableView.m */; }; + 6F982B94244F1E1200C0386E /* TableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F982B92244F1E1200C0386E /* TableView.m */; }; + 6F982B95244F1E1200C0386E /* TableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F982B92244F1E1200C0386E /* TableView.m */; }; + 6F982B96244F1E1200C0386E /* TableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F982B92244F1E1200C0386E /* TableView.m */; }; + 6F982B97244F1E1200C0386E /* TableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F982B92244F1E1200C0386E /* TableView.m */; }; 6F9897CD2412582400B390A2 /* Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F9897CC2412582400B390A2 /* Layout.m */; }; 6F9897CE2412582400B390A2 /* Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F9897CC2412582400B390A2 /* Layout.m */; }; 6F9897CF2412582400B390A2 /* Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F9897CC2412582400B390A2 /* Layout.m */; }; @@ -1903,6 +1913,8 @@ 6F0CFB7E20C94EE5006B2CE4 /* Play SWI notification service extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Play SWI notification service extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 6F0E8D961F14F62F002014C3 /* SRGChannel+PlaySRG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SRGChannel+PlaySRG.h"; sourceTree = ""; }; 6F0E8D971F14F62F002014C3 /* SRGChannel+PlaySRG.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SRGChannel+PlaySRG.m"; sourceTree = ""; }; + 6F0EDA632448B0D700F0FED2 /* RefreshControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RefreshControl.m; sourceTree = ""; }; + 6F0EDA642448B0D800F0FED2 /* RefreshControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefreshControl.h; sourceTree = ""; }; 6F0F88201ECEE69F0060A893 /* override_default_la1.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = override_default_la1.pdf; sourceTree = ""; }; 6F0F88211ECEE69F0060A893 /* override_default_la2.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = override_default_la2.pdf; sourceTree = ""; }; 6F0F88241ECEE6B30060A893 /* override_default_rtr_srf1.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = override_default_rtr_srf1.pdf; sourceTree = ""; }; @@ -2098,6 +2110,8 @@ 6F93DE1220AE9A9900B71572 /* OnboardingsViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = OnboardingsViewController.storyboard; sourceTree = ""; }; 6F93DE1820AE9BE600B71572 /* OnboardingTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OnboardingTableViewCell.h; sourceTree = ""; }; 6F93DE1920AE9BE600B71572 /* OnboardingTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OnboardingTableViewCell.m; sourceTree = ""; }; + 6F982B91244F1E1200C0386E /* TableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TableView.h; sourceTree = ""; }; + 6F982B92244F1E1200C0386E /* TableView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TableView.m; sourceTree = ""; }; 6F9897CB2412582400B390A2 /* Layout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Layout.h; sourceTree = ""; }; 6F9897CC2412582400B390A2 /* Layout.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Layout.m; sourceTree = ""; }; 6F9D2741203AD99C00FDE899 /* Playlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Playlist.h; sourceTree = ""; }; @@ -3251,8 +3265,12 @@ 6F475FAC1EB37BC6003021EA /* MediaCollectionViewCell.h */, 6F475FAD1EB37BC6003021EA /* MediaCollectionViewCell.m */, 6F475FAE1EB37BC6003021EA /* MediaCollectionViewCell.xib */, + 6F0EDA642448B0D800F0FED2 /* RefreshControl.h */, + 6F0EDA632448B0D700F0FED2 /* RefreshControl.m */, 6FEC91A721A6B39A00AA50C8 /* TableLoadMoreFooterView.h */, 6FEC91A821A6B39A00AA50C8 /* TableLoadMoreFooterView.m */, + 6F982B91244F1E1200C0386E /* TableView.h */, + 6F982B92244F1E1200C0386E /* TableView.m */, 6F475FAF1EB37BC6003021EA /* TranslucentTitleHeaderView.h */, 6F475FB01EB37BC6003021EA /* TranslucentTitleHeaderView.m */, 6F475FB11EB37BC6003021EA /* TranslucentTitleHeaderView.xib */, @@ -5873,6 +5891,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6F0EDA652448B0D800F0FED2 /* RefreshControl.m in Sources */, 6F9D2743203AD99C00FDE899 /* Playlist.m in Sources */, 086321052258C6D000C719A6 /* WatchLaterTableViewCell.m in Sources */, E66BEC1C1DA7FCED00AD4450 /* MediaPlayerViewController.m in Sources */, @@ -6013,6 +6032,7 @@ 08B2A53A2426511800C6EED3 /* SRGModule+PlaySRG.m in Sources */, 0859ADC622D72F4F00511F7F /* SearchSettingsMultiSelectionItem.m in Sources */, 6F47607D1EB37D60003021EA /* UIViewController+PlaySRG.m in Sources */, + 6F982B93244F1E1200C0386E /* TableView.m in Sources */, 6FD88F8A22D4BC41008859EF /* UISearchBar+PlaySRG.m in Sources */, 6F475FBE1EB37BC6003021EA /* DataViewController.m in Sources */, 6F12DB5021A3EFBF0054879D /* HistoryViewController.m in Sources */, @@ -6119,6 +6139,7 @@ 0827DA1F1F0D36E200A31A42 /* NSBundle+PlaySRG.m in Sources */, 6F7218141DBE75AC00575072 /* PreviewingDelegate.m in Sources */, 6F12E4E322D8676600BC1718 /* SearchHeaderView.m in Sources */, + 6F0EDA662448B0D800F0FED2 /* RefreshControl.m in Sources */, 6F80E9C321A682E70027CA2F /* TableRequestViewController.m in Sources */, 6FE1B91A1FAC34D600A58F3B /* ContentInsets.m in Sources */, 6F93DE0E20AE985C00B71572 /* OnboardingsViewController.m in Sources */, @@ -6165,6 +6186,7 @@ 08564B1E1D41111A00381549 /* HomeSectionHeaderView.m in Sources */, 6FE686E21EB9D57400067D40 /* ChannelService.m in Sources */, 6FDF08EC218B126700B2AF2C /* OnboardingPage.m in Sources */, + 6F982B94244F1E1200C0386E /* TableView.m in Sources */, 6F556B391DDC419800B5DEA2 /* SettingsBaseViewController.m in Sources */, 08C68F8B1D38DEA100BB8AAA /* PlayAppDelegate.m in Sources */, 08B77AF1240A86FD00A3BC3B /* AccessibilityIdentifierConstants.m in Sources */, @@ -6281,6 +6303,7 @@ 0827DA201F0D36E200A31A42 /* NSBundle+PlaySRG.m in Sources */, 6F7218151DBE75AC00575072 /* PreviewingDelegate.m in Sources */, 6F12E4E422D8676600BC1718 /* SearchHeaderView.m in Sources */, + 6F0EDA672448B0D800F0FED2 /* RefreshControl.m in Sources */, 6F80E9C421A682E70027CA2F /* TableRequestViewController.m in Sources */, 6FE1B91B1FAC34D600A58F3B /* ContentInsets.m in Sources */, 6F93DE0F20AE985C00B71572 /* OnboardingsViewController.m in Sources */, @@ -6327,6 +6350,7 @@ 08564B1F1D41111A00381549 /* HomeSectionHeaderView.m in Sources */, 6FE686E31EB9D57400067D40 /* ChannelService.m in Sources */, 6FDF08ED218B126700B2AF2C /* OnboardingPage.m in Sources */, + 6F982B95244F1E1200C0386E /* TableView.m in Sources */, 6F556B3A1DDC419800B5DEA2 /* SettingsBaseViewController.m in Sources */, 08C68F8C1D38DEA100BB8AAA /* PlayAppDelegate.m in Sources */, 08B77AF2240A86FD00A3BC3B /* AccessibilityIdentifierConstants.m in Sources */, @@ -6443,6 +6467,7 @@ 0827DA211F0D36E400A31A42 /* NSBundle+PlaySRG.m in Sources */, 6F7218161DBE75AC00575072 /* PreviewingDelegate.m in Sources */, 6F12E4E522D8676600BC1718 /* SearchHeaderView.m in Sources */, + 6F0EDA682448B0D800F0FED2 /* RefreshControl.m in Sources */, 6F80E9C521A682E70027CA2F /* TableRequestViewController.m in Sources */, 6FE1B91C1FAC34D600A58F3B /* ContentInsets.m in Sources */, 6F93DE1020AE985C00B71572 /* OnboardingsViewController.m in Sources */, @@ -6489,6 +6514,7 @@ 08564B201D41111A00381549 /* HomeSectionHeaderView.m in Sources */, 6FE686E41EB9D57400067D40 /* ChannelService.m in Sources */, 6FDF08EE218B126700B2AF2C /* OnboardingPage.m in Sources */, + 6F982B96244F1E1200C0386E /* TableView.m in Sources */, 6F556B3B1DDC419800B5DEA2 /* SettingsBaseViewController.m in Sources */, 08C68F8D1D38DEA100BB8AAA /* PlayAppDelegate.m in Sources */, 08B77AF3240A86FD00A3BC3B /* AccessibilityIdentifierConstants.m in Sources */, @@ -6605,6 +6631,7 @@ 0827DA221F0D36E400A31A42 /* NSBundle+PlaySRG.m in Sources */, 6F7218171DBE75AC00575072 /* PreviewingDelegate.m in Sources */, 6F12E4E622D8676600BC1718 /* SearchHeaderView.m in Sources */, + 6F0EDA692448B0D800F0FED2 /* RefreshControl.m in Sources */, 6F80E9C621A682E70027CA2F /* TableRequestViewController.m in Sources */, 6FE1B91D1FAC34D600A58F3B /* ContentInsets.m in Sources */, 6F93DE1120AE985C00B71572 /* OnboardingsViewController.m in Sources */, @@ -6651,6 +6678,7 @@ 08564B211D41111A00381549 /* HomeSectionHeaderView.m in Sources */, 6FE686E51EB9D57400067D40 /* ChannelService.m in Sources */, 6FDF08EF218B126700B2AF2C /* OnboardingPage.m in Sources */, + 6F982B97244F1E1200C0386E /* TableView.m in Sources */, 6F556B3C1DDC419800B5DEA2 /* SettingsBaseViewController.m in Sources */, 08C68F8E1D38DEA100BB8AAA /* PlayAppDelegate.m in Sources */, 08B77AF4240A86FD00A3BC3B /* AccessibilityIdentifierConstants.m in Sources */, @@ -7577,7 +7605,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 326; + CURRENT_PROJECT_VERSION = 329; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -7596,7 +7624,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MARKETING_VERSION = 3.0.0; + MARKETING_VERSION = 3.0.1; MARKETING_VERSION_SUFFIX = "-debug"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; @@ -7645,7 +7673,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 326; + CURRENT_PROJECT_VERSION = 329; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -7658,7 +7686,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MARKETING_VERSION = 3.0.0; + MARKETING_VERSION = 3.0.1; MARKETING_VERSION_SUFFIX = ""; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; @@ -8000,7 +8028,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 326; + CURRENT_PROJECT_VERSION = 329; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -8014,7 +8042,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MARKETING_VERSION = 3.0.0; + MARKETING_VERSION = 3.0.1; MARKETING_VERSION_SUFFIX = "-beta"; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; @@ -8212,7 +8240,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 326; + CURRENT_PROJECT_VERSION = 329; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -8226,7 +8254,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MARKETING_VERSION = 3.0.0; + MARKETING_VERSION = 3.0.1; MARKETING_VERSION_SUFFIX = "-nightly"; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; diff --git a/WhatsNew-beta.json b/WhatsNew-beta.json index 3254ec776..df193458e 100755 --- a/WhatsNew-beta.json +++ b/WhatsNew-beta.json @@ -102,5 +102,8 @@ "3.0.0-323": "### Bottom Navigation\n\n- The navigation has been updated to provide for better user experience and content reachability:\n - Content previously located in the side menu is now available from the videos, audios and live tabs.\n - User-centric features (notifications, favorites, history, watch later and downloads) are accessed under the More tab (or Profile tab for RTS).\n- The mini player can be dismissed when not needed.\n- Live content is consistently identified with a red label throughout the app.\n- Energy impact has been reduced, most notably when the application is in the background or idle.\n- Control center, picture in picture, AirPlay and Google Cast integrations have been improved to offer a more streamlined playback experience.", "3.0.0-324": "- Live screen layouts have been improved on iPad.\n- Page view analytics have been updated.\n- Context menus are available for iOS 13 and above.\n- Accessibility via VoiceOver has been updated for tab bar navigation.\n- Screen layouts have been improved to better make use of the available screen space, no matter the chosen font size.\n- Audio track and subtitle selection has been improved. In particular, device subtitle settings are used when casting content over AirPlay.", "3.0.0-325": "### Modern design\n\n- Use corners for thumbnails and duration labels. with centered texts.\n- Use cards UI for show accesses or media lists.\n- Live screen layouts redesigned for iPhone and iPad.\n- Better use of available space on iPad (home views and content grid views).\n- Update SRF Virus radio logo.\n\nFixes:\n- Do not pause or display Handoff notification when transferring playback.\n- Fix layouts issues on iOS 12.\n- Fix a crash occuring when reopening the application.", - "3.0.0-326": "- Event module swimlane redesign.\n- Tiny UI margin adjustments.\n- Fixed titles timeline on player (2 lines)." + "3.0.0-326": "- Event module swimlane redesign.\n- Tiny UI margin adjustments.\n- Fixed titles timeline on player (2 lines).", + "3.0.1-327": "- Medias with various aspect ratios are better displayed.\n- Homepage glitches and performance issues have been fixed.", + "3.0.1-328": "- Allow Handoff with downloaded content.\n- Fixes an issue preventing the first item in lists to be accessed with VoiceOver.", + "3.0.1-329": "- Fixes sometimes erratic scroll position when returning on a homepage.\n- Fixes double tap on tab which sometimes would not return to the top of a list." } \ No newline at end of file