make channel shorts tab work correctly for linked channels

Changelog: changed
This commit is contained in:
Kai 2025-04-23 11:38:09 -05:00
parent daa91986ef
commit 4acc867634
No known key found for this signature in database
3 changed files with 73 additions and 60 deletions

View File

@ -71,7 +71,7 @@ class ChannelContentsFragment(private val subType: String? = null) : Fragment(),
val lastPolycentricProfile = _lastPolycentricProfile; val lastPolycentricProfile = _lastPolycentricProfile;
var pager: IPager<IPlatformContent>? = null; var pager: IPager<IPlatformContent>? = null;
if (lastPolycentricProfile != null) if (lastPolycentricProfile != null)
pager= StatePolycentric.instance.getChannelContent(lifecycleScope, lastPolycentricProfile); pager= StatePolycentric.instance.getChannelContent(lifecycleScope, lastPolycentricProfile, type = subType);
if(pager == null) { if(pager == null) {
if(subType != null) if(subType != null)

View File

@ -718,7 +718,7 @@ class StatePlatform {
} }
} }
fun getChannelContent(baseClient: IPlatformClient, channelUrl: String, isSubscriptionOptimized: Boolean = false, usePooledClients: Int = 0): IPager<IPlatformContent> { fun getChannelContent(baseClient: IPlatformClient, channelUrl: String, isSubscriptionOptimized: Boolean = false, usePooledClients: Int = 0, type: String? = null): IPager<IPlatformContent> {
val clientCapabilities = baseClient.getChannelCapabilities(); val clientCapabilities = baseClient.getChannelCapabilities();
val client = if(usePooledClients > 1) val client = if(usePooledClients > 1)
_channelClientPool.getClientPooled(baseClient, usePooledClients); _channelClientPool.getClientPooled(baseClient, usePooledClients);
@ -727,66 +727,75 @@ class StatePlatform {
var lastStream: OffsetDateTime? = null; var lastStream: OffsetDateTime? = null;
val pagerResult: IPager<IPlatformContent>; val pagerResult: IPager<IPlatformContent>;
if(!clientCapabilities.hasType(ResultCapabilities.TYPE_MIXED) && if (type == null) {
( clientCapabilities.hasType(ResultCapabilities.TYPE_VIDEOS) || if(!clientCapabilities.hasType(ResultCapabilities.TYPE_MIXED) &&
clientCapabilities.hasType(ResultCapabilities.TYPE_STREAMS) || ( clientCapabilities.hasType(ResultCapabilities.TYPE_VIDEOS) ||
clientCapabilities.hasType(ResultCapabilities.TYPE_LIVE) || clientCapabilities.hasType(ResultCapabilities.TYPE_STREAMS) ||
clientCapabilities.hasType(ResultCapabilities.TYPE_POSTS) clientCapabilities.hasType(ResultCapabilities.TYPE_LIVE) ||
)) { clientCapabilities.hasType(ResultCapabilities.TYPE_POSTS)
val toQuery = mutableListOf<String>(); )) {
if(clientCapabilities.hasType(ResultCapabilities.TYPE_VIDEOS)) val toQuery = mutableListOf<String>();
toQuery.add(ResultCapabilities.TYPE_VIDEOS); if(clientCapabilities.hasType(ResultCapabilities.TYPE_VIDEOS))
if(clientCapabilities.hasType(ResultCapabilities.TYPE_STREAMS)) toQuery.add(ResultCapabilities.TYPE_VIDEOS);
toQuery.add(ResultCapabilities.TYPE_STREAMS); if(clientCapabilities.hasType(ResultCapabilities.TYPE_STREAMS))
if(clientCapabilities.hasType(ResultCapabilities.TYPE_LIVE)) toQuery.add(ResultCapabilities.TYPE_STREAMS);
toQuery.add(ResultCapabilities.TYPE_LIVE); if(clientCapabilities.hasType(ResultCapabilities.TYPE_LIVE))
if(clientCapabilities.hasType(ResultCapabilities.TYPE_POSTS)) toQuery.add(ResultCapabilities.TYPE_LIVE);
toQuery.add(ResultCapabilities.TYPE_POSTS); if(clientCapabilities.hasType(ResultCapabilities.TYPE_POSTS))
toQuery.add(ResultCapabilities.TYPE_POSTS);
if(isSubscriptionOptimized) { if(isSubscriptionOptimized) {
val sub = StateSubscriptions.instance.getSubscription(channelUrl); val sub = StateSubscriptions.instance.getSubscription(channelUrl);
if(sub != null) { if(sub != null) {
if(!sub.shouldFetchStreams()) { if(!sub.shouldFetchStreams()) {
Logger.i(TAG, "Subscription [${sub.channel.name}:${channelUrl}] Last livestream > 7 days, skipping live streams [${sub.lastLiveStream.getNowDiffDays()} days ago]"); Logger.i(TAG, "Subscription [${sub.channel.name}:${channelUrl}] Last livestream > 7 days, skipping live streams [${sub.lastLiveStream.getNowDiffDays()} days ago]");
toQuery.remove(ResultCapabilities.TYPE_LIVE); toQuery.remove(ResultCapabilities.TYPE_LIVE);
} }
if(!sub.shouldFetchLiveStreams()) { if(!sub.shouldFetchLiveStreams()) {
Logger.i(TAG, "Subscription [${sub.channel.name}:${channelUrl}] Last livestream > 15 days, skipping streams [${sub.lastLiveStream.getNowDiffDays()} days ago]"); Logger.i(TAG, "Subscription [${sub.channel.name}:${channelUrl}] Last livestream > 15 days, skipping streams [${sub.lastLiveStream.getNowDiffDays()} days ago]");
toQuery.remove(ResultCapabilities.TYPE_STREAMS); toQuery.remove(ResultCapabilities.TYPE_STREAMS);
} }
if(!sub.shouldFetchPosts()) { if(!sub.shouldFetchPosts()) {
Logger.i(TAG, "Subscription [${sub.channel.name}:${channelUrl}] Last livestream > 5 days, skipping posts [${sub.lastPost.getNowDiffDays()} days ago]"); Logger.i(TAG, "Subscription [${sub.channel.name}:${channelUrl}] Last livestream > 5 days, skipping posts [${sub.lastPost.getNowDiffDays()} days ago]");
toQuery.remove(ResultCapabilities.TYPE_POSTS); toQuery.remove(ResultCapabilities.TYPE_POSTS);
}
}
}
//Merged pager
val pagers = toQuery
.parallelStream()
.map {
val results = client.getChannelContents(channelUrl, it, ResultCapabilities.ORDER_CHONOLOGICAL) ;
when(it) {
ResultCapabilities.TYPE_STREAMS -> {
val streamResults = results.getResults();
if(streamResults.size == 0)
lastStream = OffsetDateTime.MIN;
else
lastStream = results.getResults().firstOrNull()?.datetime;
} }
} }
return@map results;
} }
.asSequence()
.toList();
val pager = MultiChronoContentPager(pagers.toTypedArray()); //Merged pager
pager.initialize(); val pagers = toQuery
pagerResult = pager; .parallelStream()
.map {
val results = client.getChannelContents(channelUrl, it, ResultCapabilities.ORDER_CHONOLOGICAL) ;
when(it) {
ResultCapabilities.TYPE_STREAMS -> {
val streamResults = results.getResults();
if(streamResults.size == 0)
lastStream = OffsetDateTime.MIN;
else
lastStream = results.getResults().firstOrNull()?.datetime;
}
}
return@map results;
}
.asSequence()
.toList();
val pager = MultiChronoContentPager(pagers.toTypedArray());
pager.initialize();
pagerResult = pager;
}
else {
pagerResult = client.getChannelContents(channelUrl, ResultCapabilities.TYPE_MIXED, ResultCapabilities.ORDER_CHONOLOGICAL);
}
} else {
pagerResult = if (type == ResultCapabilities.TYPE_SHORTS) {
client.getChannelContents(channelUrl, ResultCapabilities.TYPE_SHORTS, ResultCapabilities.ORDER_CHONOLOGICAL);
} else {
EmptyPager()
}
} }
else
pagerResult = client.getChannelContents(channelUrl, ResultCapabilities.TYPE_MIXED, ResultCapabilities.ORDER_CHONOLOGICAL);
//Subscription optimization //Subscription optimization
val sub = StateSubscriptions.instance.getSubscription(channelUrl); val sub = StateSubscriptions.instance.getSubscription(channelUrl);
@ -838,10 +847,10 @@ class StatePlatform {
return pagerResult; return pagerResult;
} }
fun getChannelContent(channelUrl: String, isSubscriptionOptimized: Boolean = false, usePooledClients: Int = 0, ignorePlugins: List<String>? = null): IPager<IPlatformContent> { fun getChannelContent(channelUrl: String, isSubscriptionOptimized: Boolean = false, usePooledClients: Int = 0, ignorePlugins: List<String>? = null, type: String? = null): IPager<IPlatformContent> {
Logger.i(TAG, "Platform - getChannelVideos"); Logger.i(TAG, "Platform - getChannelVideos");
val baseClient = getChannelClient(channelUrl, ignorePlugins); val baseClient = getChannelClient(channelUrl, ignorePlugins);
return getChannelContent(baseClient, channelUrl, isSubscriptionOptimized, usePooledClients); return getChannelContent(baseClient, channelUrl, isSubscriptionOptimized, usePooledClients, type);
} }
fun getChannelContent(channelUrl: String, type: String?, ordering: String = ResultCapabilities.ORDER_CHONOLOGICAL): IPager<IPlatformContent> { fun getChannelContent(channelUrl: String, type: String?, ordering: String = ResultCapabilities.ORDER_CHONOLOGICAL): IPager<IPlatformContent> {
val client = getChannelClient(channelUrl); val client = getChannelClient(channelUrl);

View File

@ -236,7 +236,7 @@ class StatePolycentric {
return Pair(didUpdate, listOf(url)); return Pair(didUpdate, listOf(url));
} }
fun getChannelContent(scope: CoroutineScope, profile: PolycentricProfile, isSubscriptionOptimized: Boolean = false, channelConcurrency: Int = -1): IPager<IPlatformContent>? { fun getChannelContent(scope: CoroutineScope, profile: PolycentricProfile, isSubscriptionOptimized: Boolean = false, channelConcurrency: Int = -1, type: String? = null): IPager<IPlatformContent>? {
ensureEnabled() ensureEnabled()
//TODO: Currently abusing subscription concurrency for parallelism //TODO: Currently abusing subscription concurrency for parallelism
@ -248,7 +248,11 @@ class StatePolycentric {
return@mapNotNull Pair(client, scope.async(Dispatchers.IO) { return@mapNotNull Pair(client, scope.async(Dispatchers.IO) {
try { try {
return@async StatePlatform.instance.getChannelContent(url, isSubscriptionOptimized, concurrency); if (type == null) {
return@async StatePlatform.instance.getChannelContent(url, isSubscriptionOptimized, concurrency);
} else {
return@async StatePlatform.instance.getChannelContent(url, isSubscriptionOptimized, concurrency, type = type);
}
} catch (ex: Throwable) { } catch (ex: Throwable) {
Logger.e(TAG, "getChannelContent", ex); Logger.e(TAG, "getChannelContent", ex);
return@async null; return@async null;