diff --git a/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Due/logo_rete_due-32.imageset/Contents.json b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Due/logo_rete_due-32.imageset/Contents.json new file mode 100644 index 000000000..63b345ec6 --- /dev/null +++ b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Due/logo_rete_due-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RSI_Retedue.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Due/logo_rete_due-32.imageset/RSI_Retedue.pdf b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Due/logo_rete_due-32.imageset/RSI_Retedue.pdf new file mode 100644 index 000000000..a77de40e7 Binary files /dev/null and b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Due/logo_rete_due-32.imageset/RSI_Retedue.pdf differ diff --git a/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Tre/logo_rete_tre-32.imageset/Contents.json b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Tre/logo_rete_tre-32.imageset/Contents.json new file mode 100644 index 000000000..ea2833430 --- /dev/null +++ b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Tre/logo_rete_tre-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RSI_Retetre.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Tre/logo_rete_tre-32.imageset/RSI_Retetre.pdf b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Tre/logo_rete_tre-32.imageset/RSI_Retetre.pdf new file mode 100644 index 000000000..e560b0dab Binary files /dev/null and b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Tre/logo_rete_tre-32.imageset/RSI_Retetre.pdf differ diff --git a/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Uno/logo_rete_uno-32.imageset/Contents.json b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Uno/logo_rete_uno-32.imageset/Contents.json new file mode 100644 index 000000000..a0bb72f7f --- /dev/null +++ b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Uno/logo_rete_uno-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RSI_Reteuno.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Uno/logo_rete_uno-32.imageset/RSI_Reteuno.pdf b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Uno/logo_rete_uno-32.imageset/RSI_Reteuno.pdf new file mode 100644 index 000000000..9b571a0f9 Binary files /dev/null and b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/Radio/Rete Uno/logo_rete_uno-32.imageset/RSI_Reteuno.pdf differ diff --git a/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La1/logo_la1-32.imageset/Contents.json b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La1/logo_la1-32.imageset/Contents.json new file mode 100644 index 000000000..cfd505ba0 --- /dev/null +++ b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La1/logo_la1-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RSI_LA1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La1/logo_la1-32.imageset/RSI_LA1.pdf b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La1/logo_la1-32.imageset/RSI_LA1.pdf new file mode 100644 index 000000000..927a6589e Binary files /dev/null and b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La1/logo_la1-32.imageset/RSI_LA1.pdf differ diff --git a/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La2/logo_la2-32.imageset/Contents.json b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La2/logo_la2-32.imageset/Contents.json new file mode 100644 index 000000000..779f7d0d9 --- /dev/null +++ b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La2/logo_la2-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RSI_LA2.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La2/logo_la2-32.imageset/RSI_LA2.pdf b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La2/logo_la2-32.imageset/RSI_LA2.pdf new file mode 100644 index 000000000..ecdf23d5d Binary files /dev/null and b/Application/Resources/Apps/Play RSI/RSIResources.xcassets/TV/La2/logo_la2-32.imageset/RSI_LA2.pdf differ diff --git a/Application/Resources/Apps/Play RSI/it.lproj/Localizable.strings b/Application/Resources/Apps/Play RSI/it.lproj/Localizable.strings index b83d2d747..aaf6eb01b 100755 --- a/Application/Resources/Apps/Play RSI/it.lproj/Localizable.strings +++ b/Application/Resources/Apps/Play RSI/it.lproj/Localizable.strings @@ -22,6 +22,9 @@ /* Title displayed on the radio home button */ "%@ overview" = "%@ home"; +/* Text displayed on live cells telling how much time remains for a program currently on air */ +"%@ remaining" = "Ancora %@"; + /* Label displaying the number of views on the player */ "%@ views" = "%@ visualizzazioni"; @@ -107,6 +110,9 @@ /* Settings section header */ "Content" = "Contenuto"; +/* Sort by date option */ +"Date" = "Data"; + /* Title of a delete button Title of the delete button in the alert view when deleting a download in the player view */ "Delete" = "Elimina"; @@ -123,6 +129,9 @@ /* Introductory title displayed at the top of the onboarding list */ "Discover" = "Scopri"; +/* User activity title when displaying a show page */ +"Display %@ episodes" = "Mostra le puntate di %@"; + /* No comment provided by engineer. */ "Do you want to send an anonymous crash report so we can fix the issue?" = "Desidera inviare una segnalazione (anonima) su questo problema così da permetterci di risolverlo?"; @@ -212,6 +221,11 @@ /* Explains that a content has expired, will expire or will be available in less than one hour. Displayed in the media player view. */ "less than 1 hour" = "meno di 1 ora"; +/* Suggested invocation phrase to listen to a show + Suggested invocation phrase to listen to an audio + User activity title when listening to an audio */ +"Listen to %@" = "Ascolta %@"; + /* Introductory text for what is currently on air, displayed on the mini player Short label identifying a livestream. Display in uppercase. */ "Live" = "Live"; @@ -351,7 +365,7 @@ "Pull to reload" = "Scorrere verso il basso per ricaricare"; /* Title label to present main radio livestreams */ -"Radio channels" = "Tutte le emittenti radio"; +"Radio channels" = "Reti radio"; /* Title displayed when no media is being played on the connected Google Cast receiver (name unknown) */ "Receiver is idle." = "Ricevitore inattivo."; @@ -365,6 +379,9 @@ /* Title of the action view to choose a regional radio */ "Regional radios" = "Radio regionali"; +/* Sort by relevance option */ +"Relevance" = "Pertinenza"; + /* Title of the confirmation pop-up displayed when the user is about to clean the watch later list */ "Remove all content" = "Rimuovere tutto"; @@ -451,6 +468,9 @@ /* Short label identifying content which will be available soon. */ "Soon" = "Presto"; +/* Settings section header */ +"Sort by" = "Ordinare per"; + /* Title label used to present live center medias. Only on test versions. */ "Sport" = "Sport"; @@ -565,6 +585,11 @@ /* Header for video and audio search results */ "Videos and audios" = "Video e audio"; +/* Suggested invocation phrase to watch a show + Suggested invocation phrase to watch a video + User activity title when watching a video */ +"Watch %@" = "Guarda %@"; + /* Label to present the watch later list */ "Watch later" = "Guardare dopo"; diff --git a/Application/Resources/Apps/Play RTR/RTRResources.xcassets/Radio/Radio RTR/logo_radio_rtr-32.imageset/Contents.json b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/Radio/Radio RTR/logo_radio_rtr-32.imageset/Contents.json new file mode 100644 index 000000000..6595a1a02 --- /dev/null +++ b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/Radio/Radio RTR/logo_radio_rtr-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RTR_radio.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RTR/RTRResources.xcassets/Radio/Radio RTR/logo_radio_rtr-32.imageset/RTR_radio.pdf b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/Radio/Radio RTR/logo_radio_rtr-32.imageset/RTR_radio.pdf new file mode 100644 index 000000000..21fe5da15 Binary files /dev/null and b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/Radio/Radio RTR/logo_radio_rtr-32.imageset/RTR_radio.pdf differ diff --git a/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF Info/logo_rtr_srf_info-32.imageset/Contents.json b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF Info/logo_rtr_srf_info-32.imageset/Contents.json new file mode 100644 index 000000000..65cb0149d --- /dev/null +++ b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF Info/logo_rtr_srf_info-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_Info.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF Info/logo_rtr_srf_info-32.imageset/SRF_Info.pdf b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF Info/logo_rtr_srf_info-32.imageset/SRF_Info.pdf new file mode 100644 index 000000000..ce55204fd Binary files /dev/null and b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF Info/logo_rtr_srf_info-32.imageset/SRF_Info.pdf differ diff --git a/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF1/logo_rtr_srf1-32.imageset/Contents.json b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF1/logo_rtr_srf1-32.imageset/Contents.json new file mode 100644 index 000000000..d6c8c22cb --- /dev/null +++ b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF1/logo_rtr_srf1-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF1/logo_rtr_srf1-32.imageset/SRF_1.pdf b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF1/logo_rtr_srf1-32.imageset/SRF_1.pdf new file mode 100644 index 000000000..2ee2324b8 Binary files /dev/null and b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF1/logo_rtr_srf1-32.imageset/SRF_1.pdf differ diff --git a/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF2/logo_rtr_srf2-32.imageset/Contents.json b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF2/logo_rtr_srf2-32.imageset/Contents.json new file mode 100644 index 000000000..1fc0f79c8 --- /dev/null +++ b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF2/logo_rtr_srf2-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_zwei.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF2/logo_rtr_srf2-32.imageset/SRF_zwei.pdf b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF2/logo_rtr_srf2-32.imageset/SRF_zwei.pdf new file mode 100644 index 000000000..f94f96ee1 Binary files /dev/null and b/Application/Resources/Apps/Play RTR/RTRResources.xcassets/TV/RTR auf SRF2/logo_rtr_srf2-32.imageset/SRF_zwei.pdf differ diff --git a/Application/Resources/Apps/Play RTR/rm.lproj/Localizable.strings b/Application/Resources/Apps/Play RTR/rm.lproj/Localizable.strings index 1709ed92f..243f6407e 100755 --- a/Application/Resources/Apps/Play RTR/rm.lproj/Localizable.strings +++ b/Application/Resources/Apps/Play RTR/rm.lproj/Localizable.strings @@ -22,6 +22,9 @@ /* Title displayed on the radio home button */ "%@ overview" = "%@ survista"; +/* Text displayed on live cells telling how much time remains for a program currently on air */ +"%@ remaining" = "Anc %@"; + /* Label displaying the number of views on the player */ "%@ views" = "%@ visualisaziuns"; @@ -107,6 +110,9 @@ /* Settings section header */ "Content" = "Cuntegn"; +/* Sort by date option */ +"Date" = "Data"; + /* Title of a delete button Title of the delete button in the alert view when deleting a download in the player view */ "Delete" = "Stizzar"; @@ -123,6 +129,9 @@ /* Introductory title displayed at the top of the onboarding list */ "Discover" = "Scuvrir"; +/* User activity title when displaying a show page */ +"Display %@ episodes" = "Mussa las episodas %@"; + /* No comment provided by engineer. */ "Do you want to send an anonymous crash report so we can fix the issue?" = "Vulais trametter in rapport anonim, per che nus possian schliar il problem?"; @@ -212,6 +221,11 @@ /* Explains that a content has expired, will expire or will be available in less than one hour. Displayed in the media player view. */ "less than 1 hour" = "main ch'ina ura"; +/* Suggested invocation phrase to listen to a show + Suggested invocation phrase to listen to an audio + User activity title when listening to an audio */ +"Listen to %@" = "Tadlar %@"; + /* Introductory text for what is currently on air, displayed on the mini player Short label identifying a livestream. Display in uppercase. */ "Live" = "Live"; @@ -365,6 +379,9 @@ /* Title of the action view to choose a regional radio */ "Regional radios" = "Radios regiunals"; +/* Sort by relevance option */ +"Relevance" = "Relevanza"; + /* Title of the confirmation pop-up displayed when the user is about to clean the watch later list */ "Remove all content" = "Piglia davent tut il cuntegn"; @@ -451,6 +468,9 @@ /* Short label identifying content which will be available soon. */ "Soon" = "Proximamain"; +/* Settings section header */ +"Sort by" = "Sortar tenor"; + /* Title label used to present live center medias. Only on test versions. */ "Sport" = "Sport"; @@ -565,6 +585,11 @@ /* Header for video and audio search results */ "Videos and audios" = "Videos ed audios"; +/* Suggested invocation phrase to watch a show + Suggested invocation phrase to watch a video + User activity title when watching a video */ +"Watch %@" = "Guardar %@"; + /* Label to present the watch later list */ "Watch later" = "Guardar pli tard"; diff --git a/Application/Resources/Apps/Play RTS/ApplicationConfiguration.json b/Application/Resources/Apps/Play RTS/ApplicationConfiguration.json index e781811fd..13d8c340c 100755 --- a/Application/Resources/Apps/Play RTS/ApplicationConfiguration.json +++ b/Application/Resources/Apps/Play RTS/ApplicationConfiguration.json @@ -34,6 +34,7 @@ "endToleranceRatio": 0.01, "hiddenOnboardings": "favorites,resume_playback,watch_later", "searchSettingSubtitledHidden": true, + "searchSortingCriteriumHidden": true, "subtitleAvailabilityHidden": true, "audioDescriptionAvailabilityHidden": true } diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Couleur 3/logo_couleur3-32.imageset/Contents.json b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Couleur 3/logo_couleur3-32.imageset/Contents.json new file mode 100644 index 000000000..172d82e40 --- /dev/null +++ b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Couleur 3/logo_couleur3-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RTS_radio3.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Couleur 3/logo_couleur3-32.imageset/RTS_radio3.pdf b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Couleur 3/logo_couleur3-32.imageset/RTS_radio3.pdf new file mode 100644 index 000000000..0bcb86af7 Binary files /dev/null and b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Couleur 3/logo_couleur3-32.imageset/RTS_radio3.pdf differ diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Espace 2/logo_espace2-32.imageset/Contents.json b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Espace 2/logo_espace2-32.imageset/Contents.json new file mode 100644 index 000000000..8acbb4b55 --- /dev/null +++ b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Espace 2/logo_espace2-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RTS_radio2.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Espace 2/logo_espace2-32.imageset/RTS_radio2.pdf b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Espace 2/logo_espace2-32.imageset/RTS_radio2.pdf new file mode 100644 index 000000000..d6462fb51 Binary files /dev/null and b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Espace 2/logo_espace2-32.imageset/RTS_radio2.pdf differ diff --git "a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/La 1\303\250re/logo_la1ere-32.imageset/Contents.json" "b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/La 1\303\250re/logo_la1ere-32.imageset/Contents.json" new file mode 100644 index 000000000..8de9d22fd --- /dev/null +++ "b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/La 1\303\250re/logo_la1ere-32.imageset/Contents.json" @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RTS_radio1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/La 1\303\250re/logo_la1ere-32.imageset/RTS_radio1.pdf" "b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/La 1\303\250re/logo_la1ere-32.imageset/RTS_radio1.pdf" new file mode 100644 index 000000000..959943230 Binary files /dev/null and "b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/La 1\303\250re/logo_la1ere-32.imageset/RTS_radio1.pdf" differ diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Option Musique/logo_option_musique-32.imageset/Contents.json b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Option Musique/logo_option_musique-32.imageset/Contents.json new file mode 100644 index 000000000..b0c76b793 --- /dev/null +++ b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Option Musique/logo_option_musique-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RTS_radioOM.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Option Musique/logo_option_musique-32.imageset/RTS_radioOM.pdf b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Option Musique/logo_option_musique-32.imageset/RTS_radioOM.pdf new file mode 100644 index 000000000..843a24ebe Binary files /dev/null and b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/Radio/Option Musique/logo_option_musique-32.imageset/RTS_radioOM.pdf differ diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS Info/logo_rts_info-32.imageset/Contents.json b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS Info/logo_rts_info-32.imageset/Contents.json new file mode 100644 index 000000000..7ab33a231 --- /dev/null +++ b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS Info/logo_rts_info-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RTS_Info.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS Info/logo_rts_info-32.imageset/RTS_Info.pdf b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS Info/logo_rts_info-32.imageset/RTS_Info.pdf new file mode 100644 index 000000000..b4e819231 Binary files /dev/null and b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS Info/logo_rts_info-32.imageset/RTS_Info.pdf differ diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS1/logo_rts_un-32.imageset/Contents.json b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS1/logo_rts_un-32.imageset/Contents.json new file mode 100644 index 000000000..97055f0e9 --- /dev/null +++ b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS1/logo_rts_un-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RTS_1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS1/logo_rts_un-32.imageset/RTS_1.pdf b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS1/logo_rts_un-32.imageset/RTS_1.pdf new file mode 100644 index 000000000..9c4128213 Binary files /dev/null and b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS1/logo_rts_un-32.imageset/RTS_1.pdf differ diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS2/logo_rts_deux-32.imageset/Contents.json b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS2/logo_rts_deux-32.imageset/Contents.json new file mode 100644 index 000000000..a2e9b0f30 --- /dev/null +++ b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS2/logo_rts_deux-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "RTS_2.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS2/logo_rts_deux-32.imageset/RTS_2.pdf b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS2/logo_rts_deux-32.imageset/RTS_2.pdf new file mode 100644 index 000000000..5548b08df Binary files /dev/null and b/Application/Resources/Apps/Play RTS/RTSResources.xcassets/TV/RTS2/logo_rts_deux-32.imageset/RTS_2.pdf differ diff --git a/Application/Resources/Apps/Play RTS/fr.lproj/Localizable.strings b/Application/Resources/Apps/Play RTS/fr.lproj/Localizable.strings index 8ec0aa272..0fb192cc6 100644 --- a/Application/Resources/Apps/Play RTS/fr.lproj/Localizable.strings +++ b/Application/Resources/Apps/Play RTS/fr.lproj/Localizable.strings @@ -22,6 +22,9 @@ /* Title displayed on the radio home button */ "%@ overview" = "Accueil %@"; +/* Text displayed on live cells telling how much time remains for a program currently on air */ +"%@ remaining" = "Encore %@"; + /* Label displaying the number of views on the player */ "%@ views" = "%@ vues"; @@ -107,6 +110,9 @@ /* Settings section header */ "Content" = "Contenu"; +/* Sort by date option */ +"Date" = "Date"; + /* Title of a delete button Title of the delete button in the alert view when deleting a download in the player view */ "Delete" = "Supprimer"; @@ -123,6 +129,9 @@ /* Introductory title displayed at the top of the onboarding list */ "Discover" = "Découvrez l'application"; +/* User activity title when displaying a show page */ +"Display %@ episodes" = "Afficher les épisodes pour %@"; + /* No comment provided by engineer. */ "Do you want to send an anonymous crash report so we can fix the issue?" = "Souhaitez-vous envoyer un rapport d'erreur afin que nous puissions corriger ce problème?"; @@ -212,6 +221,11 @@ /* Explains that a content has expired, will expire or will be available in less than one hour. Displayed in the media player view. */ "less than 1 hour" = "moins d'une heure"; +/* Suggested invocation phrase to listen to a show + Suggested invocation phrase to listen to an audio + User activity title when listening to an audio */ +"Listen to %@" = "Écouter %@"; + /* Introductory text for what is currently on air, displayed on the mini player Short label identifying a livestream. Display in uppercase. */ "Live" = "Direct"; @@ -365,6 +379,9 @@ /* Title of the action view to choose a regional radio */ "Regional radios" = "Radios régionales"; +/* Sort by relevance option */ +"Relevance" = "Pertinence"; + /* Title of the confirmation pop-up displayed when the user is about to clean the watch later list */ "Remove all content" = "Supprimer tout le contenu"; @@ -451,6 +468,9 @@ /* Short label identifying content which will be available soon. */ "Soon" = "Prochainement"; +/* Settings section header */ +"Sort by" = "Trier par"; + /* Title label used to present live center medias. Only on test versions. */ "Sport" = "Sport"; @@ -565,6 +585,11 @@ /* Header for video and audio search results */ "Videos and audios" = "Vidéos et audios"; +/* Suggested invocation phrase to watch a show + Suggested invocation phrase to watch a video + User activity title when watching a video */ +"Watch %@" = "Regarder %@"; + /* Label to present the watch later list */ "Watch later" = "Plus tard"; diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 1/logo_srf1-32.imageset/Contents.json b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 1/logo_srf1-32.imageset/Contents.json new file mode 100644 index 000000000..20ff1096e --- /dev/null +++ b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 1/logo_srf1-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_radio1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 1/logo_srf1-32.imageset/SRF_radio1.pdf b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 1/logo_srf1-32.imageset/SRF_radio1.pdf new file mode 100644 index 000000000..eba5424dd Binary files /dev/null and b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 1/logo_srf1-32.imageset/SRF_radio1.pdf differ diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 2/logo_srf2-32.imageset/Contents.json b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 2/logo_srf2-32.imageset/Contents.json new file mode 100644 index 000000000..457b151fc --- /dev/null +++ b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 2/logo_srf2-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_Kultur.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 2/logo_srf2-32.imageset/SRF_Kultur.pdf b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 2/logo_srf2-32.imageset/SRF_Kultur.pdf new file mode 100644 index 000000000..33373cf02 Binary files /dev/null and b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 2/logo_srf2-32.imageset/SRF_Kultur.pdf differ diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 3/logo_srf3-32.imageset/Contents.json b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 3/logo_srf3-32.imageset/Contents.json new file mode 100644 index 000000000..be2630fb0 --- /dev/null +++ b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 3/logo_srf3-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_radio3.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 3/logo_srf3-32.imageset/SRF_radio3.pdf b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 3/logo_srf3-32.imageset/SRF_radio3.pdf new file mode 100644 index 000000000..46650f60e Binary files /dev/null and b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 3/logo_srf3-32.imageset/SRF_radio3.pdf differ diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 4/logo_srf4-32.imageset/Contents.json b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 4/logo_srf4-32.imageset/Contents.json new file mode 100644 index 000000000..dea9cc772 --- /dev/null +++ b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 4/logo_srf4-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_radio4.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 4/logo_srf4-32.imageset/SRF_radio4.pdf b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 4/logo_srf4-32.imageset/SRF_radio4.pdf new file mode 100644 index 000000000..36d1c7a08 Binary files /dev/null and b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF 4/logo_srf4-32.imageset/SRF_radio4.pdf differ diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF Musikwelle/logo_srf_musikwelle-32.imageset/Contents.json b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF Musikwelle/logo_srf_musikwelle-32.imageset/Contents.json new file mode 100644 index 000000000..5a909072c --- /dev/null +++ b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF Musikwelle/logo_srf_musikwelle-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_radioMusicWelle.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF Musikwelle/logo_srf_musikwelle-32.imageset/SRF_radioMusicWelle.pdf b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF Musikwelle/logo_srf_musikwelle-32.imageset/SRF_radioMusicWelle.pdf new file mode 100644 index 000000000..16394384c Binary files /dev/null and b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/SRF Musikwelle/logo_srf_musikwelle-32.imageset/SRF_radioMusicWelle.pdf differ diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/Virus/logo_virus-32.imageset/Contents.json b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/Virus/logo_virus-32.imageset/Contents.json new file mode 100644 index 000000000..9d509bc2e --- /dev/null +++ b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/Virus/logo_virus-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_radioVirus.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/Virus/logo_virus-32.imageset/SRF_radioVirus.pdf b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/Virus/logo_virus-32.imageset/SRF_radioVirus.pdf new file mode 100644 index 000000000..929392cc8 Binary files /dev/null and b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/Radio/Virus/logo_virus-32.imageset/SRF_radioVirus.pdf differ diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF Info/logo_tv_srf_info-32.imageset/Contents.json b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF Info/logo_tv_srf_info-32.imageset/Contents.json new file mode 100644 index 000000000..65cb0149d --- /dev/null +++ b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF Info/logo_tv_srf_info-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_Info.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF Info/logo_tv_srf_info-32.imageset/SRF_Info.pdf b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF Info/logo_tv_srf_info-32.imageset/SRF_Info.pdf new file mode 100644 index 000000000..ce55204fd Binary files /dev/null and b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF Info/logo_tv_srf_info-32.imageset/SRF_Info.pdf differ diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF1/logo_tv_srf1-32.imageset/Contents.json b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF1/logo_tv_srf1-32.imageset/Contents.json new file mode 100644 index 000000000..d6c8c22cb --- /dev/null +++ b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF1/logo_tv_srf1-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF1/logo_tv_srf1-32.imageset/SRF_1.pdf b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF1/logo_tv_srf1-32.imageset/SRF_1.pdf new file mode 100644 index 000000000..2ee2324b8 Binary files /dev/null and b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF1/logo_tv_srf1-32.imageset/SRF_1.pdf differ diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF2/logo_tv_srf2-32.imageset/Contents.json b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF2/logo_tv_srf2-32.imageset/Contents.json new file mode 100644 index 000000000..1fc0f79c8 --- /dev/null +++ b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF2/logo_tv_srf2-32.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "SRF_zwei.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF2/logo_tv_srf2-32.imageset/SRF_zwei.pdf b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF2/logo_tv_srf2-32.imageset/SRF_zwei.pdf new file mode 100644 index 000000000..f94f96ee1 Binary files /dev/null and b/Application/Resources/Apps/Play SRF/SRFResources.xcassets/TV/SRF2/logo_tv_srf2-32.imageset/SRF_zwei.pdf differ diff --git a/Application/Resources/Apps/Play SRF/de.lproj/Localizable.strings b/Application/Resources/Apps/Play SRF/de.lproj/Localizable.strings index e6b5e0b12..f848bd188 100755 --- a/Application/Resources/Apps/Play SRF/de.lproj/Localizable.strings +++ b/Application/Resources/Apps/Play SRF/de.lproj/Localizable.strings @@ -22,6 +22,9 @@ /* Title displayed on the radio home button */ "%@ overview" = "Startseite %@"; +/* Text displayed on live cells telling how much time remains for a program currently on air */ +"%@ remaining" = "Noch %@"; + /* Label displaying the number of views on the player */ "%@ views" = "%@"; @@ -107,6 +110,9 @@ /* Settings section header */ "Content" = "Medientyp"; +/* Sort by date option */ +"Date" = "Datum"; + /* Title of a delete button Title of the delete button in the alert view when deleting a download in the player view */ "Delete" = "Löschen"; @@ -123,6 +129,9 @@ /* Introductory title displayed at the top of the onboarding list */ "Discover" = "Entdecken"; +/* User activity title when displaying a show page */ +"Display %@ episodes" = "Zeige die Folgen von %@"; + /* No comment provided by engineer. */ "Do you want to send an anonymous crash report so we can fix the issue?" = "Wollen Sie einen anonymen Absturzreport senden, damit wir das Problem lösen können?"; @@ -212,6 +221,11 @@ /* Explains that a content has expired, will expire or will be available in less than one hour. Displayed in the media player view. */ "less than 1 hour" = "< 1 Stunde"; +/* Suggested invocation phrase to listen to a show + Suggested invocation phrase to listen to an audio + User activity title when listening to an audio */ +"Listen to %@" = "%@ hören"; + /* Introductory text for what is currently on air, displayed on the mini player Short label identifying a livestream. Display in uppercase. */ "Live" = "Live"; @@ -365,6 +379,9 @@ /* Title of the action view to choose a regional radio */ "Regional radios" = "Radio SRF 1 mit Regionaljournal"; +/* Sort by relevance option */ +"Relevance" = "Relevanz"; + /* Title of the confirmation pop-up displayed when the user is about to clean the watch later list */ "Remove all content" = "Alle Elemente entfernen"; @@ -451,6 +468,9 @@ /* Short label identifying content which will be available soon. */ "Soon" = "In Kürze"; +/* Settings section header */ +"Sort by" = "Sortieren nach"; + /* Title label used to present live center medias. Only on test versions. */ "Sport" = "Sport"; @@ -565,6 +585,11 @@ /* Header for video and audio search results */ "Videos and audios" = "Video und Audio"; +/* Suggested invocation phrase to watch a show + Suggested invocation phrase to watch a video + User activity title when watching a video */ +"Watch %@" = "%@ schauen"; + /* Label to present the watch later list */ "Watch later" = "Später schauen"; diff --git a/Application/Resources/Apps/Play SWI/en.lproj/Localizable.strings b/Application/Resources/Apps/Play SWI/en.lproj/Localizable.strings index e9a444ea5..c0d0f279e 100755 --- a/Application/Resources/Apps/Play SWI/en.lproj/Localizable.strings +++ b/Application/Resources/Apps/Play SWI/en.lproj/Localizable.strings @@ -22,6 +22,9 @@ /* Title displayed on the radio home button */ "%@ overview" = "%@ overview"; +/* Text displayed on live cells telling how much time remains for a program currently on air */ +"%@ remaining" = "%@ remaining"; + /* Label displaying the number of views on the player */ "%@ views" = "%@ views"; @@ -107,6 +110,9 @@ /* Settings section header */ "Content" = "Content"; +/* Sort by date option */ +"Date" = "Date"; + /* Title of a delete button Title of the delete button in the alert view when deleting a download in the player view */ "Delete" = "Delete"; @@ -123,6 +129,9 @@ /* Introductory title displayed at the top of the onboarding list */ "Discover" = "Discover"; +/* User activity title when displaying a show page */ +"Display %@ episodes" = "Display %@ videos"; + /* No comment provided by engineer. */ "Do you want to send an anonymous crash report so we can fix the issue?" = "Do you want to send an anonymous crash report so we can fix the issue?"; @@ -212,6 +221,11 @@ /* Explains that a content has expired, will expire or will be available in less than one hour. Displayed in the media player view. */ "less than 1 hour" = "less than 1 hour"; +/* Suggested invocation phrase to listen to a show + Suggested invocation phrase to listen to an audio + User activity title when listening to an audio */ +"Listen to %@" = "Listen to %@"; + /* Introductory text for what is currently on air, displayed on the mini player Short label identifying a livestream. Display in uppercase. */ "Live" = "Live"; @@ -365,6 +379,9 @@ /* Title of the action view to choose a regional radio */ "Regional radios" = "Regional radios"; +/* Sort by relevance option */ +"Relevance" = "Relevance"; + /* Title of the confirmation pop-up displayed when the user is about to clean the watch later list */ "Remove all content" = "Remove all content"; @@ -451,6 +468,9 @@ /* Short label identifying content which will be available soon. */ "Soon" = "Soon"; +/* Settings section header */ +"Sort by" = "Sort by"; + /* Title label used to present live center medias. Only on test versions. */ "Sport" = "Sport"; @@ -565,6 +585,11 @@ /* Header for video and audio search results */ "Videos and audios" = "Videos and audios"; +/* Suggested invocation phrase to watch a show + Suggested invocation phrase to watch a video + User activity title when watching a video */ +"Watch %@" = "Watch %@"; + /* Label to present the watch later list */ "Watch later" = "Watch later"; diff --git a/Application/Resources/Data/parsePlayUrl.js b/Application/Resources/Data/parsePlayUrl.js index 8eceb557f..c4a0b82e4 100644 --- a/Application/Resources/Data/parsePlayUrl.js +++ b/Application/Resources/Data/parsePlayUrl.js @@ -1,6 +1,6 @@ // parsePlayUrl -var parsePlayUrlVersion = 24; +var parsePlayUrlVersion = 26; var parsePlayUrlBuild = "mmf"; if(! console) { @@ -29,11 +29,11 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { * Ex: https://tp.srgssr.ch/p/rts/default?urn=urn:rts:video:6735513 * Ex: https://player.rts.ch/p/rts/default?urn=urn:rts:video:6735513&start=60 */ - if (bu == "tp") { + if (bu == "lb") { if (pathname.startsWith("/p/")) { var mediaURN = queryParams["urn"]; if (mediaURN) { - var redirectBu = "tp"; + var redirectBu = "lb"; switch (true) { case pathname.startsWith("/p/srf/"): redirectBu = "srf"; @@ -55,6 +55,13 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { return openMediaURN(server, redirectBu, mediaURN, startTime); } } + else if (pathname.startsWith("/srgletterbox-web")) { + var mediaURN = queryParams["urn"]; + if (mediaURN) { + var startTime = queryParams["pendingSeek"]; + return openMediaURN(server, "lb", mediaURN, startTime); + } + } } /** @@ -102,7 +109,7 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { pathname = pathname.substring(4); } - if (hostname.includes("play-web")) { + if (hostname.includes("play-web") || hostname.includes("play-staging")) { pathname = pathname.substring(4); pathname = pathname.replace("/stage/play", "/play"); pathname = pathname.replace("/test/play", "/play"); @@ -217,6 +224,24 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { } } + /** + * Catch embed media urls + * + * Ex: https://www.rts.ch/play/embed?urn=urn:rts:video:580545 + * Ex: https://www.rts.ch/play/embed?urn=urn:rts:video:580545&startTime=60 + */ + if (pathname.endsWith("/embed")) { + var mediaURN = queryParams["urn"]; + if (mediaURN) { + var startTime = queryParams["startTime"]; + return openMediaURN(server, bu, mediaURN, startTime); + } + else { + // Returns default TV homepage + return openTvHomePage(server, bu); + } + } + /** * Catch live TV urls * @@ -567,6 +592,16 @@ function parseForPlayApp(scheme, hostname, pathname, queryParams, anchor) { return openTvHomePage(server, bu); } + /** + * Catch legacy bowser urls + * + * Ex: https://www.srf.ch/play/legacy-browser + *. Ex: https://www.rsi.ch/play/legacy-browser + */ + if (pathname.endsWith("/legacy-browser")) { + return openTvHomePage(server, bu); + } + /** * Catch play help urls * @@ -778,7 +813,7 @@ function schemeForBu(bu) { return "playswi"; break; case "mmf": - case "tp": + case "lb": return "letterbox"; break; default: @@ -810,7 +845,7 @@ function serverForUrl(hostname, pathname, queryParams) { } } } - else if (hostname.includes("play-web")) { + else if (hostname.includes("play-web") || hostname.includes("play-staging")) { if (pathname.includes("/stage/play")) { server = "stage"; } @@ -818,22 +853,38 @@ function serverForUrl(hostname, pathname, queryParams) { server = "test"; } } + else if (pathname.startsWith("/srgletterbox-web")) { + var serverParam = queryParams["env"]; + switch (serverParam) { + case "stage": + server = "stage"; + break; + case "test": + server = "test"; + break; + case "play mmf": + case "play+mmf": + case "mmf": + server = "play mmf"; + break; + } + } return server; } 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/")) || (hostname.includes("play-web") && pathname.startsWith("/rts/")): + 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") || (hostname.includes("srgssr") && pathname.startsWith("/srgletterbox-web")): + return "lb"; + case (hostname.includes("rts.ch") && !hostname.includes("play-staging")) || hostname.includes("srgplayer-rts") || (hostname.includes("play-mmf") && pathname.startsWith("/rts/")) || ((hostname.includes("play-web") || hostname.includes("play-staging")) && pathname.startsWith("/rts/")): return "rts"; - case hostname.includes("rsi.ch") || hostname.includes("srgplayer-rsi") || (hostname.includes("play-mmf") && pathname.startsWith("/rsi/")) || (hostname.includes("play-web") && pathname.startsWith("/rsi/")): + case hostname.includes("rsi.ch") || hostname.includes("srgplayer-rsi") || (hostname.includes("play-mmf") && pathname.startsWith("/rsi/")) || ((hostname.includes("play-web") || hostname.includes("play-staging")) && pathname.startsWith("/rsi/")): return "rsi"; - case hostname.includes("rtr.ch") || hostname.includes("srgplayer-rtr") || (hostname.includes("play-mmf") && pathname.startsWith("/rtr/")) || (hostname.includes("play-web") && pathname.startsWith("/rtr/")): + case hostname.includes("rtr.ch") || hostname.includes("srgplayer-rtr") || (hostname.includes("play-mmf") && pathname.startsWith("/rtr/")) || ((hostname.includes("play-web") || hostname.includes("play-staging")) && pathname.startsWith("/rtr/")): return "rtr"; - case hostname.includes("swissinfo.ch") || hostname.includes("srgplayer-swi") || (hostname.includes("play-mmf") && pathname.startsWith("/swi/")) || (hostname.includes("play-web") && pathname.startsWith("/swi/")): + case hostname.includes("swissinfo.ch") || hostname.includes("srgplayer-swi") || (hostname.includes("play-mmf") && pathname.startsWith("/swi/")) || ((hostname.includes("play-web") || hostname.includes("play-staging")) && pathname.startsWith("/swi/")): return "swi"; - case hostname.includes("srf.ch") || hostname.includes("srgplayer-srf") || (hostname.includes("play-mmf") && pathname.startsWith("/srf/")) || (hostname.includes("play-web") && pathname.startsWith("/srf/")): + case hostname.includes("srf.ch") || hostname.includes("srgplayer-srf") || (hostname.includes("play-mmf") && pathname.startsWith("/srf/")) || ((hostname.includes("play-web") || hostname.includes("play-staging")) && pathname.startsWith("/srf/")): return "srf"; case hostname.includes("play-mmf") && pathname.startsWith("/mmf/"): return "mmf"; diff --git a/Application/Resources/Images/CommonImages.xcassets/Icons/radioset-32.imageset/Contents.json b/Application/Resources/Images/CommonImages.xcassets/Icons/radioset-32.imageset/Contents.json new file mode 100644 index 000000000..c55ec9d3d --- /dev/null +++ b/Application/Resources/Images/CommonImages.xcassets/Icons/radioset-32.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Radio_icon.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/Application/Resources/Images/CommonImages.xcassets/Icons/radioset-32.imageset/Radio_icon.pdf b/Application/Resources/Images/CommonImages.xcassets/Icons/radioset-32.imageset/Radio_icon.pdf new file mode 100644 index 000000000..a8e4094c6 Binary files /dev/null and b/Application/Resources/Images/CommonImages.xcassets/Icons/radioset-32.imageset/Radio_icon.pdf differ diff --git a/Application/Resources/Images/CommonImages.xcassets/Icons/tv-22.imageset/Contents.json b/Application/Resources/Images/CommonImages.xcassets/Icons/tv-22.imageset/Contents.json index a15e521b2..d417840d3 100755 --- a/Application/Resources/Images/CommonImages.xcassets/Icons/tv-22.imageset/Contents.json +++ b/Application/Resources/Images/CommonImages.xcassets/Icons/tv-22.imageset/Contents.json @@ -1,15 +1,15 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "tvlive_22.pdf" + "filename" : "tvlive_22.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 }, "properties" : { "template-rendering-intent" : "template" } -} \ No newline at end of file +} diff --git a/Application/Resources/Images/CommonImages.xcassets/Icons/tv-22.imageset/tvlive_22.pdf b/Application/Resources/Images/CommonImages.xcassets/Icons/tv-22.imageset/tvlive_22.pdf old mode 100755 new mode 100644 index 9bba931f1..c5fcbddd0 Binary files a/Application/Resources/Images/CommonImages.xcassets/Icons/tv-22.imageset/tvlive_22.pdf and b/Application/Resources/Images/CommonImages.xcassets/Icons/tv-22.imageset/tvlive_22.pdf differ diff --git a/Application/Resources/Images/CommonImages.xcassets/Icons/tv-32.imageset/Contents.json b/Application/Resources/Images/CommonImages.xcassets/Icons/tv-32.imageset/Contents.json new file mode 100644 index 000000000..9267b5a53 --- /dev/null +++ b/Application/Resources/Images/CommonImages.xcassets/Icons/tv-32.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "tvlive_32.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/Application/Resources/Images/CommonImages.xcassets/Icons/tv-32.imageset/tvlive_32.pdf b/Application/Resources/Images/CommonImages.xcassets/Icons/tv-32.imageset/tvlive_32.pdf new file mode 100644 index 000000000..8fcc106bd Binary files /dev/null and b/Application/Resources/Images/CommonImages.xcassets/Icons/tv-32.imageset/tvlive_32.pdf differ diff --git a/Application/Resources/Settings.bundle/Root.inApp.plist b/Application/Resources/Settings.bundle/Root.inApp.plist index 393f813c4..bcc9badab 100644 --- a/Application/Resources/Settings.bundle/Root.inApp.plist +++ b/Application/Resources/Settings.bundle/Root.inApp.plist @@ -184,6 +184,16 @@ IASKTextAlignment IASKUITextAlignmentLeft + + Type + IASKButtonSpecifier + Title + Become a beta tester on Apple TV + Key + Button_TvBetaTesting + IASKTextAlignment + IASKUITextAlignmentLeft + Type IASKCustomViewSpecifier 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 f7491a38f..41b867eb9 100755 --- a/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.latest_result.txt +++ b/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.latest_result.txt @@ -430,7 +430,7 @@ version: 7.0.1 name: Aiolos, nameSpecified: , owner: IdeasOnCanvas, version: 1.3.0 -name: appcenter-sdk-apple, nameSpecified: , owner: microsoft, version: 3.3.1 +name: appcenter-sdk-apple, nameSpecified: , owner: microsoft, version: 3.3.3 name: CoconutKit, nameSpecified: , owner: defagos, version: 3.4 @@ -440,7 +440,7 @@ name: DZNEmptyDataSet, nameSpecified: , owner: SRGSSR, version: v1.8.1_srg1 name: FXReachability, nameSpecified: , owner: SRGSSR, version: 1.3.2_srg4 -name: ios-library, nameSpecified: , owner: urbanairship, version: 13.4.0 +name: ios-library, nameSpecified: , owner: urbanairship, version: 13.5.4 name: libextobjc, nameSpecified: , owner: SRGSSR, version: 0.6_srg2 @@ -450,7 +450,7 @@ name: Mantle, nameSpecified: , owner: Mantle, version: 2.1.1 name: Masonry, nameSpecified: , owner: SRGSSR, version: v1.1.0_srg1 -name: srganalytics-apple, nameSpecified: , owner: SRGSSR, version: 4.2.0 +name: srganalytics-apple, nameSpecified: , owner: SRGSSR, version: 4.2.1 name: srgappearance-apple, nameSpecified: , owner: SRGSSR, version: 2.1.0 @@ -462,11 +462,11 @@ name: srgdiagnostics-apple, nameSpecified: , owner: SRGSSR, version: 2.0.1 name: srgidentity-apple, nameSpecified: , owner: SRGSSR, version: 2.0.3 -name: srgletterbox-apple, nameSpecified: , owner: SRGSSR, version: 5.0.0 +name: srgletterbox-apple, nameSpecified: , owner: SRGSSR, version: 5.0.1 name: srglogger-apple, nameSpecified: , owner: SRGSSR, version: 2.0.1 -name: srgmediaplayer-apple, nameSpecified: , owner: SRGSSR, version: 5.0.0 +name: srgmediaplayer-apple, nameSpecified: , owner: SRGSSR, version: 5.0.2 name: srgnetwork-apple, nameSpecified: , owner: SRGSSR, version: 2.0.2 diff --git a/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.plist b/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.plist index 915525486..32a8c6d66 100755 --- a/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.plist +++ b/Application/Resources/Settings.bundle/com.mono0926.LicensePlist.plist @@ -16,7 +16,7 @@ File com.mono0926.LicensePlist/appcenter-sdk-apple Title - appcenter-sdk-apple (3.3.1) + appcenter-sdk-apple (3.3.3) Type PSChildPaneSpecifier @@ -160,7 +160,7 @@ File com.mono0926.LicensePlist/ios-library Title - ios-library (13.4.0) + ios-library (13.5.4) Type PSChildPaneSpecifier @@ -248,7 +248,7 @@ File com.mono0926.LicensePlist/srganalytics-apple Title - srganalytics-apple (4.2.0) + srganalytics-apple (4.2.1) Type PSChildPaneSpecifier @@ -296,7 +296,7 @@ File com.mono0926.LicensePlist/srgletterbox-apple Title - srgletterbox-apple (5.0.0) + srgletterbox-apple (5.0.1) Type PSChildPaneSpecifier @@ -312,7 +312,7 @@ File com.mono0926.LicensePlist/srgmediaplayer-apple Title - srgmediaplayer-apple (5.0.0) + srgmediaplayer-apple (5.0.2) Type PSChildPaneSpecifier diff --git a/Application/Resources/Settings.bundle/de.lproj/Settings.strings b/Application/Resources/Settings.bundle/de.lproj/Settings.strings index 720084889..c0bf3a6bd 100755 --- a/Application/Resources/Settings.bundle/de.lproj/Settings.strings +++ b/Application/Resources/Settings.bundle/de.lproj/Settings.strings @@ -4,6 +4,7 @@ "Autoplay" = "Autoplay"; "Background video playback" = "Hintergrundwiedergabe"; "Become a beta tester" = "Beta-Tester werden"; +"Become a beta tester on Apple TV" = "Beta-Tester werden auf Apple TV"; "By default, the application loads high-definition medias over cellular networks. To avoid possible extra costs, this option could be disable and the highest quality will be played only on Wi-Fi networks." = "Standardmässig werden Videos immer in der bestmöglichen Qualität geladen. Um Kosten zu vermeiden, können Sie aber das Abspielen in höchster Qualität (High Definition) in Mobilfunknetzen unterbinden. Sie benötigen dann ein WLAN-Netzwerk, um Videos in HD abzuspielen."; "Check for updates" = "Nach neuen Updates suchen"; "Clear all contents" = "Allen Inhalt entfernen"; diff --git a/Application/Resources/Settings.bundle/en.lproj/Settings.strings b/Application/Resources/Settings.bundle/en.lproj/Settings.strings index dd3cf3de8..0093e0ad6 100755 --- a/Application/Resources/Settings.bundle/en.lproj/Settings.strings +++ b/Application/Resources/Settings.bundle/en.lproj/Settings.strings @@ -4,6 +4,7 @@ "Autoplay" = "Autoplay"; "Background video playback" = "Background video playback"; "Become a beta tester" = "Become a beta tester"; +"Become a beta tester on Apple TV" = "Become a beta tester on Apple TV"; "By default, the application loads high-definition medias over cellular networks. To avoid possible extra costs, this option could be disable and the highest quality will be played only on Wi-Fi networks." = "High-definition medias are played over cellular networks by default. To avoid possible extra costs, disable this option so that high-definition medias are only played when connected to a Wi-Fi network."; "Check for updates" = "Check for updates"; "Clear all contents" = "Clear all contents"; diff --git a/Application/Resources/Settings.bundle/fr.lproj/Settings.strings b/Application/Resources/Settings.bundle/fr.lproj/Settings.strings index a4c643cf5..0ca5d23f8 100755 --- a/Application/Resources/Settings.bundle/fr.lproj/Settings.strings +++ b/Application/Resources/Settings.bundle/fr.lproj/Settings.strings @@ -4,6 +4,7 @@ "Autoplay" = "Lecture automatique"; "Background video playback" = "Lecture vidéo en arrière-plan"; "Become a beta tester" = "Devenez bêta-testeur"; +"Become a beta tester on Apple TV" = "Devenez bêta-testeur sur Apple TV"; "By default, the application loads high-definition medias over cellular networks. To avoid possible extra costs, this option could be disable and the highest quality will be played only on Wi-Fi networks." = "Par défaut, l’application charge le contenu haute définition sur les réseaux cellulaires. Pour éviter les coûts supplémentaires éventuels, cette option peut être désactivée et la meilleure qualité sera jouée uniquement sur les réseaux Wi-Fi."; "Check for updates" = "Vérifier les mises-à-jour"; "Clear all contents" = "Effacer tout le contenu"; diff --git a/Application/Resources/Settings.bundle/it.lproj/Settings.strings b/Application/Resources/Settings.bundle/it.lproj/Settings.strings index 634061e43..f2c03fe6f 100755 --- a/Application/Resources/Settings.bundle/it.lproj/Settings.strings +++ b/Application/Resources/Settings.bundle/it.lproj/Settings.strings @@ -4,6 +4,7 @@ "Autoplay" = "Autoplay"; "Background video playback" = "Play video in secondo piano"; "Become a beta tester" = "Diventare un beta tester"; +"Become a beta tester on Apple TV" = "Diventare un beta tester su Apple TV"; "By default, the application loads high-definition medias over cellular networks. To avoid possible extra costs, this option could be disable and the highest quality will be played only on Wi-Fi networks." = "Per impostazione predefinita, l'applicazione carica contenuti ad alta definizione sulle reti cellulari. Per evitare eventuali spese extra, questa opzione potrebbe essere disabilitata e la massima qualità sarà riprodotta quanto connessi a una rete Wi-Fi."; "Check for updates" = "Controlla aggiornamenti"; "Clear all contents" = "Cancellare tutti i contenuti"; diff --git a/Application/Resources/Settings.bundle/rm.lproj/Settings.strings b/Application/Resources/Settings.bundle/rm.lproj/Settings.strings index f4c3cf87b..8afb6b2f5 100755 --- a/Application/Resources/Settings.bundle/rm.lproj/Settings.strings +++ b/Application/Resources/Settings.bundle/rm.lproj/Settings.strings @@ -4,6 +4,7 @@ "Autoplay" = "Autoplay"; "Background video playback" = "Laschar ir videos davostiers"; "Become a beta tester" = "Daventa in Beta-Tester"; +"Become a beta tester on Apple TV" = "Daventa in Beta-Tester auf Apple TV"; "By default, the application loads high-definition medias over cellular networks. To avoid possible extra costs, this option could be disable and the highest quality will be played only on Wi-Fi networks." = "Sco standard chargia l'applicaziun il cuntegn en aulta resoluziun. Per evitar custs eventuals supplementars, po questa opziun vegnir deactivada e la meglera qualitad po vegnir guardada mo sur Wi-Fi."; "Check for updates" = "Verifitgar actualisaziun"; "Clear all contents" = "Stizzar tut ils cuntegns"; diff --git a/Application/Sources/Configuration/ApplicationConfiguration.h b/Application/Sources/Configuration/ApplicationConfiguration.h index 3aa5d733b..adb73e202 100755 --- a/Application/Sources/Configuration/ApplicationConfiguration.h +++ b/Application/Sources/Configuration/ApplicationConfiguration.h @@ -111,6 +111,7 @@ OBJC_EXPORT NSString * const ApplicationConfigurationDidChangeNotification; @property (nonatomic, readonly, nullable) NSURL *termsAndConditionsURL; @property (nonatomic, readonly, nullable) NSURL *dataProtectionURL; @property (nonatomic, readonly, nullable) NSURL *betaTestingURL; +@property (nonatomic, readonly, nullable) NSURL *tvBetaTestingURL; @property (nonatomic, readonly, nullable) NSURL *sourceCodeURL; @property (nonatomic, readonly, getter=areDownloadsHintsHidden) BOOL downloadsHintsHidden; @@ -156,6 +157,7 @@ OBJC_EXPORT NSString * const ApplicationConfigurationDidChangeNotification; @property (nonatomic, readonly, getter=areSearchSettingsHidden) BOOL searchSettingsHidden; @property (nonatomic, readonly, getter=isSearchSettingSubtitledHidden) BOOL searchSettingSubtitledHidden; +@property (nonatomic, readonly, getter=isSearchSortingCriteriumHidden) BOOL searchSortingCriteriumHidden; @property (nonatomic, readonly, getter=isShowsSearchHidden) BOOL showsSearchHidden; - (nullable RadioChannel *)radioChannelForUid:(NSString *)uid; diff --git a/Application/Sources/Configuration/ApplicationConfiguration.m b/Application/Sources/Configuration/ApplicationConfiguration.m index deb5e035c..c4a531434 100755 --- a/Application/Sources/Configuration/ApplicationConfiguration.m +++ b/Application/Sources/Configuration/ApplicationConfiguration.m @@ -238,6 +238,7 @@ @interface ApplicationConfiguration () @property (nonatomic) NSURL *termsAndConditionsURL; @property (nonatomic) NSURL *dataProtectionURL; @property (nonatomic) NSURL *betaTestingURL; +@property (nonatomic) NSURL *tvBetaTestingURL; @property (nonatomic) NSURL *sourceCodeURL; @property (nonatomic, getter=areDownloadsHintsHidden) BOOL downloadsHintsHidden; @@ -283,6 +284,7 @@ @interface ApplicationConfiguration () @property (nonatomic, getter=areSearchSettingsHidden) BOOL searchSettingsHidden; @property (nonatomic, getter=isSearchSettingSubtitledHidden) BOOL searchSettingSubtitledHidden; +@property (nonatomic, getter=isSearchSortingCriteriumHidden) BOOL searchSortingCriteriumHidden; @property (nonatomic, getter=isShowsSearchHidden) BOOL showsSearchHidden; #if defined(DEBUG) || defined(NIGHTLY) || defined(BETA) @@ -472,6 +474,9 @@ - (BOOL)synchronizeRemoteConfiguration NSString *betaTestingURLString = [self.remoteConfig configValueForKey:@"betaTestingURL"].stringValue; self.betaTestingURL = (betaTestingURLString.length != 0) ? [NSURL URLWithString:betaTestingURLString] : nil; + NSString *tvBetaTestingURLString = [self.remoteConfig configValueForKey:@"tvBetaTestingURL"].stringValue; + self.tvBetaTestingURL = (tvBetaTestingURLString.length != 0) ? [NSURL URLWithString:tvBetaTestingURLString] : nil; + NSString *sourceCodeURLString = [self.remoteConfig configValueForKey:@"sourceCodeURL"].stringValue; self.sourceCodeURL = (sourceCodeURLString.length != 0) ? [NSURL URLWithString:sourceCodeURLString] : nil; @@ -636,6 +641,7 @@ - (BOOL)synchronizeRemoteConfiguration self.searchSettingsHidden = [self.remoteConfig configValueForKey:@"searchSettingsHidden"].boolValue; self.searchSettingSubtitledHidden = [self.remoteConfig configValueForKey:@"searchSettingSubtitledHidden"].boolValue; + self.searchSortingCriteriumHidden = [self.remoteConfig configValueForKey:@"searchSortingCriteriumHidden"].boolValue; self.showsSearchHidden = [self.remoteConfig configValueForKey:@"showsSearchHidden"].boolValue; self.logoutMenuEnabled = [self.remoteConfig configValueForKey:@"logoutMenuEnabled"].boolValue; diff --git a/Application/Sources/Configuration/RadioChannel.h b/Application/Sources/Configuration/RadioChannel.h index af71dbc05..74068478b 100755 --- a/Application/Sources/Configuration/RadioChannel.h +++ b/Application/Sources/Configuration/RadioChannel.h @@ -14,13 +14,8 @@ NS_ASSUME_NONNULL_BEGIN /** * Images associated with the radio channel. */ -OBJC_EXPORT UIImage *RadioChannelBanner22Image(RadioChannel * _Nullable radioChannel); OBJC_EXPORT UIImage *RadioChannelLogo22Image(RadioChannel * _Nullable radioChannel); - -/** - * Image overrides. - */ -OBJC_EXPORT NSString * _Nullable RadioChannelImageOverridePath(RadioChannel * _Nullable radioChannel, NSString *type); +OBJC_EXPORT UIImage *RadioChannelLogo32Image(RadioChannel * _Nullable radioChannel); /** * Represent a radio channel in the application configuration. diff --git a/Application/Sources/Configuration/RadioChannel.m b/Application/Sources/Configuration/RadioChannel.m index 2a01614aa..69581132b 100755 --- a/Application/Sources/Configuration/RadioChannel.m +++ b/Application/Sources/Configuration/RadioChannel.m @@ -29,18 +29,12 @@ - (instancetype)initWithDictionary:(NSDictionary *)dictionary @end -UIImage *RadioChannelBanner22Image(RadioChannel *radioChannel) -{ - return [UIImage imageNamed:[NSString stringWithFormat:@"banner_%@-22", radioChannel.resourceUid]] ?: RadioChannelLogo22Image(radioChannel); -} - UIImage *RadioChannelLogo22Image(RadioChannel *radioChannel) { return [UIImage imageNamed:[NSString stringWithFormat:@"logo_%@-22", radioChannel.resourceUid]] ?: [UIImage imageNamed:@"radioset-22"]; } -NSString *RadioChannelImageOverridePath(RadioChannel *radioChannel, NSString *type) +UIImage *RadioChannelLogo32Image(RadioChannel *radioChannel) { - NSString *overrideImageName = [NSString stringWithFormat:@"override_%@_%@", type, radioChannel.resourceUid]; - return [NSBundle.mainBundle pathForResource:overrideImageName ofType:@"pdf"]; + return [UIImage imageNamed:[NSString stringWithFormat:@"logo_%@-32", radioChannel.resourceUid]] ?: [UIImage imageNamed:@"radioset-32"]; } diff --git a/Application/Sources/Configuration/TVChannel.h b/Application/Sources/Configuration/TVChannel.h index 3bcd6e866..1f497acaf 100755 --- a/Application/Sources/Configuration/TVChannel.h +++ b/Application/Sources/Configuration/TVChannel.h @@ -14,12 +14,8 @@ NS_ASSUME_NONNULL_BEGIN /** * Images associated with the TV channel. */ -OBJC_EXPORT UIImage *TVChannelBanner22Image(TVChannel * _Nullable tvChannel); - -/** - * Image overrides. - */ -OBJC_EXPORT NSString * _Nullable TVChannelImageOverridePath(TVChannel * _Nullable tvChannel, NSString *type); +OBJC_EXPORT UIImage *TVChannelLogo22Image(TVChannel * _Nullable tvChannel); +OBJC_EXPORT UIImage *TVChannelLogo32Image(TVChannel * _Nullable tvChannel); /** * Represent a TV channel in the application configuration. diff --git a/Application/Sources/Configuration/TVChannel.m b/Application/Sources/Configuration/TVChannel.m index 0867744ba..084775243 100755 --- a/Application/Sources/Configuration/TVChannel.m +++ b/Application/Sources/Configuration/TVChannel.m @@ -14,13 +14,12 @@ @implementation TVChannel @end -UIImage *TVChannelBanner22Image(TVChannel *tvChannel) +UIImage *TVChannelLogo22Image(TVChannel *tvChannel) { return [UIImage imageNamed:[NSString stringWithFormat:@"logo_%@-22", tvChannel.resourceUid]] ?: [UIImage imageNamed:@"tv-22"]; } -NSString *TVChannelImageOverridePath(TVChannel *tvChannel, NSString *type) +UIImage *TVChannelLogo32Image(TVChannel *tvChannel) { - NSString *overrideImageName = [NSString stringWithFormat:@"override_%@_%@", type, tvChannel.resourceUid]; - return [NSBundle.mainBundle pathForResource:overrideImageName ofType:@"pdf"]; + return [UIImage imageNamed:[NSString stringWithFormat:@"logo_%@-32", tvChannel.resourceUid]] ?: [UIImage imageNamed:@"tv-32"]; } diff --git a/Application/Sources/Downloads/DownloadTableViewCell.m b/Application/Sources/Downloads/DownloadTableViewCell.m index ec6b151e8..d9d5e5474 100755 --- a/Application/Sources/Downloads/DownloadTableViewCell.m +++ b/Application/Sources/Downloads/DownloadTableViewCell.m @@ -226,7 +226,7 @@ - (void)setDownload:(Download *)download [self.webFirstLabel play_setWebFirstBadge]; // Have content fit in (almost) constant size vertically by reducing the title number of lines when a tag is displayed - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; if (SRGAppearanceCompareContentSizeCategories(contentSizeCategory, UIContentSizeCategoryExtraLarge) == NSOrderedDescending) { self.titleLabel.numberOfLines = isWebFirst ? 1 : 2; } diff --git a/Application/Sources/Helpers/AnalyticsConstants.h b/Application/Sources/Helpers/AnalyticsConstants.h index 23f9868b1..2fdd9f48a 100755 --- a/Application/Sources/Helpers/AnalyticsConstants.h +++ b/Application/Sources/Helpers/AnalyticsConstants.h @@ -32,6 +32,7 @@ OBJC_EXPORT AnalyticsPageLevel const AnalyticsPageLevelVideo; typedef NSString * AnalyticsPageTitle NS_STRING_ENUM; OBJC_EXPORT AnalyticsPageTitle const AnalyticsPageTitleBetaTesting; +OBJC_EXPORT AnalyticsPageTitle const AnalyticsPageTitleTvBetaTesting; OBJC_EXPORT AnalyticsPageTitle const AnalyticsPageTitleDevices; OBJC_EXPORT AnalyticsPageTitle const AnalyticsPageTitleDownloads; OBJC_EXPORT AnalyticsPageTitle const AnalyticsPageTitleEvents; diff --git a/Application/Sources/Helpers/AnalyticsConstants.m b/Application/Sources/Helpers/AnalyticsConstants.m index 320c49ae2..d0c092f76 100755 --- a/Application/Sources/Helpers/AnalyticsConstants.m +++ b/Application/Sources/Helpers/AnalyticsConstants.m @@ -23,6 +23,7 @@ AnalyticsPageLevel const AnalyticsPageLevelVideo = @"video"; AnalyticsPageTitle const AnalyticsPageTitleBetaTesting = @"beta testing"; +AnalyticsPageTitle const AnalyticsPageTitleTvBetaTesting = @"tv beta testing"; AnalyticsPageTitle const AnalyticsPageTitleDevices = @"devices"; AnalyticsPageTitle const AnalyticsPageTitleDownloads = @"downloads"; AnalyticsPageTitle const AnalyticsPageTitleEvents = @"events"; diff --git a/Application/Sources/Helpers/Categories/SRGChannel+PlaySRG.h b/Application/Sources/Helpers/Categories/SRGChannel+PlaySRG.h index d6d87b2d2..319562ce6 100755 --- a/Application/Sources/Helpers/Categories/SRGChannel+PlaySRG.h +++ b/Application/Sources/Helpers/Categories/SRGChannel+PlaySRG.h @@ -10,7 +10,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SRGChannel (PlaySRG) -@property (nonatomic, readonly, nullable) UIImage *play_banner22Image; +@property (nonatomic, readonly, nullable) UIImage *play_logo32Image; @end diff --git a/Application/Sources/Helpers/Categories/SRGChannel+PlaySRG.m b/Application/Sources/Helpers/Categories/SRGChannel+PlaySRG.m index 0dbdef3b7..a4579f02a 100755 --- a/Application/Sources/Helpers/Categories/SRGChannel+PlaySRG.m +++ b/Application/Sources/Helpers/Categories/SRGChannel+PlaySRG.m @@ -12,17 +12,17 @@ @implementation SRGChannel (PlaySRG) -- (UIImage *)play_banner22Image +- (UIImage *)play_logo32Image { if (self.transmission == SRGTransmissionRadio) { NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @keypath(RadioChannel.new, uid), self.uid]; RadioChannel *radioChannel = [ApplicationConfiguration.sharedApplicationConfiguration.radioChannels filteredArrayUsingPredicate:predicate].firstObject; - return RadioChannelBanner22Image(radioChannel); + return RadioChannelLogo32Image(radioChannel); } else { NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @keypath(TVChannel.new, uid), self.uid]; TVChannel *tvChannel = [ApplicationConfiguration.sharedApplicationConfiguration.tvChannels filteredArrayUsingPredicate:predicate].firstObject; - return TVChannelBanner22Image(tvChannel); + return TVChannelLogo32Image(tvChannel); } } diff --git a/Application/Sources/Helpers/Categories/UIImage+PlaySRG.m b/Application/Sources/Helpers/Categories/UIImage+PlaySRG.m index a17392d7f..c299d7f6b 100755 --- a/Application/Sources/Helpers/Categories/UIImage+PlaySRG.m +++ b/Application/Sources/Helpers/Categories/UIImage+PlaySRG.m @@ -121,20 +121,4 @@ + (UIImage *)play_vectorImageAtPath:(NSString *)filePath withScale:(ImageScale)i return filePath ? [self srg_vectorImageAtPath:filePath withSize:SizeForImageScale(imageScale)] : nil; } -+ (NSString *)overrideImagePathForUid:(NSString *)uid withType:(NSString *)type -{ - ApplicationConfiguration *applicationConfiguration = ApplicationConfiguration.sharedApplicationConfiguration; - RadioChannel *radioChannel = [applicationConfiguration radioChannelForUid:uid]; - if (radioChannel) { - return RadioChannelImageOverridePath(radioChannel, type); - } - - TVChannel *tvChannel = [applicationConfiguration tvChannelForUid:uid]; - if (tvChannel) { - return TVChannelImageOverridePath(tvChannel, type); - } - - return nil; -} - @end diff --git a/Application/Sources/Helpers/Categories/UILabel+PlaySRG.m b/Application/Sources/Helpers/Categories/UILabel+PlaySRG.m index d0ef0d8b6..1ae2959ab 100755 --- a/Application/Sources/Helpers/Categories/UILabel+PlaySRG.m +++ b/Application/Sources/Helpers/Categories/UILabel+PlaySRG.m @@ -15,6 +15,33 @@ #import +static NSString *LabelFormattedDuration(NSTimeInterval duration) +{ + if (duration >= 60. * 60. * 24.) { + static NSDateComponentsFormatter *s_dateComponentsFormatter; + static dispatch_once_t s_onceToken; + dispatch_once(&s_onceToken, ^{ + s_dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init]; + s_dateComponentsFormatter.allowedUnits = NSCalendarUnitDay; + s_dateComponentsFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull; + }); + return [s_dateComponentsFormatter stringFromTimeInterval:duration]; + } + else if (duration >= 60. * 60.) { + static NSDateComponentsFormatter *s_dateComponentsFormatter; + static dispatch_once_t s_onceToken; + dispatch_once(&s_onceToken, ^{ + s_dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init]; + s_dateComponentsFormatter.allowedUnits = NSCalendarUnitHour; + s_dateComponentsFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull; + }); + return [s_dateComponentsFormatter stringFromTimeInterval:duration]; + } + else { + return NSLocalizedString(@"less than 1 hour", @"Explains that a content has expired, will expire or will be available in less than one hour. Displayed in the media player view."); + } +} + @implementation UILabel (PlaySRG) #pragma mark Public @@ -38,13 +65,13 @@ - (void)play_displayAvailabilityLabelForMediaMetadata:(id)obje if (timeAvailability == SRGTimeAvailabilityNotAvailableAnymore) { NSDate *endDate = object.endDate ?: [object.date dateByAddingTimeInterval:object.duration / 1000.]; NSTimeInterval timeIntervalAfterEnd = [nowDate timeIntervalSinceDate:endDate]; - text = [NSString stringWithFormat:NSLocalizedString(@"Not available since %@", @"Explains that a content has expired (days or hours ago). Displayed in the media player view."), PlayShortFormattedDuration(timeIntervalAfterEnd)]; + text = [NSString stringWithFormat:NSLocalizedString(@"Not available since %@", @"Explains that a content has expired (days or hours ago). Displayed in the media player view."), LabelFormattedDuration(timeIntervalAfterEnd)]; } else if (timeAvailability == SRGTimeAvailabilityAvailable && object.endDate && object.contentType != SRGContentTypeScheduledLivestream && object.contentType != SRGContentTypeLivestream) { NSDateComponents *monthsDateComponents = [NSCalendar.currentCalendar components:NSCalendarUnitDay fromDate:nowDate toDate:object.endDate options:0]; if (monthsDateComponents.day <= 30) { NSTimeInterval timeIntervalBeforeEnd = [object.endDate timeIntervalSinceDate:nowDate]; - text = [NSString stringWithFormat:NSLocalizedString(@"Still available for %@", @"Explains that a content is still online (for days or hours) but will expire. Displayed in the media player view."), PlayShortFormattedDuration(timeIntervalBeforeEnd)]; + text = [NSString stringWithFormat:NSLocalizedString(@"Still available for %@", @"Explains that a content is still online (for days or hours) but will expire. Displayed in the media player view."), LabelFormattedDuration(timeIntervalBeforeEnd)]; } } diff --git a/Application/Sources/Helpers/Layout.h b/Application/Sources/Helpers/Layout.h index 6e32058ea..be974bc0b 100644 --- a/Application/Sources/Helpers/Layout.h +++ b/Application/Sources/Helpers/Layout.h @@ -74,7 +74,7 @@ OBJC_EXPORT CGFloat LayoutTableTopAlignedCellHeight(CGFloat contentHeight, CGFlo OBJC_EXPORT CGSize LayoutMediaStandardCollectionItemSize(CGFloat itemWidth, BOOL large); /** - * Live media cell (16:9 artwork + text area) size for collection layouts, for a given item width. + * Live media cell (16:9 artwork + progress area) size for collection layouts, for a given item width. * * @param itemWidth The width of the item. */ diff --git a/Application/Sources/Helpers/Layout.m b/Application/Sources/Helpers/Layout.m index af0b7b02e..486a6e98c 100644 --- a/Application/Sources/Helpers/Layout.m +++ b/Application/Sources/Helpers/Layout.m @@ -33,7 +33,7 @@ CGFloat LayoutCollectionItemFeaturedWidth(CGFloat layoutWidth) CGFloat LayoutStandardTableSectionHeaderHeight(BOOL hasBackgroundColor) { - static NSDictionary *s_headerHeights; + static NSDictionary *s_headerHeights; static dispatch_once_t s_onceToken; dispatch_once(&s_onceToken, ^{ s_headerHeights = @{ UIContentSizeCategoryExtraSmall : @25, @@ -50,7 +50,7 @@ CGFloat LayoutStandardTableSectionHeaderHeight(BOOL hasBackgroundColor) UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @40 }; }); - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; CGFloat headerHeight = s_headerHeights[contentSizeCategory].floatValue; if (hasBackgroundColor) { headerHeight += 6.f; @@ -60,7 +60,7 @@ CGFloat LayoutStandardTableSectionHeaderHeight(BOOL hasBackgroundColor) CGFloat LayoutStandardSimpleTableCellHeight(void) { - static NSDictionary *s_heights; + static NSDictionary *s_heights; static dispatch_once_t s_onceToken; dispatch_once(&s_onceToken, ^{ s_heights = @{ UIContentSizeCategoryExtraSmall : @42, @@ -76,7 +76,7 @@ CGFloat LayoutStandardSimpleTableCellHeight(void) UIContentSizeCategoryAccessibilityExtraExtraLarge : @62, UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @62 }; }); - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; return s_heights[contentSizeCategory].floatValue; } @@ -123,39 +123,20 @@ CGSize LayoutMediaStandardCollectionItemSize(CGFloat itemWidth, BOOL large) UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @90 }; }); - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; CGFloat minTextHeight = large ? s_largeTextHeights[contentSizeCategory].floatValue : s_standardTextHeights[contentSizeCategory].floatValue; return CGSizeMake(itemWidth, ceilf(itemWidth * 9.f / 16.f + minTextHeight)); } CGSize LayoutLiveMediaStandardCollectionItemSize(CGFloat itemWidth) { - static NSDictionary *s_textHeights; - static dispatch_once_t s_onceToken; - dispatch_once(&s_onceToken, ^{ - s_textHeights = @{ UIContentSizeCategoryExtraSmall : @64, - UIContentSizeCategorySmall : @66, - UIContentSizeCategoryMedium : @68, - UIContentSizeCategoryLarge : @70, - UIContentSizeCategoryExtraLarge : @72, - UIContentSizeCategoryExtraExtraLarge : @74, - UIContentSizeCategoryExtraExtraExtraLarge : @76, - UIContentSizeCategoryAccessibilityMedium : @76, - UIContentSizeCategoryAccessibilityLarge : @76, - UIContentSizeCategoryAccessibilityExtraLarge : @76, - UIContentSizeCategoryAccessibilityExtraExtraLarge : @76, - UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @76 }; - }); - - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; - CGFloat minTextHeight = s_textHeights[contentSizeCategory].floatValue; - return CGSizeMake(itemWidth, ceilf(itemWidth * 9.f / 16.f + minTextHeight)); + return CGSizeMake(itemWidth, ceilf(itemWidth * 9.f / 16.f + 11.f)); } CGSize LayoutShowStandardCollectionItemSize(CGFloat itemWidth, BOOL large) { - static NSDictionary *s_largeTextHeights; - static NSDictionary *s_standardTextHeights; + static NSDictionary *s_largeTextHeights; + static NSDictionary *s_standardTextHeights; static dispatch_once_t s_onceToken; dispatch_once(&s_onceToken, ^{ s_largeTextHeights = @{ UIContentSizeCategoryExtraSmall : @28, @@ -185,7 +166,7 @@ CGSize LayoutShowStandardCollectionItemSize(CGFloat itemWidth, BOOL large) UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @36 }; }); - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; CGFloat minTextHeight = large ? s_largeTextHeights[contentSizeCategory].floatValue : s_standardTextHeights[contentSizeCategory].floatValue; return CGSizeMake(itemWidth, ceilf(itemWidth * 9.f / 16.f + minTextHeight)); } diff --git a/Application/Sources/Helpers/PlayAccessibilityFormatter.m b/Application/Sources/Helpers/PlayAccessibilityFormatter.m index 337d71f17..356190be7 100644 --- a/Application/Sources/Helpers/PlayAccessibilityFormatter.m +++ b/Application/Sources/Helpers/PlayAccessibilityFormatter.m @@ -14,7 +14,7 @@ static dispatch_once_t s_onceToken; dispatch_once(&s_onceToken, ^{ s_dateFormatter = [[NSDateFormatter alloc] init]; - s_dateFormatter.dateStyle = kCFDateFormatterLongStyle; + s_dateFormatter.dateStyle = NSDateFormatterLongStyle; s_dateFormatter.timeStyle = NSDateFormatterNoStyle; s_dateFormatter.doesRelativeDateFormatting = YES; }); diff --git a/Application/Sources/Helpers/PlayDurationFormatter.h b/Application/Sources/Helpers/PlayDurationFormatter.h index 0b9858c45..b85007f0b 100755 --- a/Application/Sources/Helpers/PlayDurationFormatter.h +++ b/Application/Sources/Helpers/PlayDurationFormatter.h @@ -18,9 +18,4 @@ OBJC_EXPORT NSString *PlayFormattedDuration(NSTimeInterval duration); */ OBJC_EXPORT NSString *PlayHumanReadableFormattedDuration(NSTimeInterval duration); -/** - * Formats a duration in a compact form, only telling number of days or hours. - */ -OBJC_EXPORT NSString *PlayShortFormattedDuration(NSTimeInterval duration); - NS_ASSUME_NONNULL_END diff --git a/Application/Sources/Helpers/PlayDurationFormatter.m b/Application/Sources/Helpers/PlayDurationFormatter.m index 61aa2fbab..7bccad76c 100755 --- a/Application/Sources/Helpers/PlayDurationFormatter.m +++ b/Application/Sources/Helpers/PlayDurationFormatter.m @@ -55,32 +55,3 @@ return [s_dateComponentsFormatter stringFromTimeInterval:duration]; } } - -NSString *PlayShortFormattedDuration(NSTimeInterval duration) -{ - // Display days if > 24 hours - if (duration > 60. * 60. * 24.) { - static NSDateComponentsFormatter *s_dateComponentsFormatter; - static dispatch_once_t s_onceToken; - dispatch_once(&s_onceToken, ^{ - s_dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init]; - s_dateComponentsFormatter.allowedUnits = NSCalendarUnitDay; - s_dateComponentsFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull; - }); - return [s_dateComponentsFormatter stringFromTimeInterval:duration]; - } - // Display hours if > 1 hour - else if (duration > 60. * 60.) { - static NSDateComponentsFormatter *s_dateComponentsFormatter; - static dispatch_once_t s_onceToken; - dispatch_once(&s_onceToken, ^{ - s_dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init]; - s_dateComponentsFormatter.allowedUnits = NSCalendarUnitHour; - s_dateComponentsFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull; - }); - return [s_dateComponentsFormatter stringFromTimeInterval:duration]; - } - else { - return NSLocalizedString(@"less than 1 hour", @"Explains that a content has expired, will expire or will be available in less than one hour. Displayed in the media player view."); - } -} diff --git a/Application/Sources/History/HistoryTableViewCell.m b/Application/Sources/History/HistoryTableViewCell.m index 1ccbf5230..85ad840b6 100755 --- a/Application/Sources/History/HistoryTableViewCell.m +++ b/Application/Sources/History/HistoryTableViewCell.m @@ -271,7 +271,7 @@ - (void)setMedia:(SRGMedia *)media [self.subtitlesLabel play_setSubtitlesAvailableBadge]; // Have content fit in (almost) constant size vertically by reducing the title number of lines when a tag is displayed - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; if (SRGAppearanceCompareContentSizeCategories(contentSizeCategory, UIContentSizeCategoryExtraLarge) == NSOrderedDescending) { self.titleLabel.numberOfLines = (isWebFirst || hasSubtitles || hasAudioDescription) ? 1 : 2; } diff --git a/Application/Sources/Home/HomeLiveMediaCollectionViewCell.m b/Application/Sources/Home/HomeLiveMediaCollectionViewCell.m index 8367f5db8..26c2477bb 100755 --- a/Application/Sources/Home/HomeLiveMediaCollectionViewCell.m +++ b/Application/Sources/Home/HomeLiveMediaCollectionViewCell.m @@ -20,12 +20,36 @@ #import "SRGProgramComposition+PlaySRG.h" #import "UIColor+PlaySRG.h" #import "UIImageView+PlaySRG.h" -#import "UILabel+PlaySRG.h" #import #import #import +static NSString *RemainingTimeFormattedDuration(NSTimeInterval duration) +{ + if (duration >= 60. * 60.) { + static NSDateComponentsFormatter *s_dateComponentsFormatter; + static dispatch_once_t s_onceToken; + dispatch_once(&s_onceToken, ^{ + s_dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init]; + s_dateComponentsFormatter.allowedUnits = NSCalendarUnitHour; + s_dateComponentsFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull; + }); + return [s_dateComponentsFormatter stringFromTimeInterval:duration]; + } + else { + static NSDateComponentsFormatter *s_dateComponentsFormatter; + static dispatch_once_t s_onceToken; + dispatch_once(&s_onceToken, ^{ + s_dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init]; + s_dateComponentsFormatter.allowedUnits = NSCalendarUnitMinute; + s_dateComponentsFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull; + }); + // Minimum is 1 minute + return [s_dateComponentsFormatter stringFromTimeInterval:fmax(60., duration)]; + } +} + @interface HomeLiveMediaCollectionViewCell () @property (nonatomic) SRGProgramComposition *programComposition; @@ -34,18 +58,20 @@ @interface HomeLiveMediaCollectionViewCell () @property (nonatomic, weak) IBOutlet UIView *placeholderView; @property (nonatomic, weak) IBOutlet UIImageView *placeholderImageView; +@property (nonatomic, weak) IBOutlet UIView *wrapperView; @property (nonatomic, weak) IBOutlet UIImageView *logoImageView; -@property (nonatomic, weak) IBOutlet UILabel *recentLabel; @property (nonatomic, weak) IBOutlet UILabel *titleLabel; @property (nonatomic, weak) IBOutlet UILabel *subtitleLabel; @property (nonatomic, weak) IBOutlet UIImageView *thumbnailImageView; -@property (nonatomic, weak) IBOutlet UILabel *durationLabel; @property (nonatomic, weak) IBOutlet UIView *blockingOverlayView; @property (nonatomic, weak) IBOutlet UIImageView *blockingReasonImageView; @property (nonatomic, weak) IBOutlet UIProgressView *progressView; +@property (nonatomic, weak) IBOutlet NSLayoutConstraint *topSpaceConstraint; +@property (nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *horizontalSpaceConstraints; + @property (nonatomic, weak) id channelRegistration; @end @@ -72,23 +98,28 @@ - (void)awakeFromNib self.progressView.progressTintColor = UIColor.play_progressRedColor; - self.subtitleLabel.textColor = UIColor.play_lightGrayColor; + self.titleLabel.textColor = UIColor.whiteColor; + self.subtitleLabel.textColor = UIColor.whiteColor; self.thumbnailImageView.backgroundColor = UIColor.play_grayThumbnailImageViewBackgroundColor; - self.thumbnailImageView.layer.cornerRadius = LayoutStandardViewCornerRadius; - self.thumbnailImageView.layer.masksToBounds = YES; - - self.recentLabel.layer.cornerRadius = LayoutStandardLabelCornerRadius; - self.recentLabel.layer.masksToBounds = YES; - self.recentLabel.backgroundColor = UIColor.play_blackDurationLabelBackgroundColor; - self.recentLabel.text = [NSString stringWithFormat:@" %@ ", NSLocalizedString(@"Last played", @"Label on recently played livestreams").uppercaseString]; - self.recentLabel.hidden = YES; - self.durationLabel.backgroundColor = UIColor.play_blackDurationLabelBackgroundColor; + self.wrapperView.layer.cornerRadius = LayoutStandardViewCornerRadius; + self.wrapperView.layer.masksToBounds = YES; self.blockingOverlayView.hidden = YES; } +- (void)layoutSubviews +{ + [super layoutSubviews]; + + BOOL isSmallLayout = (CGRectGetWidth(self.frame) < 170.f); + self.topSpaceConstraint.constant = isSmallLayout ? 4.f : 12.f; + [self.horizontalSpaceConstraints enumerateObjectsUsingBlock:^(NSLayoutConstraint * _Nonnull constraint, NSUInteger idx, BOOL * _Nonnull stop) { + constraint.constant = isSmallLayout ? 4.f : 8.f; + }]; +} + - (void)prepareForReuse { [super prepareForReuse]; @@ -148,10 +179,6 @@ - (NSString *)accessibilityLabel SRGChannel *channel = self.programComposition.channel ?: self.media.channel; if (channel) { NSMutableString *accessibilityLabel = [NSMutableString stringWithFormat:PlaySRGAccessibilityLocalizedString(@"%@ live", @"Live content label, with a channel title"), channel.title]; - if (! self.recentLabel.hidden) { - [accessibilityLabel appendFormat:@", %@", PlaySRGAccessibilityLocalizedString(@"Last played", @"Label on recently played livestreams")]; - } - SRGProgram *currentProgram = [self.programComposition play_programAtDate:NSDate.date]; if (currentProgram) { [accessibilityLabel appendFormat:@", %@", currentProgram.title]; @@ -218,42 +245,32 @@ - (void)reloadData self.placeholderView.hidden = YES; self.titleLabel.font = [UIFont srg_mediumFontWithTextStyle:SRGAppearanceFontTextStyleBody]; - self.durationLabel.font = [UIFont srg_mediumFontWithTextStyle:SRGAppearanceFontTextStyleCaption]; - - self.recentLabel.font = [UIFont srg_mediumFontWithTextStyle:SRGAppearanceFontTextStyleCaption]; - self.recentLabel.hidden = ! [self.media.URN isEqualToString:ApplicationSettingLastSelectedTVLivestreamURN()] - && ! [self.media.URN isEqualToString:ApplicationSettingLastSelectedRadioLivestreamURN()]; SRGBlockingReason blockingReason = [self.media blockingReasonAtDate:NSDate.date]; if (blockingReason == SRGBlockingReasonNone || blockingReason == SRGBlockingReasonStartDate) { self.blockingOverlayView.hidden = YES; - - self.titleLabel.textColor = UIColor.whiteColor; } else { self.blockingOverlayView.hidden = NO; self.blockingReasonImageView.image = [UIImage play_imageForBlockingReason:blockingReason]; - - self.titleLabel.textColor = UIColor.play_lightGrayColor; } - SRGAppearanceFontTextStyle subtitleTextStyle = SRGAppearanceFontTextStyleSubtitle; + CGFloat subtitleFontSize = 11.f; ImageScale imageScale = ImageScaleMedium; - self.subtitleLabel.font = [UIFont srg_mediumFontWithTextStyle:subtitleTextStyle]; - - [self.durationLabel play_displayDurationLabelForMediaMetadata:self.media]; + self.subtitleLabel.font = [UIFont srg_mediumFontWithSize:subtitleFontSize]; SRGChannel *channel = self.programComposition.channel ?: self.media.channel; if (channel) { - UIImage *logoImage = channel.play_banner22Image; + UIImage *logoImage = channel.play_logo32Image; self.logoImageView.image = logoImage; - self.logoImageView.hidden = (logoImage == nil); SRGProgram *currentProgram = [self.programComposition play_programAtDate:NSDate.date]; if (currentProgram) { self.titleLabel.text = currentProgram.title; - self.subtitleLabel.text = [NSString stringWithFormat:@"%@ - %@", [NSDateFormatter.play_timeFormatter stringFromDate:currentProgram.startDate], [NSDateFormatter.play_timeFormatter stringFromDate:currentProgram.endDate]]; + + NSTimeInterval remainingTimeInterval = [currentProgram.endDate timeIntervalSinceDate:NSDate.date]; + self.subtitleLabel.text = [NSString stringWithFormat:NSLocalizedString(@"%@ remaining", "Text displayed on live cells telling how much time remains for a program currently on air"), RemainingTimeFormattedDuration(remainingTimeInterval)]; float progress = [NSDate.date timeIntervalSinceDate:currentProgram.startDate] / ([currentProgram.endDate timeIntervalSinceDate:currentProgram.startDate]); self.progressView.progress = fmaxf(fminf(progress, 1.f), 0.f); @@ -274,16 +291,16 @@ - (void)reloadData } else { self.titleLabel.text = self.media.title; - self.logoImageView.hidden = YES; + self.logoImageView.image = (self.media.mediaType == SRGMediaTypeAudio) ? RadioChannelLogo32Image(nil) : TVChannelLogo32Image(nil); NSString *showTitle = self.media.show.title; if (showTitle && ! [self.media.title containsString:showTitle]) { NSMutableAttributedString *subtitle = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ - ", showTitle] - attributes:@{ NSFontAttributeName : [UIFont srg_mediumFontWithTextStyle:subtitleTextStyle] }]; + attributes:@{ NSFontAttributeName : [UIFont srg_mediumFontWithSize:subtitleFontSize] }]; NSDateFormatter *dateFormatter = NSDateFormatter.play_relativeDateAndTimeFormatter; [subtitle appendAttributedString:[[NSAttributedString alloc] initWithString:[dateFormatter stringFromDate:self.media.date].play_localizedUppercaseFirstLetterString - attributes:@{ NSFontAttributeName : [UIFont srg_lightFontWithTextStyle:subtitleTextStyle] }]]; + attributes:@{ NSFontAttributeName : [UIFont srg_lightFontWithSize:subtitleFontSize] }]]; self.subtitleLabel.attributedText = subtitle.copy; } diff --git a/Application/Sources/Home/HomeLiveMediaCollectionViewCell.xib b/Application/Sources/Home/HomeLiveMediaCollectionViewCell.xib index e10483cdd..5202672fc 100755 --- a/Application/Sources/Home/HomeLiveMediaCollectionViewCell.xib +++ b/Application/Sources/Home/HomeLiveMediaCollectionViewCell.xib @@ -1,5 +1,5 @@ - + @@ -10,173 +10,147 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - + + - - - + + + + + + + + + + + + + + + + - + - - + + + + + + - - - - + + + + + + + + + + + + + - - + + + - + - - - - - - + + - - - - - - - - - - - - - - - + + + + + + @@ -192,22 +166,24 @@ - + - - + + + + - + diff --git a/Application/Sources/Home/HomeLiveMediaVerticalListTableViewCell.h b/Application/Sources/Home/HomeLiveMediaVerticalListTableViewCell.h new file mode 100755 index 000000000..853d36435 --- /dev/null +++ b/Application/Sources/Home/HomeLiveMediaVerticalListTableViewCell.h @@ -0,0 +1,15 @@ +// +// Copyright (c) SRG SSR. All rights reserved. +// +// License information is available from the LICENSE file. +// + +#import "HomeTableViewCell.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface HomeLiveMediaVerticalListTableViewCell : HomeTableViewCell + +@end + +NS_ASSUME_NONNULL_END diff --git a/Application/Sources/Home/HomeLiveMediaVerticalListTableViewCell.m b/Application/Sources/Home/HomeLiveMediaVerticalListTableViewCell.m new file mode 100755 index 000000000..476b4406c --- /dev/null +++ b/Application/Sources/Home/HomeLiveMediaVerticalListTableViewCell.m @@ -0,0 +1,141 @@ +// +// Copyright (c) SRG SSR. All rights reserved. +// +// License information is available from the LICENSE file. +// + +#import "HomeLiveMediaVerticalListTableViewCell.h" + +#import "ApplicationSettings.h" +#import "HomeLiveMediaCollectionViewCell.h" +#import "Layout.h" +#import "UIViewController+PlaySRG.h" + +#import +#import + +@interface HomeLiveMediaVerticalListTableViewCell () + +@property (nonatomic, weak) UIView *wrapperView; +@property (nonatomic, weak) UICollectionView *collectionView; + +@end + +@implementation HomeLiveMediaVerticalListTableViewCell + +#pragma mark Class overrides + ++ (CGFloat)heightForHomeSectionInfo:(HomeSectionInfo *)homeSectionInfo bounds:(CGRect)bounds featured:(BOOL)featured +{ + CGSize itemSize = [self itemSizeForHomeSectionInfo:homeSectionInfo bounds:bounds]; + NSInteger numberOfItemsPerRow = floorf((CGRectGetWidth(bounds) - LayoutStandardMargin) / (itemSize.width + LayoutStandardMargin)); + NSInteger numberOfItems = (homeSectionInfo.items.count != 0) ? homeSectionInfo.items.count : 4; + NSInteger numberOfLines = MAX(ceilf((float)numberOfItems / numberOfItemsPerRow), 1); + return itemSize.height * numberOfLines + (numberOfLines - 1) * LayoutStandardMargin; +} + +#pragma mark Class methods + ++ (CGSize)itemSizeForHomeSectionInfo:(HomeSectionInfo *)homeSectionInfo bounds:(CGRect)bounds +{ + CGFloat approximateWidth = (CGRectGetWidth(bounds) < 1000.f) ? LayoutCollectionViewCellStandardWidth : 275.f; + CGFloat itemWidth = LayoutCollectionItemOptimalWidth(approximateWidth, CGRectGetWidth(bounds), LayoutStandardMargin, LayoutStandardMargin, LayoutStandardMargin); + return LayoutLiveMediaStandardCollectionItemSize(itemWidth); +} + +#pragma mark Object lifecycle + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { + self.backgroundColor = UIColor.clearColor; + self.selectedBackgroundView.backgroundColor = UIColor.clearColor; + + UIView *wrapperView = [[UIView alloc] initWithFrame:self.contentView.bounds]; + wrapperView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self.contentView addSubview:wrapperView]; + self.wrapperView = wrapperView; + + UICollectionViewFlowLayout *collectionViewLayout = [[UICollectionViewFlowLayout alloc] init]; + collectionViewLayout.scrollDirection = UICollectionViewScrollDirectionVertical; + collectionViewLayout.minimumLineSpacing = LayoutStandardMargin; + collectionViewLayout.minimumInteritemSpacing = LayoutStandardMargin; + + UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:wrapperView.bounds collectionViewLayout:collectionViewLayout]; + collectionView.backgroundColor = UIColor.clearColor; + collectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + collectionView.indicatorStyle = UIScrollViewIndicatorStyleWhite; + // Important. If > 1 view on-screen is found on iPhone with this property enabled, none will scroll to top + collectionView.scrollsToTop = NO; + collectionView.delegate = self; + collectionView.dataSource = self; + [wrapperView addSubview:collectionView]; + self.collectionView = collectionView; + + // Remark: The collection view is nested in a dummy view to workaround an accessibility bug + // See https://stackoverflow.com/a/38798448/760435 + wrapperView.accessibilityElements = @[collectionView]; + + NSString *mediaCellIdentifier = NSStringFromClass(HomeLiveMediaCollectionViewCell.class); + UINib *mediaCellNib = [UINib nibWithNibName:mediaCellIdentifier bundle:nil]; + [collectionView registerNib:mediaCellNib forCellWithReuseIdentifier:mediaCellIdentifier]; + } + return self; +} + +#pragma mark Overrides + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + [self.collectionView.collectionViewLayout invalidateLayout]; +} + +- (void)reloadData +{ + [super reloadData]; + + [self.collectionView reloadData]; +} + +#pragma mark UICollectionViewDataSource protocol + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + return ! [self isEmpty] ? self.homeSectionInfo.items.count : 4; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + return [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass(HomeLiveMediaCollectionViewCell.class) forIndexPath:indexPath]; +} + +#pragma mark UICollectionViewDelegate protocol + +- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(HomeLiveMediaCollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath +{ + cell.media = ! [self isEmpty] ? self.homeSectionInfo.items[indexPath.row] : nil; +} + +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + if (! [self isEmpty]) { + SRGMedia *media = self.homeSectionInfo.items[indexPath.row]; + [self.nearestViewController play_presentMediaPlayerWithMedia:media position:nil airPlaySuggestions:YES fromPushNotification:NO animated:YES completion:nil]; + } +} + +#pragma mark UICollectionViewDelegateFlowLayout protocol + +- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section +{ + return UIEdgeInsetsMake(0.f, LayoutStandardMargin, 0.f, LayoutStandardMargin); +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewFlowLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath +{ + return [HomeLiveMediaVerticalListTableViewCell itemSizeForHomeSectionInfo:self.homeSectionInfo bounds:collectionView.bounds]; +} + +@end diff --git a/Application/Sources/Home/HomeMediaListTableViewCell.m b/Application/Sources/Home/HomeMediaListTableViewCell.m index 876ee1966..311de474d 100755 --- a/Application/Sources/Home/HomeMediaListTableViewCell.m +++ b/Application/Sources/Home/HomeMediaListTableViewCell.m @@ -214,20 +214,7 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPa { if (! [self isEmpty]) { SRGMedia *media = self.homeSectionInfo.items[indexPath.row]; - - HomeSection homeSection = self.homeSectionInfo.homeSection; - if (homeSection == HomeSectionTVLive) { - ApplicationSettingSetLastSelectedTVLivestreamURN(media.URN); - } - else if (homeSection == HomeSectionRadioLive) { - ApplicationSettingSetLastSelectedRadioLivestreamURN(media.URN); - } - [self.nearestViewController play_presentMediaPlayerWithMedia:media position:nil airPlaySuggestions:YES fromPushNotification:NO animated:YES completion:^(PlayerType playerType) { - // Reset scrolling to the origin after playing a livestream, as the last played item is presented first - if (homeSection == HomeSectionTVLive || homeSection == HomeSectionRadioLive) { - self.collectionView.contentOffset = CGPointMake(0.f, self.collectionView.contentOffset.y); - } - }]; + [self.nearestViewController play_presentMediaPlayerWithMedia:media position:nil airPlaySuggestions:YES fromPushNotification:NO animated:YES completion:nil]; } } diff --git a/Application/Sources/Home/HomeSectionInfo.m b/Application/Sources/Home/HomeSectionInfo.m index 2cf1ac957..dd04dd355 100755 --- a/Application/Sources/Home/HomeSectionInfo.m +++ b/Application/Sources/Home/HomeSectionInfo.m @@ -9,6 +9,7 @@ #import "ApplicationConfiguration.h" #import "ApplicationSettings.h" #import "Favorites.h" +#import "HomeLiveMediaVerticalListTableViewCell.h" #import "HomeMediaListTableViewCell.h" #import "HomeShowListTableViewCell.h" #import "HomeShowsAccessTableViewCell.h" @@ -18,23 +19,6 @@ #import #import -static NSArray *HomeSectionReorderedMedias(NSArray *medias, NSString *firstURN) -{ - NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(SRGMedia * _Nullable media, NSDictionary * _Nullable bindings) { - return [media.URN isEqualToString:firstURN]; - }]; - SRGMedia *firstMedia = [medias filteredArrayUsingPredicate:predicate].firstObject; - if (firstMedia) { - NSMutableArray *reorderedMedias = medias.mutableCopy; - [reorderedMedias removeObject:firstMedia]; - [reorderedMedias insertObject:firstMedia atIndex:0]; - return reorderedMedias.copy; - } - else { - return medias; - } -} - @interface HomeSectionInfo () @property (nonatomic) HomeSection homeSection; @@ -95,6 +79,9 @@ - (Class)cellClass else if (self.homeSection == HomeSectionTVFavoriteShows || self.homeSection == HomeSectionRadioFavoriteShows) { return HomeShowListTableViewCell.class; } + else if (self.homeSection == HomeSectionTVLive || self.homeSection == HomeSectionRadioLive || self.homeSection == HomeSectionRadioLiveSatellite) { + return HomeLiveMediaVerticalListTableViewCell.class; + } else { return HomeMediaListTableViewCell.class; } @@ -263,9 +250,7 @@ - (void)refreshWithRequestQueue:(SRGRequestQueue *)requestQueue page:(SRGPage *) case HomeSectionTVLive: { SRGBaseRequest *request = [SRGDataProvider.currentDataProvider tvLivestreamsForVendor:vendor withCompletionBlock:^(NSArray * _Nullable medias, NSHTTPURLResponse * _Nullable HTTPResponse, NSError * _Nullable error) { [requestQueue reportError:error]; - - NSString *lastSelectedURN = ApplicationSettingLastSelectedTVLivestreamURN(); - paginatedItemListCompletionBlock(HomeSectionReorderedMedias(medias, lastSelectedURN), [SRGPage new] /* The request does not support pagination, but we need to return a page */, nil, HTTPResponse, error); + paginatedItemListCompletionBlock(medias, [SRGPage new] /* The request does not support pagination, but we need to return a page */, nil, HTTPResponse, error); }]; [requestQueue addRequest:request resume:YES]; break; @@ -362,17 +347,14 @@ - (void)refreshWithRequestQueue:(SRGRequestQueue *)requestQueue page:(SRGPage *) if (self.identifier) { SRGRequest *request = [SRGDataProvider.currentDataProvider radioLivestreamsForVendor:vendor channelUid:self.identifier withCompletionBlock:^(NSArray * _Nullable medias, NSHTTPURLResponse * _Nullable HTTPResponse, NSError * _Nullable error) { [requestQueue reportError:error]; - - NSString *lastSelectedURN = ApplicationSettingLastSelectedRadioLivestreamURN(); - paginatedItemListCompletionBlock(HomeSectionReorderedMedias(medias, lastSelectedURN), [SRGPage new] /* The request does not support pagination, but we need to return a page */, nil, HTTPResponse, error); + paginatedItemListCompletionBlock(medias, [SRGPage new] /* The request does not support pagination, but we need to return a page */, nil, HTTPResponse, error); }]; [requestQueue addRequest:request resume:YES]; } else { [self refreshRadioLivestreamsForVendor:vendor withRequestQueue:requestQueue completionBlock:^(NSArray * _Nullable medias, NSHTTPURLResponse * _Nullable HTTPResponse, NSError * _Nullable error) { // Error reporting is done by the refresh method directly, do not report twice here - NSString *lastSelectedURN = ApplicationSettingLastSelectedRadioLivestreamURN(); - paginatedItemListCompletionBlock(HomeSectionReorderedMedias(medias, lastSelectedURN), [SRGPage new] /* The request does not support pagination, but we need to return a page */, nil, HTTPResponse, error); + paginatedItemListCompletionBlock(medias, [SRGPage new] /* The request does not support pagination, but we need to return a page */, nil, HTTPResponse, error); }]; } break; diff --git a/Application/Sources/Home/HomeViewController.m b/Application/Sources/Home/HomeViewController.m index a16c39ce3..1a11a55d4 100755 --- a/Application/Sources/Home/HomeViewController.m +++ b/Application/Sources/Home/HomeViewController.m @@ -13,6 +13,7 @@ #import "Favorites.h" #import "GoogleCastBarButtonItem.h" #import "Layout.h" +#import "HomeLiveMediaVerticalListTableViewCell.h" #import "HomeSectionHeaderView.h" #import "HomeMediaListTableViewCell.h" #import "HomeSectionInfo.h" @@ -118,6 +119,9 @@ - (void)viewDidLoad Class mediaListCellClass = HomeMediaListTableViewCell.class; [self.tableView registerClass:mediaListCellClass forCellReuseIdentifier:NSStringFromClass(mediaListCellClass)]; + Class mediaVerticalListCellClass = HomeLiveMediaVerticalListTableViewCell.class; + [self.tableView registerClass:mediaVerticalListCellClass forCellReuseIdentifier:NSStringFromClass(mediaVerticalListCellClass)]; + Class showListCellClass = HomeShowListTableViewCell.class; [self.tableView registerClass:showListCellClass forCellReuseIdentifier:NSStringFromClass(showListCellClass)]; @@ -392,12 +396,7 @@ - (HomeSectionInfo *)infoForHomeSection:(HomeSection)homeSection withObject:(id) - (BOOL)isFeaturedInSection:(NSUInteger)section { - if (self.applicationSectionInfo.applicationSection == ApplicationSectionLive) { - return YES; - } - else { - return section == 0; - } + return section == 0; } - (HomeHeaderType)headerTypeForHomeSectionInfo:(HomeSectionInfo *)homeSectionInfo tableView:(UITableView *)tableView inSection:(NSUInteger)section diff --git a/Application/Sources/Library/ProfileViewController.m b/Application/Sources/Library/ProfileViewController.m index 901407596..3a1c667a2 100755 --- a/Application/Sources/Library/ProfileViewController.m +++ b/Application/Sources/Library/ProfileViewController.m @@ -230,8 +230,16 @@ - (BOOL)openApplicationSectionInfo:(ApplicationSectionInfo *)applicationSectionI return NO; } - // Do not reload a section if already the current one + // Do not reload a section if already the current one (just return to the navigation root if possible) if (! self.splitViewController.collapsed && [applicationSectionInfo isEqual:self.currentSectionInfo]) { + NSArray *viewControllers = self.splitViewController.viewControllers; + if (viewControllers.count == 2) { + UIViewController *detailViewController = viewControllers[1]; + if ([detailViewController isKindOfClass:UINavigationController.class]) { + UINavigationController *detailNavigationController = (UINavigationController *)detailViewController; + [detailNavigationController popToRootViewControllerAnimated:animated]; + } + } return YES; } diff --git a/Application/Sources/Notifications/NotificationTableViewCell.m b/Application/Sources/Notifications/NotificationTableViewCell.m index 88ed5d0d3..21dfb5ec1 100755 --- a/Application/Sources/Notifications/NotificationTableViewCell.m +++ b/Application/Sources/Notifications/NotificationTableViewCell.m @@ -103,7 +103,7 @@ - (void)setNotification:(Notification *)notification self.dateLabel.font = [UIFont srg_lightFontWithTextStyle:SRGAppearanceFontTextStyleSubtitle]; // Have content fit in (almost) constant size vertically by reducing the title number of lines when a tag is displayed - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; if (SRGAppearanceCompareContentSizeCategories(contentSizeCategory, UIContentSizeCategoryExtraLarge) == NSOrderedDescending) { self.subtitleLabel.numberOfLines = 1; } diff --git a/Application/Sources/Player/MediaPlayerViewController.m b/Application/Sources/Player/MediaPlayerViewController.m index c9072222b..89b675eeb 100755 --- a/Application/Sources/Player/MediaPlayerViewController.m +++ b/Application/Sources/Player/MediaPlayerViewController.m @@ -58,6 +58,7 @@ #import #import +#import #import #import #import @@ -609,11 +610,8 @@ - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id size.height); [self.letterboxView setFullScreen:isLandscape animated:NO /* will be animated with the view transition */]; - if (isLandscape && self.letterboxView.userInterfaceTogglable - && ! UIAccessibilityIsVoiceOverRunning() - && self.letterboxController.playbackState != SRGMediaPlayerPlaybackStatePaused - && self.letterboxController.playbackState != SRGMediaPlayerPlaybackStateEnded) { - [self.letterboxView setUserInterfaceHidden:YES animated:NO /* will be animated with the view transition */]; + if (isLandscape) { + [self hidePlayerUserInterfaceAnimated:NO /* will be animated with the view transition */]; } } [self scrollToNearestProgramAnimated:NO]; @@ -702,14 +700,16 @@ - (void)synchronizeUserActivity:(NSUserActivity *)userActivity { SRGMedia *mainChapterMedia = [self mainChapterMedia]; if (mainChapterMedia) { - userActivity.title = mainChapterMedia.title; + NSString *userActivityTitleFormat = (mainChapterMedia.mediaType == SRGMediaTypeAudio) ? NSLocalizedString(@"Listen to %@", @"User activity title when listening to an audio") : NSLocalizedString(@"Watch %@", @"User activity title when watching a video"); + userActivity.title = [NSString stringWithFormat:userActivityTitleFormat, mainChapterMedia.title]; if (mainChapterMedia.endDate) { userActivity.expirationDate = mainChapterMedia.endDate; } + BOOL isLiveStream = (mainChapterMedia.contentType == SRGContentTypeLivestream); NSNumber *position = nil; CMTime currentTime = self.letterboxController.currentTime; - if (CMTIME_IS_VALID(currentTime) + if (! isLiveStream && CMTIME_IS_VALID(currentTime) && self.letterboxController.playbackState != SRGMediaPlayerPlaybackStateIdle && self.letterboxController.playbackState != SRGMediaPlayerPlaybackStatePreparing && self.letterboxController.playbackState != SRGMediaPlayerPlaybackStateEnded) { @@ -724,6 +724,13 @@ - (void)synchronizeUserActivity:(NSUserActivity *)userActivity @"applicationVersion" : [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"] }]; userActivity.requiredUserInfoKeys = [NSSet setWithArray:userActivity.userInfo.allKeys]; userActivity.webpageURL = [ApplicationConfiguration.sharedApplicationConfiguration sharingURLForMediaMetadata:mainChapterMedia atTime:currentTime]; + + if (isLiveStream && mainChapterMedia.channel) { + userActivity.eligibleForPrediction = YES; + userActivity.persistentIdentifier = mainChapterMedia.URN; + NSString *suggestedInvocationPhraseFormat = (mainChapterMedia.mediaType == SRGMediaTypeAudio) ? NSLocalizedString(@"Listen to %@", @"Suggested invocation phrase to listen to an audio") : NSLocalizedString(@"Watch %@", @"Suggested invocation phrase to watch a video"); + userActivity.suggestedInvocationPhrase = [NSString stringWithFormat:suggestedInvocationPhraseFormat, mainChapterMedia.channel.title]; + } } else { [userActivity resignCurrent]; @@ -1083,6 +1090,16 @@ - (void)setFullScreen:(BOOL)fullScreen [self setNeedsStatusBarAppearanceUpdate]; } +- (void)hidePlayerUserInterfaceAnimated:(BOOL)animated +{ + if (self.letterboxView.userInterfaceTogglable + && ! UIAccessibilityIsVoiceOverRunning() + && self.letterboxController.playbackState != SRGMediaPlayerPlaybackStatePaused + && self.letterboxController.playbackState != SRGMediaPlayerPlaybackStateEnded) { + [self.letterboxView setUserInterfaceHidden:YES animated:animated]; + } +} + - (void)setDetailsExpanded:(BOOL)expanded animated:(BOOL)animated { if (self.detailsExpanded == expanded) { @@ -1570,6 +1587,10 @@ - (void)letterboxView:(SRGLetterboxView *)letterboxView toggleFullScreen:(BOOL)f [self setFullScreen:fullScreen]; [self updateTimelineVisibilityForFullScreen:fullScreen animated:NO]; [self updateSongPanelFor:self.traitCollection fullScreen:fullScreen]; + + if (fullScreen) { + [self hidePlayerUserInterfaceAnimated:NO]; + } }; void (^completion)(BOOL) = ^(BOOL finished) { @@ -2070,7 +2091,6 @@ - (IBAction)selectLivestreamMedia:(id)sender [self.livestreamMedias enumerateObjectsUsingBlock:^(SRGMedia * _Nonnull media, NSUInteger idx, BOOL * _Nonnull stop) { [alertController addAction:[UIAlertAction actionWithTitle:media.title style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { - ApplicationSettingSetLastSelectedRadioLivestreamURN(media.URN); ApplicationSettingSetSelectedLivestreamURNForChannelUid(media.channel.uid, media.URN); // Use the playback state if playing diff --git a/Application/Sources/Search/Settings/SearchSettingMultiSelectionViewController.m b/Application/Sources/Search/Settings/SearchSettingMultiSelectionViewController.m index 1959a9db0..3a213061e 100644 --- a/Application/Sources/Search/Settings/SearchSettingMultiSelectionViewController.m +++ b/Application/Sources/Search/Settings/SearchSettingMultiSelectionViewController.m @@ -160,7 +160,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; if (SRGAppearanceCompareContentSizeCategories(contentSizeCategory, UIContentSizeCategoryExtraLarge) == NSOrderedDescending) { return 55.f; } diff --git a/Application/Sources/Search/Settings/SearchSettingsViewController.m b/Application/Sources/Search/Settings/SearchSettingsViewController.m index f3bbfde27..536070c09 100644 --- a/Application/Sources/Search/Settings/SearchSettingsViewController.m +++ b/Application/Sources/Search/Settings/SearchSettingsViewController.m @@ -26,6 +26,7 @@ typedef NSString * SearchSettingSectionType NS_STRING_ENUM; +static SearchSettingSectionType const SearchSettingSectionTypeSortCriterium = @"sort_criterium"; static SearchSettingSectionType const SearchSettingSectionTypeMediaType = @"media_type"; static SearchSettingSectionType const SearchSettingSectionTypeTopics = @"topics"; static SearchSettingSectionType const SearchSettingSectionTypeShows = @"shows"; @@ -35,6 +36,7 @@ typedef NSString * SearchSettingRowType NS_STRING_ENUM; +static SearchSettingRowType const SearchSettingRowTypeSortCriterium = @"sort_criterium"; static SearchSettingRowType const SearchSettingRowTypeMediaType = @"media_type"; static SearchSettingRowType const SearchSettingRowTypeTopics = @"topics"; static SearchSettingRowType const SearchSettingRowTypeShows = @"shows"; @@ -304,17 +306,25 @@ - (void)updateRightBarButtonItems - (NSArray *)sectionTypesForTableView:(UITableView *)tableView { - return @[ SearchSettingSectionTypeMediaType, - SearchSettingSectionTypeTopics, - SearchSettingSectionTypeShows, - SearchSettingSectionTypePeriod, - SearchSettingSectionTypeDuration, - SearchSettingSectionTypeProperties ]; + NSMutableArray *sectionTypes = [NSMutableArray array]; + + ApplicationConfiguration *applicationConfiguration = ApplicationConfiguration.sharedApplicationConfiguration; + if (! applicationConfiguration.searchSortingCriteriumHidden) { + [sectionTypes addObject:SearchSettingSectionTypeSortCriterium]; + } + [sectionTypes addObjectsFromArray:@[ SearchSettingSectionTypeMediaType, + SearchSettingSectionTypeTopics, + SearchSettingSectionTypeShows, + SearchSettingSectionTypePeriod, + SearchSettingSectionTypeDuration, + SearchSettingSectionTypeProperties ]]; + return sectionTypes.copy; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSectionWithType:(SearchSettingSectionType)type { - NSDictionary *titles = @{ SearchSettingSectionTypeMediaType : NSLocalizedString(@"Content", @"Settings section header"), + NSDictionary *titles = @{ SearchSettingSectionTypeSortCriterium : NSLocalizedString(@"Sort by", @"Settings section header"), + SearchSettingSectionTypeMediaType : NSLocalizedString(@"Content", @"Settings section header"), SearchSettingSectionTypePeriod : NSLocalizedString(@"Period", @"Settings section header"), SearchSettingSectionTypeDuration : NSLocalizedString(@"Duration", @"Settings section header"), SearchSettingSectionTypeProperties : NSLocalizedString(@"Properties", @"Settings section header") }; @@ -333,7 +343,8 @@ - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSectionWithType propertiesRowTypes = @[ SearchSettingRowTypeDownloadAvailable, SearchSettingRowTypePlayableAbroad ]; } - NSDictionary *> *types = @{ SearchSettingSectionTypeMediaType : @[ SearchSettingRowTypeMediaType ], + NSDictionary *> *types = @{ SearchSettingSectionTypeSortCriterium : @[ SearchSettingRowTypeSortCriterium ], + SearchSettingSectionTypeMediaType : @[ SearchSettingRowTypeMediaType ], SearchSettingSectionTypeTopics : @[ SearchSettingRowTypeTopics ], SearchSettingSectionTypeShows : @[ SearchSettingRowTypeShows ], SearchSettingSectionTypePeriod : @[ SearchSettingRowTypeToday, SearchSettingRowTypeYesterday, SearchSettingRowTypeThisWeek, SearchSettingRowTypeLastWeek ], @@ -344,7 +355,8 @@ - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSectionWithType - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowWithType:(SearchSettingRowType)type atIndexPath:(NSIndexPath *)indexPath { - NSDictionary *cellClasses = @{ SearchSettingRowTypeMediaType : SearchSettingSegmentCell.class, + NSDictionary *cellClasses = @{ SearchSettingRowTypeSortCriterium : SearchSettingSegmentCell.class, + SearchSettingRowTypeMediaType : SearchSettingSegmentCell.class, SearchSettingRowTypeTopics : SearchSettingMultiSelectionCell.class, SearchSettingRowTypeShows : SearchSettingMultiSelectionCell.class, SearchSettingRowTypeToday : SearchSettingSelectorCell.class, @@ -413,6 +425,26 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)ce [self updateResults]; }]; } + else if ([type isEqualToString:SearchSettingRowTypeSortCriterium]) { + SearchSettingSegmentCell *segmentCell = (SearchSettingSegmentCell *)cell; + + static dispatch_once_t s_onceToken; + static NSDictionary *s_sortCriteria; + dispatch_once(&s_onceToken, ^{ + s_sortCriteria = @{ @0 : @(SRGSortCriteriumDefault), + @1 : @(SRGSortCriteriumDate) }; + }); + + @weakify(self) + [segmentCell setItems:@[ NSLocalizedString(@"Relevance", @"Sort by relevance option"), NSLocalizedString(@"Date", @"Sort by date option") ] reader:^NSInteger{ + return [s_sortCriteria allKeysForObject:@(settings.sortCriterium)].firstObject.integerValue; + } writer:^(NSInteger index) { + @strongify(self) + + settings.sortCriterium = [s_sortCriteria[@(index)] integerValue]; + [self updateResults]; + }]; + } else if ([type isEqualToString:SearchSettingRowTypeToday]) { SearchSettingSelectorCell *selectorCell = (SearchSettingSelectorCell *)cell; selectorCell.name = NSLocalizedString(@"Today", @"Period setting option"); @@ -627,7 +659,7 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa { SearchSettingSectionType sectionType = [self sectionTypesForTableView:tableView][indexPath.section]; if (sectionType == SearchSettingSectionTypePeriod) { - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; if (SRGAppearanceCompareContentSizeCategories(contentSizeCategory, UIContentSizeCategoryExtraLarge) == NSOrderedDescending) { return 45.f; } @@ -639,7 +671,7 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa } } else { - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; if (SRGAppearanceCompareContentSizeCategories(contentSizeCategory, UIContentSizeCategoryExtraLarge) == NSOrderedDescending) { return 55.f; } diff --git a/Application/Sources/Settings/ApplicationSettings.h b/Application/Sources/Settings/ApplicationSettings.h index 9b4cde7a5..ea5d1a9c4 100755 --- a/Application/Sources/Settings/ApplicationSettings.h +++ b/Application/Sources/Settings/ApplicationSettings.h @@ -70,12 +70,6 @@ OBJC_EXPORT BOOL ApplicationSettingBackgroundVideoPlaybackEnabled(void); OBJC_EXPORT BOOL ApplicationSettingSubtitleAvailabilityDisplayed(void); OBJC_EXPORT BOOL ApplicationSettingAudioDescriptionAvailabilityDisplayed(void); -OBJC_EXPORT NSString * _Nullable ApplicationSettingLastSelectedTVLivestreamURN(void); -OBJC_EXPORT void ApplicationSettingSetLastSelectedTVLivestreamURN(NSString * _Nullable mediaURN); - -OBJC_EXPORT NSString * _Nullable ApplicationSettingLastSelectedRadioLivestreamURN(void); -OBJC_EXPORT void ApplicationSettingSetLastSelectedRadioLivestreamURN(NSString * _Nullable mediaURN); - OBJC_EXPORT NSString * _Nullable ApplicationSettingSelectedLivestreamURNForChannelUid(NSString * _Nullable channelUid); OBJC_EXPORT void ApplicationSettingSetSelectedLivestreamURNForChannelUid(NSString * channelUid, NSString * _Nullable mediaURN); diff --git a/Application/Sources/Settings/ApplicationSettings.m b/Application/Sources/Settings/ApplicationSettings.m index 013e43981..0f41c311f 100755 --- a/Application/Sources/Settings/ApplicationSettings.m +++ b/Application/Sources/Settings/ApplicationSettings.m @@ -30,8 +30,6 @@ NSString * const PlaySRGSettingLastOpenedRadioChannelUid = @"PlaySRGSettingLastOpenedRadioChannelUid"; NSString * const PlaySRGSettingLastOpenedTabBarItem = @"PlaySRGSettingLastOpenedTabBarItem"; NSString * const PlaySRGSettingSelectedLivestreamURNForChannels = @"PlaySRGSettingSelectedLiveStreamURNForChannels"; -NSString * const PlaySRGSettingSelectedTVLivestreamURN = @"PlaySRGSettingSelectedTVLivestreamURN"; -NSString * const PlaySRGSettingSelectedRadioLivestreamURN = @"PlaySRGSettingSelectedRadioLivestreamURN"; NSString * const PlaySRGSettingServiceURL = @"PlaySRGSettingServiceURL"; NSString * const PlaySRGSettingUserLocation = @"PlaySRGSettingUserLocation"; @@ -202,30 +200,6 @@ BOOL ApplicationSettingAudioDescriptionAvailabilityDisplayed(void) return UIAccessibilityIsVoiceOverRunning() || [NSUserDefaults.standardUserDefaults boolForKey:PlaySRGSettingAudioDescriptionAvailabilityDisplayed]; } -NSString *ApplicationSettingLastSelectedTVLivestreamURN(void) -{ - return [NSUserDefaults.standardUserDefaults stringForKey:PlaySRGSettingSelectedTVLivestreamURN]; -} - -void ApplicationSettingSetLastSelectedTVLivestreamURN(NSString *mediaURN) -{ - NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults; - [userDefaults setObject:mediaURN forKey:PlaySRGSettingSelectedTVLivestreamURN]; - [userDefaults synchronize]; -} - -NSString *ApplicationSettingLastSelectedRadioLivestreamURN(void) -{ - return [NSUserDefaults.standardUserDefaults stringForKey:PlaySRGSettingSelectedRadioLivestreamURN]; -} - -void ApplicationSettingSetLastSelectedRadioLivestreamURN(NSString *mediaURN) -{ - NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults; - [userDefaults setObject:mediaURN forKey:PlaySRGSettingSelectedRadioLivestreamURN]; - [userDefaults synchronize]; -} - NSString *ApplicationSettingSelectedLivestreamURNForChannelUid(NSString *channelUid) { NSDictionary *selectedLivestreamURNForChannels = [NSUserDefaults.standardUserDefaults dictionaryForKey:PlaySRGSettingSelectedLivestreamURNForChannels]; diff --git a/Application/Sources/Settings/SettingsViewController.m b/Application/Sources/Settings/SettingsViewController.m index d7501291c..b5b4c5f43 100755 --- a/Application/Sources/Settings/SettingsViewController.m +++ b/Application/Sources/Settings/SettingsViewController.m @@ -43,6 +43,7 @@ static NSString * const SettingsFeedbackButton = @"Button_Feedback"; static NSString * const SettingsSourceCodeButton = @"Button_SourceCode"; static NSString * const SettingsBetaTestingButton = @"Button_BetaTesting"; +static NSString * const SettingsTvBetaTestingButton = @"Button_TvBetaTesting"; static NSString * const SettingsApplicationVersionCell = @"Cell_ApplicationVersion"; // Autoplay group @@ -205,6 +206,10 @@ - (void)updateSettingsVisibility [hiddenKeys addObject:SettingsBetaTestingButton]; } + if (! applicationConfiguration.tvBetaTestingURL) { + [hiddenKeys addObject:SettingsTvBetaTestingButton]; + } + self.hiddenKeys = hiddenKeys.copy; } @@ -337,6 +342,14 @@ - (void)settingsViewController:(IASKAppSettingsViewController *)settingsViewCont [SRGAnalyticsTracker.sharedTracker trackPageViewWithTitle:AnalyticsPageTitleBetaTesting levels:@[ AnalyticsPageLevelPlay, AnalyticsPageLevelApplication ]]; }]; } + else if ([specifier.key isEqualToString:SettingsTvBetaTestingButton]) { + NSURL *tvBetaTestingURL = ApplicationConfiguration.sharedApplicationConfiguration.tvBetaTestingURL; + NSAssert(tvBetaTestingURL, @"Button must not be displayed if no Apple TV beta testing URL has been specified"); + + [UIApplication.sharedApplication play_openURL:tvBetaTestingURL withCompletionHandler:^(BOOL success) { + [SRGAnalyticsTracker.sharedTracker trackPageViewWithTitle:AnalyticsPageTitleTvBetaTesting levels:@[ AnalyticsPageLevelPlay, AnalyticsPageLevelApplication ]]; + }]; + } else if ([specifier.key isEqualToString:SettingsVersionsAndReleaseNotes]) { // Clear internal App Center timestamp to force a new update request [NSUserDefaults.standardUserDefaults removeObjectForKey:@"MSAppCenterPostponedTimestamp"]; diff --git a/Application/Sources/Shows/ShowViewController.m b/Application/Sources/Shows/ShowViewController.m index 8db62c047..bf48bd57c 100755 --- a/Application/Sources/Shows/ShowViewController.m +++ b/Application/Sources/Shows/ShowViewController.m @@ -20,6 +20,7 @@ #import "UIColor+PlaySRG.h" #import "UIViewController+PlaySRG.h" +#import #import #import @@ -267,11 +268,16 @@ - (void)updateUserActivityState:(NSUserActivity *)userActivity { [super updateUserActivityState:userActivity]; - userActivity.title = self.show.title; + userActivity.title = [NSString stringWithFormat:NSLocalizedString(@"Display %@ episodes", @"User activity title when displaying a show page"), self.show.title]; [userActivity addUserInfoEntriesFromDictionary:@{ @"URNString" : self.show.URN, @"SRGShowData" : [NSKeyedArchiver archivedDataWithRootObject:self.show requiringSecureCoding:NO error:NULL], @"applicationVersion" : [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"] }]; userActivity.webpageURL = [ApplicationConfiguration.sharedApplicationConfiguration sharingURLForShow:self.show]; + + userActivity.eligibleForPrediction = YES; + userActivity.persistentIdentifier = self.show.URN; + NSString *suggestedInvocationPhraseFormat = (self.show.transmission == SRGTransmissionRadio) ? NSLocalizedString(@"Listen to %@", @"Suggested invocation phrase to listen to a show") : NSLocalizedString(@"Watch %@", @"Suggested invocation phrase to watch a show"); + userActivity.suggestedInvocationPhrase = [NSString stringWithFormat:suggestedInvocationPhraseFormat, self.show.title]; } #pragma mark UI diff --git a/Application/Sources/UI/Views/MediaCollectionViewCell.m b/Application/Sources/UI/Views/MediaCollectionViewCell.m index 67b9eeee1..68c2a2a50 100755 --- a/Application/Sources/UI/Views/MediaCollectionViewCell.m +++ b/Application/Sources/UI/Views/MediaCollectionViewCell.m @@ -239,7 +239,7 @@ - (void)setMedia:(SRGMedia *)media withDateFormatter:(NSDateFormatter *)dateForm // Have content fit in (almost) constant size vertically by reducing the title number of lines when a tag is displayed if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact) { - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; if (SRGAppearanceCompareContentSizeCategories(contentSizeCategory, UIContentSizeCategoryExtraLarge) == NSOrderedDescending) { self.titleLabel.numberOfLines = (isWebFirst || hasSubtitles || hasAudioDescription) ? 1 : 2; } diff --git a/Application/Sources/WatchLater/WatchLaterTableViewCell.m b/Application/Sources/WatchLater/WatchLaterTableViewCell.m index 5c8f8f8c6..5d9fb1cdb 100755 --- a/Application/Sources/WatchLater/WatchLaterTableViewCell.m +++ b/Application/Sources/WatchLater/WatchLaterTableViewCell.m @@ -271,7 +271,7 @@ - (void)setMedia:(SRGMedia *)media [self.subtitlesLabel play_setSubtitlesAvailableBadge]; // Have content fit in (almost) constant size vertically by reducing the title number of lines when a tag is displayed - NSString *contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; + UIContentSizeCategory contentSizeCategory = UIApplication.sharedApplication.preferredContentSizeCategory; if (SRGAppearanceCompareContentSizeCategories(contentSizeCategory, UIContentSizeCategoryExtraLarge) == NSOrderedDescending) { self.titleLabel.numberOfLines = (isWebFirst || hasSubtitles || hasAudioDescription) ? 1 : 2; } diff --git a/Cartfile b/Cartfile index fc65cfd1b..a375d6742 100755 --- a/Cartfile +++ b/Cartfile @@ -6,5 +6,5 @@ github "microsoft/appcenter-sdk-apple" ~> 3.1.0 github "SRGSSR/DZNEmptyDataSet" "v1.8.1_srg1" github "SRGSSR/Masonry" "v1.1.0_srg1" github "urbanairship/ios-library" ~> 13.3.2 -github "SRGSSR/srgletterbox-apple" "5.0.0" +github "SRGSSR/srgletterbox-apple" "5.0.1" github "SRGSSR/srguserdata-apple" "2.0.3" diff --git a/Cartfile.resolved.proprietary b/Cartfile.resolved.proprietary index 8487554d8..24b001ad9 100755 --- a/Cartfile.resolved.proprietary +++ b/Cartfile.resolved.proprietary @@ -9,19 +9,19 @@ 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.2.0" +github "SRGSSR/srganalytics-apple" "4.2.1" github "SRGSSR/srgappearance-apple" "2.1.0" github "SRGSSR/srgcontentprotection-apple" "2.0.2" github "SRGSSR/srgdataprovider-apple" "8.0.0" github "SRGSSR/srgdiagnostics-apple" "2.0.1" github "SRGSSR/srgidentity-apple" "2.0.3" -github "SRGSSR/srgletterbox-apple" "5.0.0" +github "SRGSSR/srgletterbox-apple" "5.0.1" github "SRGSSR/srglogger-apple" "2.0.1" -github "SRGSSR/srgmediaplayer-apple" "5.0.0" +github "SRGSSR/srgmediaplayer-apple" "5.0.2" github "SRGSSR/srgnetwork-apple" "2.0.2" github "SRGSSR/srguserdata-apple" "2.0.3" 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" "3.3.1" -github "urbanairship/ios-library" "13.4.0" +github "microsoft/appcenter-sdk-apple" "3.3.3" +github "urbanairship/ios-library" "13.5.4" diff --git a/Cartfile.resolved.public b/Cartfile.resolved.public index eed80646b..1182698a8 100755 --- a/Cartfile.resolved.public +++ b/Cartfile.resolved.public @@ -9,19 +9,19 @@ 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.2.0" +github "SRGSSR/srganalytics-apple" "4.2.1" github "SRGSSR/srgappearance-apple" "2.1.0" github "SRGSSR/srgcontentprotection-fake-apple" "2.0.2" github "SRGSSR/srgdataprovider-apple" "8.0.0" github "SRGSSR/srgdiagnostics-apple" "2.0.1" github "SRGSSR/srgidentity-apple" "2.0.3" -github "SRGSSR/srgletterbox-apple" "5.0.0" +github "SRGSSR/srgletterbox-apple" "5.0.1" github "SRGSSR/srglogger-apple" "2.0.1" -github "SRGSSR/srgmediaplayer-apple" "5.0.0" +github "SRGSSR/srgmediaplayer-apple" "5.0.2" github "SRGSSR/srgnetwork-apple" "2.0.2" github "SRGSSR/srguserdata-apple" "2.0.3" 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" "3.3.1" -github "urbanairship/ios-library" "13.4.0" +github "microsoft/appcenter-sdk-apple" "3.3.3" +github "urbanairship/ios-library" "13.5.4" diff --git a/Gemfile b/Gemfile index ea0afbf80..5d378ba3b 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,7 @@ source 'https://rubygems.org' gem 'fastlane' +gem 'xcode-install' plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') eval_gemfile(plugins_path) if File.exist?(plugins_path) diff --git a/Gemfile.lock b/Gemfile.lock index b0521994d..b14ceb907 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,8 +6,8 @@ GEM public_suffix (>= 2.0.2, < 5.0) atomos (0.1.3) aws-eventstream (1.1.0) - aws-partitions (1.340.0) - aws-sdk-core (3.103.0) + aws-partitions (1.345.0) + aws-sdk-core (3.104.3) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) @@ -15,8 +15,8 @@ GEM aws-sdk-kms (1.36.0) aws-sdk-core (~> 3, >= 3.99.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.74.0) - aws-sdk-core (~> 3, >= 3.102.1) + aws-sdk-s3 (1.75.0) + aws-sdk-core (~> 3, >= 3.104.1) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) aws-sigv4 (1.2.1) @@ -33,9 +33,9 @@ GEM rake (~> 13.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.5) + dotenv (2.7.6) emoji_regex (3.0.0) - excon (0.75.0) + excon (0.76.0) faraday (1.0.1) multipart-post (>= 1.2, < 3) faraday-cookie_jar (0.0.6) @@ -43,8 +43,8 @@ GEM http-cookie (~> 1.0.0) faraday_middleware (1.0.0) faraday (~> 1.0) - fastimage (2.1.7) - fastlane (2.151.2) + fastimage (2.2.0) + fastlane (2.153.1) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) aws-sdk-s3 (~> 1.0) @@ -55,9 +55,9 @@ GEM dotenv (>= 2.1.1, < 3.0.0) emoji_regex (>= 0.1, < 4.0) excon (>= 0.71.0, < 1.0.0) - faraday (>= 0.17, < 2.0) + faraday (~> 1.0) faraday-cookie_jar (~> 0.0.6) - faraday_middleware (>= 0.13.1, < 2.0) + faraday_middleware (~> 1.0) fastimage (>= 2.1.0, < 3.0.0) gh_inspector (>= 1.1.2, < 2.0.0) google-api-client (>= 0.37.0, < 0.39.0) @@ -80,7 +80,7 @@ GEM xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) - fastlane-plugin-appcenter (1.8.0) + fastlane-plugin-appcenter (1.9.0) gh_inspector (1.1.3) google-api-client (0.38.0) addressable (~> 2.5, >= 2.5.1) @@ -93,7 +93,7 @@ GEM google-cloud-core (1.5.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) - google-cloud-env (1.3.2) + google-cloud-env (1.3.3) faraday (>= 0.17.3, < 2.0) google-cloud-errors (1.0.1) google-cloud-storage (1.26.2) @@ -120,9 +120,9 @@ GEM memoist (0.16.2) mini_magick (4.10.1) mini_mime (1.0.2) - multi_json (1.14.1) + multi_json (1.15.0) multipart-post (2.0.0) - nanaimo (0.2.6) + nanaimo (0.3.0) naturally (2.2.0) os (1.1.0) plist (3.5.0) @@ -149,7 +149,7 @@ GEM terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) tty-cursor (0.7.1) - tty-screen (0.8.0) + tty-screen (0.8.1) tty-spinner (0.9.3) tty-cursor (~> 0.7) uber (0.1.0) @@ -158,12 +158,15 @@ GEM unf_ext (0.0.7.7) unicode-display_width (1.7.0) word_wrap (1.0.0) - xcodeproj (1.17.0) + xcode-install (2.6.6) + claide (>= 0.9.1, < 1.1.0) + fastlane (>= 2.1.0, < 3.0.0) + xcodeproj (1.17.1) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) - nanaimo (~> 0.2.6) + nanaimo (~> 0.3.0) xcpretty (0.3.0) rouge (~> 2.0.7) xcpretty-travis-formatter (1.0.0) @@ -175,6 +178,7 @@ PLATFORMS DEPENDENCIES fastlane fastlane-plugin-appcenter + xcode-install BUNDLED WITH 1.17.2 diff --git a/PlaySRG.xcodeproj/project.pbxproj b/PlaySRG.xcodeproj/project.pbxproj index b66f193fa..c0e6c8f41 100644 --- a/PlaySRG.xcodeproj/project.pbxproj +++ b/PlaySRG.xcodeproj/project.pbxproj @@ -1311,6 +1311,11 @@ 6FE686E31EB9D57400067D40 /* ChannelService.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FE686E01EB9D57400067D40 /* ChannelService.m */; }; 6FE686E41EB9D57400067D40 /* ChannelService.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FE686E01EB9D57400067D40 /* ChannelService.m */; }; 6FE686E51EB9D57400067D40 /* ChannelService.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FE686E01EB9D57400067D40 /* ChannelService.m */; }; + 6FE9B54424B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FE9B54224B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m */; }; + 6FE9B54524B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FE9B54224B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m */; }; + 6FE9B54624B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FE9B54224B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m */; }; + 6FE9B54724B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FE9B54224B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m */; }; + 6FE9B54824B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FE9B54224B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m */; }; 6FEC91A921A6B39A00AA50C8 /* TableLoadMoreFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FEC91A821A6B39A00AA50C8 /* TableLoadMoreFooterView.m */; }; 6FEC91AA21A6B39A00AA50C8 /* TableLoadMoreFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FEC91A821A6B39A00AA50C8 /* TableLoadMoreFooterView.m */; }; 6FEC91AB21A6B39A00AA50C8 /* TableLoadMoreFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FEC91A821A6B39A00AA50C8 /* TableLoadMoreFooterView.m */; }; @@ -2139,6 +2144,8 @@ 6FE28772248168A100358CFF /* SongTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SongTableViewCell.xib; sourceTree = ""; }; 6FE686DF1EB9D57400067D40 /* ChannelService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChannelService.h; sourceTree = ""; }; 6FE686E01EB9D57400067D40 /* ChannelService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChannelService.m; sourceTree = ""; }; + 6FE9B54224B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeLiveMediaVerticalListTableViewCell.m; sourceTree = ""; }; + 6FE9B54324B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeLiveMediaVerticalListTableViewCell.h; sourceTree = ""; }; 6FEC91A721A6B39A00AA50C8 /* TableLoadMoreFooterView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TableLoadMoreFooterView.h; sourceTree = ""; }; 6FEC91A821A6B39A00AA50C8 /* TableLoadMoreFooterView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TableLoadMoreFooterView.m; sourceTree = ""; }; 6FF3B68D2137DC8400F8A5E2 /* SRGContentProtection.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SRGContentProtection.framework; path = Carthage/Build/iOS/Static/SRGContentProtection.framework; sourceTree = ""; }; @@ -2903,6 +2910,11 @@ 08C68ECE1D38DEA100BB8AAA /* Home */ = { isa = PBXGroup; children = ( + 0887824723AD61D400629312 /* HomeLiveMediaCollectionViewCell.h */, + 0887824823AD61D500629312 /* HomeLiveMediaCollectionViewCell.m */, + 0887824923AD61D500629312 /* HomeLiveMediaCollectionViewCell.xib */, + 6FE9B54324B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.h */, + 6FE9B54224B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m */, 082590ED1F054A6A00BB527C /* HomeMediaCollectionHeaderView.h */, 082590EE1F054A6A00BB527C /* HomeMediaCollectionHeaderView.m */, 082590EF1F054A6A00BB527C /* HomeMediaCollectionHeaderView.xib */, @@ -2942,9 +2954,6 @@ 6FAF42FE1EF7CD8A0074E033 /* HomeTopicViewController.m */, 08C68ECF1D38DEA100BB8AAA /* HomeViewController.h */, 08C68ED01D38DEA100BB8AAA /* HomeViewController.m */, - 0887824723AD61D400629312 /* HomeLiveMediaCollectionViewCell.h */, - 0887824823AD61D500629312 /* HomeLiveMediaCollectionViewCell.m */, - 0887824923AD61D500629312 /* HomeLiveMediaCollectionViewCell.xib */, ); path = Home; sourceTree = ""; @@ -5789,6 +5798,7 @@ 081220AA1DD079BB00BF8326 /* DownloadsViewController.m in Sources */, 0804917B22832C5D00E4CEC2 /* HomeShowCollectionViewCell.m in Sources */, 6FB0AEFC217F4975009D707A /* SRGMediaComposition+PlaySRG.m in Sources */, + 6FE9B54424B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m in Sources */, 6FF7BB9722A78DE400FA758A /* SearchSettingSwitchCell.m in Sources */, E694A9F51D65F02700372DF0 /* CalendarViewController.m in Sources */, 6F80106920443230009FE197 /* PlayApplication.m in Sources */, @@ -5971,6 +5981,7 @@ 6F475FC91EB37BC6003021EA /* MediasViewController.m in Sources */, 6FE1B4981DCB84F00094D5BA /* AnalyticsConstants.m in Sources */, 6FF7BBA722A78DE400FA758A /* SearchSettingSelectorCell.m in Sources */, + 6FE9B54524B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m in Sources */, 6F5F4FC51DB10CFD0011CCA3 /* RelatedContentView.m in Sources */, 6F475FBF1EB37BC6003021EA /* DataViewController.m in Sources */, 0801E07C1D4A4A810008021E /* RadioChannel.m in Sources */, @@ -6147,6 +6158,7 @@ 6F475FCA1EB37BC6003021EA /* MediasViewController.m in Sources */, 6FE1B4991DCB84F00094D5BA /* AnalyticsConstants.m in Sources */, 6FF7BBA822A78DE400FA758A /* SearchSettingSelectorCell.m in Sources */, + 6FE9B54624B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m in Sources */, 6F5F4FC61DB10CFD0011CCA3 /* RelatedContentView.m in Sources */, 6F475FC01EB37BC6003021EA /* DataViewController.m in Sources */, 0801E07D1D4A4A810008021E /* RadioChannel.m in Sources */, @@ -6323,6 +6335,7 @@ 6F475FCB1EB37BC6003021EA /* MediasViewController.m in Sources */, 6FE1B49A1DCB84F00094D5BA /* AnalyticsConstants.m in Sources */, 6FF7BBA922A78DE400FA758A /* SearchSettingSelectorCell.m in Sources */, + 6FE9B54724B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m in Sources */, 6F5F4FC71DB10CFD0011CCA3 /* RelatedContentView.m in Sources */, 6F475FC11EB37BC6003021EA /* DataViewController.m in Sources */, 0801E07E1D4A4A810008021E /* RadioChannel.m in Sources */, @@ -6499,6 +6512,7 @@ 6F475FCC1EB37BC6003021EA /* MediasViewController.m in Sources */, 6FE1B49B1DCB84F00094D5BA /* AnalyticsConstants.m in Sources */, 6FF7BBAA22A78DE400FA758A /* SearchSettingSelectorCell.m in Sources */, + 6FE9B54824B84748001D95E5 /* HomeLiveMediaVerticalListTableViewCell.m in Sources */, 6F5F4FC81DB10CFD0011CCA3 /* RelatedContentView.m in Sources */, 6F475FC21EB37BC6003021EA /* DataViewController.m in Sources */, 0801E07F1D4A4A810008021E /* RadioChannel.m in Sources */, @@ -7457,7 +7471,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 338; + CURRENT_PROJECT_VERSION = 341; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -7476,7 +7490,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 3.1.0; + MARKETING_VERSION = 3.1.1; MARKETING_VERSION_SUFFIX = "-debug"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; @@ -7525,7 +7539,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 338; + CURRENT_PROJECT_VERSION = 341; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -7538,7 +7552,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 3.1.0; + MARKETING_VERSION = 3.1.1; MARKETING_VERSION_SUFFIX = ""; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; @@ -7870,7 +7884,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 338; + CURRENT_PROJECT_VERSION = 341; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -7884,7 +7898,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 3.1.0; + MARKETING_VERSION = 3.1.1; MARKETING_VERSION_SUFFIX = "-beta"; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; @@ -8077,7 +8091,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 338; + CURRENT_PROJECT_VERSION = 341; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -8091,7 +8105,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MARKETING_VERSION = 3.1.0; + MARKETING_VERSION = 3.1.1; MARKETING_VERSION_SUFFIX = "-nightly"; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; diff --git a/WhatsNew-beta.json b/WhatsNew-beta.json index df4bedbc0..23d4ff2bf 100755 --- a/WhatsNew-beta.json +++ b/WhatsNew-beta.json @@ -114,5 +114,8 @@ "3.1.0-335": "- Fix crash when updating settings.", "3.1.0-336": "- Update german translation.", "3.1.0-337": "- Display waveform for song currently being played.\n- Display current show in show list for livestreams without timeshift.\n- Apply snapping in search results for shows.", - "3.1.0-338": "- UI improvement for video livestreams.\n- Long press to copy the song title and artist name." + "3.1.0-338": "- UI improvement for video livestreams.\n- Long press to copy the song title and artist name.", + "3.1.1-339": "- Always hide the playback controls after entering full screen.\n- Fix screen incorrectly turning off when watching videos with sound over AirPlay.\n- Fix issue leading to the loading indicator being displayed more than necessary.\n- iPad profile split view: Reset right navigation to its root when tapping again on left cells.", + "3.1.1-340": "- Updated TV and radio channel overview on the Live tab. \n- Add \"sort by\" filter in Search tab.\n- iOS prediction for TV and radio livestreams.", + "3.1.1-341": "- Correctly take into account SDH accessibility opt-in when choosing subtitles automatically." } \ No newline at end of file diff --git a/docs/REMOTE_CONFIGURATION.md b/docs/REMOTE_CONFIGURATION.md index 885e782fe..426e5f0bd 100755 --- a/docs/REMOTE_CONFIGURATION.md +++ b/docs/REMOTE_CONFIGURATION.md @@ -21,6 +21,7 @@ If a remote configuration is found to be invalid (usually a mandatory parameter ## URLs * `betaTestingURL` (optional, string): The URL of the page where beta testers can register. +* `tvBetaTestingURL` (optional, string): The URL of the page where Apple TV beta testers can register. * `feedbackURL` (optional, string): The URL of the feedback form. * `dataProtectionURL` (optional, string): The URL of the data protection information page. * `impressumURL` (optional, string): The URL of the impressum page. If none is provided, the corresponding menu entry will not be displayed. @@ -99,7 +100,6 @@ The keys common to both TV and radio channels JSON dictionaries are: * `radioLatestEpisodes`: The latest episodes. * `radioLatestVideos`: The latest videos. * `radioMostPopular`: The most popular audios. -* `radioMyListShows`: Shows from "My list". * `radioShowsAccess`: A-Z and By date access buttons. ### User interface options @@ -122,6 +122,7 @@ The keys common to both TV and radio channels JSON dictionaries are: * `searchSettingsHidden` (optional, boolean): Set to `true` to hide support for search settings. * `searchSettingSubtitledHidden` (optional, boolean): Set to `true` to hide the subtitled option in the search settings. +* `searchSortingCriteriumHidden` (optional, boolean): Set to `true` to hide the sorting criterium option in the search settings. * `showsSearchHidden ` (optional, boolean): Set to `true` to hide show search results. ## Continuous playback diff --git a/fastlane/Fastfile b/fastlane/Fastfile index dbe26aba2..eb5153b3b 100755 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -27,6 +27,9 @@ platform :ios do end end + # Only used by FastLane actions + xcversion(version: '~> 11') + if cleaned_lane_condition(lane) ensure_git_status_clean Dir.chdir('..') { sh 'make bootstrap' } @@ -93,6 +96,17 @@ platform :ios do bump_build_number_beta_workflow end + desc 'Upload a new build (bitcode) on AppStore Connect with the current build number.' + lane :appStoreUploads do + notify_build_number_to_ci(nil) + + sh 'bundle exec fastlane ios swiAppStoreUpload' + sh 'bundle exec fastlane ios srfAppStoreUpload' + sh 'bundle exec fastlane ios rtsAppStoreUpload' + sh 'bundle exec fastlane ios rsiAppStoreUpload' + sh 'bundle exec fastlane ios rtrAppStoreUpload' + end + desc 'SWI: Upload a new build (bitcode) on AppStore Connect with the current build number.' lane :swiAppStoreUpload do testflight_lane(scheme: 'Play SWI') @@ -192,6 +206,11 @@ platform :ios do desc 'Build, upload to TestFlight' private_lane :testflight_lane do |options| scheme = options[:scheme] + build_number = get_build_number + + can_upload = can_upload_testflight_build(nil) + UI.message(scheme + ' ' + build_number + ' already uploaded 🔁✅') unless can_upload + next unless can_upload build_lane( configuration: 'AppStore', @@ -202,6 +221,7 @@ platform :ios do pilot( skip_waiting_for_build_processing: true ) + UI.message(scheme + ' ' + build_number + ' uploaded ✅') clean_build_artifacts end @@ -486,6 +506,15 @@ def upload_screenshots(platform) ) end +def can_upload_testflight_build(platform) + platform ||= 'ios' + + appstore_build_number = latest_testflight_build_number(platform: platform) + local_build_number = get_build_number + + (appstore_build_number < local_build_number.to_i) +end + # Beta workflow: tag the new beta, bump build number and push to the repo, # only if we're not in a release process. def bump_build_number_beta_workflow @@ -496,7 +525,7 @@ def bump_build_number_beta_workflow return if is_in_release_process - add_git_tag(tag: tag_version) + add_git_tag(tag: 'ios/' + tag_version) bump_build_number_commit push_to_git_remote end diff --git a/fastlane/README.md b/fastlane/README.md index c6fd914aa..662ad1401 100755 --- a/fastlane/README.md +++ b/fastlane/README.md @@ -26,6 +26,11 @@ For each BUs, build a new nightly on App Center, with a new build number, greate fastlane ios betas ``` For each BUs, build a new beta on App Center with the current build number. If we're not in a release or hotfix process (master, release/* or hotfix/*), tag the current version on the repository and bump the build number +### ios appStoreUploads +``` +fastlane ios appStoreUploads +``` +Upload a new build (bitcode) on AppStore Connect with the current build number. ### ios swiAppStoreUpload ``` fastlane ios swiAppStoreUpload