As noted in a comment, we need to be careful when adding props to `VideoJs` to avoid renders.
Used primitive strings (title, channelName) instead of passing the entire `claim`, which could have its reference invalidated.
## Ticket
426
## Issue
Currently, we check if we have any existing claims with the same name when uploading, i.e. "lbry://<name>". It does not include claims that you are still uploading, so you might end up with duplicate claims.
In the ticket, there is also the issue of 2 uploads sharing the same slot, causing the progress indicator to jumpy between the uploads. That has been fixed by using a guid instead of using `name`.
## Aside
I think there is another request to allow the same name but on different channel ... next time, next time ....
## Scenario
`selectHasUnclaimedRefereeReward` updated --> `AppRouter` re-render --> `dynamicRoutes` regenerates (re-mounts) list of `DiscoverPage`s
## Fix
I think `selectHasUnclaimedRefereeReward` can be moved elsewhere and would solve the problem, but avoided that since I'm not familiar with rewards enough to do minimal testing.
Memoize the Category Page routes instead.
`GetLinksData` is somewhat expensive. The value won't change until user changes the window size or selects another homepage.
As we can't call an `effect` within a `memo`, we had to extract out `isLargeScreen` as an input parameter, which is fine as it makes `GetLinksData` more functional (functional programming).
* Upload: fix redux key clash
## Issue
`params` is the "final" value that will be passed to the SDK and `channel` is not a valid argument (it should be `channel_name`). Also, it seems like we only pass the channel ID now and skip the channel name entirely.
For the anonymous case, a clash will still happen when since the channel part is hardcoded to `anonymous`.
## Approach
Generate a guid in `params` and use that as the key to handle all the cases above. We couldn't use the `uploadUrl` because v1 doesn't have it.
The old formula is retained to allow users to retry or cancel their existing uploads one last time (otherwise it will persist forever). The next upload will be using the new key.
* Upload: add tab-locking
## Issue
- The previous code does detect uploads from multiple tabs, but it was done by handling the CONFLICT error message from the backend. At certain corner-cases, this does not work well. A better way is to not allow resumption while the same file is being uploading from another tab.
- When an upload from 1 tab finishes, the GUI on the other tab does not remove the completed item. User either have to refresh or click Cancel. Clicking Cancel results in the 404 backend error. This should be avoided.
## Approach
- Added tab synchronization and locking by passing the "locked" and "removed" information through `localStorage`.
## Other considered approaches
- Wallet sync -- but decided not to pollute the wallet.
- 3rd-party redux tab syncing -- but decided it's not worth adding another module for 1 usage.
* Upload: check if locked before confirming delete
## Reproduce
Have 2 tabs + paused upload
Open "cancel" dialog in one of the tabs.
Continue upload in other tab
Confirm cancellation in first tab
Upload disappears from both tabs, but based on network traffic the upload keeps happening.
(If upload finishes the claim seems to get created)
* Settings Page: add warning for unsaved settings
## Issue
When entering Settings Page, sync-loop is disable until user exist Settings Page. If browser is closed, changes will be lost.
## Change
Add the usual browser-level modal popup.
Note that all modern browsers have stopped supporting customized messages, but I still left the message there for clarity. Tried to use our own toast for it, but the handler locks all GUI until it is serviced.
* app: remove unused props
* app: use lighter selectors
When all we need is to know if something exists or their count, use the ID version instead of the url/claim version to avoid the heavy transformation.
* Fix query selection
* Fix xml format
* Fix link url and author_url
* Refactor repeated components
* Refactor repeated embed iframe string
* Add support for passing referrer queries to src
* Change iframe id from lbry to odysee
* Improve replace logic understanding
* Fix URL
Co-authored-by: Thomas Zarebczan <tzarebczan@users.noreply.github.com>
The recent change to parse the channel from a Repost using a `claim` ended up breaking the case for abandoned claims, which `claim` will be `null`.
Fix by looking at `claim` first (faster), and falling back to the `parseURI` method if it remains inconclusive.
## Behavioral changes
- Moved Notifications to the top for mobile.
- Added separate lines between sections.
## Code changes
The array method is too restrictive (hard to move things with display logic around). It's also hard to read.
Instead of trying to populate an array, just directly populate the return tree. Added `getLink` to make things readable. It's now easier to see the sections in a glance.
## Ticket
189: Overall React Lag or Extra Re-renders / Volume slider laggy since v0.48
## The problem
Every redux update results in each mounted component's prop mapping function (the `select` and `perform` stuff) to be recalculated. This is normal per redux, but we do lots of heavy stuff there.
The slider was sending tons of redux update for the Volume and Muted setting.
## Changes
The redux volume/muted setting is just used to restore vjs to the user's setting on the next video, so it doesn't need to be updated immediately/constantly -- vjs keeps it's own video settings. Debounced that action.
* Route recommendation search to recsys 5% of the time + add `user_id`
## Ticket
334 send some recommended requests to recsys
## Approach
`doSearch`:
- If the search options include `related_to`, route that to the new `searchRecommendations` which performs the 5% check + appends `user_id` at the end. This way, we don't need to alter the function signature of `doSearch`.
- Else, run proceed as normal.
* Always go to alt provider
f
Co-authored-by: Thomas Zarebczan <thomas.zarebczan@gmail.com>
* Add remove_duplicates to tile/list claim_search except for Channel Page
This removes the any duplicates from reposts.
* Re-activate the "Hide reposts" setting
* Category Rows: default to ['stream', 'repost'] unless specified otherwise.
* apiCall: add option to not send the auth header
## Why
Want an option to make un-authenticated `resolve` calls where appropriate, to improve caching.
## How
All `apiCall`s are authenticated by default, but when clients add NO_AUTH to the params, `apiCall` will exclude the X_LBRY_AUTH_TOKEN. It will also strip NO_AUTH from the param object before sending it out.
* Add hook for 'resolve' and 'claim_search' to check and skip auth...
... if the params does not contain anything that requires the wallet.
* doResolveUri, doClaimSearch: let clients decide when to include_my_output
- No more hardcoding 'include_purchase_receipt' and 'include_is_my_output'
- doResolveUri: include these params when opening a file page. This was the only place that was doing that prior to this PR.
* is_my_output: use the signing_channel as alternative
## Notes
`is_my_output` is more expensive to resolve, so it is not being requested all the time.
## Change
Looking at the signing channel as the additional fallback, on top of `myClaimIds`.
## Aside
I think using `myClaimIds` here is redundant, as it is usually populated from `is_my_ouput`. But leaving as is for now...
* add gdpr support
* only run on production
* testing implementation
* just needs last touches then ready
* ready for merge
* add cookies to sidebar
* hide button when secureprivacy not available
* switch over to loading script as a react hook
* conditionally add secureprivacy script
* save gdpr status on session
* better design
## Why
- No memo required (no transformation).
- `makeSelect*` is an incorrect pattern.
## Changes
- Replaced makeSelectClientSetting with selectClientSetting.
- Remove unused selectShowRepostedContent.
* SyncFatalError: show nag instead of hard-crashing.
## Issue
When sync fails, we crash the app.
## Ticket
Maybe closes 39 "Better handle both internal and web backend interruptions / downtime"
## Approach
I'm tackling this from the standpoint that (1) sync errors are not that fatal -- we'll just lost a few recent changes (2) network disconnection is the common cause.
## Changes
- If we are offline:
- Inform user through a nag. All other status is meaningless if we are offline.
- If we are online:
- If api is STATUS_DOWN, show the existing crash page.
- If there is a sync error, show a nag saying settings are now potentially unsynchronized, and add a button to retry sync.
- If there is a chunk error, nag to reload.
* Attempt to detect `status=DOWN`
Previous code resolves the status to either "ok" or "not", which makes the app unable to differentiate between the "degraded" (nag) and "down" (crash) states.
## Issue
- It was checking the blacklist on every render.
- Finding opportunities to improve performance
## Changes
Since the final destination will be a dead end anyways, skip the blacklist check so that livestreams can render a bit faster when there lots of mentions.
The only downside is that a claim preview for a blacklisted item would now appear (vs. being a text previously)
## Issue
One of the bottlenecks of livestream page.
The component probably needs a re-design:
- Don't perpetually mount -- only mount when activated by the user through "@". This would avoid the heavy processing entirely.
- Better way of resolving uris (too many arrays, too many loops).
- Tom also mentioned that we should not be resolving every commenter as we see encounter them in a livestream. This is currently the case because the component is always mounted.
## Changes
Until the re-design occurs, attempt to cache the heavy processing. Also, trimmed down the amount of loops.
As long as the input parameters are the same, the selector will return the cached value so that we don't construct the list twice, which involves blocklist filtering.
`<div>` cannot be a descendend of `<p>`, and `{subtitle}`s sometimes need to have `<div>`s.
Just switch from `<p>` to `<div>`, and let the client decide when the actual text paragraphs are.
- Memo not required. `resolvingUris` is very dynamic and is a short array anyways.
- Changeg from using `indexOf` to `includes`, which is more concise.
## Issues
- 251 Dragging the floating player is super laggy
Recent changes and/or refactoring combined the effects or added dependancies into the effects, causing them to re-run excessively.
## Changes
- Restored effects to their original behavior.
- Don't perform the position check when dragging -- only do it when released.
- Do proper debouncing for the 'resize' listener -- the previous method was incorrect as a new function is created on each render.
## Changes
- doHandleSyncComplete: only call doGetAndPopulatePreferences when there is new data.
- But for that to work, we'll need to populate preferences at least once. We'll do that in doSignIn.
- We can also remove the "sync/prefs ready" mechanism that was mainly meant for Desktop.
Then came another problem: while trying to spark changes between 2 tabs, `sync/get` was saying "no change" despite the local and server hash being different. I think it is because the both `sync_hash + sync/get` combo is operating on server data, so the hash is the same. I'm guessing this is why we ended up just running doGetAndPopulatePreferences every time before PR, since this flag wasn't correct in this scenario.
- Updated `data.changed` to consider both API results and comparison with local hash.
* Exclude default homepage data at compile time
The youtuber IDs alone is pretty huge, and is unused in the `CUSTOM_HOMEPAGE=true` configuration.
* Remove Desktop items and other cleanup
- Moved constants out of the component.
- Remove SIMPLE_SITE check.
- Remove Desktop-only items
* Sidebar: limit subscription and tag section
## Issue
Too slow for huge lists
## Change
Limit to 10 initially, and load everything on "Show more"
* Fix makeSelectThumbnailForUri
- Fix memo
- Expose function to extract directly from claim if client already have it.
* pull out ads into its own file
* final touchup
* pull out lbry volume class
* using curried function
* coming along well
* almost done keyboard shortcuts
* pulling the guts out
* finishing keyboard shortcuts
* coming along well
* running but needs some testing
* almost done but could still use some testing
* all code working with some flow fixes needed
* fixing flow errors
* finishing flow errors
## Issues with `makeSelectIsSubscribed`
- It will not return true if the uri provided is canonical, because the compared subscription uri is in permanent form. This was causing certain elements like the Heart to not appear in claim tiles.
- It is super slow for large subscriptions not just because of the array size + being a hot selector, but also because it is looking up the claim twice (not memo'd) and also calling `parseURI` to determine if it's a channel, which is unnecessary if you already have the claim.
## Changes
- Optimize the selector to only look up the claim once, and make operations using already-obtained info.
## Issue
~300KB savings in `ui.js` size (production, uncompressed). Mostly coming from the emoji library.
## Notes
Most of the `Comment*` components are under `CommentsList` or `LivestreamComments`, so deferring these 2 covered most of it. The exceptions are Notification and OwnComments.
## Why
Frequently used; top in perf profile
## Changes
Most of the time, you already have the claim object in the current context. `selectClaimIsMineForUri` will retrieve the claim again, which is wasteful, even if it is memoized (looking up the cache still takes time).
Break apart the logic and added the alternative `selectClaimIsMine` for faster lookup.
* Publish button: use spinner instead of "Publishing..."
Looks better, plus the preview could take a while sometimes.
* Refactor `doPublish`. No functional change
This is to allow `doPublish` to accept a custom payload as an input (for resuming uploads), instead of always resolving it from the redux data.
* Add doPublishResume
* Support resume-able upload via tus
## Issue
38 Handle resumable file upload
## Notes
Since we can't serialize a File object, we'll need to the user to re-select the file to resume.
* Exclude "modified date" for Firefox/Android
## Issue
It appears that the modification date of the Android file changes when selected, so that file was deemed "different" when trying to resume upload.
## Change
Exclude modification date for now. Let's assume a smart user.
* Move 'currentUploads' to 'publish' reducer
`publish` is currently rehydrated, so we can ride on that and don't need to store the `currentUploads` in `localStorage` for persistence. This would allow us to store Markdown Post data too, as `localStorage` has a 5MB limit per app.
We could have also made `webReducer` rehydrate, but in this repo, there is no need to split it to another reducer. It also makes more sense to be part of publish anyway (at least to me).
This change is mostly moving items between files, with the exception of
1. An additional REHYDRATE in the publish reducer to clean up the tusUploader.
2. Not clearing `currentUploads` in CLEAR_PUBLISH.
* Restore v1 code for livestream replay, etc.
v2 (tus) does not handle `remote_url`, so the app still needs v1 for that. Since we'll still have v1 code, use v1 for previews as well.
- memo not required.
- start to not use the confusing and wrongly-named 'selectCommentsByUri' (per comment from Sean); use the existing 'selectClaimIdForUri' instead. This works because currently we do fetch any comments without first visiting a claim/uri, so we'll always have fetched the required claim, and can be queried in 'selectClaimIdForUri'.
## Issue
`normalizeUri` | `parseURI` is expensive and has been causing sluggish operations when called repeatedly or within a loop.
## Change
Since I'm not confident enough to remove the call entirely from makeSelectClaimIsMine (although I've yet to find a scenario that the uri is not already normalized), we'll try caching the calls instead.
## Results
- in a simple test of toggling between 2 category pages, we saved 20ms from `parseURI` calls alone.
- in a test of opening all categories one time, the memory usage remained similar. This makes sense since we removed a `makeSelect*` (which creates a selector for each call + not memoizing), and replaced that with a cached selector that's actually memoizing.
* Simplify dispatch map
Since none of dispatches are doing any custom transformation, just use a direct map. The number of arguments for the comment function are getting crazy.
* Block: pass comment ID for deletion when being blocked.
## Issue
238 Comments: author-name not highlighted when in Channel Community tab
## Changes
- Channel claims don't have a signing channel. Use `getChannelFromClaim`, which handles both content and channel claim.
## Ticket
223 Add ability for delegated moderators to delete comments
## Changes
- Refactored doCommentAbandon's signature so we don't end up converting between "uri" and "Claim" several times and needing to lookup redux when the client can already provide us the exact values that we need.
- Pass the new moderator fields to the API.
- Remove the need to call 'makeSelectChannelPermUrlForClaimUri' since it's a simple field query when we already have the claim.
I tried to use event.preventDefault on the click handler but that didn't
work. So instead I'm using css 'pointer-events: none' to disable click
events on the player while the player is being dragged.
https://github.com/OdyseeTeam/odysee-frontend/issues/206
- selectMyChannelClaims depends on `byId`, which currently is always invalidated per update, so it is not memoized.
- Most of the use-cases just needs the ID or the length of the array anyways, so avoid generating a Claim array (in selectMyChannelClaims) unnecessarily -- the client need to reduce it back down to IDs again :/
- The simpler boolean also removes the need to memoize the selector, which saves a bit of memory.
* Fix error logs
* Improve LBC sticker flow/clarity
* Show inline error if custom sticker amount below min
* Sort emojis alphabetically
* Improve loading of Images
* Improve quality and display of emojis and fix CSS
* Display both USD and LBC prices
* Default to LBC tip if creator can't receive USD
* Don't clear text-field after sticker is sent
* Refactor notification component
* Handle notifications
* Don't show profile pic on sticker livestream comments
* Change Sticker icon
* Fix wording and number rounding
* Fix blurring emojis
* Disable non functional emote buttons
`selectMyActiveClaims` includes pending claims, so it gets invalidated often.
For the case of comment-filtering, we don't care about pending or abandoned own claims.
* Prevent multiple parseURI calls
## Ticket
129
## Issue
Code was shortened to use `isURIValid` during the consolidation. `isURIValid` calls `normalizeURI`, which calls another `parseURI`.
`parseURI` is pretty expensive.
## Approach
- Add optional parameter to `isURIValid` to skip the normalization.
- Set those that were converted during the consolidation to skip the normalization. Also covered a few other instances where it is obvious to me that normalization is not required.
- For the rest, I can't tell for sure if it's safe to remove the normalization, so the default `normalize=true` will leave things as is.
The whole `parseURI` probably needs a refactoring, or a few lighter version for specific needs.
* Simplify isURIEqual
## Issue
`parseURI` is too expensive to be used in a loop, plus `normalizeURI` itself is calling `parseURI`.
## Approach
Not sure if it covers all cases, but just try convert colons to hashes before comparing.
## Issue
95% of `secondary.js` is unused code.
- It was meant to reduce network overhead by chunking up files needed after bootup, and also to reduce the number of `vendor-*.js` files.
- But it ended up accidentally grabbing everything, defeating the purpose of code-splitting.
Added a re-usable "yes/no" confirmation modal where the client just sets the question string and gets a callback "OK" or "Cancel" is clicked.
It doesn't make sense to create one modal for each confirmation, especially when the modal is only used in one place.
Replaced one of the existing modal as an example.
* Refactor filePrice
* Refactor Wallet Tip Components
* Add backend sticker support for comments
* Add stickers
* Refactor commentCreate
* Add Sticker Selector and sticker comment creation
* Add stickers display to comments and hyperchats
* Fix wrong checks for total Super Chats
## Issue
- Go to a channel page
- Go to Wild West
- Back
- Expand the search filter (valid here)
- Forward
## Fix
Resolve the 'expanded' setting on mount to ensure it is never true when 'hideAdvancedFilter' is set.
4a22814c broke the intention of if-block (it essentially breaks the functionality in Search page if we enable view counts there in the future).
It also seems completely unrelated to the PR.
* various control bar fixes
* fixes for mobile
* hide advertisement div by default
* fix duration bar
* more frontend touchups
* more styles
* fix for advertisement bar showing
* dont use ima on each re-render
## Issue
We previously automatically reload when there is a chunk error. This works fine if it's the case of new code was pushed recently while the user was active. But if the failure was caused by other things like network problems or the file IS actually missing, we end up in an infinite loop of refreshes.
## New approach
Tell the user to reload instead of automatically doing it.
* fix type error
fix is subscribed check
- Persist subscription data locally
- add / remove subscription during log in / out
- Use store directly in hook
Add toast error if subscription fails
Revert removal of v2
hotfix linting issue
Add custom notification handler
- fix isSupported flag
- make icon color compatible with light/dark theme
- fix icon on notifications blocked banner
wip: add push notification banner to notifications page.
- ignore failed deletions via internal API
- add ua parsing package
- add more robust meta data to token save
refactor naming + add push toggle to notification button
shift some code around
update css naming o proper BEM notation
update notifications UI
remove now unneeded util function
Update push notification system to sue firebase sdk
separate service worker webpack bundling
update service worker to use firebase sdk
Add firebase config
Add firebase and remove filemanager
Stub out the basics for browser push notifications.
* fix safari
* try smaller image for badge
* add token validation with server, refactor code
* remove param
* add special icon for web notification badge
* add translations
* add missing trans for toast error
* add pushRequest method that will not prompt users who have subscribed but since disabled notifications in the settings.
## Issue
- Each tile was checking against 4 blocklists (blacklisted, filtered, muted, commentron) on every render. Loading the front-page with Cheese alone caused 1400 calls.
- This is also part of the reason why pressing Back into the tile list takes forever.
## Fix
Since we still need to perform the checks at the app side for now, tried to memoize the operation through a selector.
## Issue
85 Add additional GA events
## Approach
Instead of placing analytic calls all over the GUI code (no separation of concerns), try to do it through a redux middleware instead.
## Changes
- Updated GA event and parameter naming after understanding how reporting works.
- Removed unused analytics.
Only picking components that are involved in a livestream for now. Ideally, all usages of `makeSelectClaimForUri` should be replaced -- will do it incrementally.
followedTags:
- Moved the filtering to the reducer side, so that we don't do it every time. We can't rely on `createSelector` because the store will be invalidated on each `USER_STATE_POPULATE`, unfortunately.
tags:
- Memoize via re-reselect for the "ForUri" selector.
## Issue
`makeSelectDataForUri` always returns a new reference, so `ClaimPreview` was constantly being rendered. It's pretty expensive since `ClaimPreview`'s rendering checks against a huge blocklist, which is another issue on it's own.
## Changes
- This commit tests the usage of `re-reselect` as the solution to the multi-instance memoization problem (https://github.com/toomuchdesign/re-reselect/blob/master/examples/1-join-selectors.md)
## Issue
When comments are refreshed, each `Comment` gets rendered 4-5 times due to reference invalidation for `othersReacts` (the data didn't actually change).
## Change
For selectors without transformation, there is no need to memoize using `createSelector` -- just access it directly. Also, don't do things like `return a[id] || {}` in a reducer, because the reference to the empty object will be different on each call.
Always return directly from the state so that the same reference is returned.
This simple change avoided the wasted resources needed for `createSelector`, and reduced to render to just 2 (initial render, and when reactions are fetched).
## Issue
Now that we batch-resolve the comment authors before displaying the comments, the linked-comment scrolling logic didn't work well with nested replies.
## Change
Previously, I didn't want to put the logic at the lowest level (`Comment`) because it was hard for the child to know whether to scroll or not. For example, we don't want to scroll when user changes the comment filters or presses the Refresh Comments button.
Relented and moved the logic to `Comment`, and pass a flag via `window` (I know this is frowned upon by some) to indicate whether a scrolling is needed.
This is probably more efficient overall as we don't need to scan the DOM, and with minimal delay as we scroll immediately after the linked-comment is mounted.
## Known issues
In markdown posts with lots of images, a layout shift due to delayed inline-image fetching can cause the scrolling to be inaccurate. This should be fixed by reserving space for markdown post images.
## Issue
60 setting.Get calls spiked since October
It was called 24 times per livestream page load.
## Notes
The effect was intended to be a one-time effect, but the dependency was changed in 2f4dedfb
* re enable preload ads
* switch macro to aniview
* point towards test server
* improving documentation
* bugfix and turn skip back on
* only run twenty percent of the time for unauthed users
* allow for embeds
* enable show internal feature
* working prototype
* seems to work well
* bugfix
* review old aniview setup
* change to production channelid
* final touchups
This reverts commit caadd889ce, reversing
changes made to 8b2c7a2b21.
## Issue
- Infinite `resolve` loop when deleted channel is present in the comments.
- Since it was only displayed comments with resolved channels, it masked away those comments. While that may or may not be regarded as a defect, I think we should do it at Commentron instead of at the app if we want to filter deleted channels. I vote to show comments from deleted channels, since it might have good conversation thread.
* Fix CSS for live chat embeds
* Fix Markdown Lists in Comments
* Disable copy link menu option on livestream comments
* Fix nested indents in Live Chat
* Fix mentions and timestamps not parsed in bullet lists
* Highlight livestream comment and menu button on hover
* Fix mention parsing
## Issue
40 Linked comments doesn't scroll for deep replies
## Notes
Don't need an effect for this, plus it was causing the parent to not pick it up for auto-scrolling.
## Issues
- The current version of the link handler doesn't seem able to control the livestream player's position.
- The "live" position is always 0:00 and everything behind it is a negative timestamp. The current timestamp parser doesn't handle negative values.
* adding functionality to detect user download speed
* calculating bandwidth speed more intelligently
* saving download speed and updating it every 30s
* all the functionality should be done needs testing
* fix linting
* use a 1mb file for calculating bandwidth
* add optional chaining plugin to babel and get bitrate from texttrack
* allow optional chaining for flow
* ignore flow error
* disable bandwidth checking functionality
* fix flow error
* Add option to pass in url-search params.
Impetus: allow linked comment ID and setting the discussion tab when clicking on the `ClaimPreview`.
* comment.list: fix typos and renamed variables
- Switch from 'author' to 'creator' to disambiguate between comment author and content author. For comment author, we'll use 'commenter' from now on.
- Corrected 'commenterClaimId' to 'creatorClaimId' (just a typo, no functional change).
* doCommentReset: change param from uri to claimId
This reduces one lookup as clients will always have the claimID ready, but might not have the full URI.
It was using URI previously just to match the other APIs.
* Add doCommentListOwn -- command to fetch own comments
Since the redux slice is set up based on content or channel ID (for Channel Discussion page), re-use the channel ID for the case of "own comments". We always clear each ID when fetching page-0, so no worries of conflict when actually browsing the Channel Discussion page.
* Comment: add option to hide the actions section
* Implement own-comments page
* Use new param to remove sort-pins-first.
comment.List currently always pushes pins to the top to support pagination. This new param removes this behavior.
I think this the best solution so far, at the expense of a slight delay in scrolling if the network call stalls.
- Added "fetching by ID" state so that we don't need to use the ugly N-retries method.
- `scrollIntoView` doesn't work if the element is already in the viewport, and the `scrollBy` adjustment doesn't take into account the y-position restoration that we perform on certain type of pages. Use `window.scrollTo` instead and taking into account current scroll position.
* Add Channel Mention selection ability
* Fix mentioned user name being smaller than other text
* Improve logic for locating a mention
* Fix mentioning with enter on livestream
* Fix breaking for invalid URI query
* Handle punctuation after mention
* Fix name display and appeareance
* Use canonical url
* Fix missing search
* fix issue where viewcounts were creating a new line
* conditionally add large view css
* conditionally apply class based on if view count should be shown
* last couple touchups
* clean up the css
* add scss to flow config
* add scss component to flow config
It was being recalculated repeatedly.
This memoizes it, although it still re-calculates occasionally despite none of the source arrays changed. I think it is due to the state change in the Preference Sync.
Note: input selectors to `createSelector` needs to be extractions-only (i.e. must not have transformations). I think most of our `makeSelect*` selectors violate this and broke memoization.
## Issue
7176
## Changes
Pitfalls of pausing render via React.memo:
- We'll miss the `doClaimSearch()` since that is sparked by an `useEffect`.
Seems like we can't avoid having a redundant copy of the previously-displayed URIs.
## Ticket
7165 homepage queries don't take into account blocked channel ids (mute does)
## Changes
resolveSearchOptions: was not grabbing redux data correctly.
* ❌ Remove old method of displaying active livestreams
Completely remove it for now to make the commit deltas clearer.
We'll replace it with the new method at the end.
* Fetch and store active-livestream info in redux
* Tiles can now query active-livestream state from redux instead of getting from parent.
* ⏪ ClaimTilesDiscover: revert and cleanup
## Simplify
- Simplify to just `uris` instead of having multiple arrays (`uris`, `modifiedUris`, `prevUris`)
- The `prevUris` is for CLS prevention. With this removal, the CLS issue is back, but we'll handle it differently later.
- Temporarily disable the view-count fetching. Code is left there so that I don't forget.
## Fix
- `shouldPerformSearch` was never true when `prefixUris` is present. Corrected the logic.
- Aside: prefix and pin is so similar in function. Hm ....
* ClaimTilesDiscover: factor out options
## Change
Move the `option` code outside and passed in as a pre-calculated prop.
## Reason
To skip rendering while waiting for `claim_search`, we need to add `React.memo(areEqual)`. However, the flag that determines if we are fetching `claim_search` (fetchingClaimSearchByQuery[]) depends on the derived options as the key.
Instead of calculating `options` twice, we moved it to the props so both sides can use it.
It also makes the component a bit more readable.
The downside is that the prop-passing might not be clear.
* ClaimTilesDiscover: reduce ~17 renders at startup to just 2.
* ClaimTilesDiscover: fill with placeholder while waiting for claim_search
## Issue
Livestream claims are fetched seperately, so they might already exists. While claim_search is running, the list only consists of livestreams (collapsed).
## Fix
Fill up the space with placeholders to prevent layout shift.
* Add 'useFetchViewCount' to handle fetching from lists
This effect also stashes fetched uris, so that we won't re-fetch the same uris during the same instance (e.g. during infinite scroll).
* ⏪ ClaimListDiscover: revert and cleanup
## Revert
- Removed the 'finalUris' stuff that was meant to "pause" visual changes when fetching. I think it'll be cleaner to use React.memo to achieve that.
## Alterations
- Added `renderUri` to make it clear which array that this component will render.
- Re-do the way we fetch view counts now that 'finalUris' is gone. Not the best method, but at least correct for now.
* ClaimListDiscover: add prefixUris, similar to ClaimTilesDiscover
This will be initially used to append livestreams at the top.
* ✅ Re-enable active livestream tiles using the new method
* doFetchActiveLivestreams: add interval check
- Added a default minimum of 5 minutes between fetches. Clients can bypass this through `forceFetch` if needed.
* doFetchActiveLivestreams: add option check
We'll need to support different 'orderBy', so adding an "options check" when determining if we just made the same fetch.
* WildWest: limit livestream tiles + add ability to show more
Most likely this behavior will change in the future, so we'll leave `ClaimListDiscover` untouched and handle the logic at the page level.
This solution uses 2 `ClaimListDiscover` -- if the reduced livestream list is visible, it handles the header; else the normal list handles the header.
* Use better tile-count on larger screens.
Used the same method as how the homepage does it.
## Issue
If you navigated to a Channel Page and returned to the homepage (or any page with ClaimPreview), the view-count is shown because we have that data.
## Fix
Instead of passing props around through the long "list" component chain (`ChannelContent -> ClaimListDiscover -> ClaimList -> ClaimPreview`) to indicate whether we should display it , just check the pathname at the lowest component level; I believe eventually we would display it everywhere anyways, so this we'll be the easiest to clean up.
## Issue
7102 Failed to initialize numberformat on some browsers
## Changes
Just revert to the non-SI notation (but still locale aware) for browsers that does not support the `compactDisplay` option.
I thought of adding an English-only abbreviation for that corner-case, but I think it's not worth the effort maintaining. There are worse issues happening on older browsers, such as icons not aligning properly in buttons and functions that require polyfilling.
## Issues
https://discord.com/channels/362322208485277697/646840786662719488/887345736033918997
## Changes
I meant to only add the macro at the client call during the refactoring, but forgot.
Having said that, I now think it's cleaner to put the macro where it is defined, and it's easier for Translators to find, so I added the macro in the definition instead of at the client call.
## Issue
1. Type something in the wunderbar.
2. While the spinner is running, press Tab to focus on "View results" button.
3. If the spinner is still running, the entire popup gets dismissed (it should not). If the spinner isn't running, the popup stays active.
## Change
It was explicitly dismissed when the <input> loses focus. It shouldn't do that if any child of the popup is in focus.
## Issue
7075 Move "explore tags" to a stable position
## Changes
Move the buttons in the suggestions popup to the top row so that it's position won't be constantly changing depending on the number of results.
* Fix Floating Player stopping on certain files
* Dont show additional player buttons from markdown and comments
* Fix markdown resizing for the same video playing
* Update changelog
* Sort props to clarify "client vs. redux". No functional change.
* ClaimListHeader: remove SIMPLE_SITE gating
* Channel Page: enable filters; add "sort by" filter.
## Issue
7059 Add option to sort oldest first on channel page
## Changes
- Enabled filters for Odysee.
- Added a new "Sort By" filter, which will only appear for "New" ordering. It doesn't make sense for "Trending" or "Top".
## Issue
7003 Can't unblock if delegator deleted their channel
## Changes
- Changed the function parameter from 'creatorId' to 'creatorUri'
- It got short-circuited because we don't resolve deleted channels. But the client already have the full creator URI (containing the needed 'name' and 'id'), so there is no need to actually look at the resolved list -- just pass the uri like all the other functions.
* Paginate: add option to disable history and url param
* Refactored blocklists into `BlockList`; no functional change
Reason:
- With each list (Personal, Admin, Mod, Muted), there's a bunch of useEffects and variables needed to handle the state. All of them are doing 99% similar things.
* Paginate blocklists
6834
* Improve 'moderator-block' list visuals
- Added "Blocked on behalf of" to make things clearer.
- Use smaller ClaimPreview for delegators to save space (there might be lots of delegators)
* Add search bar to BlockList
6834
- Only supports channel-name search, per 6834. Channel-title search would probably be too heavy on the client side.
- Fuzzy search is possible, but is too slow on huge lists. Ended up with a simpler `matchSorter.rankings.CONTAINS`, which I think would cover typical cases.
## Issue
6776 Missing follow button on channel reposts
- Missing:
- Fix: For reposts, `parseURI` will fail to determine if it's a channel because the URL doesn't have enough info. Determine from the claim object instead.
- Not working in Channel Page:
- Fix: The repost uri doesn't link back to the source channel, so we'll need to handle it.
* show error from backend properly
* cleanup code and add documentation
* persist active tab but force people to boost tab if it's on their own upload
* set tip lbc as default when none is saved in state
## Issue
3587 Show content view counts on channel pages
## Notes
Limited to just "channel pages" for now as specified in the ticket.
Can be enabled for all claim previews, as long as there's an efficient spot to run the batch fetching. Either make `fetchViewCount` prop default to true, or add the parameter in places that need it.
- Factor out for re-use in upcoming Shared Blocklist
- Improvements:
- Uses floating popup to show the suggestion/result rather than inline.
- Users can now press Enter to select the suggestion, instead of having to use the mouse.
- Users now don't need to enter '@' for channel names. They will still need to enter the full channel name, and disambiguate with claim_id if necessary.
- Fix jumpiness in position as the user types.
- Reverted #7004 as it ended up preventing the rest of the components from being localized when there is an error. Replaced that with a `setLabel` that simply checks if the component exists before setting the label.
- Fix "Autoplay Next On" not localized on initial load -- it was only localized when the setting changes. It is unfortunate that we need to also set the label in an additional `useEffect` instead of just using vjs events, but so be it.
## Issue
6712 Comment Moderation - time based bans
## Approach
- Consolidated the 3 types of blocking buttons in the comment content menu (i.e. Block, Moderator Block, Admin Block) into 1 regular Block button.
- Show a modal when Block is clicked.
- Let user choose the blocklist.
- Let user choose the timeout duration (this PR's impetus).
* recsys wip
better logging
fix floating player popout playing uri bug with recsys
lint
add empty entries to create
use beacon; fire on visibilitychange
cleanup, not record recs if not seen
ifweb recsys beacon
recsys handle embeds, cleanup
use history.listen to trigger events
fix recsys embed bug
bugfix
more default data
cleaner
cleaner
* remove tentative
* disable recsys debug logging
* Dont show countdown on Lists
* Add Repeat icon
* Add Shuffle icon
* Add Replay Icon
* Add Replay Option to autoplayCountdown
* Add Loop Control for Lists
* Add Shuffle control for Lists
* Improve View List Link and Fetch action
* Add Play Button to List page
* Add Shuffle Play Option on List Page and Menus
* Fix Modal Remove Collection I18n
* CSS: Fix Large list titles
* Fix List playback on Floating Player
* Add Theater Mode to its own class and fix bar text display
* Add Play Next VJS component
* Add Play Next Button
* Add Play Previous VJS Component
* Add Play Previous Button
* Add Autoplay Next Button
* Add separate control for autoplay next in list
* Bump redux
* Update CHANGELOG.md
## Issue
6989 console errors and warnings are getting out of hand!
## Notes
This method was previously criticized in 5643. But given that no better solution has been submitted after a long while, nor is there a new solution for doing i18n, I'm reviving it again. It'll be no worse from the status quo.
Despite try-catch being overkill, I think the code-clarity outweighs the performance issues (if any, in the first place). Also, we are only suppressing the error in a very specialized function which even if it fails, will simply be a no-op and the GUI falling back to English.
## Ticket
6946: Linked-comment scroll position is inconsistent
## Issues
- If it is a deeply-nested reply, the positioning is incorrect.
- If there are pinned comments, the positioning is way off.
- If there is a delay in mounting, the positioning doesn't happen.
- When clicking on the comment's date to highlight it, the comment goes missing and the scroll position is weird.
## Changes
- Take into account that replies can be linked-comments.
- Perform a "one-time" search for the linked-comment after the initial fetch, if necessary. The expensive DOM search is only be executed minimally.
Remove defunct "show comment menu on hover" implementation.
It was re-rendering on every mouse movement, plus the css classname no longer exists, and also it wasn't working right in the first place (reverted few Desktop revision back, and all it did was highlighting the menu rather than controlling the visibility).
If we want the "show comment menu on hover" behavior again in the future, the CPU usage problem can probably be addressed by debouncing/throttling state-change.
Trying to action this issue: Pressing escape in wunderbar should do something useful #2116, I also added ctrl-K as a keyboard shortcut to bring the wunderbar into focus.
## Issue
- While changing the "Back" behavior in the Settings Page PR, it was a pain to troubleshoot when the entire history list is listed as "odysee.com".
- If you have multiple tabs open, it's hard to know which is which for non-claim and non-channel pages.
## Approach
Initially, I thought of overriding the document's title through the `<Page>` component, since the titles are usually defined there. However, given that the router is already doing the overriding, I think it's best to do the same thing all in one place.
Downside: it might get missed when a new page is added.
## Unknown
- Not sure if are rules for titles. There seems to be a mix of sites -- some have specific titles per page, most just use the site title for each page.
- I think the `return` statement in the `useEffect` is unnecessary, since it'll just be setting to the same value now during the cleanup stage. (??)
## Issue
6956 Desktop: something wrong with Custom Comment Server setting
## Notes
- Should be calling `Comments.setServerUrl` to ensure all private variables are updated.
- Skip the react-setting update if there is no change.
more improvements, fix url, do the same for cover
remember url, error if invalid
unneeded addition
Fix delayed message
Lint
Allow empty values (placeholder and Gerbil)
Fix filepath crash
Fix button
Previously, we decide when to display "Show More" based on the current fetched reply count vs. total replies in Commentron. It was already troublesome as `comment.List` and `comment.replies` give different values (one includes blocked content, while another does not).
Now, we are further filtering the list with Commentron blocklists (personal, admin, moderator), so it is not feasible to run the logic based on reply count.
## Solution
- Keep track of number of remaining pages instead and use that to determine when to display "Show More".
- While it doesn't solve the "Show N replies" mismatch (YT has this problem too), it prevents the button from lingering.
- In the event that all replies are blocked, just show an empty space (same as YT). I didn't like the previous version that cluttered the space with "comment(s) blocked".
The previous version treats each navigation as a link, ala Chrome Settings. I liked it because I can enter a settings section directly via URL, and can always back-track each section.
Anyway, changed it to the typical "up" behavior, traversing back the hierarchy of settings pages.
It was phrased negatively as the feedback back then was the string should match whatever is on the actual dialog (which was "Skip preview and confirmation"). But now it looks odd when we have an additional title string. We think titles should be positively phrased, hence the change.
Changed from constants to object. This allows us to skip prettier's auto line-breaking with just one comment (instead of for each constant), plus I like object style to group things together in general.
I think it looks better to not place the title within the card's border when there are multiple cards in a page, like in the case of the new Settings Layout. Otherwise, it's hard to differentiate between title and settings-row.
The proper method is to style Card itself, but this is a quick fix for the Settings Page PR. Will come back to it later.
All <Setting*> components will have an ID that corresponds to the sidebar link. When clicked, we scroll to the position of the card by searching for the element with the ID. It behaves simiar to # anchor navigation.
I like this model mainly because in Mobile, users don't need to keep opening the drawer to navigate -- they just need to scroll. This allows us to use the same design for Mobile and App.
Placed settings that we allow for unauthenticated users under <SettingUnauthenticated>. While it is redundant, it's easier to handle the grouping, and more readable overall.
Also made visual changes for the new Settings Page.
## SyncToggle:
It will no longer be under a dedicated Card, so the "Sync" title is not there to give context for the case of "no verified email".
Changed it such that the checkbox is always visible (it's label is self-explanatory) but disable when email is not set. The "Add Email" button will then appear below, so everything now makes sense in context.
* remove help card from lists page
* filtering to playlists page
* refactor
* clear playlists filter on escape
* rename
* no show playlist limit for now
* Automatically claim initial rewards (new_user & email_verified) when accessing creating channel, edit channel and upload
* Do not try to get initial rewards if already claimed.
## Ticket
5457 Create file thumbnail fallback image for odysee
## Approach
Since `background-image` does not invoke an `onerror` event, create a test Image instance to have the `onerror` capability. This technique is used by majority of plugins. No additional fetch is seen with this technique.
## Ticket
6879: Previously pinned livestream comments show as latest
## Issue
`comment.List` will always display the pinned comment first, hence the problem when the chat is refreshed.
## Approach
Completely split pinned comments from top-level comments in the Reducer, and the let the GUI (e.g. regular comments, livestream comments) decide how they want to display it.
For the case of livestream, there is no need to repeat the pinned comments in the regular chat area, since there is a dedicated area on top.
## Ticket
6886 Livestream auto-scroll problems
## Issue
- `performedInitialScroll` was problematic as it won't allow auto-scroll even when user scrolled back to the bottom.
- The dependence on `commentElement` seems to assume a certain comment height? Not sure.
## Approach
- Add a scroll listener and stash the last scroll position.
- When a message is received, check if it's at the bottom. If yes, maintain that position after the new comment is added. If not, leave as is.
- When submitting a comment, always reset to the bottom.
## Ticket
6743: Desktop: "Back" in Following Page no longer restores scroll position
## Issue
This was a side-effect of "6609 claimListDiscover: don't re-render until query is done". That PR did not handle the case of navigating backwards, which typically would just need to display past results. It ended up always starting with a blank list on mount, so the scroll position could not be restored correctly.
I don't know why it still worked on Web/Chrome -- maybe the latest browser knows how to move to desired scroll position when the height is available.
## Change
If navigating backwards, initialize the final URI list with the previous result. It is almost always correct, and if not, will be corrected in the effects. This saves us one re-render when navigating backwards too.
## Issue
6467 Add status indicators for messages from creator, delegated moderator, global moderator
## Changes
- Added the required icons.
- Added tooltip.
## Notes
- Left out "creator" since we are already highlighting the creator's name.
- Note that currently the status is only available via websocket deltas. `comment.List` does not provide the data.
- When `comment.List` includes the info, regular comments will automatically include these badges.
* remove unused conditional
get stuff ready for merge
bugfix and cleanup
requested changes
fixing flow errors
fix last flow error and touchups
fiat and lbc tabs coming along
support setting currency as the default tab via query param
add wallet fiat balance
fixing naming
add fiat transactions
using es6 to populate data
should be fine but keeps crashing
transaction listing working
add no transactions thing
about to add a third tab
add third tab
add card last 4 to transaction history
some renaming
show payments successfully
show filler for subscriptions
display if no transactions or subs
working but in the wrong component
approaching something thats working
showing total tipped amount
about to add last couple features
cleanup
More touchups
adding last features
calculate the total amount of unique creators tipped
couple touchups
remove transaction listings from settings
add view transactions buttons
small optimization
add subscriptions section
fix lot of linting errors and make command more userful
* some copy changes
* about to add last couple changes
* update still require verification
* fix button spacing
* hide subscriptions sections and fix links
* cleanups before merging
* more cleanup
* cleanup with last four fix
* changing tab functionality
* bugfix and fix presentation of cards
* fix transactions bug
* change order and remove logs
* remove unused code in account
* more linter fixes
* update account balance presentation
* fix flow errors
To avoid calling `setting.Get` excessively, we'll fetch the latest settings one last time before sending a tip. We'll also fetch in several areas, like when a comment action fails (most likely creator just enforced a minimum).
This will be easier when websocket send an update.
## General
- `setting.List`: returns full creator settings. Requires signature (i.e. you own the channel)
- `setting.Get`: returns a public subset of the creator settings. No signature required, and it is mainly used by the GUI to determine the constraints of a channel (e.g. comments enabled? min tip requirements? etc.). Does not include private settings like "blocked words list".
`doFetchCreatorSettings` will handle both of these. Clients that uses the stashed results (`settingsByChannelId`) just needs to be aware the result might not contain everything, depending on whether you own the channel or not.
## Misc Related Changes
- Finally fix the reducer for COMMENT_FETCH_SETTINGS_COMPLETED to not purge the data on each call.
- Change `doFetchCreatorSettings` to operate on a single channel instead of multiple. We ended up not using the multple mode anyway, so it was wasteful code trying to batch the promises.
- `commentsDisabledChannelIds` is no longer needed. Previously, this was created just to differentiate between Creator (full) and Channel (subset) settings. It's cleaner to just use one object, so eliminated this.
- Remove unused 'commentingEnabled'.
## Aside
- There are now 2 ways to know if a channel has disabled comments: (1) from `comment.list` and `setting.Get|List`. Both of them updates `settingsByChannelId`, so it'll still be a single place for the GUI to check against.
## Issue
> 5459 Add setting for changing your comment server. Visible on desktop (and possibly defaulting to Odysee URL), hidden on odysee.
## Comments
Not sure how this would actually work properly without the user recompiling the app to handle server differences. For example, even when we use our own server but switch between v1 and v2, some code changes are need to handle the differences. At that point, it seems easier for the user to just change the .env file? Anyway...
## Changes
- Added Desktop-only options to define custom server. [Settings > Advanced Settings > "Comment server" section].
* fix frontend bug
* show superchats in order properly
* scroll properly when switching tabs
* calculate fiat tips properly
* sum up lbc amounts
* refactor code a bit remove why isnt this working bit
* bugfix cant tip fiat if no lbc balance
* add toast when someone does a tip for a comment
* add error toast for card page
* show error on account connection page
* automatically truncate to two decimals
* close to working perfectly
* show decimals value better
* increase size of input value
* one bug left but almost working perfectly
* reverse so newest transactions come first
* fixing bug caused by floating point precision
* eslint fixes
* remove unused conditional
* get stuff ready for merge
* bugfix and cleanup
* requested changes
* fixing flow errors
* fix last flow error and touchups
* fix i18n and remove logs
Co-authored-by: Anthony <contact@anthonymayfield.com>
* raw ingredients done adding functionality
* essentially working just need a cleanup
* almost working with a couple bugs
* almost working but a bug or two
* seems to be working well
* seems to be working well but needs a cleanup
* couple of bug fixes
* basically working now cleaning up
* seems to be working pretty well
* cleanup unnecessary changes
* eslint fixes
* bugfix seek event
* bugfix and andrey fix and better docs
* getting ready to add last piece of functionality
* handle seek events properly
* add dynamic duration to calculate interval properly
* fix lint errors
* last couple changes
* only run watchman with analytics on and on prod
* flow fixes
Co-authored-by: zeppi <jessopb@gmail.com>
Renamed variables for clarity while at it.
"Item added to %name%" is probably redundant due to toast passing through <i18nMessage>, causing a double translation.
Anyway, added all the resolved string for now to avoid them popping up in app-string during development.
Previous:
~~Although it was collecting info for all platforms, the data is only sent for Odysee.~~ Correction: it became enabled for all platform after `master` became Odysee.
New:
Only send out the telemetry for `IS_WEB` or if there's user consent.
## Issue
6366 Recsys Evaluation Telemetry
The recommended list from lighthouse is obtained from `makeSelectRecommendedContentForUri`. This list is further tweaked by the GUI (e.g. move autoplay next item to top, remove blocked content, etc.). Recsys wants the final recommendation list and the clicked index (in exact order), so we need pass these info to the videojs recsys plugin somehow. Also, Recsys wants a recommendation list ID as well as the parent (referrer) ID, we so need to track the clicks and navigation.
## General Approach
- It seems easiest to just spew back the final (displayed) list and all the required info to Redux, and the recsys plugin (or anyone else in the future) can grab it.
- Try to touch few files as possible. The dirty work should all reside in `<RecommendedContent>` only.
## Changes
- `ClaimPreview`: add optional parameters to store an ID of the container that it is in (for this case, it is `ClaimList`) as well as the index within the container.
- When clicked, we store the container ID in the navigation history `state` object.
- For general cases, anyone can check this state from `history.location.state` to know which container referred/navigated to the current page. For the recsys use case, we can use this as the `parentUUID`.
- `ClaimList`: just relay `onClick` and set IDs.
- `RecommendedContent`: now handles the uuid generation (for both parent and child) and stores the data in Redux.
## Issue
6721 Notifications: Thumbnail for "new content" not showing up in Desktop layout
## Change
The `className` wasn't propagated during the `FileThumbnail` refactoring to `Thumbs`.
## Issue
6068 Fix "Cumulative Layout Shift" for Core Web Vitals
In Posts, the Comments section appears first while we fetch the MD file. When the MD is fetched, Comments get pushed to the bottom (or shifted up for short posts), hence the red CLS scores.
## Approach
There are too many layers between `<FilePage>` and `<DocumentViewer>` to pass the `loading` state around to hide the Comments section, so just make Comments fade in after a 2s delay.
## Changes
- Posts: Add 2s fade-in delay to Comments.
- Posts: remove the gray placeholder. This improves the score a bit more, and reduces flicker as well. There's already a spinner from `FileRenderInline` to tell the user to be patient.
- Posts: add a minimum 30vh height so that short posts don't get collapsed too much, causing the `FileDetails` and Comments to shift. Small shifts are fine as long as CLS is below 0.1.
## Issue
6542 Livestream listing and blocked list kills CLS score
This is basically a repeat of what was done on `claimTileDiscover` (homepage), but now on `claimListDiscover` (category pages).
This handles the unnecessary re-render when:
- the uri list temporarily being zero while waiting for new claim-search results.
- livestream claim-search invalidating the list.
## Changes
Store the last uri list and use that when we know that claim-search is still not done.
## Tests
1. Ran Lighthouse on category pages (force a livestream channel on it). CLS score must be green.
2. Block `claim_search` from Dev Tools and move to another category. The page should say "timed out" instead of "no results" (i.e. maintain existing behavior).
## Issue
6589
## Notes
`parseURI` will return `isChannel=false` due to the reposted channel URL not having the '@' symbol.
Since we already have the claim object, check `value_type` directly instead.
Pop up Menu Fixes and Improvements
Improve re-directs
Fix file deletion
Improve code, and more
Fix List Layout collection popup
Allow to edit list
Fix blocking when not logged or no channel
Fix Edit and Delete showing for not owned Lists
Fix actions breaking when not logged in
Fix List options not showing
Lint
Shorten logic
Lint
Recently changed to `<OptimizedImg>`, which was assuming the `src` never changes.
dejavu ... we also hit this issue when implementing the `IntersectionObserver` lazy-loading.
Objective:
- Get appropriately sized images to improve performance and Core Vitals score.
- Ensure images using "objectFit=cover" doesn't get stretched out if the source is large enough.
- Peg to 100px increments for better caching.
Notes:
- Skip images hosted in '/public'. If we really want to optimize it, then we'll need to provide the full path in the code, otherwise CDN lookup will fail.
- use `selectActiveChannelClaim` as that takes the current channel list into account (i.e. correct state when all channels are deleted).
- `selectActiveChannelId` should probably be removed or not exposed through a selector, as it is not updated when channel list changes?
show visible card and add remove card button
show your transactions even if you dont have a card
fix presentational issues
show your transactions even if you dont have a card
fix presentational issues
add link to channel section
update yarn
show donation location
add remove card modal still needs completion and also changed how stripe is used on settings stripe card page
add confirm remove card modal to router
move bank account stuff to settings page
move account functionality to settings page
continuing to move account transactions to settings
list transactions for creator
updating copy
touchup tip error
do a better job autofocusing
bugfix
show an error on the card page if api returns 500
building out frontend for comment tip
display dollar sign if its a fiat tip
more frontend work
more frontend work
more frontend bug fixes
working with hardcoded payment intent id
working but with one bug
bugfixed
add toast if payment fails
add add card button
cant get claim id but otherwise done
more frontend work
call is working
show fiat for livestream comments
add is fiat on comments
round and show values properly
dont allow review if tiperror
copy displaying properly
disable buttons conditionally properly
remove card button working
remove card working with a workaround by refreshing page
bugfix
send toast when tip on comment
jeremy frontend changes
only show cart on lbc
Not sure if this will ever occur, but technically possible from the code point of view. Try adding this to see if it stops the spikes in `reaction.list` calls.
Someone mentioned about odysee.com showing "tip" related text when supporting own claim. Now it should default to "Boost" related text for own claims.
L167: Not edited but not sure if "claimIsMine" is needed there any more.
add watch later hover action
replace watch later popup item for favorites
lint
styling for watch_later overlay
Add label
Use just claim, add requiresAuth
Add list icon
Tone down text
Turn WL Hover Button into component
Change WL hover icons
small revert
Keep watch later in the menu
## Issue
- `Comment.replies` currently represent all replies, while `comment.List` returns a filtered version, so the actual replies could be less.
- The actual replies is represented by `total_filtered_items`, but we only get that after making a fetch. So, users could click "Show more" but get nothing.
## Fix
- Stop showing "Show more" based on `total_filtered_items`.
- If there is a balance, display 1 dummy comment to represent all blocked replies. This handles the case of "Show more" being displayed but ended up with 0 replies if all replies were blocked.
## Future
Note that `Comment.replies` might be changed to represented filtered comments in the near future (refer to Beamer), so the GUI is made such that the dummy just won't appear when that change happens.
Seeing the spinner too much can be annoying.
- This approach works, but currently, when the list is very long, something is taking up resources and the handler couldn't be processed, so the effect is lost (still seeing the spinner). See 6473.
- Since we are now prefetching, bumped the debounceMs a bit.
It was waiting too near the viewport to load on certain zoom levels. This will maintain the same physical distance for the "approaching viewport" buffer regardless of zoom levels.
## Changes
- Change to canonical_url (with ':').
- The old format of 'claimName/claimId' needs to be supported still, since we shipped with it.
## Notes
- It would be nice to use regex instead of 2 separate paths, but I couldn't figure out how to make the koa variables work.
We currently handle major errors through ErrorBoundary. If the error is network related, ErrorBoundary ends up blank if it's components are lazy-loaded.
#codesplit
## Issue
Sub item in <6119 Creator Settings: beyond "Muted Words">
## Changes
- Removed the existing 5s min gap on livestreams.
- Enabled the 'slow mode min gap' in Creator Settings
This change now affects both comments in claims and livestream comments.
## Issue
The loading circle wasn't showing up, causing confusion.
Splitting CSS doesn't seem trivial as there seems to be a huge dependency on the load order. Pretty much similar to what this person is facing https://lihautan.com/css-code-splitting/#the-problem
## Change
This reverts videojs-specific changes from 4d638bcf.
## Issue
When seeking on a video, RecommendedContent gets re-rendered, which causes the 20 ClaimPreviews to be re-rendered, several times. ClaimPreview has lots of children, plus it's constantly checking against the blacklist, among other things.
## Fix
The culprit seems to be the `recommendedContent` array -- the address may be different, but the contents are the same.
Do a deep compare instead.
- [x] (6332) The IntersectionObserver method of lazy-loading loads cached images visibly late on slower devices. Previously, it was also showing the "broken image" icon briefly, which we mended by placing a dummy transparent image as the initial src.
- Reverted that ugly transparent image fix.
- Use the browser's built-in `loading="lazy"` instead. Sorry, Safari.
- [x] Size-optimization did not take "device pixel ratio" into account.
- When resizing an image through the CDN, we can't just take the dimensions of the tag in pixels directly -- we need to take zooming into account, otherwise the image ends up blurry.
- Previously, we quickly disabled optimization for the channel avatar in the Channel Page because of this. Now that we know the root-cause, the change was reverted and we now go through the CDN with appropriate sizes. This also improves our Web Vital scores.
- [x] Size-optimization wasn't really implemented for all ChannelThumbnail instances.
- The CDN-optimized size was hardcoded to the largest instance, so small images like sidebar thumbnails are still loading images that are unnecessarily larger.
- There's a little-bit of hardcoding of values from CSS here, but I think it's a ok compromise (not something we change often). It also doesn't need to be exact -- the "device pixel ratio" calculate will ensure it's slightly larger than what we need.
- [x] Set `width` and `height` of `<img>` to improve CLS.
- Addresses Ligthhouse complaints, although technically the shifting was addressed at the `ClaimPreviewTile` level (sub-container dimensions are well defined).
- Notes: the values don't need to be the final CSS-adjusted sizes. It just needs to be in the right aspect ratio to help the browser pre-allocate space to avoid shifts.
- [x] Add option to disable lazy-load Channel Thumbnails
- The guidelines mentioned that items that are already in the viewport should not enable `loading="lazy"`.
- We have a few areas where it doesn't make sense to lazy-load (e.g. thumbnail in Header, channel selector dropdown, publish preview, etc.).
## Issue
The scroll listener never unregisters, and is always registering itself on every scroll. I believe it was done that way to also handle the case of "element is already in viewport when mounted".
## Change
Tried to separate both "element is already in viewport when mounted" and "element scrolled into viewport" into different effects.
The timeout value used is a bit arbitrary, but is needed because the initial size is (0, 0), and to debounce any layout shifts. Reasoning: If an element is explicitly placed under this wrapper, the additional delay is acceptable since it's meant to be lazy-loaded anyway.
about to test something
generate programatically
beginning of the frontend
stripe integration page seems to be working
add user
put functionality behind conditional tag
connect frontend working well
adding environment variables to save success and failure url
bugfix
bugfix
final clean up
adding credit card page
seems to be coming along
calls successfully coming from the frontend
fixing up frontend
cleaning up
frontend coming along
client secret working
basic frontend in place
adding tip page
adding more to the tip frontend
frontend almost done
tabs coming along
one last thing to do for frontend
adding explainer text as custom function
putting finishing touches on tabs
support tabs working well
disable fiat toggle when card not connected
fix frontend gui bug
bugfix and pull out label function
fix symbol for tip gui
modal when card is not yet saved
fix fiat disabled bug
knowing whether card is added programatically
sending tip with frontend
tip functionality working
show unpaid balance
add frontend for card add section
update frontend
update frontend
bugfix
change to use react instead of css
update how stripe is instantiated
fix bug
use customer setup
coming along
working but needs optimization
persist if card is saved
adding anonymous tip functionality
fix nan bug
build stripe endpoints programatically
show for all users for time being
allow the stripe key to automatically switch to live environment
bugfix
bugfix
fix jslint
fix channel page support button
better docs
show customer transactions on frontend
basic table in place
various page updates per jeremys notes
showing card details
nicer tip history table
add better prompt to add card on file viewer page
some linting
time
put connect account behind fiat enabled
no persist fiat mode
wallet calls
tip stuff
## Issue
3779 RSS feed for channels
## Initial implementation details
- RSS only (not atom)
- Grabs latest 10 entries (Beamer have concerns)
## Credit
Referenced the community version mentioned in 3779
- The `rateChange` event now logs the updated speed,
not just the time at which it occurred.
- The `scrub` now (more) accurately logs the position
it came from before the destination.
- The recsys events get consolidated for logical consistency.
## Issue
With autoplay off, clicking on another video from the Recommended section didn't update the video poster.
## Fix
Made a mistake assuming that the whole component will be re-mounted, so was only setting the thumbnail once.
Even with the caching changes, a 150kB thumbnail still takes 1-2s to fetch. This impacts the score.
## Change
(1) Start with a large-enough placeholder image (has to be larger than the final image -- inflating doesn't count), then delay just enough for scoring, then switch to the real thumbnail.
(2) Since we are now doing post-mount stuff, we have the exact dimensions to optimize the claim thumbnail. This reduces the typically-several-MBs thumbnail to kBs.
These are chunks that will be requested immediately after ui.js when opening the homepage, so consolidate them into 1 chunk to reduce network overhead.
More work can/should be done to reduce the secondary chunk.
Make immediate GUI feedback to convey the current status, which can be the following:
- typing
- waiting lighthouse results
- waiting claim resolve
- no results or failed.
## Issue
6301: don't use CDN for GIF thumbnails
## Note
Just a minor mistake in the recent thumbnail refactoring; left out the handling when `allowGif` is true.
While Lighthouse allows looser searching like "Tom from LBRY", it doesn't show the expected results when direct channel name with partial ID is entered to disambiguate.
## Issue
6236 Add context menu to file page
## Notes
The download button actually handles a lot of things -- generating 'streamingUrl', differences between Web and Desktop, download progress for Desktop, etc. A simpler fix would be to put something else (maybe "Share") into the overflow menu instead.
Anyway, went ahead to do it per 6236, but retained the item for Desktop since we need a progress label.
This is the list of channels that authorized me as a moderator.
Similar to `moderation.BlockList`, this will only be fetched at startup/reload for now. I don't think there is a need to constantly monitor this. Users just need to refresh to see the moderator GUI elements after the delegator has granted them access.
## Issue
Closes 6159 "Support Comments Enabled/Disabled for comment.List API"
## New behavior
- `disable-comments` tag will block the comments component entirely.
- `settings.commentsEnabled`:
- When false, will pause comment fetching, posting and replying.
- Any already-fetched comments will stay on screen (unless user reloads/F5).
(1) Reduced the debouncing duration so that the final element can be rendered asap after visible.
- If the user is scrolling non-stop, it would continue to debounce and the GUI ends up not showing the final element.
- 25ms seems enough to prevent the initial false-positive that occurs in the scenario of "adjacent/upper elements resized late, so our element was briefly on screen when mounted". If not enough, we can make this a parameter.
(2) Removed `lastUpdateDate` that was a quick hack for Recommended section. We don't use it on that element anymore, so remove the hack to keep the file clean.
(1) The previous code assumed the element is always smaller than the screen. When used on large items like "homepage categories", it'll never load because the element exceeds the screen width or height.
(2) Added optional placeholder element. This allows us to put a cheaper element while waiting, so that the layout doesn't shift when we finally render. This is visually better when scrolling, and complies with Web Vitals.
wip
wip - everything but publish, autoplay, and styling
collection publishing
add channel to collection publish
cleanup
wip
bump
clear mass add after success
move collection item management controls
redirect replace to published collection id
bump
playlist selector on create
bump
use new collection add ui element
bump
wip
gitignore
add content json
wip
bump
context add to playlist
basic collections page style pass wip
wip: edits, buttons, styles...
change fileAuthor to claimAuthor
update, pending bugfixes, delete modal progress, collection header, other bugfixes
bump
cleaning
show page bugfix
builtin collection headers
no playlists, no grid title
wip
style tweaks
use normal looking claim previews for collection tiles
add collection changes
style library previews
collection menulist for delete/view on library
delete modal works for unpublished
rearrange collection publish tabs
clean up collection publishing and items
show on odysee
begin collectoin edit header and css renaming
better thumbnails
bump
fix collection publish redirect
view collection in menu does something
copy and thumbs
list previews, pending, context menus, list page
enter to add collection, lists page empty state
playable lists only, delete feature, bump
put fileListDownloaded back
better collection titles
improve collection claim details
fix horiz more icon
fix up channel page
style, copy, bump
refactor preview overlay properties,
fix reposts showing as floppydisk
add watch later toast,
small overlay properties on wunderbar results,
fix collection actions buttons
bump
cleanup
cleaning, refactoring
bump
preview thumb styling, cleanup
support discover page lists search
sync, bump
bump, fix sync more
enforce builtin order for now
new lists page empty state
try to indicate unpublished edits in lists
bump
fix autoplay and linting
consts, fix autoplay
bugs
fixes
cleanup
fix, bump
lists experimental ui, fixes
refactor listIndex out
hack in collection fallback thumb
bump
## Issue
5873 Unify swap and buy flow // swaps round 2
## Changes
- Added "Buy|Swap" tab in the Buy Page and display the Swap component when needed.
- Removed 'Swap' button from Wallet Page.
- "Buy More" and related tooltips updated to "Buy or Swap Credits".
1. Lock the width of the second pane so that the layout doesn't shift after the image is fetched.
2. The image is huge, so pass through the optimizer.
- Wait until the container is mounted to get the exact image width.
Unfortunately, it still takes 0.8s on average to fetch the image, regardless of how small the image has been optimized.
Login graphic improvements
1. Lock the width of the second pane so that the layout doesn't shift after the image is fetched.
2. The image is huge, so pass through the optimizer.
- Wait until the container is mounted to get the exact image width.
Unfortunately, it still takes 1s (on average) to fetch the image, regardless of how small the image has been optimized.
## Issue
6135
While waiting for the lazy-loader IntersectionObserver to initialize, and for the real image to be fetched, an undefined `src` results in the "broken image" thumbnail.
## Fix
Use a transparent image as the starting point. This visually retains the current behavior but minus the "broken image" part.
## Issue
GUI fix for 5979 `claim search runs twice sometimes and "refreshes" view`
The search query might encounter minor alterations after rendered (e.g. for the case of 5979, the `moderation.Blocklist` data came late). The code currently resets the result to 0 before initiating `claim_search`, so we see the GUI blink.
## Idea
There is a possibility that the query-change does not alter the final results in the end. Instead of reseting to the results to zero, hold on to the previous results until the fetch is done.
## Known issue
The tiles no longer blink if there is no change, but the "LIVE" indicator still does. I didn't want to propagate the info too deep, so leaving as is for now. It can be considered a feature ("blinking LIVE indicator" :))
## Results
- No blinking if results stay the same.
- Minimal tile-shifting if new ones are added or removed.
- In the current Odysee homepage, reduced React commits from 88 to 76 (save some CPU cycles).
## Changes:
1) TagSearch: hide the "control tags" in the Creator Settings page (irrelevant).
2) TagSearch: show the "control tags" when creating/editing Channel (let's use `setting.CommentsEnabled` instead).
3) TagSearch: show the "control tags" when creating/editing Content (`disable-comments` can be used to block comments at the per-claim level, e.g. allow comments in general but block only for specific claims).
## Missing pieces:
For (2) and (3), some work is needed to hide the comment GUI when `setting.CommentsEnabled` is disabled for a particular channel. That flag is not ready in Commentron yet, so I'm not sure how this will be done at the moment. In other words, the checkbox does nothing at the moment.
## Potential flaw:
This change will hide all control tags. If we have more tags in the future and would like to selectively disable some, we'll have to change this parameter to an array instead. Since the usage is not widespread at the moment, a single `disableControlFlag` seems cleaner (don't over-think it yet).
## Issue
Part of `5834 Performance investigation`
In a homepage with 120 tiles, the lists get rendered 3 times during initial update. The sub-components are updating recursively (will investigate), so instead of 120 DateTime renders, we have 1000+ renders.
The resolved DateTime string for `timeAgo` rarely changes, and even if the string was "a few seconds ago", there's no real need to constantly update it.
## Change
Require a minimum 1-minute delta when deciding whether the component should update. Clients can change this value as needed.
## Test
- [x] Verified `shouldComponentUpdate` doesn't end up taking more time than not having it (it's in micro-second range, compared to the millisecond render).
- [x] Profiler showed no significant improvement for low number of DateTime components, but for the 120 DateTime case, almost 1/4 of a second is saved.
- FileRenderInitiator: we don't display if it's not Audio or Video ("playables"). But only do that if it's free or was purchased, otherwise there's no button to buy it.
- FileRenderInline: if the user have not purchased it, don't show anything (not even the spinner).
## Issue
When opening a video directly in Chrome Incognito, the video should autoplay (since that's the default Lbry setting), but it doesn't due to browser policy
https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
## Changes
- We don't want to forcefully mute the video when `autoplay=true`; we just want to do it when the browser policy is applied.
- Fortunately, there is already an existing code-block for us to check that.
## Test cases
- [x] "Autoplay=Off" should not be affected.
- [x] After manually unmuting, the next autoplayed video should not be muted (this is "user interacted" opening, so the policy allows autoplay)
- [x] If manually muting, the next autoplayed video should retain user's last setting.
## Known issues
- I've seen `error` occasionally being undefined in the `catch` block. In those cases, the solution doesn't work. We could remove `if (player.autoplay() && !player.muted())` and simply just try muting it, but for now it's better to ensure `NotAllowedError` is due to unmuted first before applying the fix.
- This doesn't work for Firefox as there is an explicit "Allow Autoplay" button in the address bar that user needs to click themselves. Applies to all sites.
It's useful to show the thumbnail as the player's backdrop when Video Autoplay is OFF, but it's a wasted fetch when it's ON because the videojs component will be blocking it.
Although it's the same image as the ClaimPreview, this one will be in full size, so a fetch will always happen.
Aside: videojs handles the backdrop for the audio and embed case, so this change won't affect those items.
```
<VideoJs
poster={isAudio || (embedded && !autoplayIfEmbedded) ? thumbnail : ''}
/>
```
Future: for "mobile + autoplay=OFF", we should consider using the optimized thumbnail. 6074 should help.
* Restore "use cdn for channel thumbnails"
This reverts commit e7adc607fa.
* ChannelThumbnail: disable optimization in Channel Page and for GIFs
## Issue
5564: Don't use optimized URLs on channel pages (profile/banner)
## Notes
This is not the best/full solution yet, but it is better than what we have to today (one step in the right direction).
Optimized channel thumbnail size is currently hardcoded to a lowest common denominator.
- Pro(s):
- For images used in multiple places (different sizes) in a page, the total time needed to get the optimized version for each size is too much. Also, the optimizer seems to increase the size of the image in some cases. So, getting 1 image and re-using it is faster for this scenario.
- Simpler code (no need to mount first -> get dimension -> load image)
- Cons:
- We aren't fully optimizing the size, so not really addressing Core Web Vitals score problem.
- e.g. in the front page, we could have used a smaller image for the channel thumbnails.
- We haven't address the problem with large screen sizes.
* Restore channel selector
This reverts b5cc0bb42d
* ChannelThumbnail: fix lazy-loading
- Closes 6066: Revisit lazy-loading Channel thumbnails
- Properly fixes 5933: Thumbnail lazy-load causes ChannelSelector icon to not update.
- Add effect-dependency on `channelThumbnail` and `thumbError`.
- Really perform the lazy-loading now.
- `data-src` was not used, so it wasn't actually lazy loading previously.
* dont use no_channel_ids on channel content claim search
* ClaimMenuList not filtering own content initially
* fix errors
Co-authored-by: Thomas Zarebczan <thomas.zarebczan@gmail.com>
* own comments show first in controversial / best #5905
* workaround to place my recent comment at the top
* only most recent comment
* lint fix
Co-authored-by: Thomas Zarebczan <thomas.zarebczan@gmail.com>
* Release date -- initial attempt (squashed and rebased)
- Use white color for calendar buttons in release date input
- Update icon color for release date input
- Allow to set time in release date and display it under additional options
- Add release date field
* Upgrade to latest react-datetime-picker.
I believe this also picks up the y18n security fix.
* Handle dark theme and general style fixes.
* [+redux] Change how release_time is edited.
- `releaseTime` is now a number instead of a string, matching `release_time`. It was getting confusing what the variable units were.
- `releaseTime` will always match `release_time` for an edit. It will be used in the GUI to reset just the date to the original, instead of having to reset the entire form.
- `releaseTimeEdited` will be used by `updatePublishForm` in the GUI to represent the desired new release time. Set to `undefined` if we don't want to change the date.
* Add 'Reset|Now|Default' buttons instead of overloading the date-picker's "X" button.
Before this, the "X" button resets to the original (previous) publish date for Edits, and resets to current time for New Claims. This is very confusing, so added explicit text-based buttons -- hopefully this is more intuitive.
* bump redux to master
Co-authored-by: Franco Montenegro <franco.montenegro.ruke@gmail.com>
Co-authored-by: Thomas Zarebczan <thomas.zarebczan@gmail.com>
## Issue
6010: hyperchat send display issues with GIF profiles
The FreezeFrameWrapper have no `src` to freeze due to the lazy loading.
## Fix
Delay the freezing by making the lazy-load effect return a state to indicate when then `src` has been loaded.
Since the lazy-loader will `unobserve` after loading, the state will never go back to false, so we don't need to handle the case of preventing `new FreezeFrameWrapper` from being called multiple times from it's effect.
## Issue
Closes 6022 Notifications: Creator Commented
## Changes
- Beautify - show creator icon instead of generic bell.
- Link to comment directly instead of the claim.
* Add ICON.INFO - "i" within a circle.
Basically, an inverted ICON.ALERT.
* Posts: restore "Tip unlock | Claim details" component
## Issue
5882: tip unlock + claim id detials missing from markdown posts view
## Notes
The easiest solution would be to put `FileDescription` into posts, but I think that goes against the clean up of the Post layout, where the focus should be on the content. The faded style of the File Details section seems too distracting, plus we don't want the File Description anyway.
Fixed by:
- Make the existing "LBC amount" clickable to show credit details. An additional padlock will appear if the content is yours and you have tips to unlock.
- Add an "info" icon beside it to show file details.
These "link" buttons are usually lit, but I dimmed it in this case to make them stand out less. Again, focusing on Post content instead of buttons.
* Show full notification text via tooltip
The tooltip fixes the system notifications problem (mentioned below), and also allows one to quickly read the entire comment without actually having to visit the comment.
Currently, we only show about 50 characters in the notification, truncating it to an ellipsis when exceeded.
This is not much of a problem for dynamic text (e.g. comments) since the full text can be seen after clicking on the notification (brings you to the comment). For system notifications, this is problematic since there's no other way to know what the full text was.
Tried to dynamically change the font size to auto fit, but it wasn't fruitful. Even if it did work, it'll probably won't be legible for a 2000-character comment, plus the entire list will look weird with various font sizes.
* Beautify "missed out" notification; bring user to Verify page.
## Issue
6021: Notifications: Missed Out
## Changes
- The notification already brings the user to the `/rewards`. Tweaked it to directly enter the Verify Page.
- Use LBC icon instead of generic bell for this notification.
* Fix ability to delete own comments in livestream
## Issue
5832: can't remove own comments in live stream mode (if you have multiple channels?)
Looks like it was just missing `commentIsMine` for the new component.
* Disable editing livestream comments
It doesn't do anything at the moment, anyways.
* Disable deleting hyperchats
The "total tipped" will get deducted when hyperchats are deleted, which doesn't make sense (doesn't reflect actual total that the creator received).
* Swap: populate 'status' from 'btc/swap' response instead of waiting for first websocket input.
## Issue
Clsoes 5975: swap stop at processing even though response comes through
## Notes
Occasionally, the first websocket message doesn't come through (seems like the commerce didn't send?). There's really no need to wait for one more 'status=NEW' message to ensure the right data is being populated (being over-cautious here).
* Beautify the "exact amount" advice.
Scenarios where active livestreams will not appear:
- creation date is way back.
- homepage section options excludes livestreams.
Make an explicit `claim_search` but with `has_no_source` if the client wants `liveLivestreamsFirst`.
If there are lots of channels with livestreams, there's a possibility that the final list will be larger than what was requested. We could trim it to be within the original `options.pageSize` range, but I left that out for now.