## Ticket
31: "quality selector not available on safari browsers"
## Notes
The quality selector isn't populated in some Apple products -- a known issue with videojs as the platform doesn't relay the info.
But it seems like only iPhone is affected, so let's enable the override for all platforms except iPhone.
## Ticket
1368
> can we remove the repost filter option on categories outside of wildwest/following?
## Approach
Using `context` to:
- reduce the amount of files that need to change.
- avoid prop-drilling.
- allow the ability to dynamically define the Filter's allowed values in a contained manner.
Clients that don't need customization simply does not need to wrap their component with the context.
The context only contains Content Type for now, but can include anything that future clients need to dynamically adjust.
## Ticket
Part of 1368 ("if user overrides the category homepage language with a different language setting + use 'search this language' option, use that instead. It's not typical this will happen, but probably expected.")
## Change
- Refactored to move more logic into `resolveLangForClaimSearch`
- Replaced the ternary version to make it more readable (hopefully).
- Inverted the language filter precedence by honoring the user's setting first.
- Note: for both User and Category, URLSearchParams will always take precedence.
- I got the previous logic completely wrong.
- Wild West's release time now comes from the homepage definition, but since the definition currently does not support "start of week", continue to hardcode the customization here.
- This logic also fixes the release_time for Tags.
## Ticket
1358 - flicker on livestream tile when viewers updates
## Change
Defining the component that way results in unique Card wrapper on each resolve, so everything gets torn down and re-mounted, causing the flicker.
There is a css side-effect though: the tags changed from red to black. But tags are inconsistent through the app ... sometimes black, sometimes red (I think it should always be red + smaller font from the body).
Re-used lots of Anthony's code + made fixes to a few areas including the publish page.
a
new videojs
video.js@7.18.1 + http-streaming@2.14.2
remove console log
Mainly only useful for Wild West, which doesn't use `channel_ids` (otherwise, the homepage maintainer could just exclude the id from `channel_ids` directly).
- Router: no need to specify the route directly anymore (will come from definition), but we still need to disable it for certain regions.
- Sidebar: no need to custom addition anymore.
## Ticket
`odysee-homepages :: 1318`
It was previously done in `GetLinkData`, but accidentally removed in d854a992.
It is DRY-er to do it here rather than at the client side.
Also needed to filter in the homepage-sort dialog, so move the definition to a constant array.
## Ticket
1308, 1363 - "Hide/skip "removed" recsys entries"
## Change
Ported the `isAbandoned` handling from the list-layout to the tile-layout (yet another grumble on why tile vs. list is not just a css difference but an entire different component).
## Misc
Because "ClaimList + tileLayout" was showing abandoned claims by default, search around to see if it was still needed. I think only collectionsListMine would require that (or maybe not, can remove later).
* Fix report page on mobile
* Fix mature tag colors in light theme
* Adjust spacing for badges in navigation
* Fix reply input background for notification on mobile
## Ticket
1074
In mobile, the second livestream tile in Following gets missing because of the Ad being in 'replace' mode.
## Change
Switch from 'replace' to 'insert' mode in Mobile layout.
If missing (replaced) tiles is not a desired behavior, the true fix would be to always use 'insert' mode, and either live with the uneven tiles or wait for our design master's solution.
It was meant to be general-purpose in the first-place, but ended being tied to ads due to time constraint and also bad documentation.
No functional change.
## Issue
1345
## Change
The refactor in 04c5ac46 broke the logic, because `!hasCost` would incorrectly include an undefined `costInfo` (haven't fetched) as free content.
## Issue
??
## Behavioral Changes
- Use `claim_search` instead of `claim_list` to retrieve all all own claims with the same name (case-insensitive).
- Caveat: annonymous posts will be excluded.
- When a clash occurs, there is a possibility that we have multiple existing entries (e.g. "xxX", "xXx"). Since we don't know which one is best to fall back, I removed the "edit" button for this and replaced with a simpler text
## Code Note
- If not mistaken, the rest of the code still needs `selectMyClaimForUri` to be case-sensitive, so augment the selector to support both through an optional parameter.
As of this commit, only the Channel Page is fetching the data through the new API, which has the viewer count correctly populated.
For both "0" and "undefined", continue to show as "LIVE".
The code currently supports both the baked-in homepages, as well as fetching from `/$/api/content/v1/get`.
As the latter is currently a circular round-trip, just use the baked-in version until the service is moved elsewhere. Loading performance will be better.
Just like ClaimListDiscover, stop `claim_search`-ing if the result is a failure (null).
Leaving the placeholder tiles as is for now. Can show the timed out message like ClaimListDiscover -- just toggle SHOW_TIMEOUT_MSG.
Potentially closes 1319
## Note
- `persistor.purge` returns a promise, we should wait for the resolved results before reloading, instead of just adding an arbitrary `setTimeout`.
- Perhaps the `setTimeout` method is to ignore a super-long or hanged purge (not sure), but it wouldn't be right since it would end up in a limbo state.
- Log errors to get clues for future.
- Reduced code by moving the reload to `finally`.
## Change
Due to "Own Comments" being implemented the same way as "Discussion Page", the comment lookup did not work for the abandoning case.
Just skip the local cleanup of `byId` -- it doesn't matter, as the GUI uses `selectCommentsForUri` to grab the per-channel comments, so it would still disappear in the GUI immediately.
## Ticket
1307 newly added categories aren't adding to existing customized homepage
## Change
In Customize, new categories were appended at the bottom, but forgot to repeat the behavior on the actual homepage itself.
## Issue
Desktop 7022: i18n: Notification title localization lost
## Approach
The current code breaks up the string into an array of strings, so i18n is somewhat impossible.
Since 99%¹ of dynamic notifications come with a `dynamic` property for all the replaceable values, we can actually reconstruct the string however we want.
¹ <sub>_as far as I can find, only `fiat_tip` does not provide the value via `dynamic`, i.e. hardcoded in the string. Boo._</sub>
### Benefits of this approach:
- able to localize the string again
- able to customize the string (e.g. making claim titles italic, fix typos, use more concise strings, etc.)
### Problems with this approach:
- if the api overloads a particular notification type with several strings, then the approach is broken.
- Ex. For the case of `comment` type, the overload is whether the comment is a normal comment or hyperchat. But I was able to replicate the logic to differentiate them, so all is good.
- For the case of "livestream reminder in 30 minutes", we would have to inspect the string to differentiate against "is live streaming". I think this reminder is not being used, so I didn't do it yet.
- some work is needed to maintain the code when the server side updates something. But we are already manually maintaining the i18n strings anyway, so it shouldn't be too much of a burden.
- With the exception of the overload problem, any new notification type will simply pass through as un-localized, so things should continue to work, i.e. no need to update the front-end immediately 🤞
Ticket: 1180
I believe the original intention was "if a claim was previously resolved, but without authentication (no `is_my_output` data), then resolve again with `include_is_my_output`"
Update to exclude that logic for Incognito.
## Aside
The check for `!canonicalUrl` is interesting:
- Are there claims that really don't have `canonical_url`? If yes, would that end up in an infinite `resolve` loop?
- When collapsing, scroll back to the first comment instead of hanging in the Recommended section.
- Enhancement for 5380bc04: don't show "Collapse/Expanse" if there's only 1 comment. The comment itself is already collapsed to 3 lines, so it won't take up too much height.
- Fix css: recalling what Dan mentioned: if following BEM right (modifiers shouldn't be used standalone), we wouldn't incorrectly use `@extend` in this case and confuse the reader.
- Enlarged the empty spacing to make it symmetrical with the Recommended section below it.
## Issue
Thumbnails in mobile, especially tablets, is blurry
## Change
Account for the larger thumbnail width in mobile.
Approximation is based on `$breakpoint-small: 900px;`
## Issue
In Medium layout, the Expand/Collapse button would still appear even for 0 comments.
## Approach
Hide the button when comments = 0, but didn't hide the section because the separator line feels useful as a visual guide to mark the sections.
## Issue
- Due to the timer used, the script could be loaded after the path-checking useEffect ran.
- Stale closure is also an issue.
## Approach
Create refs for the props, and listen to `onload` as well to resolve the visibility state.
## Issue
- Adding `content__non-clickable` everywhere probably isn't the right way when we move forward to separating `all.scss`.
- Not intuitive -- easier to use if it's an attribute to `ClaimPreview`.
## Change
- Consolidate to a re-usable `non-clickable` class.
- Made Wallet Send search preview non-clickable as a temporary band aid until the channel-finder is consolidated.
- `listBlocked`: something is overriding the pointer, so non-clickable isn't working. Removed for now -- doesn't really matter.
https://github.com/AdeleD/react-paginate/ issues/125#issuecomment-276625181
Apparently, the page bubble cannot be made clickable due to accessibility issues, so the click area is very small.
Changed the css as suggested by the maintainer.
## Issue
Ticket: 108
## Interesting
Uploads Page uses `claim_list`
Channel Page uses `claim_search
A second `claim_list` would instantly show updated results, but `claim_search` takes a long while to reflect the deletion.
## Change
This PR only handles the `claim_list` (Uploads Page).
The `claim_search` version would be troublesome to handle. If a refresh would bring back the results (due to the `claim_search` slow update behavior), we would need to store the deleted claim persistently. Then ...
- Store where? rehydrate?
- When to clear?
- How to make each `ClaimList` filter this out without polluting the code? etc.
...will be messy. Feels easier to "fix" at the `claim_search` level to make it update faster (maybe a command to clear cache at server or something).
Ticket: 1256
For `notify`, "file is currently locked" and "no such file or directory" is indication that the previous "failed" SDK call actually worked. Tell the user to check the transactions.
This is the band aid until odysee-api/401 is addressed.
## Cause
It broke because lack of awareness that we can't use our components in preview mode. For some reason, we don't have redux access in SimpleMDE's preview mode.
## Change
- Restore the stub for iframes
- Fix preview for images, and apply the same styling as in posts.
Partial copy from https://github.com/Rovak/InlineAttachment
We need to make some changes to handle xhr errors. Given than the repo hasn't been updated in 7 years, and it's a hassle to push the changes or fork the repo, just copy over the required files.
pinnedUrls = resolve
pinnedClaimIds = claim_search
Make `pinnedClaimIds` take precedence for now, since the homepage is defining both to support Android.
For some reason, I previously made `pinnedUrls` the priority, thinking this should be the "correct" one to use when the SDK is fixed.
## Issue
Maybe related to https://github.com/OdyseeTeam/odysee-frontend/issues/99#issuecomment-1042384649
## Notes
`fileInfo` does not contain `metadata` anymore -- not sure what happened. With zero duration, `videoPlayedEnoughToResetPosition` was never true.
But the claim usually contains the duration already, so we can use that. There are some audio/video claims that don't, but those are a minority.
Expanded homepage pins to support 2 types of input (if both are passed in, pinnedUrls take precedence):
(1) pinnedUrls --> uses doResolveUris (resolve)
(2) pinnedClaimIds --> uses doResolveClaimIds (claim_search)
Instead of injecting the pinned URLs directly, we inject from `resolvedPinUris`, which will be blank until the uris are resolved, thus preventing it from being resolved individually from the tiles.
There's additional complexity with the `claim_search` method, as the rest of the code deals with uris instead of IDs. Fortunately, it's all contained with `useResolvePins`, so removal would be easier when the batch `resolve` issue is fixed.
Ticket: 1228
## Code changes
- Pass through `getTimeAgoStr` so that the value gets localized.
- Pass the simpler `number` around instead of the `moment` object for better memoization.
## Notable differences
Due to how `getTimeAgoStr` is written, we now get to see the time actually counting down, vs "in a few seconds" currently in production. I think the counting-down behavior was the original intentional, since a 1s timer was used (otherwise, a 1-minute timer could be used) ... or maybe not since streams may not start on the dot.
I think we want to keep Premium as a product name (consistent for all languages). It was popping up in the `window.new_strings` because the current code localizes every link.
## Issue
Accumulation of so many strings for a "successful tip" that it is getting annoying to re-translate them for minor changes.
## Change
- Consolidate and re-use strings.
- Make the tip string currency-agnostic so we don't have to touch it again. The amount and currency is moved to the `subMessage`.
- Fix spacing being incorrectly enforced through i18n (it should be done via code/css).
Ticket: 1189
## Issue
There is a bug in a batched `resolve` that returns jumbled data. Temporarily switch to `claim_search` until that is fixed.
## Notable differences:
- `resolve` will tell us directly that a claim has been removed or filtered, so redux will mark the ID as such. `claim_search` simply returns nothing, so we will still end up with an extra `resolve` for these items when the component tries to display it.
- The new function currently does not handle Collections (i.e. resolving individual items in the Collection) and Reposts. Given that this is temporarily, I'd like to leave `doClaimSearch` as is, instead of trying to replicate what's in `doResolveUris`.
## Notes:
Since we don't care if the resolve fails (and we weren't doing anything in the `catch` anyways), use `finally` instead.
There is anecdote that we need to wait up to 2 minutes to preven the locking scenario.
`https://github.com/tus/tusd/pull/667#issuecomment-1079647640`
## Change
Instead of multiple retries at short intervals, do a one-time retry after a 2-minute wait. We'll do this until the fix is available in tusd v2.
- Non-error = pink background, Error = dark red. The former provides bad contrast for --color-text-subtitle.
- Use opacity instead of a hardcoded color.
- Remove the need for an object key. Just use an array. It gets hard to maintain as more messages come in, and so far there is no need to access the configs directly.
- Just focus on handling the message and not creating a toast object. Leave the latter to the client.
- Remove the odd resolve call that's lingering in `App`. Feels out of place, plus we don't need it now since the "active subs" claim search would contain resolved results.
- Don't search for active subs if Following count is zero.
Continuation of 1009 (2eae20f0)
It can probably be handled inside the existing getThumbnailCdnUrl to reduce 1 function, but since the functionality is somewhat different (the proxy doesn't compress), it's probably clearer to separate it.
It has been broken for a while, probably since the theme changes?
- Anyway, removed the effort to get the exact mounted size before requesting the image from CDN.
- When it works, it does prevent blurry image in different screen resolutions, but it's hard to maintain and too expensive.
ChannelThumbnail: use 64 to cover both the 64 and 40 case (the cached image will work on both, potentially reducing a call). I think the size is close enough to not trigger a Core Vital size warning.
Ticket: 946
- Copied the functionality from ClaimTileDiscover. Tried to use the same variable names to help the future consolidation work.
- Removed `excludeUris` from `ClaimList` as it makes the caching harder.
Clean up for 17a9b84d
We are now using `subSection` for livestreams, so no point passing in `prefixUris`, which causes additional processing.
(It wasn't visible because `showNoSourceClaims` was removed, but processing still happens).
- Only add for unauthenticated users for now. We can change that to look at premium later without having to touch `app/view.jsx`.
- Only show the ad after knowing the ad is filled; this prevents the invisible container from blocking stuff while waiting, or even worse, when not filled.
## Issue
- Errors like "unexpected token at..." and "failed to fetch" are being logged, rather than the actual call error.
- Publish SDK timeout is sometimes successful, but the user doesn't know, so they re-created the same claim
## Change
- Attempt to make the logs more helpful, and the error message more meaningful to the user.
- Starting off with 'publish' and tip SDK call as an experiment. Can add others if this method works.
- Add close button to allow immediate dismissal.
- Add ability to support sub messages. Will be typically used for error codes, etc.
- Add ability to define 'long' auto-dismiss duration (15s) vs. the default of 5s.
- I didn't add 'off' because there is a comment saying that this scenario should use the Error Modal instead, so respecting that for now.
- Forgot that we've concluded to not translate 'Premium/Premium+' and keep that as a product name. This is the same as competitors.
- For other instances of "Premium" in a longer string, we'll just have to communicate with translators to not translate it.
- Remove a few old strings.
This should be equivalent to the previous, just that the promises are stored in an object rather than variable. Benefits:
- Allows a single "prettier-ignore" to bypass the multiline import.
- Slightly less work when adding new modals by not having to create a named variable and handle the switch-case.
The webpack lazy-load syntax is unfortunately verbose, so this is the best I can come up with for now.
## Issue
- "Following" was showing up in place of "Featured"
- "Following" doesn't appear until livestreams are fetched, causing shifts.
When "Upcoming Livestreams" was implemented, it was trying to retain the original behavior of not showing "Following" title if that was the first in the list.
Not only is it a chicken-and-egg problem, but it causes extra renders due to the need to check if the other guys was rendered.
With FYP, there are now more combinations to handle.
## Change
Just show the title...
Was trying to save 1 state by assuming the homepage will be in a busy state and the ad-detection code will finish first. But this is not true for those with a small Following count.
- Variable names are for translators to determine the context, so choose more relevant names. e.g 'displayedInterval' and 'date_range' will not make much sense to a non-programmer.
- No need to localize dev-only strings.
- Various other fixes.
* Factor out lighthouse-result processing code for FYP re-use.
The FYP results will be in the same format as LH.
* Recsys: add ability to pass in specific uuid to use
For FYP, we want to pass the UUID as a param when searching for recommendations. The search comes before the recsys entry creation, so we need to generate the UUID first when searching, and then tell recsys to use that specific ID.
* Redux: fetch and store FYP
Note that the gid cannot be used as "hash" for the uri list -- it doesn't necessarily change when the list changes, so we can't use it to optimize redux. For now, just always update/render when re-fetched.
* UI for FYP
* Mark rendered FYPs
* Pass the FYP ID down the same way as Collection ID
Not ideal, but at least it's in the same pattern as existing code for now. The whole prop-drilling problem with the claim components will be fixed together later.
* Include 'gid' and 'uuid' in recommendation search
* Allow users to mark recommendations that they dislike
* Pass auth-token to all FYP requests + remove beacon use
beacons are unreliable and often blocked
* Only show FYP for members
* FYP readme page
* small fixes
* fyp
Co-authored-by: Thomas Zarebczan <thomas.zarebczan@gmail.com>
* various cleanups
* more touchups
* select currency to use based on location
* fix sidebar
* fixing strings and other touchups
* refactor and do proper string interpolation
* fix stripe error
* text bugfix
* Adjust help
Co-authored-by: Thomas Zarebczan <thomas.zarebczan@gmail.com>
Ticket: 1079 Support geoblocking channels/videos
## Changes
- Replaced the .env version with iapi version.
- Includes 'videos' blocking and custom messages.
* Homepage-Following: insert instead of replace when ad-blocker is detected.
`window.odysee_ad_blocker_detected` was not meant to be used outside of `<Ads>`, since it wouldn't spark a GUI update. But since homepages are rendered several times, perhaps it doesn't matter and we can skip adding to redux for now.
* Handle uBlock origin
If refreshed via "Clear Cache and Hard Reload", the detection method fails, but it does perform an internal redirect, so treat that as a failure.
* Add last used collection to right click menu.
* Small fix for last used collection when it's a published collection.
* Update last used collection when a collection is pending or published.
* Small refactor to get the last used collection.
We need to store the resolved claims first before marking COLLECTION_ITEMS_RESOLVE_COMPLETED, otherwise the GUI still sees undefined claims.
798 just accidentally flipped the order due to refactoring, I believe. It's now back to original.
Closes 916 "NaN in Total Staked Amount"
Contemplated putting the fallback into `<CreditAmount>` itself, but decided to minimize testing. Not sure if there are clients that would rely on NaN being used.
* Add swipe layout support for Collection Tiles
* Lists: use swipe layout for mobile
Ticket: 950 "playlists page - right now we show watch later on top, and if you have stuff here, you have to scroll down to other playlists. Show a selector on top? Whatever other improvements we can make here to improve UX."
The solution didn't work 100%, only reduces the chances of happening significantly. So far, still can happen on hot-reload during development.
- Reverted 15bd26399f.
- Fix by just hiding the unoccupied aniBox
- Initially, we did a bunch of forceful CSS to make the ad tile resize properly when the browser resizes. This was causing the EU ad to display incorrectly. Turns out, that css is no longer needed after the BEM-style re-write.
- Changed the floating ad selector to cover both EU and non-EU version. It's probably still not the best given it relies on style rather than ID, but the ID seems dynamic.
Closes 605 "Add pagination support to channel search"
## Previous Attempt
The previous attempt (69de63c4) didn't work because the wunderbar is part of the list component, so it is unmounted when we switch between the Normal and Filtered list, causing it to lose focus while typing.
Also, creating another full-blown ClaimList* component is really redundant (we should be consolidating instead).
## Approach
ClaimListDiscover recently added a new `subSection`, so we can place the filtered `ClaimList` here without causing the wunderbar to unmount.
Wrapped the "lighthouse search with channel_id" into `searchResults.jsx` for now as a quick and isolated solution. When we refactor ClaimList*, we can then consider incorporating into `doSearch`.
The tile placeholder method didn't work well because the component doesn't know how big the page size is, so we always end up rendering 1 placeholder tile, followed by N (= page size) placeholders (if not yet resolved). It's pretty ugly.
Removed comments:
- Incorrect/misleading: "injected item" does not mean "ads". It can be any React component that you want to put at a specific index.
- Redundant: don't explain the syntax. It's very annoying having to maintain the comment when the logic changes.
- Instead of 2 ways to display ads (DOM injection + React method) and having both of them clash, just do it the predictable React way.
- Augment the existing React version to support tile layout + ability to place in last visible slot.
- Consolidate styling code to scss ... DOM manipulations were making it even harder to maintain.
- Removed the need to check for ad-blockers for now. It was being executed every time an ad is displayed, and now that we are displaying ads in more places, the gains doesn't justify the performance loss. Also, it wasn't being done for Recommended ads anyway, so the inconsistency probably means it's not needed in the first place.
Other known issues fixed:
- double ad injection when changing language via nag.
- additional "total-blocking-time" due to ads at startup removed.
- fixed ads not appearing in mobile homepage until navigated away and back to homepage.
- enable ads in channel page.
- support for both List and Tile layout.
Since `triggerBlacklist` is just a simple boolean and `<Ads>` is not doing any additional logic on top of it, it doesn't make sense to pass as a parameter. Just not mount the component -- it's more concise and obvious at the client side.
Ticket: 1018
Reference: 2575c5d
- Restored position of the ad to the 4th slot.
- Moved repeated query out of the map predicate (`droppableProvided ?`)
- For draggables, make the injected item always on top for now. There are draggables with injected items at the moment.
## Cause
When 'selectRecommendedContentForUri' is filtering results against the blocklist, it relies on claim data which could be unresolved yet. It filters to empty results for this scenario, hence the flashing message.
## Change
Just return raw results when claims are not resolved yet, so that the GUI knows it needs to show the placeholders while resolving. After resolving, it'll go through the blocklist filtering again.
## Issue
Closes 1020 strange refresh on signup + youtube sync
It's due to the sync-on-focus.
## Change
Only show the spinner for the initial wallet sync. I thought we can do without the spinner for sync completely, but based on the comments below, better to retain that for the initial sync. I think the rest of the stages don't need to block over a sync call.
```
// Don't claim the reward if sync is enabled until after a sync has been completed successfully
// If we do it before, we could end up trying to sync a wallet with a non-zero balance which will fail to sync
```
This is a follow-up for #1016
Still doesn't affect anything at the moment, but this reduce the amount of work needed when we yank out the homepages from our bundle later.
Currently, homepages are still build as part of the app, so this change doesn't bring much benefit other than to support the wrapper app.
When the service is moved away from the app, we won't have to rebuild the app when homepages change, and also the ui.js bundle would be smaller without the need to code-split.
## Issues
Ad-filtering:
- Filtering was done whether or not ads are injected.
- Constants are repeatedly calculated.
- No short-circuiting in the for-loop.
- No memoization (being called 5-6 times on average due to redux updates, can't avoid that).
Others:
- Potentially passing null claimID to recsys (I think this is the issue that Johnny reported in Slack).
## Changes
- Moved 1-time calculations outside of the function.
- Optimized the filtering function and memoize it.
- Reduce unnecessary props since we are passing the whole `Claim` object already.
- Fix recsys being called when claim is not resolved yet (null claimId).
- Move away from the incorrect `makeSelect*` selectors.
* Use locale/get response to suggest homepage and language switch
* Fix language modal condition
* Fixes from review
* Fixes from review
* Fix gdpr
* string
* Fix multiple options behavior
* Fix gdpr and use only one fetch
* Only show if no languages set or loaded
* pt-br
* Fix ad
* Fix homepage select
* Fix zh langs
Clients can still choose to roll their own way of showing "is fetching", like how ClaimListDiscover displays a whole bunch of placeholder tiles. This just serves as a default.
List-layout is not scrollable, and doesn't look good either. Force to tile-only until we can fix it. If we decide to always use tile-only, then remove the parameter for ScheduledStreams.
- `filteredSubscriptions` was running the filter code whether or not it actually required filtering, because the `!subscriptionFilter` logic is placed in the predicate. While it is a clean one-liner, it is slow when the subs list is huge.
- While at it, moved the code into `getSubscriptionSection` to isolate things.
- The sidebar was resolving the entire subs list, which is super slow for a list of 500+. Since we now have a "Manage Subscriptions" page, just batch-resolve the N visible subs.
- TODO: the code should probably be moved from 'app' to 'sideNavigate'.
The idea of using claim_search to indirectly batch-resolve didn't work out well. There's something wrong with the claim_search pagination where some results are duplicated in multiple pages, while some are missing. It's also returning less results that than the given number of claim ids, so sometimes the infinite scroll breaks.
The `useDualLayout` junk is super confusing to maintain and no longer extensible.
At the expense of making the "livestream + regular" list no longer seamlessly continuous when expanded (or when there just a handful of livestreams), use the new `subSection` feature to inject the livestream tiles. This is far easier to manage and tweak.
## Issues
1. We were manually adding `selectLanguage(state)` as a prop to components used in Settings Page to trigger a render. Flaws:
- Unclear that the unused prop is just to trigger a render.
- Manually adding on a case-by-case basis will break over time, especially when language can now be changed outside of the Settings Page.
2. The translation file fetching is delayed and also takes time, so the GUI will end up having mixed strings on F5, depending on when the fetch completed.
## Approach
Make the app wrapper have a key that's tied to the language and translation data, so the entire app renders when language changes. Seems like a common design in most apps.
## Ticket
921 language refresh / selection issues
## Ticket
968 Truncate views/subs in other areas
## Changes
- Corrected logic for `minThresholdToApply`, which was ignoring the case of "no threshold", causing it to not be truncated in Channel Page. We want to always truncate there due to the smaller cards.
- Missed out handling `ClaimPreviewSubtitle`.