From c83a9924e22c868c23ec98576dc87e0f1201cf9e Mon Sep 17 00:00:00 2001 From: Koen J <git@unkto.com> Date: Wed, 5 Mar 2025 17:04:48 +0100 Subject: [PATCH] Implemented new ApiMethods calls. --- .../platformplayer/Extensions_Polycentric.kt | 40 +- .../PolycentricCreateProfileActivity.kt | 6 +- .../PolycentricImportProfileActivity.kt | 4 +- .../activities/PolycentricProfileActivity.kt | 6 +- .../platformplayer/dialogs/CommentDialog.kt | 2 +- .../channel/tab/ChannelAboutFragment.kt | 6 +- .../channel/tab/ChannelContentsFragment.kt | 2 +- .../channel/tab/ChannelListFragment.kt | 2 +- .../tab/ChannelMonetizationFragment.kt | 2 +- .../channel/tab/IChannelTabFragment.kt | 2 +- .../mainactivity/main/ChannelFragment.kt | 54 +-- .../mainactivity/main/CommentsFragment.kt | 2 +- .../mainactivity/main/PostDetailFragment.kt | 30 +- .../mainactivity/main/VideoDetailView.kt | 62 +-- .../topbar/NavigationTopBarFragment.kt | 2 +- .../images/PolycentricModelLoader.java | 17 +- .../polycentric/PolycentricCache.kt | 353 ------------------ .../futo/platformplayer/states/StateCache.kt | 10 +- .../futo/platformplayer/states/StateMeta.kt | 2 +- .../platformplayer/states/StatePolycentric.kt | 56 +-- .../states/StateSubscriptionGroups.kt | 41 +- .../states/StateSubscriptions.kt | 7 - .../stores/CachedPolycentricProfileStorage.kt | 31 -- .../platformplayer/views/MonetizationView.kt | 5 +- .../futo/platformplayer/views/SupportView.kt | 2 +- .../views/adapters/ChannelViewPagerAdapter.kt | 2 +- .../views/adapters/CommentViewHolder.kt | 19 +- .../CommentWithReferenceViewHolder.kt | 2 +- .../views/adapters/PlaylistView.kt | 1 - .../views/adapters/SubscriptionViewHolder.kt | 1 - .../adapters/feedtypes/PreviewPostView.kt | 1 - .../adapters/feedtypes/PreviewVideoView.kt | 1 - .../viewholders/CreatorBarViewHolder.kt | 1 - .../adapters/viewholders/CreatorViewHolder.kt | 1 - .../viewholders/SubscriptionBarViewHolder.kt | 1 - .../SubscriptionGroupListViewHolder.kt | 1 - .../views/others/CreatorThumbnail.kt | 4 +- .../views/overlays/SupportOverlay.kt | 2 +- .../views/overlays/WebviewOverlay.kt | 2 - .../views/segments/CommentsList.kt | 2 +- dep/polycentricandroid | 2 +- 41 files changed, 124 insertions(+), 665 deletions(-) delete mode 100644 app/src/main/java/com/futo/platformplayer/polycentric/PolycentricCache.kt delete mode 100644 app/src/main/java/com/futo/platformplayer/stores/CachedPolycentricProfileStorage.kt diff --git a/app/src/main/java/com/futo/platformplayer/Extensions_Polycentric.kt b/app/src/main/java/com/futo/platformplayer/Extensions_Polycentric.kt index 74f1372e..139407ed 100644 --- a/app/src/main/java/com/futo/platformplayer/Extensions_Polycentric.kt +++ b/app/src/main/java/com/futo/platformplayer/Extensions_Polycentric.kt @@ -1,13 +1,13 @@ package com.futo.platformplayer import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.states.AnnouncementType import com.futo.platformplayer.states.StateAnnouncement import com.futo.platformplayer.states.StatePlatform import com.futo.polycentric.core.ProcessHandle import com.futo.polycentric.core.Store import com.futo.polycentric.core.SystemState +import com.futo.polycentric.core.base64UrlToByteArray import userpackage.Protocol import kotlin.math.abs import kotlin.math.min @@ -40,33 +40,25 @@ fun Protocol.ImageBundle?.selectHighestResolutionImage(): Protocol.ImageManifest return imageManifestsList.filter { it.byteCount < maximumFileSize }.maxByOrNull { abs(it.width * it.height) } } +fun String.getDataLinkFromUrl(): Protocol.URLInfoDataLink? { + val urlData = if (this.startsWith("polycentric://")) { + this.substring("polycentric://".length) + } else this; + + val urlBytes = urlData.base64UrlToByteArray(); + val urlInfo = Protocol.URLInfo.parseFrom(urlBytes); + if (urlInfo.urlType != 4L) { + return null + } + + val dataLink = Protocol.URLInfoDataLink.parseFrom(urlInfo.body); + return dataLink +} + fun Protocol.Claim.resolveChannelUrl(): String? { return StatePlatform.instance.resolveChannelUrlByClaimTemplates(this.claimType.toInt(), this.claimFieldsList.associate { Pair(it.key.toInt(), it.value) }) } fun Protocol.Claim.resolveChannelUrls(): List<String> { return StatePlatform.instance.resolveChannelUrlsByClaimTemplates(this.claimType.toInt(), this.claimFieldsList.associate { Pair(it.key.toInt(), it.value) }) -} - -suspend fun ProcessHandle.fullyBackfillServersAnnounceExceptions() { - val systemState = SystemState.fromStorageTypeSystemState(Store.instance.getSystemState(system)) - if (!systemState.servers.contains(PolycentricCache.SERVER)) { - Logger.w("Backfill", "Polycentric prod server not added, adding it.") - addServer(PolycentricCache.SERVER) - } - - val exceptions = fullyBackfillServers() - for (pair in exceptions) { - val server = pair.key - val exception = pair.value - - StateAnnouncement.instance.registerAnnouncement( - "backfill-failed", - "Backfill failed", - "Failed to backfill server $server. $exception", - AnnouncementType.SESSION_RECURRING - ); - - Logger.e("Backfill", "Failed to backfill server $server.", exception) - } } \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/activities/PolycentricCreateProfileActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/PolycentricCreateProfileActivity.kt index d5fce50b..f7432c05 100644 --- a/app/src/main/java/com/futo/platformplayer/activities/PolycentricCreateProfileActivity.kt +++ b/app/src/main/java/com/futo/platformplayer/activities/PolycentricCreateProfileActivity.kt @@ -11,16 +11,16 @@ import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import com.futo.platformplayer.R import com.futo.platformplayer.UIDialogs -import com.futo.platformplayer.fullyBackfillServersAnnounceExceptions import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.polycentric.PolycentricStorage import com.futo.platformplayer.setNavigationBarColorAndIcons import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StatePolycentric import com.futo.platformplayer.views.LoaderView +import com.futo.polycentric.core.ApiMethods import com.futo.polycentric.core.ProcessHandle import com.futo.polycentric.core.Store +import com.futo.polycentric.core.fullyBackfillServersAnnounceExceptions import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -87,7 +87,7 @@ class PolycentricCreateProfileActivity : AppCompatActivity() { Logger.e(TAG, "Failed to save process secret to secret storage.", e) } - processHandle.addServer(PolycentricCache.SERVER); + processHandle.addServer(ApiMethods.SERVER); processHandle.setUsername(username); StatePolycentric.instance.setProcessHandle(processHandle); } catch (e: Throwable) { diff --git a/app/src/main/java/com/futo/platformplayer/activities/PolycentricImportProfileActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/PolycentricImportProfileActivity.kt index 825463b3..ab6d70a3 100644 --- a/app/src/main/java/com/futo/platformplayer/activities/PolycentricImportProfileActivity.kt +++ b/app/src/main/java/com/futo/platformplayer/activities/PolycentricImportProfileActivity.kt @@ -12,12 +12,12 @@ import androidx.lifecycle.lifecycleScope import com.futo.platformplayer.R import com.futo.platformplayer.UIDialogs import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.polycentric.PolycentricStorage import com.futo.platformplayer.setNavigationBarColorAndIcons import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StatePolycentric import com.futo.platformplayer.views.overlays.LoaderOverlay +import com.futo.polycentric.core.ApiMethods import com.futo.polycentric.core.KeyPair import com.futo.polycentric.core.Process import com.futo.polycentric.core.ProcessSecret @@ -145,7 +145,7 @@ class PolycentricImportProfileActivity : AppCompatActivity() { } StatePolycentric.instance.setProcessHandle(processHandle); - processHandle.fullyBackfillClient(PolycentricCache.SERVER); + processHandle.fullyBackfillClient(ApiMethods.SERVER); withContext(Dispatchers.Main) { startActivity(Intent(this@PolycentricImportProfileActivity, PolycentricProfileActivity::class.java)); finish(); diff --git a/app/src/main/java/com/futo/platformplayer/activities/PolycentricProfileActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/PolycentricProfileActivity.kt index e296a118..3493363e 100644 --- a/app/src/main/java/com/futo/platformplayer/activities/PolycentricProfileActivity.kt +++ b/app/src/main/java/com/futo/platformplayer/activities/PolycentricProfileActivity.kt @@ -21,10 +21,8 @@ import com.bumptech.glide.Glide import com.futo.platformplayer.R import com.futo.platformplayer.UIDialogs import com.futo.platformplayer.dp -import com.futo.platformplayer.fullyBackfillServersAnnounceExceptions import com.futo.platformplayer.images.GlideHelper.Companion.crossfade import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.polycentric.PolycentricStorage import com.futo.platformplayer.selectBestImage import com.futo.platformplayer.setNavigationBarColorAndIcons @@ -32,8 +30,10 @@ import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StatePolycentric import com.futo.platformplayer.views.buttons.BigButton import com.futo.platformplayer.views.overlays.LoaderOverlay +import com.futo.polycentric.core.ApiMethods import com.futo.polycentric.core.Store import com.futo.polycentric.core.SystemState +import com.futo.polycentric.core.fullyBackfillServersAnnounceExceptions import com.futo.polycentric.core.systemToURLInfoSystemLinkUrl import com.futo.polycentric.core.toBase64Url import com.futo.polycentric.core.toURLInfoSystemLinkUrl @@ -145,7 +145,7 @@ class PolycentricProfileActivity : AppCompatActivity() { lifecycleScope.launch(Dispatchers.IO) { try { - processHandle.fullyBackfillClient(PolycentricCache.SERVER) + processHandle.fullyBackfillClient(ApiMethods.SERVER) withContext(Dispatchers.Main) { updateUI(); diff --git a/app/src/main/java/com/futo/platformplayer/dialogs/CommentDialog.kt b/app/src/main/java/com/futo/platformplayer/dialogs/CommentDialog.kt index 9d0282f0..794c8537 100644 --- a/app/src/main/java/com/futo/platformplayer/dialogs/CommentDialog.kt +++ b/app/src/main/java/com/futo/platformplayer/dialogs/CommentDialog.kt @@ -22,7 +22,6 @@ import com.futo.platformplayer.api.media.models.comments.PolycentricPlatformComm import com.futo.platformplayer.api.media.models.ratings.RatingLikeDislikes import com.futo.platformplayer.constructs.Event1 import com.futo.platformplayer.dp -import com.futo.platformplayer.fullyBackfillServersAnnounceExceptions import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.selectBestImage import com.futo.platformplayer.states.StateApp @@ -30,6 +29,7 @@ import com.futo.platformplayer.states.StatePolycentric import com.futo.polycentric.core.ClaimType import com.futo.polycentric.core.Store import com.futo.polycentric.core.SystemState +import com.futo.polycentric.core.fullyBackfillServersAnnounceExceptions import com.futo.polycentric.core.systemToURLInfoSystemLinkUrl import com.futo.polycentric.core.toURLInfoSystemLinkUrl import com.google.android.material.button.MaterialButton diff --git a/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelAboutFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelAboutFragment.kt index 8a412f75..777443c5 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelAboutFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelAboutFragment.kt @@ -13,7 +13,6 @@ import com.futo.platformplayer.R import com.futo.platformplayer.api.media.models.channels.IPlatformChannel import com.futo.platformplayer.dp import com.futo.platformplayer.fixHtmlLinks -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.resolveChannelUrl import com.futo.platformplayer.selectBestImage @@ -21,6 +20,7 @@ import com.futo.platformplayer.setPlatformPlayerLinkMovementMethod import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.toHumanNumber import com.futo.platformplayer.views.platform.PlatformLinkView +import com.futo.polycentric.core.PolycentricProfile import com.futo.polycentric.core.toName import com.futo.polycentric.core.toURLInfoSystemLinkUrl @@ -134,9 +134,7 @@ class ChannelAboutFragment : Fragment, IChannelTabFragment { } } if(!map.containsKey("Harbor")) - this.context?.let { - map.set("Harbor", polycentricProfile.getHarborUrl(it)); - } + map.set("Harbor", polycentricProfile.getHarborUrl()); if (map.isNotEmpty()) setLinks(map, if (polycentricProfile.systemState.username.isNotBlank()) polycentricProfile.systemState.username else _lastChannel?.name ?: "") diff --git a/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelContentsFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelContentsFragment.kt index a7e313e3..b26c9b35 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelContentsFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelContentsFragment.kt @@ -29,7 +29,6 @@ import com.futo.platformplayer.engine.exceptions.PluginException import com.futo.platformplayer.engine.exceptions.ScriptCaptchaRequiredException import com.futo.platformplayer.exceptions.ChannelException import com.futo.platformplayer.fragment.mainactivity.main.FeedView -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.states.StateCache import com.futo.platformplayer.states.StatePlatform @@ -39,6 +38,7 @@ import com.futo.platformplayer.views.FeedStyle import com.futo.platformplayer.views.adapters.ContentPreviewViewHolder import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader import com.futo.platformplayer.views.adapters.feedtypes.PreviewContentListAdapter +import com.futo.polycentric.core.PolycentricProfile import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlin.math.max diff --git a/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelListFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelListFragment.kt index 807fbd90..dc32acaa 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelListFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelListFragment.kt @@ -16,12 +16,12 @@ import com.futo.platformplayer.constructs.Event1 import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.engine.exceptions.ScriptCaptchaRequiredException import com.futo.platformplayer.fragment.mainactivity.main.ChannelFragment -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.resolveChannelUrl import com.futo.platformplayer.states.StatePlatform import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader import com.futo.platformplayer.views.adapters.viewholders.CreatorViewHolder +import com.futo.polycentric.core.PolycentricProfile class ChannelListFragment : Fragment, IChannelTabFragment { private var _channels: ArrayList<IPlatformChannel> = arrayListOf(); diff --git a/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelMonetizationFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelMonetizationFragment.kt index 53268d16..fd401042 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelMonetizationFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/ChannelMonetizationFragment.kt @@ -8,8 +8,8 @@ import android.widget.TextView import androidx.fragment.app.Fragment import com.futo.platformplayer.R import com.futo.platformplayer.api.media.models.channels.IPlatformChannel -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile import com.futo.platformplayer.views.SupportView +import com.futo.polycentric.core.PolycentricProfile class ChannelMonetizationFragment : Fragment, IChannelTabFragment { diff --git a/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/IChannelTabFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/IChannelTabFragment.kt index 2b615d25..3821b34c 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/IChannelTabFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/channel/tab/IChannelTabFragment.kt @@ -1,7 +1,7 @@ package com.futo.platformplayer.fragment.channel.tab import com.futo.platformplayer.api.media.models.channels.IPlatformChannel -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile +import com.futo.polycentric.core.PolycentricProfile interface IChannelTabFragment { fun setChannel(channel: IPlatformChannel) diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ChannelFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ChannelFragment.kt index 817a8ca2..6be65482 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ChannelFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ChannelFragment.kt @@ -42,7 +42,6 @@ import com.futo.platformplayer.images.GlideHelper.Companion.crossfade import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.models.SearchType import com.futo.platformplayer.models.Subscription -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.selectBestImage import com.futo.platformplayer.selectHighestResolutionImage import com.futo.platformplayer.states.StatePlatform @@ -55,29 +54,14 @@ import com.futo.platformplayer.views.adapters.ChannelViewPagerAdapter import com.futo.platformplayer.views.others.CreatorThumbnail import com.futo.platformplayer.views.overlays.slideup.SlideUpMenuOverlay import com.futo.platformplayer.views.subscriptions.SubscribeButton -import com.futo.polycentric.core.OwnedClaim -import com.futo.polycentric.core.PublicKey -import com.futo.polycentric.core.Store -import com.futo.polycentric.core.SystemState -import com.futo.polycentric.core.systemToURLInfoSystemLinkUrl +import com.futo.polycentric.core.ApiMethods +import com.futo.polycentric.core.PolycentricProfile import com.futo.polycentric.core.toURLInfoSystemLinkUrl import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import kotlinx.serialization.Serializable - -@Serializable -data class PolycentricProfile( - val system: PublicKey, val systemState: SystemState, val ownedClaims: List<OwnedClaim> -) { - fun getHarborUrl(context: Context): String{ - val systemState = SystemState.fromStorageTypeSystemState(Store.instance.getSystemState(system)); - val url = system.systemToURLInfoSystemLinkUrl(systemState.servers.asIterable()); - return "https://harbor.social/" + url.substring("polycentric://".length); - } -} class ChannelFragment : MainFragment() { override val isMainView: Boolean = true @@ -144,15 +128,14 @@ class ChannelFragment : MainFragment() { private val _onPageChangeCallback = object : ViewPager2.OnPageChangeCallback() {} - private val _taskLoadPolycentricProfile: TaskHandler<PlatformID, PolycentricCache.CachedPolycentricProfile?> + private val _taskLoadPolycentricProfile: TaskHandler<PlatformID, PolycentricProfile?> private val _taskGetChannel: TaskHandler<String, IPlatformChannel> init { inflater.inflate(R.layout.fragment_channel, this) - _taskLoadPolycentricProfile = - TaskHandler<PlatformID, PolycentricCache.CachedPolycentricProfile?>({ fragment.lifecycleScope }, + _taskLoadPolycentricProfile = TaskHandler<PlatformID, PolycentricProfile?>({ fragment.lifecycleScope }, { id -> - return@TaskHandler PolycentricCache.instance.getProfileAsync(id) + return@TaskHandler ApiMethods.getPolycentricProfileByClaim(ApiMethods.SERVER, ApiMethods.FUTO_TRUST_ROOT, id.claimFieldType.toLong(), id.claimType.toLong(), id.value!!) }).success { setPolycentricProfile(it, animate = true) }.exception<Throwable> { Logger.w(TAG, "Failed to load polycentric profile.", it) } @@ -328,7 +311,7 @@ class ChannelFragment : MainFragment() { _creatorThumbnail.setThumbnail(parameter.thumbnail, true) Glide.with(_imageBanner).clear(_imageBanner) - loadPolycentricProfile(parameter.id, parameter.url) + loadPolycentricProfile(parameter.id) } _url = parameter.url @@ -342,7 +325,7 @@ class ChannelFragment : MainFragment() { _creatorThumbnail.setThumbnail(parameter.channel.thumbnail, true) Glide.with(_imageBanner).clear(_imageBanner) - loadPolycentricProfile(parameter.channel.id, parameter.channel.url) + loadPolycentricProfile(parameter.channel.id) } _url = parameter.channel.url @@ -359,16 +342,8 @@ class ChannelFragment : MainFragment() { _tabs.selectTab(_tabs.getTabAt(selectedTabIndex)) } - private fun loadPolycentricProfile(id: PlatformID, url: String) { - val cachedPolycentricProfile = PolycentricCache.instance.getCachedProfile(url, true) - if (cachedPolycentricProfile != null) { - setPolycentricProfile(cachedPolycentricProfile, animate = true) - if (cachedPolycentricProfile.expired) { - _taskLoadPolycentricProfile.run(id) - } - } else { - _taskLoadPolycentricProfile.run(id) - } + private fun loadPolycentricProfile(id: PlatformID) { + _taskLoadPolycentricProfile.run(id) } private fun setLoading(isLoading: Boolean) { @@ -533,20 +508,13 @@ class ChannelFragment : MainFragment() { private fun setPolycentricProfileOr(url: String, or: () -> Unit) { setPolycentricProfile(null, animate = false) - - val cachedProfile = channel?.let { PolycentricCache.instance.getCachedProfile(url) } - if (cachedProfile != null) { - setPolycentricProfile(cachedProfile, animate = false) - } else { - or() - } + or() } private fun setPolycentricProfile( - cachedPolycentricProfile: PolycentricCache.CachedPolycentricProfile?, animate: Boolean + profile: PolycentricProfile?, animate: Boolean ) { val dp35 = 35.dp(resources) - val profile = cachedPolycentricProfile?.profile val avatar = profile?.systemState?.avatar?.selectBestImage(dp35 * dp35)?.let { it.toURLInfoSystemLinkUrl( profile.system.toProto(), it.process, profile.systemState.servers.toList() diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/CommentsFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/CommentsFragment.kt index dce725f6..0dae227d 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/CommentsFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/CommentsFragment.kt @@ -23,7 +23,6 @@ import com.futo.platformplayer.api.media.models.comments.IPlatformComment import com.futo.platformplayer.api.media.models.comments.PolycentricPlatformComment import com.futo.platformplayer.api.media.models.video.IPlatformVideoDetails import com.futo.platformplayer.constructs.TaskHandler -import com.futo.platformplayer.fullyBackfillServersAnnounceExceptions import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StatePlatform @@ -32,6 +31,7 @@ import com.futo.platformplayer.views.adapters.CommentWithReferenceViewHolder import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader import com.futo.platformplayer.views.overlays.RepliesOverlay import com.futo.polycentric.core.PublicKey +import com.futo.polycentric.core.fullyBackfillServersAnnounceExceptions import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.net.UnknownHostException diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/PostDetailFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/PostDetailFragment.kt index 86555b11..d4dc1672 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/PostDetailFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/PostDetailFragment.kt @@ -33,10 +33,8 @@ import com.futo.platformplayer.api.media.models.ratings.RatingLikes import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.dp import com.futo.platformplayer.fixHtmlWhitespace -import com.futo.platformplayer.fullyBackfillServersAnnounceExceptions import com.futo.platformplayer.images.GlideHelper.Companion.crossfade import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.setPlatformPlayerLinkMovementMethod import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StatePlatform @@ -47,7 +45,6 @@ import com.futo.platformplayer.views.adapters.ChannelTab import com.futo.platformplayer.views.adapters.feedtypes.PreviewPostView import com.futo.platformplayer.views.comments.AddCommentView import com.futo.platformplayer.views.others.CreatorThumbnail -import com.futo.platformplayer.views.others.Toggle import com.futo.platformplayer.views.overlays.RepliesOverlay import com.futo.platformplayer.views.pills.PillRatingLikesDislikes import com.futo.platformplayer.views.platform.PlatformIndicator @@ -57,6 +54,8 @@ import com.futo.polycentric.core.ApiMethods import com.futo.polycentric.core.ContentType import com.futo.polycentric.core.Models import com.futo.polycentric.core.Opinion +import com.futo.polycentric.core.PolycentricProfile +import com.futo.polycentric.core.fullyBackfillServersAnnounceExceptions import com.google.android.flexbox.FlexboxLayout import com.google.android.material.imageview.ShapeableImageView import com.google.android.material.shape.CornerFamily @@ -112,7 +111,7 @@ class PostDetailFragment : MainFragment { private var _isLoading = false; private var _post: IPlatformPostDetails? = null; private var _postOverview: IPlatformPost? = null; - private var _polycentricProfile: PolycentricCache.CachedPolycentricProfile? = null; + private var _polycentricProfile: PolycentricProfile? = null; private var _version = 0; private var _isRepliesVisible: Boolean = false; private var _repliesAnimator: ViewPropertyAnimator? = null; @@ -169,7 +168,7 @@ class PostDetailFragment : MainFragment { UIDialogs.showGeneralRetryErrorDialog(context, context.getString(R.string.failed_to_load_post), it, ::fetchPost, null, _fragment); } else TaskHandler(IPlatformPostDetails::class.java) { _fragment.lifecycleScope }; - private val _taskLoadPolycentricProfile = TaskHandler<PlatformID, PolycentricCache.CachedPolycentricProfile?>(StateApp.instance.scopeGetter, { PolycentricCache.instance.getProfileAsync(it) }) + private val _taskLoadPolycentricProfile = TaskHandler<PlatformID, PolycentricProfile?>(StateApp.instance.scopeGetter, { ApiMethods.getPolycentricProfileByClaim(ApiMethods.SERVER, ApiMethods.FUTO_TRUST_ROOT, it.claimFieldType.toLong(), it.claimType.toLong(), it.value!!) }) .success { it -> setPolycentricProfile(it, animate = true) } .exception<Throwable> { Logger.w(TAG, "Failed to load claims.", it); @@ -274,7 +273,7 @@ class PostDetailFragment : MainFragment { }; _buttonStore.setOnClickListener { - _polycentricProfile?.profile?.systemState?.store?.let { + _polycentricProfile?.systemState?.store?.let { try { val uri = Uri.parse(it); val intent = Intent(Intent.ACTION_VIEW); @@ -334,7 +333,7 @@ class PostDetailFragment : MainFragment { } try { - val queryReferencesResponse = ApiMethods.getQueryReferences(PolycentricCache.SERVER, ref, null,null, + val queryReferencesResponse = ApiMethods.getQueryReferences(ApiMethods.SERVER, ref, null,null, arrayListOf( Protocol.QueryReferencesRequestCountLWWElementReferences.newBuilder().setFromType( ContentType.OPINION.value).setValue( @@ -604,16 +603,8 @@ class PostDetailFragment : MainFragment { private fun fetchPolycentricProfile() { val author = _post?.author ?: _postOverview?.author ?: return; - val cachedPolycentricProfile = PolycentricCache.instance.getCachedProfile(author.url, true); - if (cachedPolycentricProfile != null) { - setPolycentricProfile(cachedPolycentricProfile, animate = false); - if (cachedPolycentricProfile.expired) { - _taskLoadPolycentricProfile.run(author.id); - } - } else { setPolycentricProfile(null, animate = false); _taskLoadPolycentricProfile.run(author.id); - } } private fun setChannelMeta(value: IPlatformPost?) { @@ -639,17 +630,18 @@ class PostDetailFragment : MainFragment { _repliesOverlay.cleanup(); } - private fun setPolycentricProfile(cachedPolycentricProfile: PolycentricCache.CachedPolycentricProfile?, animate: Boolean) { - _polycentricProfile = cachedPolycentricProfile; + private fun setPolycentricProfile(polycentricProfile: PolycentricProfile?, animate: Boolean) { + _polycentricProfile = polycentricProfile; - if (cachedPolycentricProfile?.profile == null) { + val pp = _polycentricProfile; + if (pp == null) { _layoutMonetization.visibility = View.GONE; _creatorThumbnail.setHarborAvailable(false, animate, null); return; } _layoutMonetization.visibility = View.VISIBLE; - _creatorThumbnail.setHarborAvailable(true, animate, cachedPolycentricProfile.profile.system.toProto()); + _creatorThumbnail.setHarborAvailable(true, animate, pp.system.toProto()); } private fun fetchPost() { diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt index afda7722..8d930838 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt @@ -94,12 +94,10 @@ import com.futo.platformplayer.engine.exceptions.ScriptUnavailableException import com.futo.platformplayer.exceptions.UnsupportedCastException import com.futo.platformplayer.fixHtmlLinks import com.futo.platformplayer.fixHtmlWhitespace -import com.futo.platformplayer.fullyBackfillServersAnnounceExceptions import com.futo.platformplayer.getNowDiffSeconds import com.futo.platformplayer.helpers.VideoHelper import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.models.Subscription -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.receivers.MediaControlReceiver import com.futo.platformplayer.selectBestImage import com.futo.platformplayer.states.AnnouncementType @@ -158,6 +156,8 @@ import com.futo.polycentric.core.ApiMethods import com.futo.polycentric.core.ContentType import com.futo.polycentric.core.Models import com.futo.polycentric.core.Opinion +import com.futo.polycentric.core.PolycentricProfile +import com.futo.polycentric.core.fullyBackfillServersAnnounceExceptions import com.futo.polycentric.core.toURLInfoSystemLinkUrl import com.google.protobuf.ByteString import kotlinx.coroutines.Dispatchers @@ -294,7 +294,7 @@ class VideoDetailView : ConstraintLayout { private set; private var _historicalPosition: Long = 0; private var _commentsCount = 0; - private var _polycentricProfile: PolycentricCache.CachedPolycentricProfile? = null; + private var _polycentricProfile: PolycentricProfile? = null; private var _slideUpOverlay: SlideUpMenuOverlay? = null; private var _autoplayVideo: IPlatformVideo? = null @@ -409,12 +409,12 @@ class VideoDetailView : ConstraintLayout { }; _monetization.onSupportTap.subscribe { - _container_content_support.setPolycentricProfile(_polycentricProfile?.profile); + _container_content_support.setPolycentricProfile(_polycentricProfile); switchContentView(_container_content_support); }; _monetization.onStoreTap.subscribe { - _polycentricProfile?.profile?.systemState?.store?.let { + _polycentricProfile?.systemState?.store?.let { try { val uri = Uri.parse(it); val intent = Intent(Intent.ACTION_VIEW); @@ -1236,16 +1236,8 @@ class VideoDetailView : ConstraintLayout { _creatorThumbnail.setThumbnail(video.author.thumbnail, false); _channelName.text = video.author.name; - val cachedPolycentricProfile = PolycentricCache.instance.getCachedProfile(video.author.url, true); - if (cachedPolycentricProfile != null) { - setPolycentricProfile(cachedPolycentricProfile, animate = false); - if (cachedPolycentricProfile.expired) { - _taskLoadPolycentricProfile.run(video.author.id); - } - } else { - setPolycentricProfile(null, animate = false); - _taskLoadPolycentricProfile.run(video.author.id); - } + setPolycentricProfile(null, animate = false); + _taskLoadPolycentricProfile.run(video.author.id); _player.clear(); @@ -1405,11 +1397,8 @@ class VideoDetailView : ConstraintLayout { setTabIndex(2, true) } else { when (Settings.instance.comments.defaultCommentSection) { - 0 -> if (Settings.instance.other.polycentricEnabled) setTabIndex( - 0, - true - ) else setTabIndex(1, true); - 1 -> setTabIndex(1, true); + 0 -> if (Settings.instance.other.polycentricEnabled) setTabIndex(0, true) else setTabIndex(1, true) + 1 -> setTabIndex(1, true) 2 -> setTabIndex(StateMeta.instance.getLastCommentSection(), true) } } @@ -1447,16 +1436,8 @@ class VideoDetailView : ConstraintLayout { _buttonSubscribe.setSubscribeChannel(video.author.url); setDescription(video.description.fixHtmlLinks()); _creatorThumbnail.setThumbnail(video.author.thumbnail, false); - - - val cachedPolycentricProfile = - PolycentricCache.instance.getCachedProfile(video.author.url, true); - if (cachedPolycentricProfile != null) { - setPolycentricProfile(cachedPolycentricProfile, animate = false); - } else { - setPolycentricProfile(null, animate = false); - _taskLoadPolycentricProfile.run(video.author.id); - } + setPolycentricProfile(null, animate = false); + _taskLoadPolycentricProfile.run(video.author.id); _platform.setPlatformFromClientID(video.id.pluginId); val subTitleSegments: ArrayList<String> = ArrayList(); @@ -1485,7 +1466,7 @@ class VideoDetailView : ConstraintLayout { fragment.lifecycleScope.launch(Dispatchers.IO) { try { val queryReferencesResponse = ApiMethods.getQueryReferences( - PolycentricCache.SERVER, ref, null, null, + ApiMethods.SERVER, ref, null, null, arrayListOf( Protocol.QueryReferencesRequestCountLWWElementReferences.newBuilder() .setFromType(ContentType.OPINION.value).setValue( @@ -1501,10 +1482,8 @@ class VideoDetailView : ConstraintLayout { val likes = queryReferencesResponse.countsList[0]; val dislikes = queryReferencesResponse.countsList[1]; - val hasLiked = - StatePolycentric.instance.hasLiked(ref.toByteArray())/* || extraBytesRef?.let { StatePolycentric.instance.hasLiked(it) } ?: false*/; - val hasDisliked = - StatePolycentric.instance.hasDisliked(ref.toByteArray())/* || extraBytesRef?.let { StatePolycentric.instance.hasDisliked(it) } ?: false*/; + val hasLiked = StatePolycentric.instance.hasLiked(ref.toByteArray())/* || extraBytesRef?.let { StatePolycentric.instance.hasLiked(it) } ?: false*/; + val hasDisliked = StatePolycentric.instance.hasDisliked(ref.toByteArray())/* || extraBytesRef?.let { StatePolycentric.instance.hasDisliked(it) } ?: false*/; withContext(Dispatchers.Main) { _rating.visibility = View.VISIBLE; @@ -2805,13 +2784,12 @@ class VideoDetailView : ConstraintLayout { } } - private fun setPolycentricProfile(cachedPolycentricProfile: PolycentricCache.CachedPolycentricProfile?, animate: Boolean) { - _polycentricProfile = cachedPolycentricProfile; + private fun setPolycentricProfile(profile: PolycentricProfile?, animate: Boolean) { + _polycentricProfile = profile val dp_35 = 35.dp(context.resources) - val profile = cachedPolycentricProfile?.profile; val avatar = profile?.systemState?.avatar?.selectBestImage(dp_35 * dp_35) - ?.let { it.toURLInfoSystemLinkUrl(profile.system.toProto(), it.process, profile.systemState.servers.toList()) }; + ?.let { it.toURLInfoSystemLinkUrl(profile.system.toProto(), it.process, profile.systemState.servers.toList()) } if (avatar != null) { _creatorThumbnail.setThumbnail(avatar, animate); @@ -2820,12 +2798,12 @@ class VideoDetailView : ConstraintLayout { _creatorThumbnail.setHarborAvailable(profile != null, animate, profile?.system?.toProto()); } - val username = cachedPolycentricProfile?.profile?.systemState?.username + val username = profile?.systemState?.username if (username != null) { _channelName.text = username } - _monetization.setPolycentricProfile(cachedPolycentricProfile); + _monetization.setPolycentricProfile(profile); } fun setProgressBarOverlayed(isOverlayed: Boolean?) { @@ -3013,7 +2991,7 @@ class VideoDetailView : ConstraintLayout { Logger.w(TAG, "Failed to load recommendations.", it); }; - private val _taskLoadPolycentricProfile = TaskHandler<PlatformID, PolycentricCache.CachedPolycentricProfile?>(StateApp.instance.scopeGetter, { PolycentricCache.instance.getProfileAsync(it) }) + private val _taskLoadPolycentricProfile = TaskHandler<PlatformID, PolycentricProfile?>(StateApp.instance.scopeGetter, { ApiMethods.getPolycentricProfileByClaim(ApiMethods.SERVER, ApiMethods.FUTO_TRUST_ROOT, it.claimFieldType.toLong(), it.claimType.toLong(), it.value!!) }) .success { it -> setPolycentricProfile(it, animate = true) } .exception<Throwable> { Logger.w(TAG, "Failed to load claims.", it); diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/topbar/NavigationTopBarFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/topbar/NavigationTopBarFragment.kt index 4348edac..3309c851 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/topbar/NavigationTopBarFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/topbar/NavigationTopBarFragment.kt @@ -14,9 +14,9 @@ import com.futo.platformplayer.R import com.futo.platformplayer.api.media.IPlatformClient import com.futo.platformplayer.api.media.models.PlatformAuthorLink import com.futo.platformplayer.api.media.models.channels.IPlatformChannel -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile import com.futo.platformplayer.models.Playlist import com.futo.platformplayer.views.casting.CastButton +import com.futo.polycentric.core.PolycentricProfile class NavigationTopBarFragment : TopFragment() { private var _buttonBack: ImageButton? = null; diff --git a/app/src/main/java/com/futo/platformplayer/images/PolycentricModelLoader.java b/app/src/main/java/com/futo/platformplayer/images/PolycentricModelLoader.java index ded61ffc..c0155a33 100644 --- a/app/src/main/java/com/futo/platformplayer/images/PolycentricModelLoader.java +++ b/app/src/main/java/com/futo/platformplayer/images/PolycentricModelLoader.java @@ -1,5 +1,7 @@ package com.futo.platformplayer.images; +import static com.futo.platformplayer.Extensions_PolycentricKt.getDataLinkFromUrl; + import android.util.Log; import androidx.annotation.NonNull; @@ -12,10 +14,14 @@ import com.bumptech.glide.load.model.ModelLoader; import com.bumptech.glide.load.model.ModelLoaderFactory; import com.bumptech.glide.load.model.MultiModelLoaderFactory; import com.bumptech.glide.signature.ObjectKey; -import com.futo.platformplayer.polycentric.PolycentricCache; +import com.futo.polycentric.core.ApiMethods; import kotlin.Unit; +import kotlinx.coroutines.CoroutineScopeKt; import kotlinx.coroutines.Deferred; +import kotlinx.coroutines.Dispatchers; +import userpackage.Protocol; + import java.lang.Exception; import java.nio.ByteBuffer; import java.util.concurrent.CancellationException; @@ -60,7 +66,14 @@ public class PolycentricModelLoader implements ModelLoader<String, ByteBuffer> { @Override public void loadData(@NonNull Priority priority, @NonNull DataFetcher.DataCallback<? super ByteBuffer> callback) { Log.i("PolycentricModelLoader", this._model); - _deferred = PolycentricCache.getInstance().getDataAsync(_model); + + Protocol.URLInfoDataLink dataLink = getDataLinkFromUrl(_model); + if (dataLink == null) { + callback.onLoadFailed(new Exception("Data link cannot be null")); + return; + } + + _deferred = ApiMethods.Companion.getDataFromServerAndReassemble(CoroutineScopeKt.CoroutineScope(Dispatchers.getIO()), dataLink); _deferred.invokeOnCompletion(throwable -> { if (throwable != null) { Log.e("PolycentricModelLoader", "getDataAsync failed throwable: " + throwable.toString()); diff --git a/app/src/main/java/com/futo/platformplayer/polycentric/PolycentricCache.kt b/app/src/main/java/com/futo/platformplayer/polycentric/PolycentricCache.kt deleted file mode 100644 index abe4ca8e..00000000 --- a/app/src/main/java/com/futo/platformplayer/polycentric/PolycentricCache.kt +++ /dev/null @@ -1,353 +0,0 @@ -package com.futo.platformplayer.polycentric - -import com.futo.platformplayer.api.media.PlatformID -import com.futo.platformplayer.constructs.BatchedTaskHandler -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile -import com.futo.platformplayer.getNowDiffSeconds -import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.resolveChannelUrls -import com.futo.platformplayer.serializers.OffsetDateTimeSerializer -import com.futo.platformplayer.states.StatePolycentric -import com.futo.platformplayer.stores.CachedPolycentricProfileStorage -import com.futo.platformplayer.stores.FragmentedStorage -import com.futo.polycentric.core.ApiMethods -import com.futo.polycentric.core.ContentType -import com.futo.polycentric.core.OwnedClaim -import com.futo.polycentric.core.PublicKey -import com.futo.polycentric.core.SignedEvent -import com.futo.polycentric.core.StorageTypeSystemState -import com.futo.polycentric.core.SystemState -import com.futo.polycentric.core.base64ToByteArray -import com.futo.polycentric.core.base64UrlToByteArray -import com.futo.polycentric.core.getClaimIfValid -import com.futo.polycentric.core.getValidClaims -import com.google.protobuf.ByteString -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.cancel -import kotlinx.serialization.Serializable -import userpackage.Protocol -import java.nio.ByteBuffer -import java.time.OffsetDateTime -import kotlin.system.measureTimeMillis - -class PolycentricCache { - data class CachedOwnedClaims(val ownedClaims: List<OwnedClaim>?, val creationTime: OffsetDateTime = OffsetDateTime.now()) { - val expired get() = creationTime.getNowDiffSeconds() > CACHE_EXPIRATION_SECONDS - } - @Serializable - data class CachedPolycentricProfile(val profile: PolycentricProfile?, @Serializable(with = OffsetDateTimeSerializer::class) val creationTime: OffsetDateTime = OffsetDateTime.now()) { - val expired get() = creationTime.getNowDiffSeconds() > CACHE_EXPIRATION_SECONDS - } - - private val _cache = hashMapOf<PlatformID, CachedOwnedClaims>() - private val _profileCache = hashMapOf<PublicKey, CachedPolycentricProfile>() - private val _profileUrlCache: CachedPolycentricProfileStorage; - private val _scope = CoroutineScope(Dispatchers.IO); - init { - Logger.i(TAG, "Initializing Polycentric cache"); - val time = measureTimeMillis { - _profileUrlCache = FragmentedStorage.get<CachedPolycentricProfileStorage>("profileUrlCache") - } - Logger.i(TAG, "Initialized Polycentric cache (${_profileUrlCache.map.size}, ${time}ms)"); - } - - private val _taskGetProfile = BatchedTaskHandler<PublicKey, CachedPolycentricProfile>(_scope, - { system -> - val signedEventsList = ApiMethods.getQueryLatest( - SERVER, - system.toProto(), - listOf( - ContentType.BANNER.value, - ContentType.AVATAR.value, - ContentType.USERNAME.value, - ContentType.DESCRIPTION.value, - ContentType.STORE.value, - ContentType.SERVER.value, - ContentType.STORE_DATA.value, - ContentType.PROMOTION_BANNER.value, - ContentType.PROMOTION.value, - ContentType.MEMBERSHIP_URLS.value, - ContentType.DONATION_DESTINATIONS.value - ) - ).eventsList.map { e -> SignedEvent.fromProto(e) }; - - val signedProfileEvents = signedEventsList.groupBy { e -> e.event.contentType } - .map { (_, events) -> events.maxBy { it.event.unixMilliseconds ?: 0 } }; - - val storageSystemState = StorageTypeSystemState.create() - for (signedEvent in signedProfileEvents) { - storageSystemState.update(signedEvent.event) - } - - val signedClaimEvents = ApiMethods.getQueryIndex( - SERVER, - system.toProto(), - ContentType.CLAIM.value, - limit = 200 - ).eventsList.map { e -> SignedEvent.fromProto(e) }; - - val ownedClaims: ArrayList<OwnedClaim> = arrayListOf() - for (signedEvent in signedClaimEvents) { - if (signedEvent.event.contentType != ContentType.CLAIM.value) { - continue; - } - - val response = ApiMethods.getQueryReferences( - SERVER, - Protocol.Reference.newBuilder() - .setReference(signedEvent.toPointer().toProto().toByteString()) - .setReferenceType(2) - .build(), - null, - Protocol.QueryReferencesRequestEvents.newBuilder() - .setFromType(ContentType.VOUCH.value) - .build() - ); - - val ownedClaim = response.itemsList.map { SignedEvent.fromProto(it.event) }.getClaimIfValid(signedEvent); - if (ownedClaim != null) { - ownedClaims.add(ownedClaim); - } - } - - Logger.i(TAG, "Retrieved profile (ownedClaims = $ownedClaims)"); - val systemState = SystemState.fromStorageTypeSystemState(storageSystemState); - return@BatchedTaskHandler CachedPolycentricProfile(PolycentricProfile(system, systemState, ownedClaims)); - }, - { system -> return@BatchedTaskHandler getCachedProfile(system); }, - { system, result -> - synchronized(_cache) { - _profileCache[system] = result; - - if (result.profile != null) { - for (claim in result.profile.ownedClaims) { - val urls = claim.claim.resolveChannelUrls(); - for (url in urls) - _profileUrlCache.map[url] = result; - } - } - - _profileUrlCache.save(); - } - }); - - private val _batchTaskGetClaims = BatchedTaskHandler<PlatformID, CachedOwnedClaims>(_scope, - { id -> - val resolved = if (id.claimFieldType == -1) ApiMethods.getResolveClaim(SERVER, system, id.claimType.toLong(), id.value!!) - else ApiMethods.getResolveClaim(SERVER, system, id.claimType.toLong(), id.claimFieldType.toLong(), id.value!!); - Logger.v(TAG, "getResolveClaim(url = $SERVER, system = $system, id = $id, claimType = ${id.claimType}, matchAnyField = ${id.value})"); - val protoEvents = resolved.matchesList.flatMap { arrayListOf(it.claim).apply { addAll(it.proofChainList) } } - val resolvedEvents = protoEvents.map { i -> SignedEvent.fromProto(i) }; - return@BatchedTaskHandler CachedOwnedClaims(resolvedEvents.getValidClaims()); - }, - { id -> return@BatchedTaskHandler getCachedValidClaims(id); }, - { id, result -> - synchronized(_cache) { - _cache[id] = result; - } - }); - - private val _batchTaskGetData = BatchedTaskHandler<String, ByteBuffer>(_scope, - { - val dataLink = getDataLinkFromUrl(it) ?: throw Exception("Only URLInfoDataLink is supported"); - return@BatchedTaskHandler ApiMethods.getDataFromServerAndReassemble(dataLink); - }, - { return@BatchedTaskHandler null }, - { _, _ -> }); - - fun getCachedValidClaims(id: PlatformID, ignoreExpired: Boolean = false): CachedOwnedClaims? { - if (!StatePolycentric.instance.enabled || id.claimType <= 0) { - return CachedOwnedClaims(null); - } - - synchronized(_cache) { - val cached = _cache[id] - if (cached == null) { - return null - } - - if (!ignoreExpired && cached.expired) { - return null; - } - - return cached; - } - } - - //TODO: Review all return null in this file, perhaps it should be CachedX(null) instead - fun getValidClaimsAsync(id: PlatformID): Deferred<CachedOwnedClaims> { - if (!StatePolycentric.instance.enabled || id.value == null || id.claimType <= 0) { - return _scope.async { CachedOwnedClaims(null) }; - } - - Logger.v(TAG, "getValidClaims (id: $id)") - val def = _batchTaskGetClaims.execute(id); - def.invokeOnCompletion { - if (it == null) { - return@invokeOnCompletion - } - - handleException(it, handleNetworkException = { /* Do nothing (do not cache) */ }, handleOtherException = { - //Cache failed result - synchronized(_cache) { - _cache[id] = CachedOwnedClaims(null); - } - }) - }; - return def; - } - - fun getDataAsync(url: String): Deferred<ByteBuffer> { - StatePolycentric.instance.ensureEnabled() - return _batchTaskGetData.execute(url); - } - - fun getCachedProfile(url: String, ignoreExpired: Boolean = false): CachedPolycentricProfile? { - if (!StatePolycentric.instance.enabled) { - return CachedPolycentricProfile(null) - } - - synchronized (_profileCache) { - val cached = _profileUrlCache.get(url) ?: return null; - if (!ignoreExpired && cached.expired) { - return null; - } - - return cached; - } - } - - fun getCachedProfile(system: PublicKey, ignoreExpired: Boolean = false): CachedPolycentricProfile? { - if (!StatePolycentric.instance.enabled) { - return CachedPolycentricProfile(null) - } - - synchronized(_profileCache) { - val cached = _profileCache[system] ?: return null; - if (!ignoreExpired && cached.expired) { - return null; - } - - return cached; - } - } - - suspend fun getProfileAsync(id: PlatformID, urlNullCache: String? = null): CachedPolycentricProfile? { - if (!StatePolycentric.instance.enabled || id.claimType <= 0) { - return CachedPolycentricProfile(null); - } - - val cachedClaims = getCachedValidClaims(id); - if (cachedClaims != null) { - if (!cachedClaims.ownedClaims.isNullOrEmpty()) { - Logger.v(TAG, "getProfileAsync (id: $id) != null (with cached valid claims)") - return getProfileAsync(cachedClaims.ownedClaims.first().system).await(); - } else { - return null; - } - } else { - Logger.v(TAG, "getProfileAsync (id: $id) no cached valid claims, will be retrieved") - - val claims = getValidClaimsAsync(id).await() - if (!claims.ownedClaims.isNullOrEmpty()) { - Logger.v(TAG, "getProfileAsync (id: $id) != null (with retrieved valid claims)") - return getProfileAsync(claims.ownedClaims.first().system).await() - } else { - synchronized (_cache) { - if (urlNullCache != null) { - _profileUrlCache.setAndSave(urlNullCache, CachedPolycentricProfile(null)) - } - } - return null; - } - } - } - - fun getProfileAsync(system: PublicKey): Deferred<CachedPolycentricProfile?> { - if (!StatePolycentric.instance.enabled) { - return _scope.async { CachedPolycentricProfile(null) }; - } - - Logger.i(TAG, "getProfileAsync (system: ${system})") - val def = _taskGetProfile.execute(system); - def.invokeOnCompletion { - if (it == null) { - return@invokeOnCompletion - } - - handleException(it, handleNetworkException = { /* Do nothing (do not cache) */ }, handleOtherException = { - //Cache failed result - synchronized(_cache) { - val cachedProfile = CachedPolycentricProfile(null); - _profileCache[system] = cachedProfile; - } - }) - }; - return def; - } - - private fun handleException(e: Throwable, handleNetworkException: () -> Unit, handleOtherException: () -> Unit) { - val isNetworkException = when(e) { - is java.net.UnknownHostException, - is java.net.SocketTimeoutException, - is java.net.ConnectException -> true - else -> when(e.cause) { - is java.net.UnknownHostException, - is java.net.SocketTimeoutException, - is java.net.ConnectException -> true - else -> false - } - } - if (isNetworkException) { - handleNetworkException() - } else { - handleOtherException() - } - } - - companion object { - private val system = Protocol.PublicKey.newBuilder() - .setKeyType(1) - .setKey(ByteString.copyFrom("gX0eCWctTm6WHVGot4sMAh7NDAIwWsIM5tRsOz9dX04=".base64ToByteArray())) //Production key - //.setKey(ByteString.copyFrom("LeQkzn1j625YZcZHayfCmTX+6ptrzsA+CdAyq+BcEdQ".base64ToByteArray())) //Test key koen-futo - .build(); - - private const val TAG = "PolycentricCache" - const val SERVER = "https://srv1-prod.polycentric.io" - private var _instance: PolycentricCache? = null; - private val CACHE_EXPIRATION_SECONDS = 60 * 5; - - @JvmStatic - val instance: PolycentricCache - get(){ - if(_instance == null) - _instance = PolycentricCache(); - return _instance!!; - }; - - fun finish() { - _instance?.let { - _instance = null; - it._scope.cancel("PolycentricCache finished"); - } - } - - fun getDataLinkFromUrl(it: String): Protocol.URLInfoDataLink? { - val urlData = if (it.startsWith("polycentric://")) { - it.substring("polycentric://".length) - } else it; - - val urlBytes = urlData.base64UrlToByteArray(); - val urlInfo = Protocol.URLInfo.parseFrom(urlBytes); - if (urlInfo.urlType != 4L) { - return null - } - - val dataLink = Protocol.URLInfoDataLink.parseFrom(urlInfo.body); - return dataLink - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/states/StateCache.kt b/app/src/main/java/com/futo/platformplayer/states/StateCache.kt index 7d91c9ce..8157ed2a 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateCache.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateCache.kt @@ -6,7 +6,6 @@ import com.futo.platformplayer.api.media.structures.DedupContentPager import com.futo.platformplayer.api.media.structures.IPager import com.futo.platformplayer.api.media.structures.MultiChronoContentPager import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.resolveChannelUrl import com.futo.platformplayer.serializers.PlatformContentSerializer import com.futo.platformplayer.stores.db.ManagedDBStore @@ -50,14 +49,7 @@ class StateCache { val subs = StateSubscriptions.instance.getSubscriptions(); Logger.i(TAG, "Subscriptions CachePager polycentric urls"); val allUrls = subs - .map { - val otherUrls = PolycentricCache.instance.getCachedProfile(it.channel.url)?.profile?.ownedClaims?.mapNotNull { c -> c.claim.resolveChannelUrl() } ?: listOf(); - if(!otherUrls.contains(it.channel.url)) - return@map listOf(listOf(it.channel.url), otherUrls).flatten(); - else - return@map otherUrls; - } - .flatten() + .map { it.channel.url } .distinct() .filter { StatePlatform.instance.hasEnabledChannelClient(it) }; diff --git a/app/src/main/java/com/futo/platformplayer/states/StateMeta.kt b/app/src/main/java/com/futo/platformplayer/states/StateMeta.kt index b20866bf..bd45b205 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateMeta.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateMeta.kt @@ -14,7 +14,7 @@ class StateMeta { return when(lastCommentSection.value){ "Polycentric" -> 0; "Platform" -> 1; - else -> 1 + else -> 0 } } fun setLastCommentSection(value: Int) { diff --git a/app/src/main/java/com/futo/platformplayer/states/StatePolycentric.kt b/app/src/main/java/com/futo/platformplayer/states/StatePolycentric.kt index e98aff0c..9d6f7437 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StatePolycentric.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StatePolycentric.kt @@ -21,9 +21,7 @@ import com.futo.platformplayer.api.media.structures.IPager import com.futo.platformplayer.api.media.structures.MultiChronoContentPager import com.futo.platformplayer.awaitFirstDeferred import com.futo.platformplayer.dp -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.polycentric.PolycentricStorage import com.futo.platformplayer.resolveChannelUrl import com.futo.platformplayer.selectBestImage @@ -33,6 +31,7 @@ import com.futo.polycentric.core.ApiMethods import com.futo.polycentric.core.ClaimType import com.futo.polycentric.core.ContentType import com.futo.polycentric.core.Opinion +import com.futo.polycentric.core.PolycentricProfile import com.futo.polycentric.core.ProcessHandle import com.futo.polycentric.core.PublicKey import com.futo.polycentric.core.SignedEvent @@ -234,34 +233,7 @@ class StatePolycentric { if (!enabled) { return Pair(false, listOf(url)); } - var polycentricProfile: PolycentricProfile? = null; - try { - val polycentricCached = PolycentricCache.instance.getCachedProfile(url, cacheOnly) - polycentricProfile = polycentricCached?.profile; - if (polycentricCached == null && channelId != null) { - Logger.i("StateSubscriptions", "Get polycentric profile not cached"); - if(!cacheOnly) { - polycentricProfile = runBlocking { PolycentricCache.instance.getProfileAsync(channelId, if(doCacheNull) url else null) }?.profile; - didUpdate = true; - } - } else { - Logger.i("StateSubscriptions", "Get polycentric profile cached"); - } - } - catch(ex: Throwable) { - Logger.w(StateSubscriptions.TAG, "Polycentric getCachedProfile failed for subscriptions", ex); - //TODO: Some way to communicate polycentric failing without blocking here - } - if(polycentricProfile != null) { - val urls = polycentricProfile.ownedClaims.groupBy { it.claim.claimType } - .mapNotNull { it.value.firstOrNull()?.claim?.resolveChannelUrl() }.toMutableList(); - if(urls.any { it.equals(url, true) }) - return Pair(didUpdate, urls); - else - return Pair(didUpdate, listOf(url) + urls); - } - else - return Pair(didUpdate, listOf(url)); + return Pair(didUpdate, listOf(url)); } fun getChannelContent(scope: CoroutineScope, profile: PolycentricProfile, isSubscriptionOptimized: Boolean = false, channelConcurrency: Int = -1): IPager<IPlatformContent>? { @@ -325,7 +297,7 @@ class StatePolycentric { id = PlatformID("polycentric", author, null, ClaimType.POLYCENTRIC.value.toInt()), name = systemState.username, url = author, - thumbnail = systemState.avatar?.selectBestImage(dp_25 * dp_25)?.let { img -> img.toURLInfoSystemLinkUrl(system.toProto(), img.process, listOf(PolycentricCache.SERVER)) }, + thumbnail = systemState.avatar?.selectBestImage(dp_25 * dp_25)?.let { img -> img.toURLInfoSystemLinkUrl(system.toProto(), img.process, listOf(ApiMethods.SERVER)) }, subscribers = null ), msg = if (post.content.count() > PolycentricPlatformComment.MAX_COMMENT_SIZE) post.content.substring(0, PolycentricPlatformComment.MAX_COMMENT_SIZE) else post.content, @@ -349,7 +321,7 @@ class StatePolycentric { suspend fun getLikesDislikesReplies(reference: Protocol.Reference): LikesDislikesReplies { ensureEnabled() - val response = ApiMethods.getQueryReferences(PolycentricCache.SERVER, reference, null, + val response = ApiMethods.getQueryReferences(ApiMethods.SERVER, reference, null, null, listOf( Protocol.QueryReferencesRequestCountLWWElementReferences.newBuilder() @@ -382,7 +354,7 @@ class StatePolycentric { } val pointer = Protocol.Pointer.parseFrom(reference.reference) - val events = ApiMethods.getEvents(PolycentricCache.SERVER, pointer.system, Protocol.RangesForSystem.newBuilder() + val events = ApiMethods.getEvents(ApiMethods.SERVER, pointer.system, Protocol.RangesForSystem.newBuilder() .addRangesForProcesses(Protocol.RangesForProcess.newBuilder() .setProcess(pointer.process) .addRanges(Protocol.Range.newBuilder() @@ -400,11 +372,11 @@ class StatePolycentric { } val post = Protocol.Post.parseFrom(ev.content); - val systemLinkUrl = ev.system.systemToURLInfoSystemLinkUrl(listOf(PolycentricCache.SERVER)); + val systemLinkUrl = ev.system.systemToURLInfoSystemLinkUrl(listOf(ApiMethods.SERVER)); val dp_25 = 25.dp(StateApp.instance.context.resources) val profileEvents = ApiMethods.getQueryLatest( - PolycentricCache.SERVER, + ApiMethods.SERVER, ev.system.toProto(), listOf( ContentType.AVATAR.value, @@ -433,7 +405,7 @@ class StatePolycentric { id = PlatformID("polycentric", systemLinkUrl, null, ClaimType.POLYCENTRIC.value.toInt()), name = nameEvent?.event?.lwwElement?.value?.decodeToString() ?: "Unknown", url = systemLinkUrl, - thumbnail = imageBundle?.selectBestImage(dp_25 * dp_25)?.let { img -> img.toURLInfoSystemLinkUrl(ev.system.toProto(), img.process, listOf(PolycentricCache.SERVER)) }, + thumbnail = imageBundle?.selectBestImage(dp_25 * dp_25)?.let { img -> img.toURLInfoSystemLinkUrl(ev.system.toProto(), img.process, listOf(ApiMethods.SERVER)) }, subscribers = null ), msg = if (post.content.count() > PolycentricPlatformComment.MAX_COMMENT_SIZE) post.content.substring(0, PolycentricPlatformComment.MAX_COMMENT_SIZE) else post.content, @@ -445,12 +417,12 @@ class StatePolycentric { ) } - suspend fun getCommentPager(contextUrl: String, reference: Protocol.Reference, extraByteReferences: List<ByteArray>? = null): IPager<IPlatformComment> { + suspend fun getCommentPager(contextUrl: String, reference: Reference, extraByteReferences: List<ByteArray>? = null): IPager<IPlatformComment> { if (!enabled) { return EmptyPager() } - val response = ApiMethods.getQueryReferences(PolycentricCache.SERVER, reference, null, + val response = ApiMethods.getQueryReferences(ApiMethods.SERVER, reference, null, Protocol.QueryReferencesRequestEvents.newBuilder() .setFromType(ContentType.POST.value) .addAllCountLwwElementReferences(arrayListOf( @@ -486,7 +458,7 @@ class StatePolycentric { } override suspend fun nextPageAsync() { - val nextPageResponse = ApiMethods.getQueryReferences(PolycentricCache.SERVER, reference, _cursor, + val nextPageResponse = ApiMethods.getQueryReferences(ApiMethods.SERVER, reference, _cursor, Protocol.QueryReferencesRequestEvents.newBuilder() .setFromType(ContentType.POST.value) .addAllCountLwwElementReferences(arrayListOf( @@ -534,7 +506,7 @@ class StatePolycentric { return@mapNotNull LazyComment(scope.async(_commentPoolDispatcher){ Logger.i(TAG, "Fetching comment data for [" + ev.system.key.toBase64() + "]"); val profileEvents = ApiMethods.getQueryLatest( - PolycentricCache.SERVER, + ApiMethods.SERVER, ev.system.toProto(), listOf( ContentType.AVATAR.value, @@ -558,7 +530,7 @@ class StatePolycentric { val unixMilliseconds = ev.unixMilliseconds //TODO: Don't use single hardcoded sderver here - val systemLinkUrl = ev.system.systemToURLInfoSystemLinkUrl(listOf(PolycentricCache.SERVER)); + val systemLinkUrl = ev.system.systemToURLInfoSystemLinkUrl(listOf(ApiMethods.SERVER)); val dp_25 = 25.dp(StateApp.instance.context.resources) return@async PolycentricPlatformComment( contextUrl = contextUrl, @@ -566,7 +538,7 @@ class StatePolycentric { id = PlatformID("polycentric", systemLinkUrl, null, ClaimType.POLYCENTRIC.value.toInt()), name = nameEvent?.event?.lwwElement?.value?.decodeToString() ?: "Unknown", url = systemLinkUrl, - thumbnail = imageBundle?.selectBestImage(dp_25 * dp_25)?.let { img -> img.toURLInfoSystemLinkUrl(ev.system.toProto(), img.process, listOf(PolycentricCache.SERVER)) }, + thumbnail = imageBundle?.selectBestImage(dp_25 * dp_25)?.let { img -> img.toURLInfoSystemLinkUrl(ev.system.toProto(), img.process, listOf(ApiMethods.SERVER)) }, subscribers = null ), msg = if (post.content.count() > PolycentricPlatformComment.MAX_COMMENT_SIZE) post.content.substring(0, PolycentricPlatformComment.MAX_COMMENT_SIZE) else post.content, diff --git a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt index 7da01216..f979251d 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptionGroups.kt @@ -1,54 +1,17 @@ package com.futo.platformplayer.states -import com.futo.platformplayer.Settings -import com.futo.platformplayer.UIDialogs -import com.futo.platformplayer.api.media.models.ResultCapabilities -import com.futo.platformplayer.api.media.models.channels.IPlatformChannel -import com.futo.platformplayer.api.media.models.channels.SerializedChannel -import com.futo.platformplayer.api.media.models.contents.IPlatformContent -import com.futo.platformplayer.api.media.platforms.js.JSClient -import com.futo.platformplayer.api.media.platforms.js.SourcePluginConfig -import com.futo.platformplayer.api.media.structures.* -import com.futo.platformplayer.api.media.structures.ReusablePager.Companion.asReusable import com.futo.platformplayer.constructs.Event0 -import com.futo.platformplayer.constructs.Event1 -import com.futo.platformplayer.constructs.Event2 -import com.futo.platformplayer.engine.exceptions.PluginException -import com.futo.platformplayer.engine.exceptions.ScriptCaptchaRequiredException -import com.futo.platformplayer.engine.exceptions.ScriptCriticalException -import com.futo.platformplayer.exceptions.ChannelException -import com.futo.platformplayer.findNonRuntimeException -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile -import com.futo.platformplayer.getNowDiffDays import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.models.Subscription import com.futo.platformplayer.models.SubscriptionGroup -import com.futo.platformplayer.polycentric.PolycentricCache -import com.futo.platformplayer.resolveChannelUrl -import com.futo.platformplayer.states.StateHistory.Companion import com.futo.platformplayer.stores.FragmentedStorage import com.futo.platformplayer.stores.StringDateMapStorage -import com.futo.platformplayer.stores.SubscriptionStorage -import com.futo.platformplayer.stores.v2.ReconstructStore -import com.futo.platformplayer.stores.v2.ManagedStore -import com.futo.platformplayer.subscription.SubscriptionFetchAlgorithm -import com.futo.platformplayer.subscription.SubscriptionFetchAlgorithms import com.futo.platformplayer.sync.internal.GJSyncOpcodes import com.futo.platformplayer.sync.models.SyncSubscriptionGroupsPackage -import com.futo.platformplayer.sync.models.SyncSubscriptionsPackage -import kotlinx.coroutines.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import java.time.OffsetDateTime -import java.util.concurrent.ExecutionException -import java.util.concurrent.ForkJoinPool -import java.util.concurrent.ForkJoinTask -import kotlin.collections.ArrayList -import kotlin.coroutines.resumeWithException -import kotlin.coroutines.suspendCoroutine -import kotlin.streams.asSequence -import kotlin.streams.toList -import kotlin.system.measureTimeMillis /*** * Used to maintain subscription groups diff --git a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt index 52fb9f2e..65892a1e 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt @@ -15,7 +15,6 @@ import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.models.ImportCache import com.futo.platformplayer.models.Subscription import com.futo.platformplayer.models.SubscriptionGroup -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.resolveChannelUrl import com.futo.platformplayer.stores.FragmentedStorage import com.futo.platformplayer.stores.StringDateMapStorage @@ -335,12 +334,6 @@ class StateSubscriptions { return true; } - //TODO: This causes issues, because what if the profile is not cached yet when the susbcribe button is loaded for example? - val cachedProfile = PolycentricCache.instance.getCachedProfile(urls.first(), true)?.profile; - if (cachedProfile != null) { - return cachedProfile.ownedClaims.any { c -> _subscriptions.hasItem { s -> c.claim.resolveChannelUrl() == s.channel.url } }; - } - return false; } } diff --git a/app/src/main/java/com/futo/platformplayer/stores/CachedPolycentricProfileStorage.kt b/app/src/main/java/com/futo/platformplayer/stores/CachedPolycentricProfileStorage.kt deleted file mode 100644 index b9c036ac..00000000 --- a/app/src/main/java/com/futo/platformplayer/stores/CachedPolycentricProfileStorage.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.futo.platformplayer.stores - -import com.futo.platformplayer.polycentric.PolycentricCache -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json - -@kotlinx.serialization.Serializable -class CachedPolycentricProfileStorage : FragmentedStorageFileJson() { - var map: HashMap<String, PolycentricCache.CachedPolycentricProfile> = hashMapOf(); - - override fun encode(): String { - val encoded = Json.encodeToString(this); - return encoded; - } - - fun get(key: String) : PolycentricCache.CachedPolycentricProfile? { - return map[key]; - } - - fun setAndSave(key: String, value: PolycentricCache.CachedPolycentricProfile) : PolycentricCache.CachedPolycentricProfile { - map[key] = value; - save(); - return value; - } - - fun setAndSaveBlocking(key: String, value: PolycentricCache.CachedPolycentricProfile) : PolycentricCache.CachedPolycentricProfile { - map[key] = value; - saveBlocking(); - return value; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/views/MonetizationView.kt b/app/src/main/java/com/futo/platformplayer/views/MonetizationView.kt index 62da748b..b109acb5 100644 --- a/app/src/main/java/com/futo/platformplayer/views/MonetizationView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/MonetizationView.kt @@ -16,11 +16,11 @@ import com.futo.platformplayer.constructs.Event0 import com.futo.platformplayer.constructs.Event1 import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.views.AnyAdapterView.Companion.asAny import com.futo.platformplayer.views.adapters.viewholders.StoreItemViewHolder import com.futo.platformplayer.views.platform.PlatformIndicator +import com.futo.polycentric.core.PolycentricProfile import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json @@ -125,8 +125,7 @@ class MonetizationView : LinearLayout { } } - fun setPolycentricProfile(cachedPolycentricProfile: PolycentricCache.CachedPolycentricProfile?) { - val profile = cachedPolycentricProfile?.profile; + fun setPolycentricProfile(profile: PolycentricProfile?) { if (profile != null) { if (profile.systemState.store.isNotEmpty()) { _buttonStore.visibility = View.VISIBLE; diff --git a/app/src/main/java/com/futo/platformplayer/views/SupportView.kt b/app/src/main/java/com/futo/platformplayer/views/SupportView.kt index ad3017e7..c85d3450 100644 --- a/app/src/main/java/com/futo/platformplayer/views/SupportView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/SupportView.kt @@ -14,10 +14,10 @@ import androidx.core.view.isVisible import androidx.core.view.size import com.bumptech.glide.Glide import com.futo.platformplayer.R -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile import com.futo.platformplayer.images.GlideHelper.Companion.crossfade import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.views.buttons.BigButton +import com.futo.polycentric.core.PolycentricProfile import com.futo.polycentric.core.toURLInfoSystemLinkUrl import com.google.android.material.imageview.ShapeableImageView diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/ChannelViewPagerAdapter.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/ChannelViewPagerAdapter.kt index 665829db..3bd06903 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/ChannelViewPagerAdapter.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/ChannelViewPagerAdapter.kt @@ -17,7 +17,7 @@ import com.futo.platformplayer.fragment.channel.tab.ChannelListFragment import com.futo.platformplayer.fragment.channel.tab.ChannelMonetizationFragment import com.futo.platformplayer.fragment.channel.tab.ChannelPlaylistsFragment import com.futo.platformplayer.fragment.channel.tab.IChannelTabFragment -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile +import com.futo.polycentric.core.PolycentricProfile import com.google.android.material.tabs.TabLayout diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/CommentViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/CommentViewHolder.kt index fe9c6079..74f7d53c 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/CommentViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/CommentViewHolder.kt @@ -18,8 +18,6 @@ import com.futo.platformplayer.api.media.models.ratings.RatingLikeDislikes import com.futo.platformplayer.api.media.models.ratings.RatingLikes import com.futo.platformplayer.constructs.Event1 import com.futo.platformplayer.fixHtmlLinks -import com.futo.platformplayer.fullyBackfillServersAnnounceExceptions -import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.setPlatformPlayerLinkMovementMethod import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StatePolycentric @@ -29,6 +27,7 @@ import com.futo.platformplayer.views.LoaderView import com.futo.platformplayer.views.others.CreatorThumbnail import com.futo.platformplayer.views.pills.PillButton import com.futo.platformplayer.views.pills.PillRatingLikesDislikes +import com.futo.polycentric.core.ApiMethods import com.futo.polycentric.core.Opinion import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -81,24 +80,18 @@ class CommentViewHolder : ViewHolder { throw Exception("Not implemented for non polycentric comments") } - if (args.hasLiked) { - args.processHandle.opinion(c.reference, Opinion.like); + val newOpinion: Opinion = if (args.hasLiked) { + Opinion.like } else if (args.hasDisliked) { - args.processHandle.opinion(c.reference, Opinion.dislike); + Opinion.dislike } else { - args.processHandle.opinion(c.reference, Opinion.neutral); + Opinion.neutral } _layoutComment.alpha = if (args.dislikes > 2 && args.dislikes.toFloat() / (args.likes + args.dislikes).toFloat() >= 0.7f) 0.5f else 1.0f; StateApp.instance.scopeOrNull?.launch(Dispatchers.IO) { - try { - Logger.i(TAG, "Started backfill"); - args.processHandle.fullyBackfillServersAnnounceExceptions(); - Logger.i(TAG, "Finished backfill"); - } catch (e: Throwable) { - Logger.e(TAG, "Failed to backfill servers.", e) - } + ApiMethods.setOpinion(args.processHandle, c.reference, newOpinion) } StatePolycentric.instance.updateLikeMap(c.reference, args.hasLiked, args.hasDisliked) diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/CommentWithReferenceViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/CommentWithReferenceViewHolder.kt index db66a1a9..c4b9a51e 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/CommentWithReferenceViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/CommentWithReferenceViewHolder.kt @@ -16,7 +16,6 @@ import com.futo.platformplayer.api.media.models.ratings.RatingLikeDislikes import com.futo.platformplayer.constructs.Event1 import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.fixHtmlLinks -import com.futo.platformplayer.fullyBackfillServersAnnounceExceptions import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.setPlatformPlayerLinkMovementMethod import com.futo.platformplayer.states.StateApp @@ -26,6 +25,7 @@ import com.futo.platformplayer.views.others.CreatorThumbnail import com.futo.platformplayer.views.pills.PillButton import com.futo.platformplayer.views.pills.PillRatingLikesDislikes import com.futo.polycentric.core.Opinion +import com.futo.polycentric.core.fullyBackfillServersAnnounceExceptions import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.util.IdentityHashMap diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/PlaylistView.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/PlaylistView.kt index c8d86b14..c9cb8b73 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/PlaylistView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/PlaylistView.kt @@ -16,7 +16,6 @@ import com.futo.platformplayer.constructs.Event1 import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.images.GlideHelper.Companion.crossfade import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.views.FeedStyle import com.futo.platformplayer.views.others.CreatorThumbnail diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/SubscriptionViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/SubscriptionViewHolder.kt index 05a3f5e7..a9e7110a 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/SubscriptionViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/SubscriptionViewHolder.kt @@ -15,7 +15,6 @@ import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.dp import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.models.Subscription -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.selectBestImage import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.toHumanTimeIndicator diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/feedtypes/PreviewPostView.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/feedtypes/PreviewPostView.kt index cbf0b8a6..1d90e09c 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/feedtypes/PreviewPostView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/feedtypes/PreviewPostView.kt @@ -30,7 +30,6 @@ import com.futo.platformplayer.dp import com.futo.platformplayer.fixHtmlWhitespace import com.futo.platformplayer.images.GlideHelper.Companion.crossfade import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.toHumanNowDiffString import com.futo.platformplayer.views.FeedStyle diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/feedtypes/PreviewVideoView.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/feedtypes/PreviewVideoView.kt index f2123832..75d332e5 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/feedtypes/PreviewVideoView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/feedtypes/PreviewVideoView.kt @@ -24,7 +24,6 @@ import com.futo.platformplayer.getNowDiffSeconds import com.futo.platformplayer.images.GlideHelper.Companion.crossfade import com.futo.platformplayer.images.GlideHelper.Companion.loadThumbnails import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.selectBestImage import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StateDownloads diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/CreatorBarViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/CreatorBarViewHolder.kt index 897718bf..9a171df6 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/CreatorBarViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/CreatorBarViewHolder.kt @@ -11,7 +11,6 @@ import com.futo.platformplayer.constructs.Event1 import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.dp import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.selectBestImage import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.views.adapters.AnyAdapter diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/CreatorViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/CreatorViewHolder.kt index b5784d4c..93576fec 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/CreatorViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/CreatorViewHolder.kt @@ -12,7 +12,6 @@ import com.futo.platformplayer.constructs.Event1 import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.dp import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.selectBestImage import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.toHumanNumber diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/SubscriptionBarViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/SubscriptionBarViewHolder.kt index da491cf6..e56fcf3a 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/SubscriptionBarViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/SubscriptionBarViewHolder.kt @@ -12,7 +12,6 @@ import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.dp import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.models.Subscription -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.selectBestImage import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.views.adapters.AnyAdapter diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/SubscriptionGroupListViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/SubscriptionGroupListViewHolder.kt index 19fe8a30..4f601d26 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/SubscriptionGroupListViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/SubscriptionGroupListViewHolder.kt @@ -19,7 +19,6 @@ import com.futo.platformplayer.dp import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.models.Subscription import com.futo.platformplayer.models.SubscriptionGroup -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.selectBestImage import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.views.adapters.AnyAdapter diff --git a/app/src/main/java/com/futo/platformplayer/views/others/CreatorThumbnail.kt b/app/src/main/java/com/futo/platformplayer/views/others/CreatorThumbnail.kt index 2f592123..472a516f 100644 --- a/app/src/main/java/com/futo/platformplayer/views/others/CreatorThumbnail.kt +++ b/app/src/main/java/com/futo/platformplayer/views/others/CreatorThumbnail.kt @@ -11,8 +11,8 @@ import androidx.constraintlayout.widget.ConstraintLayout import com.bumptech.glide.Glide import com.futo.platformplayer.R import com.futo.platformplayer.constructs.Event1 +import com.futo.platformplayer.getDataLinkFromUrl import com.futo.platformplayer.images.GlideHelper.Companion.crossfade -import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.views.IdenticonView import userpackage.Protocol @@ -68,7 +68,7 @@ class CreatorThumbnail : ConstraintLayout { if (url.startsWith("polycentric://")) { try { - val dataLink = PolycentricCache.getDataLinkFromUrl(url) + val dataLink = url.getDataLinkFromUrl() setHarborAvailable(true, animate, dataLink?.system); } catch (e: Throwable) { setHarborAvailable(false, animate, null); diff --git a/app/src/main/java/com/futo/platformplayer/views/overlays/SupportOverlay.kt b/app/src/main/java/com/futo/platformplayer/views/overlays/SupportOverlay.kt index dfc59e05..e451806c 100644 --- a/app/src/main/java/com/futo/platformplayer/views/overlays/SupportOverlay.kt +++ b/app/src/main/java/com/futo/platformplayer/views/overlays/SupportOverlay.kt @@ -5,8 +5,8 @@ import android.util.AttributeSet import android.widget.LinearLayout import com.futo.platformplayer.R import com.futo.platformplayer.constructs.Event0 -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile import com.futo.platformplayer.views.SupportView +import com.futo.polycentric.core.PolycentricProfile class SupportOverlay : LinearLayout { val onClose = Event0(); diff --git a/app/src/main/java/com/futo/platformplayer/views/overlays/WebviewOverlay.kt b/app/src/main/java/com/futo/platformplayer/views/overlays/WebviewOverlay.kt index 06deadb8..27befb1e 100644 --- a/app/src/main/java/com/futo/platformplayer/views/overlays/WebviewOverlay.kt +++ b/app/src/main/java/com/futo/platformplayer/views/overlays/WebviewOverlay.kt @@ -6,9 +6,7 @@ import android.webkit.WebView import android.widget.LinearLayout import com.futo.platformplayer.R import com.futo.platformplayer.constructs.Event0 -import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.views.SupportView class WebviewOverlay : LinearLayout { val onClose = Event0(); diff --git a/app/src/main/java/com/futo/platformplayer/views/segments/CommentsList.kt b/app/src/main/java/com/futo/platformplayer/views/segments/CommentsList.kt index 965d3014..a1ccd142 100644 --- a/app/src/main/java/com/futo/platformplayer/views/segments/CommentsList.kt +++ b/app/src/main/java/com/futo/platformplayer/views/segments/CommentsList.kt @@ -22,12 +22,12 @@ import com.futo.platformplayer.api.media.structures.IPager import com.futo.platformplayer.constructs.Event1 import com.futo.platformplayer.constructs.TaskHandler import com.futo.platformplayer.engine.exceptions.ScriptUnavailableException -import com.futo.platformplayer.fullyBackfillServersAnnounceExceptions import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StatePolycentric import com.futo.platformplayer.views.adapters.CommentViewHolder import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader +import com.futo.polycentric.core.fullyBackfillServersAnnounceExceptions import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.net.UnknownHostException diff --git a/dep/polycentricandroid b/dep/polycentricandroid index 44edd69e..f87f00ab 160000 --- a/dep/polycentricandroid +++ b/dep/polycentricandroid @@ -1 +1 @@ -Subproject commit 44edd69ece9cac4a6dd95a84ca91299e44f3650a +Subproject commit f87f00ab9e1262e300246b8963591bdf3a8fada7 -- GitLab