## Behavior in homepage
- Mobile: show after every other category
- Desktop: show after first category, then every 2 categories.
## Known issue:
- "FYP" is not part of the categories array at the moment, so it does mess up the behavior.
## Notes
I think this is also called "in-content" by adnim (not 100% sure of the terminology).
My bad, added an unnecessary check in the previous change that shorted the logic too early.
Accessing an object using 'null' or 'undefined' as the key won't cause trouble (and is expected in this case), so just suppress flow instead of fixing it using
`channelId && geoBlockLists.livestreams[channelId]`
https://github.com/OdyseeTeam/odysee-frontend/issues/1100#issuecomment-1138928520
... but leave Following as "no limit"
The primary reason for this case is due to News and Wild West having lots of livestreams. But instead of just applying the limit to these 2 and polluting the loop, just limit it for all Categories.
Requires a related commit from the homepages repo.
## Changes
- Add ability to reset the sort order.
- Make 'News' and 'Wild West' a "hideByDefault" category. It can be made visible in the homepage from the customization dialog.
## Ticket
1572
Always check for availability before use.
## Changes
- Consolidated the keys into one place for easier tracking.
- It'll also be easier to code using constant autocomplete.
- Cleaned up the wrapper to be as close as the original.
- Updated existing code to use the wrapper (even if they already handled the availability) to encourage future code to just use the wrapper.
## Issue
- Closes "1535 bunch of channels (from featured?) resolved on page load"
- It was due to the use of reposts in the Category. As we did not store the repost's original channel claim, `ChannelThumbnail` couldn't find the author and requested a separate `resolve`.
## Change
Store the repost's original channel claim as well.
## Issue
Contents aren't block if you own them, but need to tell creator that is it blocked for others.
## Change
- Show a banner on Content and Channel Page for this scenario.
- Hover tooltip is available for the full text. For mobile, tapping it reveals the message.
Note that this only applies to the locale from where the creator is viewing it from. We can ignore locale, but would then need to display _all_ geo-restrictions related to the content in a list.
- Add ability to store `entries` into Redux.
- Sync to redux in the same interval as when playing position is saved (re-use timer).
- On startup, send any stashed entries and clear them.
* Show-page: split out some effects
Break apart the large effect for easier tweaking, abiding by the 1-action-per-effect guideline.
This also fixes the dependency list. After checking with Haffa, the exclusion of `pathname` and `hash` from the list is probably to avoid hitting `doResolveUri`. This should no longer be an issue after the split, so no suppression needed.
* Show-page: fix "no content found" flicker
## Issue
1539: "Recently been seeing a flicker of "content not found" when direct loading content or channel links on mobile"
## Cause
`doResolveUri` can only be called after the initial mount (in the effect), so at first render, `isResolvingUri` won't be set yet, so we briefly ended up in the "no content found" path.
## Change
Factor out the logic that determines if we should send `doResolveUri`. This allows us to know that the upcoming effect will be sending `doResolveUri`, so we can hold off displaying "no content found".
* Show-page: don't delay the spinner when resolving
## Reason
The delay causes a blank page + footer, which looks bad.
* Remove claim from channel page when geoblock conditions hits
Ticket: 1100
* Handle geoblocked channel page
## Ticket
1100
## Issue
"If a channel is geoblocked, the entire channel page (even showing titles, etc. would be against the law)"
## Issues
- Not safe to call the parent callback from the render function. It must be called from an effect or
- `onHidden` is only called when blacklisted, but it can also be hidden from other circumstances.
- While those other circumstances doesn't apply for FYP (the first client that relies on `onHidden`, it's incorrect from a code perspective, unless it is renamed to `onBlacklisted`.
## Change
- Move the callback execution into an effect.
- Ensure `onHidden` is for all situations that it is hidden.
Effects cannot be defined after the render function returns early, so it was not possible to add new effects when the derived variables that it depends on are way down below.
1. Hardcoding breaks any image changes done on dev instances or locally.
2. The relative path is bad, and there are few more instances of it. But continue as is for now, will file a ticket to fix this.
3. Fix caching.
- Don't want to show it in Incognito.
- Only show it in when entered from homepage, or in the Help page.
- Record the hash of the viewed announcement and update the wallet with it.
This stores the hash for the last viewed announcement.
The intention is so that the announcement won't re-appear when logging into another device.
However, this does mean that announcements would need to wait until the first sync to decide whether to appear or not, which can be quite a delay.
This requires an accompanying commit in the homepages repo (see "Add announcement support").
Using `raw-loader` to import markdown files as a string works for the app-side, but didn't work well in web-side. Falling back to copying the announcement files to `dist` and reading them via `readFileSync`. Don't really like this -- will return with an alternative.
Moving away from the function version to the object version. Trying to track down why the effect that closes the modal ran when the pathname did not change. My only guess is the unstable hideModal reference due to the function mapping. There is no customization needed, so the object version is preferred anyways.
`doOpenModal` isn't used, so I just removed that.
* PublishFile: fix render function violation
Per doc:
> A React component should not cause side effects in other components during rendering.
Even in own render function (allowed to call), it should be avoided as it could cause infinite loops.
* PublishFile: fix useEffect infinite loop due to bad dependency
## Issue
One of the effects was adding an internal wrapper function as a dependency. As this is a functional component, the wrapper is re-created on every render and would spark the effect. That effect also updates redux (depending on the code path), so we end up in a loop.
## Change 1
Two options to fix the dependency:
1. Just remove the wrappers from the list, since we "know" it is essentially the same function (i.e. it's not function-variable that could point to something else at runtime).
2. Peek into the wrapper and determine what are the actual dependencies (usually props or data derived from props).
Solution 2 is the norm.
Aside: wrappers are usually the root-cause of incorrect dependencies, because they mask away the actual code. Need to always peek into it.
## Change 2
Next, change the dispatch-to-props map from function version to object version so that we have stable references to the actions. The object version is also preferred when we don't need to make any customizations to the actions.
This reverts commit f6f15531d4.
The root-cause was known (8dd0982f), and I don't think it worked because:
1. The issue happened at the web side which didn't have logging.
2. The `[object Promise]` came after the `get`, not before.
`tileUris` is being used as an effect dependency, but it gets re-created on every render (same content, different reference), so the `setUriBuffer` effect ended up in a loop.
* Allow drawer to be resized
- Basically re-writes the drag behavior into the Drawer component instead of using SwipeableDrawer, getting more flexibility of where to stop and what to do
- More improvements like the backdrop effect, animations and window resize behavior
* Fix console errors
* Close drawer on unmount so other pages dont load open
* Allow livestream chat to be resized horizontally
* Fix mobile browser size
- address bar etc could be on the way
* Handle popout chat
* Fix pause with floating player
working example
use my forked package
touchups to presentation
Make progress bar thumbnail sprite pixel perfect
add vtt path
fix progress bar a bit
add a black background
use odysee team package
fix two issues for merge
more analytics + refactor
- passes player with time to start (until we move this api to watchman)
- supports livestream metrics for buffering
- fixes bug with buffering over 10 second period
- less head calls by moving to videojs-events
* review fixes
## Issue
I couldn't find where the i18n went because the "events" refactor is just as confusing as the original -- unrelated things are still lumped together in a file.
Also, factoring based on events isn't useful -- it is features that drive what events are needed, not the other way around. This forces features to register events here, and do other things elsewhere? It will be more intuitive to have a one-file-per-feature structure.
## Change
Use existing frameworks to encapsulate things to manageable units/features:
(1) the React useEffect files (can be used isolate out React features like 'tap-to-mute' handling).
(2) the videojs plugins framework.
It's also possible to move the use of `useClaimListInfiniteScroll` into `claimList` itself, but opted to keep them separate for now so that `claimList` doesn't end up a bloated file like `claimListDiscover`.
- and some changes to activeLivestream redux since it would return undefined if fetching and no claim, so now it returns null when no activeLivestream is found
* Redesign threadline and fetching state
- threadline goes right below channel avatar, mimicking reddits implementation, has a increase effect on hover and is slimmer, creating more space for comments on screen
- fetching state now replaces show/hide button, also mimicking reddit, and now says that it is loading, instead of a blank spinner, and also improves space a bit
* Redesign comment threads
- Allow for infinite comment chains
- Can go back and forth between the pages
- Can go back to all comments or to the first comment in the chain
- Some other improvements, which include:
- add title on non-drawer comment sections (couldn't see amount of comments)
- fix Expandable component (would begin expanded and collapse after the effect runs, which looked bad and shifted the layout, now each comments greater than the set length begins collapsed)
- used constants for consistency
* Fix replying to last thread comment
* Fix buttons condition (only on fetched comment to avoid deleted case)
* Fix auto-scroll
* Bring back instant feedback for Show More replies
* Improve thread back links
- Now going back to all comments links the top-level comment for easier navigation
- Going back to ~ previous ~ now goes back into the chain instead of topmost level
* Clear timeouts due to unrelated issue
* Fix deep thread linked comment case and more scroll improvements
* More minor changes
* Flow
* Fix commentList tile style
* Fix long channel names overflowing on small screens
* More scroll changes
* Fix threadline
* Revert "Fix long channel names overflowing on small screens"
This reverts commit e4d2dc7da5861ed8136a60f3352e41a690cd4d33.
* Fix replies fetch
* Revert "Fix replies fetch"
This reverts commit ec70054675a604a7a5f3764ba07c36bf7b0f49c8.
* Cleanup and make smooth
* Always use linked comment on threads
* Cleanup
* Higlight thread comment
* Fix comment body styles
## Issues from the initial attempt
- There are 2 versions of `Lbry` and `buildURI` -- the app and web-server version. There are subtle differences between them, and for the app case, importing the web-server version results in a query into an invalid URL.
- It changed the function from returning a string to returning a promise.
## Changes
- Since the new function (renamed to `fetchStreamUrl` for clarity) is currently only needed for web-server, I moved it into the `web` folder to avoid misuse in app.
- Await on the promise. Unfortunately, this also means the entire chain of function calls need to be adjusted to be `async`.
In the first attempt (PR 1497, 4d44d81f), the `generateStreamUrl` was tweaked to fetch a `Lbry.get`, which returns a promise. On top of a few async issues on its own, we also can't just simply `await` here since render functions need to be pure.
Fortunately, there is already redux structure for `get`, and Sean happened to already be passing all the required stuff here (sight beyond sight!), so it's just a matter of calling it.
Again, render functions need to be pure, so the fetch has be in an effect, so the component might take several renders to get the image painted. But oddly this seems to avoid the occurrence of showing the fallback spaceman image (just an observation, no proof of correlation).
## Issue
Ticket: 1484
The commit `7622e7a: Fix release time on category pages` passes in the `releaseTime` prop, which usually means we want that value to be override.
## Change
Only pass the prop when there 'freshness' filter is not active.
... because preference might be "Hide wallet = true". This eliminates the gap during login or boot up that temporarily shows the wallet balance.
Ticket: 1365
1446
- Requires an accompanying commit in `odysee-frontend`.
- The change assumes that the `odysee-frontend` is the only project that uses these files directly, i.e. other clients will use the API instead.
- consolidate cases that need to auto set an active channel (like edit page) into channelSelector component
- also for consistency since some components would do it with button click and others on page mount
- prevent clear function on those pages (kind of a manual process to insert each page into the router condition)
- reverts active channel functionality back to how it was previously, making the default channel simply a sync fallback and removing all complexity and confusion
From the previous commit, we are now showing toasts in the reverse order (latest to oldest).
Next, extend the "hide snack" timer to handle multiple snacks. It will dismiss them one by one, restarting itself until no more toasts.
Show a stacked GUI when there are multiple toasts.
Users can still manually dismiss the toasts.
Several issues with the clamping behavior:
- Problems trying to sync with the activeChannel setting.
- Corner-cases like unable to un-react because the comment and react channel was different; global mods not be able to change channels to do certain actions.
Just let the user know what are the channel(s) that they used to comment previously in the Toast.
If we can't confirm that user has not used another channel to comment, then don't allow commenting at all. Otherwise, there's no point doing the check.
## Why
Lost in a rebase. The GUI clamping was just meant to complement this (so that user knows what's going on), but ended up being the only thing that was pushed.
## Changes
- If the fetch failed or still in progress, we ask the user to wait or simply refresh the page.
- If already commented from another channel, bail and inform via Toast.
- this way, you can choose an active channel for something like commenting but when that component is unmounted, you always go back to the default channel (like leaving page)
- Moved from reach/ui to material/ui menu components, because reach ui wouldn't work with 2 menus
- This channel selector stores the default on settings
- setActiveChannelIfNotSet was deprecated, if the account has channels, it will always return a channel even if there is no active channel or stored channel
- Make the chapters button appear consistently.
- Previously, it was only appearing for Original.
- We still hide it for mobile, as per previous explanation.
- Changed the Chapters button position and popup aesthetics.
799
## Issue
`TxoList` is not shown when balance is zero. A zero balance doesn't always mean zero transactions.
## Fix
Just like in other components, don't make `YrblWalletEmpty` a mutually-exclusive thing.
- Deemed not useful in mobile, unless you have an S-pen that can hover.
- The chapters button (that invokes the chapters popup) would make more sense in Mobile, but we need to deal with the limited controlbar space first (e.g. overflow menu system)
We were already limiting the call to once-per-5-minutes (for the succesful case), so just need to put failure cases into the mix.
Retry 3 times before stopping.
## Issue 1263
Previously, we tried to inform the user that when an SDK call such as `support_create` and `publish` fails (specifically, timed out), the operation could be successful -- please check the transactions later.
However, we only covered the case of `fetch` actually getting a response that indicated a timeout, e.g. "status = 524". For our SDK case, the timeout scenario is an error that goes into the `catch` block. In the `catch` block, we can't differentiate whether it is a timeout because it only returns a generic "failed to fetch" message.
## New Approach
Since `fetch` does not support a timeout value, the usual solution is to wrap it with a `setTimeout`. This already exists in our code as `fetchWithTimeout` (yay).
By setting a timeout that is lower than the browser's default and also lower than the SDK operation (90s for most commands, 5m for `publish`), we would now have a way to detect a timeout and inform the user.
Firefox's 90s seems to be the lowest common denominator ... so 60s was chosen as the default (added some buffer).
For the case of 'publish', it is actually called in the backend, so wrap the xhr call with a timeout as well.
- Corrected flow definitions.
- Properly differentiate between "not yet fetched" and "no membership" as "undefined" and "<empty string>", respectively. There are GUI elements that need to know the unfetched case.
## New behavior:
- If you have commented on a claim before, the channel selector will be clamped to that channel.
- There might be more than 1 channel if commented in the past.
- This includes blocked comments, i.e. if the creator blocked you, you will not see your comment, yet your channel-selector is clamped to the used channel.
- EXCEPTION: you can use other channels if it's your own claim (for now).
## Approach
- Run `comment.List` over all your channels on the specific content. This covers nested replies and pagination (sweet).
- So, if the total is non-zero, mark that channel(s) as having commented on the claim.
- Only fetch this once per content claim.
- In the comment channel-selector, clamp the list to this value.
## Issue
1075, spam prevention.
## Approach
- When making a reaction, fetch reactions for all my channels for the particular comment id, and reject the reaction is any was found.
- Report the channel name in the toast so that user can at least know which channel to select in order to undo the reaction.
## Ticket
1320
## Approach
- Create a layer on top of the `Lbry` to log failures. `ApiFailureMgr` encapsulates this.
- Only logging `claim_search` for now as a start. Can be used for all methods.
- When a `claim_search` (with the same options) repeatedly failed for 5 times within 500ms, block subsequent calls for a duration of 1 minute.
- These values can be adjusted.
Completely remove any need to update things on our side when a Category is added or changed.
Will need to inform homepage owners to directly translate the 'label' field, so we don't need to use our translation system.
## Issue
1378
> "Content Type: Any" uses `claim_type: [streams, reposts, channels]`, with `stream_types: ["video", "audio"]`, so channels aren't returned, and not any types of streams either. Probably shouldn't have `stream_type` filter there.
(This also happens in categories, but maybe wanted in there?)
## Root
Due to this line in `ClaimListDiscover`:
`defaultStreamType = SIMPLE_SITE ? [CS.FILE_VIDEO, CS.FILE_AUDIO] : undefined, // add param for DEFAULT_STREAM_TYPE`
Wanted to check if this fallback was meant for Categories only or any list, but the git history is not preserved because Odysee was a squashed single-commit back in the `SIMPLE_SITE` days.
## Change
Will assume it was meant for Category Page only and moved that line from the component and into the client-side.
This also means that clients of `ClaimListDiscover` without `streamTypes` and `defaultStreamTypes` defined will no longer have `stream_types: ['video', 'audio']` as the automatic fallback (they must define `defaultStreamTypes` themselves). I think this modal is clearer -- it doesn't make sense to have filters like "content=any" but overridden quietly to `video|audio`.
## 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".