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