Compare commits

..

9 Commits

Author SHA1 Message Date
Kelvin 44eacc2a47 Stable refs 2023-11-10 20:38:46 +01:00
Kelvin 8135d61398 Fix language issue 2023-11-10 20:34:43 +01:00
Kelvin 66208f8265 Merge branch 'master' of gitlab.futo.org:videostreaming/grayjay 2023-11-10 19:49:20 +01:00
Kelvin f52251e23a Hide creators, Fix hide video, 2023-11-10 19:49:09 +01:00
Koen dbea93efe5 Merge branch 'master' of gitlab.futo.org:videostreaming/grayjay 2023-11-10 12:10:30 +01:00
Koen 3bf0740bd1 Fixed control cast on non-fullscreen. 2023-11-10 12:10:12 +01:00
Kelvin fa7f1b11f3 Merge branch 'master' of gitlab.futo.org:videostreaming/grayjay 2023-11-09 19:49:51 +01:00
Kelvin ff914bbdf4 Temporary subscription workarounds 2023-11-09 19:49:45 +01:00
Koen b822078d4b Fixed support tab falsely showing when a creator does not have a polycentric profile. 2023-11-09 19:12:54 +01:00
13 changed files with 113 additions and 21 deletions
@@ -123,7 +123,7 @@ class Settings : FragmentedStorageFileJson() {
@FormField(R.string.home, "group", R.string.configure_how_your_home_tab_works_and_feels, 0) @FormField(R.string.language, "group", -1, 0)
var language = LanguageSettings(); var language = LanguageSettings();
@Serializable @Serializable
class LanguageSettings { class LanguageSettings {
@@ -166,6 +166,17 @@ class Settings : FragmentedStorageFileJson() {
@FormField(R.string.preview_feed_items, FieldForm.TOGGLE, R.string.preview_feed_items_description, 6) @FormField(R.string.preview_feed_items, FieldForm.TOGGLE, R.string.preview_feed_items_description, 6)
var previewFeedItems: Boolean = true; var previewFeedItems: Boolean = true;
@FormField(R.string.clear_hidden, FieldForm.BUTTON, R.string.clear_hidden_description, 7)
@FormFieldButton(R.drawable.ic_visibility_off)
fun clearHidden() {
StateMeta.instance.removeAllHiddenCreators();
StateMeta.instance.removeAllHiddenVideos();
SettingsActivity.getActivity()?.let {
UIDialogs.toast(it, "Creators and videos should show up again");
}
}
} }
@FormField(R.string.search, "group", -1, 2) @FormField(R.string.search, "group", -1, 2)
@@ -216,6 +227,9 @@ class Settings : FragmentedStorageFileJson() {
@Serializable(with = FlexibleBooleanSerializer::class) @Serializable(with = FlexibleBooleanSerializer::class)
var fetchOnAppBoot: Boolean = true; var fetchOnAppBoot: Boolean = true;
@FormField(R.string.fetch_on_tab_opened, FieldForm.TOGGLE, R.string.fetch_on_tab_opened_description, 6)
var fetchOnTabOpen: Boolean = true;
@FormField(R.string.background_update, FieldForm.DROPDOWN, R.string.experimental_background_update_for_subscriptions_cache, 7) @FormField(R.string.background_update, FieldForm.DROPDOWN, R.string.experimental_background_update_for_subscriptions_cache, 7)
@DropdownFieldOptionsId(R.array.background_interval) @DropdownFieldOptionsId(R.array.background_interval)
var subscriptionsBackgroundUpdateInterval: Int = 0; var subscriptionsBackgroundUpdateInterval: Int = 0;
@@ -246,6 +260,9 @@ class Settings : FragmentedStorageFileJson() {
@FormField(R.string.track_playtime_locally, FieldForm.TOGGLE, R.string.track_playtime_locally_description, 10) @FormField(R.string.track_playtime_locally, FieldForm.TOGGLE, R.string.track_playtime_locally_description, 10)
var allowPlaytimeTracking: Boolean = true; var allowPlaytimeTracking: Boolean = true;
@FormField(R.string.always_reload_from_cache, FieldForm.TOGGLE, R.string.always_reload_from_cache_description, 11)
var alwaysReloadFromCache: Boolean = false;
} }
@FormField(R.string.player, "group", R.string.change_behavior_of_the_player, 4) @FormField(R.string.player, "group", R.string.change_behavior_of_the_player, 4)
@@ -389,8 +389,13 @@ class UISlideOverlays {
val watchLater = StatePlaylists.instance.getWatchLater(); val watchLater = StatePlaylists.instance.getWatchLater();
items.add(SlideUpMenuGroup(container.context, container.context.getString(R.string.actions), "actions", items.add(SlideUpMenuGroup(container.context, container.context.getString(R.string.actions), "actions",
(listOf( (listOf(
SlideUpMenuItem(container.context, R.drawable.ic_download, container.context.getString(R.string.download), container.context.getString(R.string.download_the_video), container.context.getString(R.string.download), SlideUpMenuItem(container.context, R.drawable.ic_download, container.context.getString(R.string.download), container.context.getString(R.string.download_the_video), container.context.getString(R.string.download), {
{ showDownloadVideoOverlay(video, container, true); }, false)) showDownloadVideoOverlay(video, container, true);
}, false),
SlideUpMenuItem(container.context, R.drawable.ic_visibility_off, container.context.getString(R.string.hide_creator_from_home), "", "hide_creator", {
StateMeta.instance.addHiddenCreator(video.author.url);
UIDialogs.toast(container.context, "[${video.author.name}] hidden, you may need to reload home");
}))
+ actions) + actions)
)); ));
items.add( items.add(
@@ -83,7 +83,7 @@ class ChannelContentCache {
val items = validStores.flatMap { it.getItems() } val items = validStores.flatMap { it.getItems() }
.sortedByDescending { it.datetime }; .sortedByDescending { it.datetime };
return DedupContentPager(PlatformContentPager(items, Math.min(150, items.size)), StatePlatform.instance.getEnabledClients().map { it.id }); return DedupContentPager(PlatformContentPager(items, Math.min(30, items.size)), StatePlatform.instance.getEnabledClients().map { it.id });
} }
fun uncacheContent(content: SerializedPlatformContent) { fun uncacheContent(content: SerializedPlatformContent) {
@@ -1,22 +1,20 @@
package com.futo.platformplayer.fragment.channel.tab package com.futo.platformplayer.fragment.channel.tab
import android.content.Intent
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.futo.platformplayer.R import com.futo.platformplayer.R
import com.futo.platformplayer.api.media.models.channels.IPlatformChannel import com.futo.platformplayer.api.media.models.channels.IPlatformChannel
import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile
import com.futo.platformplayer.logging.Logger
import com.futo.platformplayer.views.SupportView import com.futo.platformplayer.views.SupportView
import com.futo.platformplayer.views.buttons.BigButton
class ChannelMonetizationFragment : Fragment, IChannelTabFragment { class ChannelMonetizationFragment : Fragment, IChannelTabFragment {
private var _supportView: SupportView? = null private var _supportView: SupportView? = null
private var _textMonetization: TextView? = null
private var _lastChannel: IPlatformChannel? = null; private var _lastChannel: IPlatformChannel? = null;
private var _lastPolycentricProfile: PolycentricProfile? = null; private var _lastPolycentricProfile: PolycentricProfile? = null;
@@ -26,21 +24,22 @@ class ChannelMonetizationFragment : Fragment, IChannelTabFragment {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_channel_monetization, container, false); val view = inflater.inflate(R.layout.fragment_channel_monetization, container, false);
_supportView = view.findViewById(R.id.support); _supportView = view.findViewById(R.id.support);
_textMonetization = view.findViewById(R.id.text_monetization);
_lastChannel?.also { _lastChannel?.also {
setChannel(it); setChannel(it);
}; };
_lastPolycentricProfile?.also { _supportView?.visibility = View.GONE;
setPolycentricProfile(it, animate = false); _textMonetization?.visibility = View.GONE;
} setPolycentricProfile(_lastPolycentricProfile, animate = false);
return view; return view;
} }
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView(); super.onDestroyView();
_supportView = null; _supportView = null;
_textMonetization = null;
} }
override fun setChannel(channel: IPlatformChannel) { override fun setChannel(channel: IPlatformChannel) {
@@ -49,7 +48,15 @@ class ChannelMonetizationFragment : Fragment, IChannelTabFragment {
fun setPolycentricProfile(polycentricProfile: PolycentricProfile?, animate: Boolean) { fun setPolycentricProfile(polycentricProfile: PolycentricProfile?, animate: Boolean) {
_lastPolycentricProfile = polycentricProfile _lastPolycentricProfile = polycentricProfile
_supportView?.setPolycentricProfile(polycentricProfile, animate) if (polycentricProfile != null) {
_supportView?.setPolycentricProfile(polycentricProfile, animate)
_supportView?.visibility = View.VISIBLE
_textMonetization?.visibility = View.GONE
} else {
_supportView?.setPolycentricProfile(null, animate)
_supportView?.visibility = View.GONE
_textMonetization?.visibility = View.VISIBLE
}
} }
companion object { companion object {
@@ -152,7 +152,7 @@ class HomeFragment : MainFragment() {
} }
override fun filterResults(contents: List<IPlatformContent>): List<IPlatformContent> { override fun filterResults(contents: List<IPlatformContent>): List<IPlatformContent> {
return contents.filter { it !is IPlatformVideo || !StateMeta.instance.isVideoHidden(it.url) }; return contents.filter { !StateMeta.instance.isVideoHidden(it.url) && !StateMeta.instance.isCreatorHidden(it.author.url) };
} }
private fun loadResults() { private fun loadResults() {
@@ -121,7 +121,7 @@ class SubscriptionsFeedFragment : MainFragment() {
recyclerData.lastLoad.getNowDiffSeconds() > 60 ) { recyclerData.lastLoad.getNowDiffSeconds() > 60 ) {
recyclerData.lastLoad = OffsetDateTime.now(); recyclerData.lastLoad = OffsetDateTime.now();
if(StateSubscriptions.instance.getOldestUpdateTime().getNowDiffMinutes() > 5) if(StateSubscriptions.instance.getOldestUpdateTime().getNowDiffMinutes() > 5 && Settings.instance.subscriptions.fetchOnTabOpen)
loadResults(false); loadResults(false);
else if(recyclerData.results.size == 0) else if(recyclerData.results.size == 0)
loadCache(); loadCache();
@@ -193,7 +193,15 @@ class SubscriptionsFeedFragment : MainFragment() {
return@TaskHandler resp; return@TaskHandler resp;
}) })
.success { loadedResult(it); } .success {
if(!Settings.instance.subscriptions.alwaysReloadFromCache)
loadedResult(it);
else {
finishRefreshLayoutLoader();
setLoading(false);
loadCache();
}
} //TODO: Remove
.exception<RateLimitException> { .exception<RateLimitException> {
fragment.lifecycleScope.launch(Dispatchers.IO) { fragment.lifecycleScope.launch(Dispatchers.IO) {
val subs = StateSubscriptions.instance.getSubscriptions(); val subs = StateSubscriptions.instance.getSubscriptions();
@@ -256,7 +264,10 @@ class SubscriptionsFeedFragment : MainFragment() {
else null; else null;
_filterSettings.save(); _filterSettings.save();
}; };
loadResults(false) if(Settings.instance.subscriptions.fetchOnTabOpen) //TODO: Do this different, temporary workaround
loadResults(false);
else
loadCache();
} }
override fun filterResults(results: List<IPlatformContent>): List<IPlatformContent> { override fun filterResults(results: List<IPlatformContent>): List<IPlatformContent> {
@@ -5,15 +5,39 @@ import com.futo.platformplayer.stores.StringHashSetStorage
class StateMeta { class StateMeta {
val hiddenVideos = FragmentedStorage.get<StringHashSetStorage>("hiddenVideos"); val hiddenVideos = FragmentedStorage.get<StringHashSetStorage>("hiddenVideos");
val hiddenCreators = FragmentedStorage.get<StringHashSetStorage>("hiddenCreators");
fun isVideoHidden(videoUrl: String) : Boolean { fun isVideoHidden(videoUrl: String) : Boolean {
return hiddenVideos.contains(videoUrl); return hiddenVideos.contains(videoUrl);
} }
fun addHiddenVideo(videoUrl: String) { fun addHiddenVideo(videoUrl: String) {
hiddenVideos.addDistinct(videoUrl); hiddenVideos.addDistinct(videoUrl);
hiddenVideos.save();
} }
fun removeHiddenVideo(videoUrl: String) { fun removeHiddenVideo(videoUrl: String) {
hiddenVideos.remove(videoUrl); hiddenVideos.remove(videoUrl);
hiddenVideos.save();
}
fun removeAllHiddenVideos() {
hiddenVideos.removeAll();
hiddenVideos.save();
}
fun isCreatorHidden(creatorUrl: String): Boolean {
return hiddenCreators.contains(creatorUrl);
}
fun addHiddenCreator(creatorUrl: String) {
hiddenCreators.addDistinct(creatorUrl);
hiddenCreators.save();
}
fun removeHiddenCreator(creatorUrl: String) {
hiddenCreators.remove(creatorUrl);
hiddenCreators.save();
}
fun removeAllHiddenCreators() {
hiddenCreators.removeAll();
hiddenCreators.save();
} }
companion object { companion object {
@@ -35,6 +35,11 @@ class StringHashSetStorage : FragmentedStorageFileJson() {
values.remove(obj); values.remove(obj);
} }
} }
fun removeAll() {
synchronized(values) {
values.clear();
}
}
fun set(vararg objs: String) { fun set(vararg objs: String) {
synchronized(values) { synchronized(values) {
values.clear(); values.clear();
@@ -219,7 +219,7 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
updateRotateLock(); updateRotateLock();
}; };
_control_cast.setOnClickListener { _control_cast.setOnClickListener {
UIDialogs.showCastingDialog(context);
}; };
_control_minimize_fullscreen.setOnClickListener { _control_minimize_fullscreen.setOnClickListener {
@@ -6,5 +6,18 @@
<com.futo.platformplayer.views.SupportView <com.futo.platformplayer.views.SupportView
android:id="@+id/support" android:id="@+id/support"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
android:visibility="gone"/>
<TextView
android:id="@+id/text_monetization"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_gravity="center"
android:text="@string/this_creator_has_not_setup_any_monetization_features"
android:fontFamily="@font/inter_light"
android:textColor="#ACACAC"
android:textSize="12dp"
android:visibility="gone" />
</FrameLayout> </FrameLayout>
+10
View File
@@ -7,6 +7,7 @@
<string name="add_to">Add to</string> <string name="add_to">Add to</string>
<string name="lorem_ipsum" translatable="false">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</string> <string name="lorem_ipsum" translatable="false">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</string>
<string name="add_to_queue">Add to queue</string> <string name="add_to_queue">Add to queue</string>
<string name="general">General</string>
<string name="home">Home</string> <string name="home">Home</string>
<string name="recommendations">Recommendations</string> <string name="recommendations">Recommendations</string>
<string name="more">More</string> <string name="more">More</string>
@@ -312,9 +313,14 @@
<string name="import_data_description">Select a file to import, support various files (alternative to opening directly)</string> <string name="import_data_description">Select a file to import, support various files (alternative to opening directly)</string>
<string name="external_storage">External Storage</string> <string name="external_storage">External Storage</string>
<string name="feed_style">Feed Style</string> <string name="feed_style">Feed Style</string>
<string name="language">Language</string>
<string name="app_language">App Language</string> <string name="app_language">App Language</string>
<string name="may_require_restart">May require restart</string> <string name="may_require_restart">May require restart</string>
<string name="fetch_on_app_boot">Fetch on app boot</string> <string name="fetch_on_app_boot">Fetch on app boot</string>
<string name="fetch_on_tab_opened">Fetch on tab opened</string>
<string name="fetch_on_tab_opened_description">Fetch new results when the tab is opened (if no results yet, disabling is not recommended unless you have issues)</string>
<string name="always_reload_from_cache">Always reload from cache</string>
<string name="always_reload_from_cache_description">This is not recommended, but a possible workaround for some issues.</string>
<string name="get_answers_to_common_questions">Get answers to common questions</string> <string name="get_answers_to_common_questions">Get answers to common questions</string>
<string name="give_feedback_on_the_application">Give feedback on the application</string> <string name="give_feedback_on_the_application">Give feedback on the application</string>
<string name="info">Info</string> <string name="info">Info</string>
@@ -341,6 +347,8 @@
<string name="reinstall_embedded_plugins">Reinstall Embedded Plugins</string> <string name="reinstall_embedded_plugins">Reinstall Embedded Plugins</string>
<string name="remove_cached_version">Remove Cached Version</string> <string name="remove_cached_version">Remove Cached Version</string>
<string name="remove_the_last_downloaded_version">Remove the last downloaded version</string> <string name="remove_the_last_downloaded_version">Remove the last downloaded version</string>
<string name="clear_hidden">Clear Hidden</string>
<string name="clear_hidden_description">Removes all hidden creators and videos, showing them again</string>
<string name="reset_announcements">Reset announcements</string> <string name="reset_announcements">Reset announcements</string>
<string name="reset_hidden_announcements">Reset hidden announcements</string> <string name="reset_hidden_announcements">Reset hidden announcements</string>
<string name="restore_automatic_backup">Restore Automatic Backup</string> <string name="restore_automatic_backup">Restore Automatic Backup</string>
@@ -485,6 +493,7 @@
<string name="page">Page</string> <string name="page">Page</string>
<string name="hide">Hide</string> <string name="hide">Hide</string>
<string name="hide_from_home">Hide from Home</string> <string name="hide_from_home">Hide from Home</string>
<string name="hide_creator_from_home">Hide Creator from Home</string>
<string name="play_feed_as_queue">Play Feed as Queue</string> <string name="play_feed_as_queue">Play Feed as Queue</string>
<string name="play_entire_feed">Play entire feed</string> <string name="play_entire_feed">Play entire feed</string>
<string name="queued">Queued</string> <string name="queued">Queued</string>
@@ -639,6 +648,7 @@
<string name="this_creator_has_not_set_any_support_options_on_harbor_polycentric">This creator has not set any support options on Harbor (Polycentric)</string> <string name="this_creator_has_not_set_any_support_options_on_harbor_polycentric">This creator has not set any support options on Harbor (Polycentric)</string>
<string name="load_more">Load More</string> <string name="load_more">Load More</string>
<string name="stopped_after_requestcount_to_avoid_rate_limit_click_load_more_to_load_more">Stopped after {requestCount} to avoid rate limit, click load more to load more.</string> <string name="stopped_after_requestcount_to_avoid_rate_limit_click_load_more_to_load_more">Stopped after {requestCount} to avoid rate limit, click load more to load more.</string>
<string name="this_creator_has_not_setup_any_monetization_features">This creator has not setup any monetization features</string>
<string-array name="home_screen_array"> <string-array name="home_screen_array">
<item>Recommendations</item> <item>Recommendations</item>
<item>Subscriptions</item> <item>Subscriptions</item>