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."
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.
## 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.
## 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'.
## 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`.
* Bump react-draggable
Old version was giving out console errors for outdated react functions
* Refactor fileRenderFloating
* Merge fileRenderMobile into fileRenderFloating
* Fixes from review
* Attempt fix failed to view live
This reverts commit b3c4ce05fa.
The suggested 2-list approach broke the search bar because the bar is part of the list, so it gets unmounted while the user is typing. Oops.
## Ticket
lbry-desktop 6841
## Issue
If you are already at the homepage and you click the "Home" or "Odysee" logo again, the entire page reloads, causing the whole startup sequence to re-run (lots of fetches).
This can be annoying when not intended (e.g. clicked too many times), as startup is slow for some and we also lose non-persistent Redux data (for debugging).
I believe the requirement was just to reload the homepage tiles, as they might be showing stale ones after a while. A full reload was the quick-and-easy fix.
## Approach
Best not to touch the complicated `ClaimTilesDiscover`, so just clear the search cache key in this scenario. `ClaimTilesDiscover` will then pick this up and perform a new `claim_search`.
## Issue
535
## Change
- Header: Use the "channel list undefined" instead of "active channel url undefined" to determine if the button should be "pending".
- App: restore the use of `activeChannelClaim` instead of `activeChannelId`. In the existing design, the latter is never cleared is some situations, so the former is more accurate as it takes the current channel list into account. We might want to hide (not export) `activeChannelId` to avoid this mis-use again.
## Why
The playing URI was being cleared every time we leave the File Page, I believe to prevent the floating from continue playing outside of the File Page.
## Approach
Close FileRenderMobile by checking playingUri/primaryURI instead.
For the case of livestreams, just display it.
- Marked optional props properly.
- Re-ordered to make it easier to differentiate "props used in jsx" vs. "from redux".
Separated the commit to make the upcoming diffs easier to read.
Code-splits the module into "dnd.js", reducing the ui.js bundle size. This module is only needed when viewing lists.
## Room for improvement
`ClaimList` can probably improve further by only using the dnd components in "edit" mode.
## Implementation notes
- The modules are not default exports, so the additional chaining to `React.lazy` was required.
- Experimenting with using an Object to store the import so that a single "prettier-ignore" can be used to make it not wrap.
- The FlowFixMe came from the original code. It is unclear why it is needed to resolve the module, but Haffa mentioned it's something related to .flowconfig.
## Ticket
852 Markdown inline images in comments don't work for any channel level
## Change
The prior commit simplified the props from individual comment fields to just 1 `Comment` object, but there was a typo in the parameter where it should be `channel_url` instead of `author_uri`.
- The previous 2MB was a CDN limit (more of a mistake). That has been increased to a far greater number, so we're setting a more reasonable 5MB limit.
- The previous code checks/shows the "size exceeded" message after the file has been uploaded ... in the `catch` block. This will not work since the CDN now allows a 5MB file.
- Fixed by checking the size before actually uploading.
## Issue
When pressing "Done", it will call the upload function, which usually results in a "please select a file" error, or the file being uploaded if a file was selected prior to switching to "Use Url".
- Move stickers and emojis to a single menu comment-selectors on both mobile and desktop
- More style improvements
- Some fixes
- Fix livechat scrolling
- CommentsList needs to return a title with comment amounts
- mobile player dimensions needed to fill in the cover
- hid livestream header for now until figuring out a better presentation
- ~colum-reverse~ was causing problems with MUI's drawer scrolling, so reversed the chat order and made it ~column~ by default
- Hid bottom expand navigation if component not yet opened
- some other style changes in the middle
- Biggest change: Moved mobile player logic outside of fileRenderFloating into its own component fileRenderMobile, since there is no need for all that extra resizing and dragging code (for now, as mobile doesn't have a floating player)
- Moved player to the header height
- Removed rounded borders and margins
- Only pass necessary props
- Created new initialize play redux action
- Removed deprecated ~file app download~ keyboard functionality, moved preventDefault to videojs keyboard events to prevent ~space~ moving down the page
- moved doPrepareEdit incognito and channel calls to separate action
- same with download
- Tooltips
- No major differences between mobile or default returned components so removed condition since mobile style will be changed later on this branch
* Fix avatar occasionally stuck in spaceman
## Issue
Sometimes, we'll see a channel profile (e.g. in upper-right, in channel selector) stuck in the fallback Spaceman image.
This is due to OptimizedImage always starting with a blank src, and updated later when the mounted size has been determined. ChannelThumbnail, which uses OptimizedImage, captured the `onError` due to blank src.
## Fix
Don't mount the <img> until the optimum size has been determined.
* FileThumbnail: skip resolve if thumbnail url is specified
* UriIndicator: skip resolve if channel info is specified
* Notifications: disable batch resolve + use fetched data if available + fallback to resolve if n/a
The fallback is using the individual resolve when no direct data is provided and claim is undefined.
* Patch to restore position upon returning to video until more fully fleshed out fix can be introduced
* Add code to notify other open tabs of position saving
* Fix typo
* Wrap localStorage access in try/catch in event browser settings make it unavailable
* Remove formatting changes
* Move constant from 'pages' to 'player'
* Move dispatch out of try/catch
* Fixed typo
fixed the issue by removing the useRect, and putting in a resize event, going to try and make the code cleaner by removing all that logic and putting it in a hook.
## Issue
On large screens, the comment field and autoplay countdown can both be visible at the same time. The currently code only stops the timer when the countdown component is not visible on screen.
The page annoyingly navigates away while typing.
## Change
When servicing the timer, check if the current active element is an input type. As far as I know, there is no React equivalent for this.
1. Added size-specific error message.
2. Route whatever Vanwa's error instead of showing "unexpected json token". It's ugly, but at least it contains the reason string.
## Issue
Closes 385
## Approach
As mentioned in the ticket, the current places where that info is needed is in the Invites Page and Social Share Component.
1. Invites Page: it is already doing the fetch on mount, so no issue there.
2. Social Share: show spinner until the data is fetched.
## Issue
Closes "87 Repost - Top result should show followers properly"
The winning url for "bret" search is "lbry://bret", which is a repost.
## Change
We need to use the canon url to retrieved the fetched view count.
* Refactor CommentBadge
* Refactor livestreamComment component
* Refactor and split livestreamComment CSS
* Refactor livestreamComments component
* Refactor and split livestreamComments CSS
* Remove never used spinner
* Refactor livestream Page
* Refactor page component
* Refactor livestreamLayout component
* Break apart livestreamComments into separate sibling components
- This helps separating LivestreamComments to deal with only the comments, and the LivestreamLayout to be used for its own Page as a Popout option, and also for a layered approach for mobile
* Create Popout Chat Page, Add Popout Chat Menu Option
* Add Hide Chat option
* sockety improvements
* Websocket changes
Co-authored-by: Thomas Zarebczan <thomas.zarebczan@gmail.com>
* Resolve claim and stream types when there is a filter
## Symptom
Channel Page 'Content Type' filter not working
## Issue
The Advanced Filter work by placing a `?content=` URL param. The list component then parses it and makes the `claim_search` params accordingly. But:
1. There is a mix up in how the list component treats `?content=`.
- The original code seems to treat this as a way to define the type externally but only for a list without `claimType` defined via code. In other words, if `claimType="something"`, `?content=` is ignored.
- On the other hand, the Advanced Filter relies on `?content=` being used.
2. `?content=` is then split between `claimType` and `streamType`. The current code does not check if the split makes sense, e.g. if `?content=channel` and `streamType=['video']`, these 2 are incompatible and produces no results.
## Change
1. I'm not really sure what's the original intention, but let's just make `?content=` as an override/filter.
2. `?content=` should probably be limited to always be a subset of `claimType` and `streamType`. But this seems complicated to do, so for now let's just make always override/filter everything. For that, we need to make sure the filtered `claimType` -- `streamType` combo makes sense.
* Fix 'Channel' filter not working in Wild West
## Cause
The Wild West list defines `release_time` to be 1 week ago. As long as this parameter exists, a channel `claim_search` produces no results (I thought channels have creation dates?). That is why an unfiltered Wild West never showed Channel Tiles.
## Change
The existing `release_time` handling does seem to hint that we should not set the parameter when searching for Channels. Expanded that to consider the final (filtered) claim type, not just the original.
## Issue
After enabling Advanced Filter in Category Pages, the 'Content Type' filter only works for "repost/video/list".
## Root-cause
When `streamType` is not provided, it defaults to 'Video|Audio', making it always "defined":
```
streamType = SIMPLE_SITE ? [CS.FILE_VIDEO, CS.FILE_AUDIO] : undefined,
```
This seem to override the purpose of `defaultStreamType`, which will not be used unless the client explicitly set `streamType=null`, which currently is only being applied for `RECENT_FROM_FOLLOWING[]`.
```
const streamTypeParam =
streamType || (CS.FILE_TYPES.includes(contentTypeParam) && contentTypeParam) || defaultStreamType || null;
```
* Add ordering Icons
* Refactor doCollectionEdit
- It required claims as parameter, when only uris are used to populate the collection, so that was changed to pass down the uris instead.
- There were unused and mostly unnecessary functions inside, for example the parameter claimIds was never used so it would never enter the claimSearch function which again would be used to generate uris, so it's better to just use uris as parameter
* Add List Reordering changes
* Add toggle button for list editing
* Add toggle on content page collection sidebar
* Enable drag-n-drop to re-order list items
https://www.youtube.com/watch?v=aYZRRyukuIw
* Allow removing all unavailable claims from a List
* Fix <g> on icons
* Fix section buttons positioning
* Move preventDefault and stopPropagation to buttons div instead of each button, preventing clicking even if disabled opening the claim
* Change dragging cursor
* Fix sizing
* Fix dragging component
* Restrict dragging to vertical axis
* Ignore shuffle state for ordering
* Fix console errors
* Mobile fixes
* Fix sidebar spacing
* Fix grey on mobile after click
* Tooltip: add 'followCursor' and 'placement' option
When used on a `<span>` with short text but large empty area, the location of the tooltip was at the bottom-center of the area, which isn't ideal.
I think 'followCursor' should be the default, but making it optional for now to minimize testing.
Also added the 'placement' prop -- for the span case again, the mouse cursor is blocking the tooltip.
* View/Follower count: only use compact when > 10k
## Issue
Received complaints -- some people prefer to see full resolution.
## Changes
- As a compromise, we'll only apply the compact notation when the value is greater than 10k, with the exception of Tile View Count, where we'll always apply it due to space limitation.
- Also added Tooltip for Follower count.
## Fixes
- The string was always in 'en' locale in some instances, so it wasn't grouping up digits properly in Japanese (groups of 4), for example.
## Issue
When "Upcoming livestream" appears in a list, infinite scroll stops working.
## Cause
The difference between `mainEl.getBoundingClientRect().bottom` and `window.innerHeight` became slightly greater than 0.5, so it was deemed as "haven't reached the bottom".
## Change
Coincidently, I've been wanting to make the inf scroll load earlier (instead of after reaching the absolute bottom) to make the experience smoother, so added a 200px threshold, which is roughly the height of a tile. This gets us the new behavior while also fixes the original problem.
* Test out a horizontal scroll for upcoming (tile only for now)
* - add support for list layout
- add following label on home page
- clan up css and naming conventions
* Update header type + show only if scheduled streams are showing
## Issue
Closes 627 account header doesn't refresh on sign up / log in
## Changes
Looking back at "[Header] Changes, fixes and improvements (#493)", noticed that old code was looking at `has_verified_email` instead of just checking whether an email exists. So, restored original code.
This does have a side-effect of the Logout button not showing any email address underneath it immediately after sign up (with the flow cancelled). But I vaguely recall it was that way previously. A refresh cleans it up.
Perhaps another `user/me` when leaving the Sign Up page can make everything in sync, but this PR simpler to test.
* Add a setting to hide scheduled livestreams from home/following
* Add a hide button in the scheduled stream header.
* Fix typo + make sure pref is synced
* Update publish form when editing livestream + update to radios for liveststream release time
* Fix bug where upload tools may remain visible upon switching upload type, even when no option to upload is available.
* move publish source state up, when editing livestream only show scheduling option when source is none.
* Reset any set release time if switching to live stream mode.
* Update date/time cmpnts to reset any chnages they made on umount. Update schedule date/time cmpnt to clear release time when selecting anytime option.
* Additional filtering of internal tags
* Default to replay view when editing a liveststream
- Query for that tag in the upcoming section
- Improve special tag organization
- Filter out the internal tags in the UI
- Add missing types to publish state
The number of props to pass is getting out hand, so just pass the Comment object directly.
Also, moved the "is my comment" check into LivestreamComment, so we don't need to pass it as a prop from the parent.
Props: either use primitives, stable references or memoized objects to reduce renders. This update will simplify the existing `areEqual`. It is still needed though as some props are hard to memoize from where they are called, or should simply be ignore.
Was trying to save one event listener in the previous implementation and rely on other redux state-changes to spark a GUI update, but turns out there are scenarios where nothing is updated and the "offline" nag is stuck on screen.
## Change
Do it properly using the event listeners. The nag should now update promptly.
Changing the string means it will stay in English until retranslated. Reverting so that it can re-use existing translated database.
I don't think there is a clash in the `followingCount` variable, so the change was probably unnecessary.
* Refactor userChannelFollowIntro
* Add community based channels to signup auto follow
* Add German channels
* Remove main english channels and leave only community ones for auto follow
lbry-desktop--6844
This negates 49abbecb.
Now that we have a dedicated chromecast button, we don't need to hack Chrome's default cast button to appear on top of vjs-mobile-ui. The hack no longer works anyway, since the CSS exposure has been deprecated around mid 2020 -- it is still available, but its abilities has become less and less.
- The graphic was meant to be 50% of the card width, but was squished.
- Try to reduce scrolling by making everything fit in a 100% zoom on a 1080p screen.
The previous version was trying to fetch an optimized image with the exact size required, but the URL given was pre-optimized, so it wasn't working correctly. The additional work is also slow (seems to lock up mobile a bit), and since it wasn't functional, just removed it entirely.
It will be easier to just pre-reduce the image size to something suitable for a 1080p screen (the most common screen size at the moment).
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).