Compare commits

...

6 commits

Author SHA1 Message Date
drewhancock
c0e62d2513
change tagline
"i caught you a delicious bass" from napoleon dynamite
2021-07-11 21:54:37 -05:00
drewhancock
c4696fe51d
someordinarygamers 2021-07-11 14:38:00 -05:00
infinite-persistence
88cd620e77 Odysee: fix missing '--color-help-warning-bg' for Dark 2021-07-10 11:35:57 +08:00
drewhancock
369e624f47
alison morrow 2021-07-09 18:48:17 -05:00
zeppi
dae60c4ff1 patch-rss-bug 2021-07-09 16:52:12 -04:00
Thomas Zarebczan
0101a5d59f odysee
fix replay select styling

make meme a link

Fix audio references

get newest livestream claim in livestreamLink

pin crackermilk

fix livestream banner placement

fix live page

fix rebase

fix rebase

fix error nag

fix darkmode blockquote style

break word on livestream comment text

fix dark mode snack

fix live badge

fix lint

small fixes - word wrap, live badge

wip

Fix invisible snack in Odysee Light Theme

Revert "wip"

This reverts commit d17e477fe0.

Revert "small fixes - word wrap, live badge"

This reverts commit 0e431d4038.

fix blank

pinned destiny

fix badges and homepage again

only get livestreams live for less than a day

pinned hammy and olivia

multi pin

pin destiny

updated pinned videos

update tagline

Update view.jsx

pins

updated destiny's video

updated pinned videos

removed destiny, added lie likes music

pinned destiny and mason's woodshop

removed hammy and olivia

unpinned mason's woodshop

removed pins

added hammy and olivia
pinned sam seder
unpinned destiny and hammy and olivia
Fix merge on ChannelThumbnails

- sam seder, + hammy & olivia and passion for food
update tagline (#6086)

removed everyone, added kona and suba
Theme color fixes (odysee) (#6089)

* Cherry-pick master's 'base-theme.scss'

* Non-functional cleanup (remove dups, re-order, etc.)

* Dark: update positive Toast to --color-primary as well.

This follows the intention of the refactoring, which I guess was (1) reduce the number of color names (2) reduce the number of customizations needed.

The only issue I have with this is that the current Odysee primary color is pink, which can be intepreted as an error.

The original (pre-refactoring color was green).

For now, I follow the refactoring path. We can tweak this later.

* Fix text color inside '--color-card-background-highlighted'

Light: use base-theme (it was the same value anyway).
Dark: use bright text.

* Dark: add some contrast between the components

The color for the background, header, card, placeholder, etc. is almost identical -- it looks like there are all in the same component. The almost-invisible border doesn't help. One would have to crank up the monitor's contrast setting to see separation of components.

Brighten up the components a bit, somewhat following the same scale as lbry.tv's dark theme.

Overall, I still think it's too dark. The Card's background color can still be brightened up further for better contrast, but I try not to make too drastic of a change for now.

The original lbry.tv's gray theme is the most pleasant theme I've seen so far, but this is all subjective.
changed pins

removed kona and suba
added destiny
changed pins

removed destiny
pinned sgtducky
changed pins

removed sgtducky
added hammy and olivia
added chrissie mayr
added the bite shot
changed pins

removed the bite shot
added heads of tech
changed pins

removed hammy and olivia
removed chrissie mayr
changed pins

removed heads of tech
added crackermilk
changed pins

removed crackermilk
added some ordinary gamer
added passion for food
changed pins

removed some ordinary gamers
removed passion for food
added emmy hucker
changed pins

added game knights
Update view.jsx

Force rebuild
changed pins

removed emmy hucker
changed pins

removed game knights
added crackermilk
changed pins

removed crackermilk
added some ordinary gamer
changed pins

removed some ordinary gamers
added passion for food
added green renaissance
changed pins

removed passion for food
removed green renaissance
added expand love
changed pins

removed expand love
added dr nora
change tagline (#6122)

there's so much room for activities

comment out music

changed pins

removed dr nora
added kona and suba

changed pins

removed kona and suba
added destiny
changed pins

removed destiny
added crackermilk
changed pins

removed crackermilk
added someordinarygamers
change tagline

Drake, where's the door hole?

changed pins

unpinned someordinarygamers
pinned kona and suba
Add message for mature content

changed pin
changed pins

removed creative model

changed pins

added bcpov
added krish mohan
added cigarvixen

changed pins

removed krish mohan
added adrian logan

bump

fix footer

change tagline

just like the simulations

changed pins

removed:
bcpov
cigarvixen
adrian logan

added:
someordinarygamers

quick fix for reposts

oops

fix channel tabs

changed pin

removed someordinarygamers
added kona and suba
changed pins

removed kona and suba
added dirtyworkz
added crackermilk

fix channel tabs again again

changed pins

someordinarygamers
arvie's cookbook

changed pins

removed some ordinary gamers
removed arvie's cookbook
added fna van life

changed pins

removed fna vanlife
added game knights

change tagline

"this cave is not a natural formation"

changed pins

removed game knights
added some ordinary gamers

fix popup

put footer back

bump lightouse throttle

bump lighthouse throttle

changed pins

removed some orginary gamers
added adrian logan

pinned bret weinstein

fix referral

fix-superchats

changed pins

removed bret weinstein
added passion for food
added dark horse clips

fix incorrect variable being used to determine view state

changed pins

removed passion for food

changed pins

removed bret weinstein
added sgt ducky

add recsys related functionality

Create plugin to hold code for recsys

send recsys on dispose

cleanup recsys code

add userId to props validation

appease the linter

add todo note

extra characters

pinned jungle survival

fix autoplay for transcoded files

change tagline

changed pins

pinned destiny

pinned chris williamson

FIX video.js event firing issues fore RecsysPlugin

- 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.

Wunderbar: change throttle to debounce + add min chars

6314: prevent lighthouse spam from wunderbar

- Wunderbar: change throttle to debounce + add min chars.
- useLighthouse: added option to not throttle.

Wunderbar: immediate feedback to convey status

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.

pinned someordinarygamers

Wunderbar: bump debounce to 1s

per feedback

pinned jungle survival

pinned james julier

Fix compile error

Lint

summit pin

summit pin

update pins

added humblemechanic
removed everyone else

update pins

pinned samtime

FIX stop event translation and remove preprocessing

I think different browsers behave in different ways for the media
API. As a result, I think I was losing information for browsers
that weren't the same as mine (Chromium). For now, preprocessing
is removed. In the future, I'll add it again (better storage
and transmission properties).

updated pin

change pins

(cherry picked from commit 041f420416)

pinned someordinarygamers

auth only for stripe

restore playlists tab

fix missing i18n on channel page

pinned zimmerhandcrafted

change tagline

big gulps, huh?

change pin

Revert lazy-loading videojs

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

This reverts videojs-specific changes from 4d638bcf.

odyrecon

use ENABLE_UI_NOTIFICATIONS

use ENABLE_MATURE

oops

use ENABLE_MATURE for fileTitleSection

pinned orf

pinned ourselves

selecthumb copy

use ENABLE_UI_NOT. on sideNav

showNoSourceClaims

changed pin

fix livestream claims display

...

fix?

fix

Fix invalid semicolon
2021-07-09 14:41:18 -04:00
69 changed files with 2122 additions and 790 deletions

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
static/img/lbry-favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -38,6 +38,9 @@ type Analytics = {
playerLoadedEvent: (?boolean) => void,
playerStartedEvent: (?boolean) => void,
videoStartEvent: (string, number) => void,
adsFetchedEvent: () => void,
adsReceivedEvent: (any) => void,
adsErrorEvent: (any) => void,
videoBufferEvent: (
StreamClaim,
{
@ -50,9 +53,6 @@ type Analytics = {
readyState: number,
}
) => void,
adsFetchedEvent: () => void,
adsReceivedEvent: (any) => void,
adsErrorEvent: (any) => void,
emailProvidedEvent: () => void,
emailVerifiedEvent: () => void,
rewardEligibleEvent: () => void,

View file

@ -144,7 +144,8 @@ function ChannelContent(props: Props) {
hideAdvancedFilter={!showFilters}
tileLayout={tileLayout}
uris={searchResults}
channelIds={[claim.claim_id]}
streamType={CS.CONTENT_ALL}
channelIds={[claimId]}
claimType={claimType}
feeAmount={CS.FEE_AMOUNT_ANY}
defaultOrderBy={CS.ORDER_BY_NEW}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View file

@ -2,7 +2,7 @@
import React from 'react';
import { parseURI } from 'lbry-redux';
import classnames from 'classnames';
import Gerbil from './gerbil.png';
import Spaceman from './spaceman.png';
import FreezeframeWrapper from 'component/fileThumbnail/FreezeframeWrapper';
import ChannelStakedIndicator from 'component/channelStakedIndicator';
import { getThumbnailCdnUrl } from 'util/thumbnail';
@ -117,7 +117,7 @@ function ChannelThumbnail(props: Props) {
ref={thumbnailRef}
alt={__('Channel profile picture')}
className="channel-thumbnail__default"
src={!thumbError && url ? url : Gerbil}
src={!thumbError && url ? url : Spaceman}
width={thumbnailSize}
height={thumbnailSize}
loading={noLazyLoad ? undefined : 'lazy'}
@ -133,7 +133,7 @@ function ChannelThumbnail(props: Props) {
ref={thumbnailRef}
alt={__('Channel profile picture')}
className="channel-thumbnail__custom"
src={!thumbError && url ? url : Gerbil}
src={!thumbError && url ? url : Spaceman}
width={thumbnailSize}
height={thumbnailSize}
loading={noLazyLoad ? undefined : 'lazy'}

View file

@ -72,6 +72,8 @@ type Props = {
liveLivestreamsFirst?: boolean,
livestreamMap?: { [string]: any },
hasSource?: boolean,
limitClaimsPerChannel?: number,
releaseTime?: string,
showNoSourceClaims?: boolean,
isChannel?: boolean,
empty?: string,
@ -104,8 +106,8 @@ function ClaimListDiscover(props: Props) {
claimType,
pageSize,
defaultClaimType,
streamType,
defaultStreamType,
streamType = CS.FILE_VIDEO,
defaultStreamType = CS.FILE_VIDEO,
freshness,
defaultFreshness = CS.FRESH_WEEK,
renderProperties,
@ -124,6 +126,8 @@ function ClaimListDiscover(props: Props) {
forceShowReposts = false,
languageSetting,
searchInLanguage,
limitClaimsPerChannel,
releaseTime,
scrollAnchor,
showHiddenByUser = false,
liveLivestreamsFirst,
@ -170,12 +174,12 @@ function ClaimListDiscover(props: Props) {
const durationParam = urlParams.get(CS.DURATION_KEY) || null;
const channelIdsInUrl = urlParams.get(CS.CHANNEL_IDS_KEY);
const channelIdsParam = channelIdsInUrl ? channelIdsInUrl.split(',') : channelIds;
const feeAmountParam = urlParams.get('fee_amount') || feeAmount;
const feeAmountParam = urlParams.get('fee_amount') || feeAmount || CS.FEE_AMOUNT_ONLY_FREE;
const originalPageSize = pageSize || CS.PAGE_SIZE;
const dynamicPageSize = isLargeScreen ? Math.ceil(originalPageSize * (3 / 2)) : originalPageSize;
const historyAction = history.action;
let orderParam = orderBy || urlParams.get(CS.ORDER_BY_KEY) || defaultOrderBy;
let orderParam = orderBy || urlParams.get(CS.ORDER_BY_KEY) || defaultOrderBy || orderParamEntry;
if (!orderParam) {
if (historyAction === 'POP') {
@ -219,6 +223,7 @@ function ClaimListDiscover(props: Props) {
fee_amount?: string,
has_source?: boolean,
has_no_source?: boolean,
limit_claims_per_channel?: number,
} = {
page_size: dynamicPageSize,
page,
@ -241,6 +246,10 @@ function ClaimListDiscover(props: Props) {
options.has_source = true;
}
if (limitClaimsPerChannel) {
options.limit_claims_per_channel = limitClaimsPerChannel;
}
if (feeAmountParam && claimType !== CS.CLAIM_CHANNEL) {
options.fee_amount = feeAmountParam;
}
@ -270,7 +279,10 @@ function ClaimListDiscover(props: Props) {
options.reposted_claim_id = repostedClaimId;
}
if (claimType !== CS.CLAIM_CHANNEL) {
// IF release time, set it, else set fallback release times using the hack below.
if (releaseTime) {
options.release_time = releaseTime;
} else if (claimType !== CS.CLAIM_CHANNEL) {
if (orderParam === CS.ORDER_BY_TOP && freshnessParam !== CS.FRESH_ALL) {
options.release_time = `>${Math.floor(moment().subtract(1, freshnessParam).startOf('hour').unix())}`;
} else if (orderParam === CS.ORDER_BY_NEW || orderParam === CS.ORDER_BY_TRENDING) {
@ -348,9 +360,25 @@ function ClaimListDiscover(props: Props) {
const hasMatureTags = tagsParam && tagsParam.split(',').some((t) => MATURE_TAGS.includes(t));
const claimSearchCacheQuery = createNormalizedClaimSearchKey(options);
const claimSearchResult = claimSearchByQuery[claimSearchCacheQuery];
let claimSearchResult = claimSearchByQuery[claimSearchCacheQuery];
const claimSearchResultLastPageReached = claimSearchByQueryLastPageReached[claimSearchCacheQuery];
// uncomment to fix an item on a page
// const fixUri = 'lbry://@corbettreport#0/lbryodysee#5';
// if (
// orderParam === CS.ORDER_BY_NEW &&
// claimSearchResult &&
// claimSearchResult.length > 2 &&
// window.location.pathname === '/$/rabbithole'
// ) {
// if (claimSearchResult.indexOf(fixUri) !== -1) {
// claimSearchResult.splice(claimSearchResult.indexOf(fixUri), 1);
// } else {
// claimSearchResult.pop();
// }
// claimSearchResult.splice(2, 0, fixUri);
// }
const [prevOptions, setPrevOptions] = React.useState(null);
if (!isJustScrollingToNewPage(prevOptions, options)) {
@ -474,7 +502,7 @@ function ClaimListDiscover(props: Props) {
claimType={claimType}
streamType={streamType}
defaultStreamType={defaultStreamType}
feeAmount={feeAmount}
// feeAmount={feeAmount}
orderBy={orderBy}
defaultOrderBy={defaultOrderBy}
hideAdvancedFilter={hideAdvancedFilter}

View file

@ -103,7 +103,7 @@ function ClaimMenuList(props: Props) {
}
const shareUrl: string = generateShareUrl(SHARE_DOMAIN, uri);
const rssUrl: string = isChannel ? generateRssUrl(URL, uri) : '';
const rssUrl: string = isChannel ? generateRssUrl(SHARE_DOMAIN, uri) : '';
const isCollectionClaim = claim && claim.value_type === 'collection';
// $FlowFixMe
const isPlayable =

View file

@ -217,7 +217,6 @@ function ClaimPreviewTile(props: Props) {
<UriIndicator uri={uri} />
</div>
)}
{/* CHECK CLAIM MENU LIST PARAMS (IS REPOST?) */}
<ClaimMenuList uri={uri} collectionId={listId} channelUri={channelUri} isRepost={isRepost} />
</h2>
</NavLink>

View file

@ -146,7 +146,7 @@ function ClaimTilesDiscover(props: Props) {
mutedUris,
liveLivestreamsFirst,
livestreamMap,
// pin, // let's pin from /web folder
pin,
prefixUris,
showNoSourceClaims,
} = props;
@ -154,7 +154,7 @@ function ClaimTilesDiscover(props: Props) {
const { location } = useHistory();
const urlParams = new URLSearchParams(location.search);
const feeAmountInUrl = urlParams.get('fee_amount');
const feeAmountParam = feeAmountInUrl || feeAmount;
const feeAmountParam = feeAmountInUrl || feeAmount || CS.FEE_AMOUNT_ONLY_FREE;
const mutedAndBlockedChannelIds = Array.from(new Set(mutedUris.concat(blockedUris).map((uri) => uri.split('#')[1])));
const liveUris = [];
@ -286,11 +286,33 @@ function ClaimTilesDiscover(props: Props) {
return undefined;
};
const modifiedUris = uris ? uris.slice() : [];
const fixUris = [
"lbry://@SomeOrdinaryGamers#a/the-sonic-fanbase-did-something#d",
];
if (pin && modifiedUris && modifiedUris.length > 2 && window.location.pathname === '/') {
fixUris.forEach((fixUri) => {
if (modifiedUris.indexOf(fixUri) !== -1) {
modifiedUris.splice(modifiedUris.indexOf(fixUri), 1);
} else {
modifiedUris.pop();
}
});
modifiedUris.splice(2, 0, ...fixUris);
}
return (
<ul className="claim-grid">
{uris && uris.length
? uris.map((uri, index) => (
<ClaimPreviewTile key={uri} uri={uri} properties={renderProperties} live={resolveLive(index)} />
{modifiedUris && modifiedUris.length
? modifiedUris.map((uri, index) => (
<ClaimPreviewTile
showNoSourceClaims={hasNoSource || showNoSourceClaims}
key={uri}
uri={uri}
properties={renderProperties}
live={resolveLive(index)}
/>
))
: new Array(pageSize)
.fill(1)

View file

@ -31,7 +31,10 @@ type Props = {
isReply: boolean,
activeChannel: string,
activeChannelClaim: ?ChannelClaim,
livestream?: boolean,
bottom: boolean,
onSubmit: (string, string) => void,
livestream: boolean,
embed?: boolean,
toast: (string) => void,
claimIsMine: boolean,
sendTip: ({}, (any) => void, (any) => void) => void,
@ -51,7 +54,11 @@ export function CommentCreate(props: Props) {
isReply,
parentId,
activeChannelClaim,
onSubmit,
bottom,
livestream,
embed,
toast,
claimIsMine,
sendTip,
justCommented,
@ -87,7 +94,7 @@ export function CommentCreate(props: Props) {
function altEnterListener(e: SyntheticKeyboardEvent<*>) {
const KEYCODE_ENTER = 13;
if ((e.ctrlKey || e.metaKey) && e.keyCode === KEYCODE_ENTER) {
if ((livestream || e.ctrlKey || e.metaKey) && e.keyCode === KEYCODE_ENTER) {
e.preventDefault();
buttonref.current.click();
}
@ -155,6 +162,10 @@ export function CommentCreate(props: Props) {
setCommentFailure(false);
justCommented.push(res.comment_id);
if (onSubmit) {
onSubmit(commentValue, activeChannelClaim.name);
}
if (onDoneReplying) {
onDoneReplying();
}
@ -179,6 +190,11 @@ export function CommentCreate(props: Props) {
<div
role="button"
onClick={() => {
if (embed) {
window.open(`https://odysee.com/$/${PAGES.AUTH}?redirect=/$/${PAGES.LIVESTREAM}`);
return;
}
const pathPlusRedirect = `/$/${PAGES.CHANNEL_NEW}?redirect=${pathname}`;
if (livestream) {
window.open(pathPlusRedirect);
@ -232,6 +248,7 @@ export function CommentCreate(props: Props) {
className={classnames('comment__create', {
'comment__create--reply': isReply,
'comment__create--nested-reply': isNested,
'comment__create--bottom': bottom,
})}
>
<FormField

View file

@ -77,7 +77,7 @@ export default function CommentReactions(props: Props) {
<Button
requiresAuth={IS_WEB}
title={__('Upvote')}
icon={ICONS.UPVOTE}
icon={myReacts.includes(REACTION_TYPES.LIKE) ? ICONS.FIRE_ACTIVE : ICONS.FIRE}
className={classnames('comment__action', {
'comment__action--active': myReacts && myReacts.includes(REACTION_TYPES.LIKE),
})}
@ -87,7 +87,7 @@ export default function CommentReactions(props: Props) {
<Button
requiresAuth={IS_WEB}
title={__('Downvote')}
icon={ICONS.DOWNVOTE}
icon={myReacts.includes(REACTION_TYPES.DISLIKE) ? ICONS.SLIME_ACTIVE : ICONS.SLIME}
className={classnames('comment__action', {
'comment__action--active': myReacts && myReacts.includes(REACTION_TYPES.DISLIKE),
})}

View file

@ -29,6 +29,7 @@ type Props = {
myChannels: ?Array<ChannelClaim>,
doToast: ({ message: string }) => void,
clearPlayingUri: () => void,
hideRepost?: boolean,
isLivestreamClaim: boolean,
reactionsDisabled: boolean,
download: (string) => void,
@ -48,6 +49,7 @@ function FileActions(props: Props) {
myChannels,
clearPlayingUri,
doToast,
hideRepost,
isLivestreamClaim,
reactionsDisabled,
download,
@ -113,24 +115,26 @@ function FileActions(props: Props) {
const lhsSection = (
<>
{ENABLE_FILE_REACTIONS && !reactionsDisabled && <FileReactions uri={uri} />}
{ENABLE_FILE_REACTIONS && !reactionsDisabled && <FileReactions uri={uri} livestream={isLivestreamClaim} />}
<ClaimSupportButton uri={uri} fileAction />
<ClaimCollectionAddButton uri={uri} fileAction />
<Button
button="alt"
className="button--file-action"
icon={ICONS.REPOST}
label={
claim.meta.reposted > 1 ? __(`%repost_total% Reposts`, { repost_total: claim.meta.reposted }) : __('Repost')
}
description={__('Repost')}
requiresAuth={IS_WEB}
onClick={handleRepostClick}
/>
{!hideRepost && (
<Button
button="alt"
className="button--file-action"
icon={ICONS.REPOST}
label={
claim.meta.reposted > 1 ? __(`%repost_total% Reposts`, { repost_total: claim.meta.reposted }) : __('Repost')
}
description={__('Repost')}
requiresAuth={IS_WEB}
onClick={handleRepostClick}
/>
)}
<Button
className="button--file-action"
icon={ICONS.SHARE}
label={__('Share')}
label={isMobile ? undefined : __('Share')}
title={__('Share')}
onClick={() => openModal(MODALS.SOCIAL_SHARE, { uri, webShareable, collectionId })}
/>

View file

@ -1,4 +1,5 @@
// @flow
import * as REACTION_TYPES from 'constants/reactions';
import * as ICONS from 'constants/icons';
import React from 'react';
import classnames from 'classnames';
@ -15,18 +16,44 @@ type Props = {
likeCount: number,
dislikeCount: number,
myReaction: ?string,
livestream?: boolean,
};
function FileReactions(props: Props) {
const { claim, uri, doFetchReactions, doReactionLike, doReactionDislike, likeCount, dislikeCount } = props;
const {
claim,
uri,
doFetchReactions,
doReactionLike,
doReactionDislike,
myReaction,
likeCount,
dislikeCount,
livestream,
} = props;
const claimId = claim && claim.claim_id;
const channel = claim && claim.signing_channel && claim.signing_channel.name;
const isCollection = claim && claim.value_type === 'collection'; // hack because nudge gets cut off by card on cols.
React.useEffect(() => {
if (claimId) {
function fetchReactions() {
doFetchReactions(claimId);
}
}, [claimId, doFetchReactions]);
let fetchInterval;
if (claimId) {
fetchReactions();
if (livestream) {
fetchInterval = setInterval(fetchReactions, 45000);
}
}
return () => {
if (fetchInterval) {
clearInterval(fetchInterval);
}
};
}, [claimId, doFetchReactions, livestream]);
return (
<>
@ -41,20 +68,46 @@ function FileReactions(props: Props) {
title={__('I like this')}
requiresAuth={IS_WEB}
authSrc="filereaction_like"
className={classnames('button--file-action')}
label={formatNumberWithCommas(likeCount, 0)}
className={classnames('button--file-action', { 'button--fire': myReaction === REACTION_TYPES.LIKE })}
label={
<>
{myReaction === REACTION_TYPES.LIKE && (
<>
<div className="button__fire-glow" />
<div className="button__fire-particle1" />
<div className="button__fire-particle2" />
<div className="button__fire-particle3" />
<div className="button__fire-particle4" />
<div className="button__fire-particle5" />
<div className="button__fire-particle6" />
</>
)}
{formatNumberWithCommas(likeCount, 0)}
</>
}
iconSize={18}
icon={ICONS.UPVOTE}
icon={myReaction === REACTION_TYPES.LIKE ? ICONS.FIRE_ACTIVE : ICONS.FIRE}
onClick={() => doReactionLike(uri)}
/>
<Button
requiresAuth={IS_WEB}
authSrc={'filereaction_dislike'}
title={__('I dislike this')}
className={classnames('button--file-action')}
label={formatNumberWithCommas(dislikeCount, 0)}
className={classnames('button--file-action', { 'button--slime': myReaction === REACTION_TYPES.DISLIKE })}
label={
<>
{myReaction === REACTION_TYPES.DISLIKE && (
<>
<div className="button__slime-stain" />
<div className="button__slime-drop1" />
<div className="button__slime-drop2" />
</>
)}
{formatNumberWithCommas(dislikeCount, 0)}
</>
}
iconSize={18}
icon={ICONS.DOWNVOTE}
icon={myReaction === REACTION_TYPES.DISLIKE ? ICONS.SLIME_ACTIVE : ICONS.SLIME}
onClick={() => doReactionDislike(uri)}
/>
</>

View file

@ -21,8 +21,8 @@ function FileSubtitle(props: Props) {
<FileViewCount uri={uri} livestream={livestream} activeViewers={activeViewers} isLive={isLive} />
</div>
<FileActions uri={uri} />
{/* did I need these params? */}
<FileActions uri={uri} hideRepost={livestream} livestream={livestream} />
</div>
);
}

View file

@ -37,12 +37,12 @@ function FileViewCount(props: Props) {
return (
<span className="media__subtitle--centered">
{isLive &&
{livestream &&
__('%viewer_count% currently %viewer_state%', {
viewer_count: activeViewers === undefined ? '...' : activeViewers,
viewer_state: isLive ? __('watching') : __('waiting'),
})}
{!isLive &&
{!livestream &&
activeViewers === undefined &&
(viewCount !== 1 ? __('%view_count% views', { view_count: formattedViewCount }) : __('1 view'))}
{!SIMPLE_SITE && <HelpLink href="https://lbry.com/faq/views" />}

View file

@ -5,7 +5,8 @@ import FilePrice from 'component/filePrice';
import { formatLbryUrlForWeb } from 'util/url';
import { withRouter } from 'react-router';
import { URL } from 'config';
import * as ICONS from 'constants/icons';
import OdyseeLogo from 'component/header/odysee_logo.png';
import OdyseeLogoWithText from 'component/header/odysee_white.png';
type Props = {
uri: string,
@ -36,7 +37,10 @@ function FileViewerEmbeddedTitle(props: Props) {
{...contentLinkProps}
/>
<div className="file-viewer__embedded-info">
<Button className="file-viewer__overlay-logo" icon={ICONS.LBRY} aria-label={__('Home')} {...lbryLinkProps} />
<Button className="file-viewer__overlay-logo" aria-label={__('Home')} {...lbryLinkProps}>
<img src={OdyseeLogo} className=" mobile-only" />
<img src={OdyseeLogoWithText} className=" mobile-hidden" />
</Button>
{isInApp && <FilePrice uri={uri} />}
</div>
</div>

View file

@ -1,5 +1,5 @@
// @flow
import { LOGO_TITLE, ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM } from 'config';
import { ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM } from 'config';
import * as ICONS from 'constants/icons';
import { SETTINGS } from 'lbry-redux';
import * as PAGES from 'constants/pages';
@ -19,6 +19,8 @@ import ChannelThumbnail from 'component/channelThumbnail';
import { remote } from 'electron';
import { IS_MAC } from 'component/app/view';
// @endif
import OdyseeLogoWithWhiteText from './odysee_white.png';
import OdyseeLogoWithText from './odysee.png';
type Props = {
user: ?User,
@ -87,8 +89,8 @@ const Header = (props: Props) => {
sidebarOpen,
setSidebarOpen,
isAbsoluteSideNavHidden,
user,
hideCancel,
user,
activeChannelClaim,
activeChannelStakedLevel,
} = props;
@ -100,7 +102,7 @@ const Header = (props: Props) => {
const isPwdResetPage = history.location.pathname.includes(PAGES.AUTH_PASSWORD_RESET);
const hasBackout = Boolean(backout);
const { backLabel, backNavDefault, title: backTitle, simpleTitle: simpleBackTitle } = backout || {};
const notificationsEnabled = (user && user.experimental_ui) || false;
// const notificationsEnabled = (user && user.experimental_ui) || false;
const livestreamEnabled = Boolean(
ENABLE_NO_SOURCE_CLAIMS &&
user &&
@ -246,19 +248,12 @@ const Header = (props: Props) => {
icon={ICONS.MENU}
onClick={() => setSidebarOpen(!sidebarOpen)}
>
{isAbsoluteSideNavHidden && isMobile && notificationsEnabled && <NotificationBubble />}
{isAbsoluteSideNavHidden && isMobile && <NotificationBubble />}
</Button>
</span>
)}
<Button
className="header__navigation-item header__navigation-item--lbry"
// @if TARGET='app'
label={'LBRY'}
// @endif
// @if TARGET='web'
label={LOGO_TITLE} // eslint-disable-line
// @endif
icon={ICONS.LBRY}
className="header__navigation-item header__navigation-item--lbry header__navigation-item--button-mobile"
onClick={() => {
if (history.location.pathname === '/') window.location.reload();
}}
@ -268,7 +263,12 @@ const Header = (props: Props) => {
}}
// @endif
{...homeButtonNavigationProps}
/>
>
<img
src={currentTheme === 'light' ? OdyseeLogoWithText : OdyseeLogoWithWhiteText}
className="header__odysee"
/>
</Button>
{!authHeader && (
<div className="header__center">
@ -285,7 +285,7 @@ const Header = (props: Props) => {
<HeaderMenuButtons
authenticated={authenticated}
notificationsEnabled={notificationsEnabled}
notificationsEnabled
history={history}
handleThemeToggle={handleThemeToggle}
currentTheme={currentTheme}
@ -438,6 +438,10 @@ function HeaderMenuButtons(props: HeaderMenuButtonProps) {
<Icon aria-hidden icon={ICONS.CHANNEL} />
{__('New Channel')}
</MenuItem>
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.YOUTUBE_SYNC}`)}>
<Icon aria-hidden icon={ICONS.YOUTUBE} />
{__('Sync YouTube Channel')}
</MenuItem>
{livestreamEnabled && (
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.LIVESTREAM}`)}>

View file

@ -158,7 +158,7 @@ export default function LivestreamComments(props: Props) {
</div>
)}
<div ref={commentsRef} className="livestream__comments-wrapper">
{viewMode === VIEW_MODE_CHAT && superChatsTotalAmount > 0 && (
{viewMode === VIEW_MODE_CHAT && superChatsTotalAmount > 0 && superChats && (
<div className="livestream-superchats__wrapper">
<div className="livestream-superchats__inner">
{superChats.map((superChat: Comment) => (

View file

@ -0,0 +1,9 @@
import { connect } from 'react-redux';
import { makeSelectClaimForUri } from 'lbry-redux';
import LivestreamFeed from './view';
const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state),
});
export default connect(select)(LivestreamFeed);

View file

@ -0,0 +1,38 @@
// @flow
import { BITWAVE_USERNAME, BITWAVE_EMBED_URL } from 'constants/livestream';
import React from 'react';
import FileTitleSection from 'component/fileTitleSection';
import LivestreamComments from 'component/livestreamComments';
type Props = {
uri: string,
claim: ?StreamClaim,
activeViewers: number,
};
export default function LivestreamFeed(props: Props) {
const { claim, uri, activeViewers } = props;
if (!claim) {
return null;
}
return (
<>
<div className="section card-stack">
<div className="file-render file-render--video livestream">
<div className="file-viewer">
<iframe
src={`${BITWAVE_EMBED_URL}/${BITWAVE_USERNAME}?skin=odysee&autoplay=1`}
scrolling="no"
allowFullScreen
/>
</div>
</div>
<FileTitleSection uri={uri} livestream activeViewers={activeViewers} />
</div>
<LivestreamComments uri={uri} />
</>
);
}

View file

@ -17,7 +17,7 @@ export default function LivestreamLink(props: Props) {
const { push } = useHistory();
const [livestreamClaim, setLivestreamClaim] = React.useState(false);
const [isLivestreaming, setIsLivestreaming] = React.useState(false);
const livestreamChannelId = channelClaim.claim_id || ''; // TODO: fail in a safer way, probably
const livestreamChannelId = (channelClaim && channelClaim.claim_id) || ''; // TODO: fail in a safer way, probably
React.useEffect(() => {
if (livestreamChannelId) {
@ -29,7 +29,7 @@ export default function LivestreamLink(props: Props) {
})
.then((res) => {
if (res && res.items && res.items.length > 0) {
const claim = res.items[res.items.length - 1];
const claim = res.items[0];
setLivestreamClaim(claim);
}
})

View file

@ -5,14 +5,12 @@ import classnames from 'classnames';
type Props = {
unseenCount: number,
inline: boolean,
user: ?User,
};
export default function NotificationHeaderButton(props: Props) {
const { unseenCount, inline = false, user } = props;
const notificationsEnabled = user && user.experimental_ui;
const { unseenCount, inline = false } = props;
if (unseenCount === 0 || !notificationsEnabled) {
if (unseenCount === 0) {
return null;
}

View file

@ -19,9 +19,8 @@ export default function NotificationHeaderButton(props: Props) {
// notifications,
// fetching,
doSeeAllNotifications,
user,
// user,
} = props;
const notificationsEnabled = user && user.experimental_ui;
const { push } = useHistory();
function handleMenuClick() {
@ -32,10 +31,6 @@ export default function NotificationHeaderButton(props: Props) {
push(`/$/${PAGES.NOTIFICATIONS}`);
}
if (!notificationsEnabled) {
return null;
}
return (
<Button
onClick={handleMenuClick}

View file

@ -512,7 +512,7 @@ function PublishFile(props: Props) {
{fileSelectSource === SOURCE_UPLOAD && showFileUpload && (
<>
<FileSelector
label={SIMPLE_SITE ? __('Video/audio file') : __('File')}
label={__('File')}
disabled={disabled}
currentPath={currentFile}
onFileChosen={handleFileChange}
@ -612,7 +612,7 @@ function PublishFile(props: Props) {
{/* @if TARGET='app' */}
{showFileUpload && (
<FileSelector
label={__('File')}
label={__('Video file')}
disabled={disabled}
currentPath={currentFile}
onFileChosen={handleFileChange}

View file

@ -182,9 +182,9 @@ function PublishForm(props: Props) {
}
} else {
if (editingURI) {
customSubtitle = __('Update your video');
customSubtitle = __('Update your video/audio');
} else {
customSubtitle = __('Upload that unlabeled video you found behind the TV in 1991');
customSubtitle = __('Upload that unlabeled video or cassette you found behind the TV in 1991');
}
}
@ -566,6 +566,7 @@ function PublishForm(props: Props) {
<Button
key={String(modeName)}
icon={modeName}
iconSize={18}
label={__(MODE_TO_I18N_STR[String(modeName)] || '---')}
button="alt"
onClick={() => {

View file

@ -312,6 +312,11 @@ function SideNavigation(props: Props) {
<li className="navigation-link">
<Button label={__('FAQ')} href="https://odysee.com/@OdyseeHelp:b" />
</li>
<li className="navigation-link">
<Button label={__('Community Guidelines')} href="https://odysee.com/@OdyseeHelp:b/Community-Guidelines:c" />
</li>
<li className="navigation-link">
<Button label={__('Support --[used in footer; general help/support]--')} href="https://lbry.com/support" />
</li>

View file

@ -11,7 +11,6 @@ import { AUTO_FOLLOW_CHANNELS, SIMPLE_SITE } from 'config';
type Props = {
subscribedChannels: Array<Subscription>,
onContinue: () => void,
onBack: () => void,
channelSubscribe: (sub: Subscription) => void,
homepageData: any,
prefsReady: boolean,
@ -45,25 +44,25 @@ function UserChannelFollowIntro(props: Props) {
<Card
title={__('Find channels to follow')}
subtitle={__(
'LBRY works better if you find and follow a couple creators you like. You can also block channels you never want to see.'
'Odysee works better if you find and follow a couple creators you like. You can also block channels you never want to see.'
)}
actions={
<React.Fragment>
<div className="section__actions--between">
<Button button="secondary" onClick={onBack} label={__('Back')} />
<Button
button={subscribedChannels.length < 1 ? 'alt' : 'primary'}
onClick={onContinue}
label={subscribedChannels.length < 1 ? __('Skip') : __('Continue')}
/>
</div>
<div className="section__body">
<ClaimListDiscover
defaultOrderBy={CS.ORDER_BY_TOP}
hideFilters
meta={
<Button
button={subscribedChannels.length < 1 ? 'alt' : 'primary'}
onClick={onContinue}
label={subscribedChannels.length < 1 ? __('Skip') : __('Continue')}
/>
}
defaultOrderBy={CS.ORDER_BY_TRENDING}
defaultFreshness={CS.FRESH_ALL}
claimType="channel"
claimIds={SIMPLE_SITE ? undefined : PRIMARY_CONTENT_CHANNEL_IDS}
defaultTags={followingCount > 3 ? CS.TAGS_FOLLOWED : undefined}
claimIds={SIMPLE_SITE ? PRIMARY_CONTENT_CHANNEL_IDS : undefined}
claimType={CS.CLAIM_CHANNEL}
maxPages={3}
/>
{followingCount > 0 && (
<Nag

View file

@ -1,5 +1,4 @@
// @flow
import * as PAGES from 'constants/pages';
import React from 'react';
import classnames from 'classnames';
import { useHistory } from 'react-router';
@ -7,7 +6,6 @@ import UserEmailNew from 'component/userEmailNew';
import UserEmailVerify from 'component/userEmailVerify';
import UserFirstChannel from 'component/userFirstChannel';
import UserChannelFollowIntro from 'component/userChannelFollowIntro';
import UserTagFollowIntro from 'component/userTagFollowIntro';
import YoutubeSync from 'page/youtubeSync';
import { DEFAULT_BID_FOR_FIRST_CHANNEL } from 'component/userFirstChannel/view';
import { YOUTUBE_STATUSES } from 'lbryinc';
@ -42,7 +40,6 @@ type Props = {
creatingChannel: boolean,
setClientSetting: (string, boolean, ?boolean) => void,
followingAcknowledged: boolean,
tagsAcknowledged: boolean,
rewardsAcknowledged: boolean,
interestedInYoutubeSync: boolean,
doToggleInterestedInYoutubeSync: () => void,
@ -67,7 +64,6 @@ function UserSignUp(props: Props) {
fetchingChannels,
creatingChannel,
followingAcknowledged,
tagsAcknowledged,
rewardsAcknowledged,
setClientSetting,
interestedInYoutubeSync,
@ -118,8 +114,7 @@ function UserSignUp(props: Props) {
interestedInYoutubeSync);
const showYoutubeTransfer = hasVerifiedEmail && hasYoutubeChannels && !isYoutubeTransferComplete;
const showFollowIntro = step === 'channels' || (hasVerifiedEmail && !followingAcknowledged);
const showTagsIntro = step === 'tags' || (hasVerifiedEmail && !tagsAcknowledged);
const canHijackSignInFlowWithSpinner = hasVerifiedEmail && !showFollowIntro && !showTagsIntro && !rewardsAcknowledged;
const canHijackSignInFlowWithSpinner = hasVerifiedEmail && !showFollowIntro && !rewardsAcknowledged;
const isCurrentlyFetchingSomething = fetchingChannels || claimingReward || syncingWallet || creatingChannel;
const isWaitingForSomethingToFinish =
// If the user has claimed the email award, we need to wait until the balance updates sometime in the future
@ -206,22 +201,6 @@ function UserSignUp(props: Props) {
}}
/>
),
showTagsIntro && (
<UserTagFollowIntro
onContinue={() => {
let url = `/$/${PAGES.AUTH}?reset_scroll=1&${STEP_PARAM}=channels`;
if (redirect) {
url += `&${REDIRECT_PARAM}=${redirect}`;
}
if (shouldRedirectImmediately) {
url += `&${REDIRECT_IMMEDIATELY_PARAM}=true`;
}
replace(url);
setSettingAndSync(SETTINGS.TAGS_ACKNOWLEDGED, true);
}}
/>
),
showYoutubeTransfer && (
<div>
<YoutubeTransferStatus /> <Confetti recycle={false} style={{ position: 'fixed' }} />

View file

@ -12,7 +12,7 @@ import LbcSymbol from 'component/common/lbc-symbol';
type Props = {
errorMessage: ?string,
isPending: boolean,
verifyUserIdentity: string => void,
verifyUserIdentity: (string) => void,
verifyPhone: () => void,
fetchUser: () => void,
skipLink?: string,
@ -60,7 +60,7 @@ class UserVerify extends React.PureComponent<Props> {
SITE_NAME,
}}
>
Verified accounts are eligible to earn LBRY Credits for views, watching and reposting content, sharing
Verified accounts are eligible to earn LBRY Credits for views, watching and reposting videos, sharing
invite links etc. Verifying also helps us keep the %SITE_NAME% community safe too! %Refresh% or %Skip%.
</I18nMessage>
</p>
@ -73,9 +73,7 @@ class UserVerify extends React.PureComponent<Props> {
<Card
icon={ICONS.PHONE}
title={__('Verify phone number')}
subtitle={__(
'You will receive an SMS text message confirming your phone number is valid. Does not work for Canada and possibly other regions.'
)}
subtitle={__('You will receive an SMS text message confirming your phone number is valid.')}
actions={
<Fragment>
<Button

View file

@ -95,10 +95,10 @@ class RecsysPlugin extends Component {
this.player = player;
this.recsysEvents = [];
this.loadedAt = Date.now();
this.lastTimeUpdate = null;
this.currentTimeUpdate = null;
this.loadedAt = Date.now();
this.playInitiated = false;
this.inPause = false;
// Plugin event listeners
player.on('playing', (event) => this.onPlay(event));
@ -113,83 +113,13 @@ class RecsysPlugin extends Component {
}
addRecsysEvent(recsysEvent) {
if (!this.playInitiated) {
switch (recsysEvent.event) {
case RecsysData.event.start:
this.playInitiated = true;
break;
case RecsysData.event.scrub:
// If playback hasn't started, swallow scrub events. They offer some
// information, but if there isn't a subsequent play event, it's
// mostly nonsensical.
return undefined;
case RecsysData.event.stop:
// If playback hasn't started, swallow stop events. This means
// you're going to start from an offset but the start event
// captures that information. (With the ambiguity that you can't
// tell if they scrubbed, landed at the offset, or restarted. But
// I don't think that matters much.)
return undefined;
case RecsysData.event.speed:
if (this.recsysEvents.length > 0 && this.recsysEvents[0].event === RecsysData.event.speed) {
// video.js will sometimes fire the default play speed followed by the
// user preference. This is not useful information so we can keep the latter.
this.recsysEvents.pop();
}
}
} else {
const lastEvent = this.recsysEvents[this.recsysEvents.length - 1];
switch (recsysEvent.event) {
case RecsysData.event.scrub:
if (lastEvent.event === RecsysData.event.stop) {
// Video.js fires a stop before the seek. This extra information isn't
// useful to log though, so this code prunes the stop event if it was
// within 0.25 seconds.
if (Math.abs(lastEvent.offset - recsysEvent.offset) < 0.25) {
this.recsysEvents.pop();
recsysEvent.offset = lastEvent.arg;
}
} else if (lastEvent.event === RecsysData.event.start) {
// If the last event was a play and this event is a scrub close to
// that play position, I think it's just a weird emit order for
// video.js and we don't need to log the scrub.
if (Math.abs(lastEvent.offset - recsysEvent.arg) < 0.25) {
return undefined;
}
}
break;
case RecsysData.event.start:
if (lastEvent.event === RecsysData.event.scrub) {
// If the last event was a seek and this is a play,
// it's reasonable to just implicitly assume the play occurred,
// no need to create the play event.
return undefined;
} else if (lastEvent.event === RecsysData.event.start) {
// A start followed by a start is a buffering event.
// It may make sense to keep these. A user may abandon
// a page *not because it's bad content but because
// there are network troubles right now*.
}
break;
}
}
// For now, don't do client-side preprocessing. I think there
// are browser inconsistencies and preprocessing loses too much info.
this.recsysEvents.push(recsysEvent);
}
getRecsysEvents() {
return this.recsysEvents.map((event) => {
if (event !== RecsysData.event.stop) {
return event;
}
// I used the arg in stop events to smuggle the seek time into
// the scrub events. But the backend doesn't expect it.
const dup = { ...event };
delete dup.arg;
return dup;
});
return this.recsysEvents;
}
sendRecsysEvents() {
@ -207,16 +137,17 @@ class RecsysPlugin extends Component {
const recsysEvent = newRecsysEvent(RecsysData.event.start, this.player.currentTime());
this.log('onPlay', recsysEvent);
this.addRecsysEvent(recsysEvent);
this.inPause = false;
this.lastTimeUpdate = recsysEvent.offset;
}
onPause(event) {
// The API doesn't want an `arg` for `STOP` events. However, video.js
// emits these before the seek events, and that seems to be the easiest
// way to lift time you are seeking from into the scrub record (via lastTimeUpdate).
// Hacky, but works.
const recsysEvent = newRecsysEvent(RecsysData.event.stop, this.player.currentTime(), this.lastTimeUpdate);
const recsysEvent = newRecsysEvent(RecsysData.event.stop, this.player.currentTime());
this.log('onPause', recsysEvent);
this.addRecsysEvent(recsysEvent);
this.inPause = true;
}
onEnded(event) {
@ -226,26 +157,50 @@ class RecsysPlugin extends Component {
}
onRateChange(event) {
// This is actually a bug. The offset should be the offset. The change speed should be change speed.
// Otherise, you don't know where it changed and the time calc is wrong.
const recsysEvent = newRecsysEvent(RecsysData.event.speed, this.player.currentTime(), this.player.playbackRate());
this.log('onRateChange', recsysEvent);
this.addRecsysEvent(recsysEvent);
}
onTimeUpdate(event) {
this.lastTimeUpdate = this.currentTimeUpdate;
this.currentTimeUpdate = this.player.currentTime();
const nextCurrentTime = this.player.currentTime();
if (!this.inPause && Math.abs(this.lastTimeUpdate - nextCurrentTime) < 0.5) {
// Don't update lastTimeUpdate if we are in a pause segment.
//
// However, if we aren't in a pause and the time jumped
// the onTimeUpdate event probably fired before the pause and seek.
// Don't update in that case, either.
this.lastTimeUpdate = this.currentTimeUpdate;
}
this.currentTimeUpdate = nextCurrentTime;
}
onSeeked(event) {
// The problem? `lastTimeUpdate` is wrong.
// So every seeks l
const curTime = this.player.currentTime();
// If the immediately prior event is a pause?
const recsysEvent = newRecsysEvent(RecsysData.event.scrub, this.lastTimeUpdate, this.player.currentTime());
this.log('onSeeked', recsysEvent);
this.addRecsysEvent(recsysEvent);
// There are three patterns for seeking:
//
// Assuming the video is playing,
//
// 1. Dragging the player head emits: onPause -> onSeeked -> onSeeked -> ... -> onPlay
// 2. Key press left right emits: onSeeked -> onPlay
// 3. Clicking a position emits: onPause -> onSeeked -> onPlay
//
// If the video is NOT playing,
//
// 1. Dragging the player head emits: onSeeked
// 2. Key press left right emits: onSeeked
// 3. Clicking a position emits: onSeeked
const fromTime = this.lastTimeUpdate;
if (fromTime !== curTime) {
// This removes duplicates that aren't useful.
const recsysEvent = newRecsysEvent(RecsysData.event.scrub, fromTime, curTime);
this.log('onSeeked', recsysEvent);
this.addRecsysEvent(recsysEvent);
}
}
onDispose(event) {

View file

@ -56,14 +56,14 @@ type Props = {
userId: ?number,
};
type VideoJSOptions = {
controls: boolean,
preload: string,
playbackRates: Array<number>,
responsive: boolean,
poster?: string,
muted?: boolean,
};
// type VideoJSOptions = {
// controls: boolean,
// preload: string,
// playbackRates: Array<number>,
// responsive: boolean,
// poster?: string,
// muted?: boolean,
// };
const videoPlaybackRates = [0.25, 0.5, 0.75, 1, 1.1, 1.25, 1.5, 1.75, 2];
@ -72,7 +72,7 @@ const IS_IOS =
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
!window.MSStream;
const VIDEO_JS_OPTIONS: VideoJSOptions = {
const VIDEO_JS_OPTIONS = {
preload: 'auto',
playbackRates: videoPlaybackRates,
responsive: true,

View file

@ -180,7 +180,7 @@ function VideoViewer(props: Props) {
}
}, [embedded, setIsEndededEmbed, autoplaySetting, setShowAutoplayCountdown, adUrl, setAdUrl]);
function onPlay(player) {
function onPlay() {
setIsLoading(false);
setIsPlaying(true);
setShowAutoplayCountdown(false);
@ -233,14 +233,19 @@ function VideoViewer(props: Props) {
Promise.race([playPromise, timeoutPromise]).catch((error) => {
if (typeof error === 'object' && error.name && error.name === 'NotAllowedError') {
// Autoplay disallowed by browser
player.play();
if (player.autoplay() && !player.muted()) {
player.muted(true);
// another version had player.play()
}
}
// Autoplay failed
if (PLAY_TIMEOUT_ERROR) {
setIsLoading(false);
setIsPlaying(false);
const retryPlayPromise = player.play();
Promise.race([retryPlayPromise, timeoutPromise]).catch((error) => {
setIsLoading(false);
setIsPlaying(false);
});
} else {
setIsLoading(false);
setIsPlaying(false);
@ -259,10 +264,9 @@ function VideoViewer(props: Props) {
player.on('tracking:buffered', doTrackingBuffered);
player.on('tracking:firstplay', doTrackingFirstPlay);
player.on('ended', onEnded);
player.on('play', () => onPlay(player));
player.on('pause', () => onPause(player));
player.on('dispose', () => onDispose(player));
player.on('play', onPlay);
player.on('pause', onPause);
player.on('dispose', onDispose);
player.on('error', () => {
const error = player.error();
if (error) {

View file

@ -21,7 +21,9 @@ export default function WebUploadList(props: Props) {
!!uploadCount && (
<Card
title={__('Currently uploading')}
subtitle={uploadCount > 1 ? __('You files are currently uploading.') : __('Your file is currently uploading.')}
subtitle={
uploadCount > 1 ? __('You videos are currently uploading.') : __('Your video is currently uploading.')
}
body={
<section>
{/* $FlowFixMe */}

View file

@ -118,9 +118,7 @@ export default function YoutubeTransferStatus(props: Props) {
{isNotElligible && (
<I18nMessage
tokens={{
here: (
<Button button="link" href="https://lbry.com/faq/youtube" label={__('here')} />
),
here: <Button button="link" href="https://lbry.com/faq/youtube" label={__('here')} />,
email: SITE_HELP_EMAIL,
}}
>

View file

@ -1,6 +1,6 @@
export const FF_MAX_CHARS_DEFAULT = 2000;
export const FF_MAX_CHARS_IN_COMMENT = 2000;
export const FF_MAX_CHARS_IN_LIVESTREAM_COMMENT = 500;
export const FF_MAX_CHARS_IN_LIVESTREAM_COMMENT = 300;
export const FF_MAX_CHARS_IN_DESCRIPTION = 5000;
export const FF_MAX_CHARS_REPORT_CONTENT_DETAILS = 500;
export const FF_MAX_CHARS_REPORT_CONTENT_ADDRESS = 255;

View file

@ -44,8 +44,9 @@ class ModalPublishSuccess extends React.PureComponent<Props> {
'Your livestream is now pending. You will be able to start shortly at the streaming dashboard.'
);
} else {
publishMessage = __('Your file is now pending on LBRY. It will take a few minutes to appear for other users.');
publishMessage = __('Your video will appear on Odysee shortly.');
}
clearPublish();
function handleClose() {
closeModal();
@ -54,7 +55,7 @@ class ModalPublishSuccess extends React.PureComponent<Props> {
return (
<Modal isOpen type="card" contentLabel={__(contentLabel)} onAborted={handleClose}>
<Card
title={__('Success')}
title={livestream ? __('Livestream Created') : __('Upload Complete')}
subtitle={publishMessage}
body={
<React.Fragment>

View file

@ -8,6 +8,7 @@ import {
selectMyChannelClaims,
makeSelectClaimIsStreamPlaceholder,
SETTINGS,
doClearPublish,
} from 'lbry-redux';
import { selectFfmpegStatus, makeSelectClientSetting } from 'redux/selectors/settings';
import { doPublishDesktop } from 'redux/actions/publish';
@ -32,6 +33,7 @@ const select = (state, props) => {
const perform = (dispatch) => ({
publish: (filePath, preview) => dispatch(doPublishDesktop(filePath, preview)),
clearPublish: () => dispatch(doClearPublish()),
closeModal: () => dispatch(doHideModal()),
setEnablePublishPreview: (value) => dispatch(doSetClientSetting(SETTINGS.ENABLE_PUBLISH_PREVIEW, value)),
});

View file

@ -53,7 +53,7 @@ function ModalRemoveFile(props: Props) {
name="claim_abandon"
label={
<I18nMessage
tokens={{ lbc: <LbcSymbol prefix={__('reclaim %amount%', { amount: claim.amount })} /> }}
tokens={{ lbc: <LbcSymbol postfix={claim.amount} /> }}
>
Remove from blockchain (%lbc%)
</I18nMessage>

View file

@ -12,7 +12,7 @@ class ModalTransactionFailed extends React.PureComponent<Props> {
return (
<Modal isOpen contentLabel={__('Transaction failed')} title={__('Transaction failed')} onConfirmed={closeModal}>
<p>{__('Sorry about that. Contact help@lbry.com if you continue to have issues.')}</p>
<p>{__('Sorry about that. Contact help@odysee.com if you continue to have issues.')}</p>
</Modal>
);
}

View file

@ -1,4 +1,5 @@
// @flow
import { SIMPLE_SITE } from 'config';
import * as PAGES from 'constants/pages';
import React from 'react';
import { Modal } from 'modal/modal';
@ -15,18 +16,27 @@ const YoutubeWelcome = (props: Props) => {
<Modal isOpen type="card" onAborted={doHideModal}>
<Confetti recycle={false} style={{ position: 'fixed' }} numberOfPieces={100} />
<Card
title={__("You're free!")}
title={!SIMPLE_SITE ? __("You're free!") : __('Welcome to Odysee')}
subtitle={
<React.Fragment>
<p>
{__("You've escaped the land of spying, censorship, and exploitation.")}
<span className="emoji"> 💩</span>
</p>
<p>
{__('Welcome to the land of content freedom.')}
<span className="emoji"> 🌈</span>
</p>
</React.Fragment>
!SIMPLE_SITE ? (
<React.Fragment>
<p>
{__("You've escaped the land of spying, censorship, and exploitation.")}
<span className="emoji"> 💩</span>
</p>
<p>
{__('Welcome to the land of content freedom.')}
<span className="emoji"> 🌈</span>
</p>
</React.Fragment>
) : (
<React.Fragment>
<p>
{__('You make the party extra special!')}
<span className="emoji"> 💖</span>
</p>
</React.Fragment>
)
}
actions={
<div className="card__actions">

12
ui/page/adsTest/index.js Normal file
View file

@ -0,0 +1,12 @@
import { connect } from 'react-redux';
import { makeSelectClaimForUri, doResolveUri } from 'lbry-redux';
import AdsTestPage from './view';
export default connect(
(state) => ({
claim: makeSelectClaimForUri('lbry://fullscreenrelease#7')(state),
}),
{
doResolveUri,
}
)(AdsTestPage);

20
ui/page/adsTest/view.jsx Normal file
View file

@ -0,0 +1,20 @@
// @flow
// import React from 'react';
// import FilePage from 'page/file';
type Props = {
doResolveUri: (string) => void,
claim: ?StreamClaim,
};
export default function AdsTestPage(props: Props) {
return null;
// const { doResolveUri, claim } = props;
// const hasClaim = claim !== undefined;
// React.useEffect(() => {
// if (!hasClaim) {
// doResolveUri('lbry://fullscreenrelease#7');
// }
// }, [hasClaim, doResolveUri]);
// return <div>{hasClaim && <FilePage uri="lbry://fullscreenrelease#7" />}</div>;
}

View file

@ -1,13 +1,12 @@
// @flow
import * as ICONS from 'constants/icons';
import * as PAGES from 'constants/pages';
// import * as ICONS from 'constants/icons';
// import * as PAGES from 'constants/pages';
import * as CS from 'constants/claim_search';
import React from 'react';
import Page from 'component/page';
import Button from 'component/button';
import ClaimTilesDiscover from 'component/claimTilesDiscover';
// import Button from 'component/button';
import ClaimListDiscover from 'component/claimListDiscover';
import * as CS from 'constants/claim_search';
import { toCapitalCase } from 'util/string';
// import { toCapitalCase } from 'util/string';
import { SIMPLE_SITE } from 'config';
const MORE_CHANNELS_ANCHOR = 'MoreChannels';
@ -19,89 +18,87 @@ type Props = {
homepageData: any,
};
type ChannelsFollowingItem = {
title: string,
link?: string,
help?: any,
options?: {},
};
function ChannelsFollowingDiscover(props: Props) {
const { followedTags, subscribedChannels, blockedChannels, homepageData } = props;
const {
// followedTags,
// subscribedChannels,
// blockedChannels,
homepageData,
} = props;
const { PRIMARY_CONTENT_CHANNEL_IDS } = homepageData;
let rowData: Array<ChannelsFollowingItem> = [];
const notChannels = subscribedChannels
.map(({ uri }) => uri)
.concat(blockedChannels)
.map(uri => uri.split('#')[1]);
// let rowData: Array<ChannelsFollowingItem> = [];
// const notChannels = subscribedChannels
// .map(({ uri }) => uri)
// .concat(blockedChannels)
// .map(uri => uri.split('#')[1]);
rowData.push({
title: 'Top Channels Of All Time',
link: `/$/${PAGES.DISCOVER}?claim_type=channel&${CS.ORDER_BY_KEY}=${CS.ORDER_BY_TOP}&${CS.FRESH_KEY}=${CS.FRESH_ALL}`,
options: {
pageSize: 12,
claimType: 'channel',
orderBy: ['effective_amount'],
},
});
// rowData.push({
// title: 'Top Channels Of All Time',
// link: `/$/${PAGES.DISCOVER}?claim_type=channel&${CS.ORDER_BY_KEY}=${CS.ORDER_BY_TOP}&${CS.FRESH_KEY}=${CS.FRESH_ALL}`,
// options: {
// pageSize: 12,
// claimType: 'channel',
// orderBy: ['effective_amount'],
// },
// });
rowData.push({
title: 'Latest From @lbrycast',
link: `/@lbrycast:4`,
options: {
orderBy: ['release_time'],
pageSize: 8,
channelIds: ['4c29f8b013adea4d5cca1861fb2161d5089613ea'],
},
});
// rowData.push({
// title: 'Latest From @lbrycast',
// link: `/@lbrycast:4`,
// options: {
// orderBy: ['release_time'],
// pageSize: 8,
// channelIds: ['4c29f8b013adea4d5cca1861fb2161d5089613ea'],
// },
// });
rowData.push({
title: 'Trending Channels',
link: `/$/${PAGES.DISCOVER}?claim_type=channel`,
options: {
pageSize: 8,
claimType: 'channel',
orderBy: ['trending_group', 'trending_mixed'],
},
});
// rowData.push({
// title: 'Trending Channels',
// link: `/$/${PAGES.DISCOVER}?claim_type=channel`,
// options: {
// pageSize: 8,
// claimType: 'channel',
// orderBy: ['trending_group', 'trending_mixed'],
// },
// });
if (followedTags.length > 0 && followedTags.length < 5) {
const followedRows = followedTags.map((tag: Tag) => ({
title: `Trending Channels for #${toCapitalCase(tag.name)}`,
link: `/$/${PAGES.DISCOVER}?t=${tag.name}&claim_type=channel`,
options: {
claimType: 'channel',
pageSize: 4,
tags: [tag.name],
},
}));
rowData.push(...followedRows);
}
// if (followedTags.length > 0 && followedTags.length < 5) {
// const followedRows = followedTags.map((tag: Tag) => ({
// title: `Trending Channels for #${toCapitalCase(tag.name)}`,
// link: `/$/${PAGES.DISCOVER}?t=${tag.name}&claim_type=channel`,
// options: {
// claimType: 'channel',
// pageSize: 4,
// tags: [tag.name],
// },
// }));
// rowData.push(...followedRows);
// }
if (followedTags.length > 4) {
rowData.push({
title: 'Trending For Your Tags',
link: `/$/${PAGES.TAGS_FOLLOWING}?claim_type=channel`,
options: {
claimType: 'channel',
tags: followedTags.map(tag => tag.name),
},
});
}
// if (followedTags.length > 4) {
// rowData.push({
// title: 'Trending For Your Tags',
// link: `/$/${PAGES.TAGS_FOLLOWING}?claim_type=channel`,
// options: {
// claimType: 'channel',
// tags: followedTags.map(tag => tag.name),
// },
// });
// }
const rowDataWithGenericOptions = rowData.map(row => {
return {
...row,
options: {
...row.options,
notChannels,
},
};
});
// const rowDataWithGenericOptions = rowData.map(row => {
// return {
// ...row,
// options: {
// ...row.options,
// notChannels,
// },
// };
// });
return (
<Page>
{rowDataWithGenericOptions.map(({ title, link, help, options = {} }) => (
{/* {rowDataWithGenericOptions.map(({ title, link, help, options = {} }) => (
<div key={title} className="claim-grid__wrapper">
<h1 className="section__actions">
{link ? (
@ -120,17 +117,17 @@ function ChannelsFollowingDiscover(props: Props) {
<ClaimTilesDiscover {...options} />
</div>
))}
<h1 id={MORE_CHANNELS_ANCHOR} className="claim-grid__title">
{__('More Channels')}
</h1>
{/* odysee: claimIds = PRIMARY_CONTENT_CHANNEL_IDS if simplesite CLD */}
))} */}
<ClaimListDiscover
defaultOrderBy={CS.ORDER_BY_TRENDING}
defaultFreshness={CS.FRESH_ALL}
claimType={CS.CLAIM_CHANNEL}
claimIds={SIMPLE_SITE ? PRIMARY_CONTENT_CHANNEL_IDS : undefined}
scrollAnchor={MORE_CHANNELS_ANCHOR}
maxPages={3}
hideFilters
header={<h1 className="section__title">{__('Moon cheese is an acquired taste')}</h1>}
/>
</Page>
);

View file

@ -2,6 +2,7 @@
import { SHOW_ADS, DOMAIN, SIMPLE_SITE, ENABLE_NO_SOURCE_CLAIMS } from 'config';
import * as ICONS from 'constants/icons';
import * as PAGES from 'constants/pages';
import * as CS from 'constants/claim_search';
import React, { useRef } from 'react';
import Page from 'component/page';
import ClaimListDiscover from 'component/claimListDiscover';
@ -11,11 +12,11 @@ import { useIsMobile } from 'effects/use-screensize';
import analytics from 'analytics';
import HiddenNsfw from 'component/common/hidden-nsfw';
import Icon from 'component/common/icon';
import * as CS from 'constants/claim_search';
import Ads from 'web/component/ads';
import LbcSymbol from 'component/common/lbc-symbol';
import I18nMessage from 'component/i18nMessage';
import useGetLivestreams from 'effects/use-get-livestreams';
import moment from 'moment';
type Props = {
location: { search: string },
@ -97,8 +98,8 @@ function DiscoverPage(props: Props) {
} else {
headerLabel = (
<span>
<Icon icon={(dynamicRouteProps && dynamicRouteProps.icon) || ICONS.DISCOVER} size={10} />
{(dynamicRouteProps && dynamicRouteProps.title) || __('All Content')}
<Icon icon={(dynamicRouteProps && dynamicRouteProps.icon) || ICONS.WILD_WEST} size={10} />
{(dynamicRouteProps && dynamicRouteProps.title) || __('Wild West')}
</span>
);
}
@ -106,9 +107,11 @@ function DiscoverPage(props: Props) {
return (
<Page noFooter fullWidthPage={tileLayout}>
<ClaimListDiscover
limitClaimsPerChannel={3}
hideAdvancedFilter
hideFilters={!dynamicRouteProps}
header={repostedUri ? <span /> : undefined}
tileLayout={repostedUri ? false : tileLayout}
defaultOrderBy={dynamicRouteProps ? undefined : CS.ORDER_BY_TRENDING}
claimType={claimType ? [claimType] : undefined}
headerLabel={headerLabel}
tags={tags}
@ -117,9 +120,18 @@ function DiscoverPage(props: Props) {
injectedItem={
SHOW_ADS && IS_WEB ? (SIMPLE_SITE ? false : !isAuthenticated && <Ads small type={'video'} />) : false
}
// Assume wild west page if no dynamicRouteProps
// Not a very good solution, but just doing it for now
// until we are sure this page will stay around
releaseTime={!dynamicRouteProps && `>${Math.floor(moment().subtract(1, 'day').startOf('week').unix())}`}
feeAmount={!dynamicRouteProps && CS.FEE_AMOUNT_ANY}
channelIds={
(dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.channelIds) || undefined
}
limitClaimsPerChannel={
(dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.limitClaimsPerChannel) ||
undefined
}
meta={
!dynamicRouteProps ? (
<a

View file

@ -1,4 +1,5 @@
// @flow
import * as PAGES from 'constants/pages';
import * as React from 'react';
import classnames from 'classnames';
import { lazyImport } from 'util/lazyImport';
@ -11,6 +12,9 @@ import FileRenderDownload from 'component/fileRenderDownload';
import RecommendedContent from 'component/recommendedContent';
import CollectionContent from 'component/collectionContentSidebar';
import CommentsList from 'component/commentsList';
import { Redirect } from 'react-router';
import Button from 'component/button';
import I18nMessage from 'component/i18nMessage';
import Empty from 'component/common/empty';
const PostViewer = lazyImport(() => import('component/postViewer' /* webpackChunkName: "postViewer" */));
@ -32,7 +36,9 @@ type Props = {
collection?: Collection,
collectionId: string,
videoTheaterMode: boolean,
claimIsMine: boolean,
commentsDisabled: boolean,
isLivestream: boolean,
};
function FilePage(props: Props) {
@ -49,9 +55,12 @@ function FilePage(props: Props) {
linkedComment,
setPrimaryUri,
videoTheaterMode,
claimIsMine,
commentsDisabled,
collection,
collectionId,
isLivestream,
} = props;
const cost = costInfo ? costInfo.cost : null;
const hasFileInfo = fileInfo !== undefined;
@ -124,6 +133,10 @@ function FilePage(props: Props) {
);
}
if (!claimIsMine && isLivestream) {
return <Redirect to={`/$/${PAGES.LIVESTREAM}`} />;
}
if (obscureNsfw && isMature) {
return (
<Page className="file-page" filePage isMarkdown={isMarkdown}>
@ -144,6 +157,18 @@ function FilePage(props: Props) {
{!isMarkdown && (
<div className="file-page__secondary-content">
<div>
{claimIsMine && isLivestream && (
<div className="livestream__creator-message">
<h4>{__('Only visible to you')}</h4>
<I18nMessage>
People who view this link will be redirected to your livestream. Make sure to use this for sharing
so your title and thumbnail are displayed properly.
</I18nMessage>
<div className="section__actions">
<Button button="primary" navigate={`/$/${PAGES.LIVESTREAM}`} label={__('View livestream')} />
</div>
</div>
)}
{RENDER_MODES.FLOATING_MODES.includes(renderMode) && <FileTitleSection uri={uri} />}
{commentsDisabled && <Empty text={__('The creator of this content has disabled comments.')} />}
{!commentsDisabled && <CommentsList uri={uri} linkedComment={linkedComment} />}

View file

@ -134,6 +134,13 @@ function HomePage(props: Props) {
</p>
</div>
)}
<h1 className="home__meme">
<Button button="link" href="https://odysee.com/@Odysee:8?view=discussion">
{'i caught you a delicious bass'}
</Button>
</h1>
{rowData.map(({ title, route, link, icon, help, options = {} }, index) => {
return getRowElements(title, route, link, icon, help, options, index);
})}

View file

@ -14,12 +14,12 @@ import { selectUserVerifiedEmail } from 'redux/selectors/user';
import SearchPage from './view';
const select = (state, props) => {
const showMature = selectShowMatureContent(state);
const urlParams = new URLSearchParams(props.location.search);
let urlQuery = urlParams.get('q') || null;
if (urlQuery) {
urlQuery = urlQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' ');
}
const showMature = selectShowMatureContent(state);
const query = makeSelectQueryWithOptions(
urlQuery,
SIMPLE_SITE

View file

@ -1,6 +1,6 @@
// @flow
import * as PAGES from 'constants/pages';
import * as MODALS from 'constants/modal_types';
// import * as MODALS from 'constants/modal_types';
import * as ICONS from 'constants/icons';
import * as React from 'react';
import { SETTINGS } from 'lbry-redux';
@ -17,7 +17,7 @@ import classnames from 'classnames';
import { getPasswordFromCookie } from 'util/saved-passwords';
// $FlowFixMe
import homepages from 'homepages';
import { Lbryio } from 'lbryinc';
// import { Lbryio } from 'lbryinc';
import Yrbl from 'component/yrbl';
type Price = {
@ -170,7 +170,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
const {
daemonSettings,
allowAnalytics,
showNsfw,
// showNsfw,
isAuthenticated,
currentTheme,
themes,
@ -183,12 +183,12 @@ class SettingsPage extends React.PureComponent<Props, State> {
setClientSetting,
toggle3PAnalytics,
floatingPlayer,
hideReposts,
// hideReposts,
clearPlayingUri,
darkModeTimes,
clearCache,
openModal,
myChannelUrls,
// openModal,
} = this.props;
const { storedPassword } = this.state;
const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0;
@ -206,6 +206,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
className="card-stack"
>
{/* @if TARGET='web' */}
{isAuthenticated &&
<Card
title={__('Add card to tip creators in USD')}
actions={
@ -219,6 +220,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
</div>
}
/>
}
{/* @endif */}
<Card title={__('Language')} actions={<SettingLanguage />} />
@ -374,7 +376,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
)}
/>
<FormField
{/* <FormField
type="checkbox"
name="hide_reposts"
onChange={(e) => {
@ -388,7 +390,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
checked={hideReposts}
label={__('Hide reposts')}
helper={__('You will not see reposts by people you follow or receive email notifying about them.')}
/>
/> */}
{/* <FormField
type="checkbox"
@ -399,7 +401,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
helper={__('Anonymous content is published without a channel.')}
/> */}
<FormField
{/* <FormField
type="checkbox"
name="show_nsfw"
onChange={() =>
@ -412,7 +414,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
helper={__(
'Mature content may include nudity, intense sexuality, profanity, or other adult content. By displaying mature content, you are affirming you are of legal age to view mature content in your country or jurisdiction. '
)}
/>
/> */}
</React.Fragment>
}
/>

View file

@ -1,5 +1,6 @@
// @flow
import * as ACTIONS from 'constants/action_types';
import { SEARCH_OPTIONS } from 'constants/search';
import { buildURI, doResolveUris, batchActions, isURIValid, makeSelectClaimForUri } from 'lbry-redux';
import {
makeSelectSearchUris,
@ -135,6 +136,10 @@ export const doFetchRecommendedContent = (uri: string, mature: boolean) => (disp
if (!mature) {
options['nsfw'] = false;
}
options[SEARCH_OPTIONS.CLAIM_TYPE] = SEARCH_OPTIONS.INCLUDE_FILES;
options[SEARCH_OPTIONS.MEDIA_VIDEO] = true;
const { title } = claim.value;
if (title && options) {
dispatch(doSearch(title, options));

View file

@ -11,9 +11,9 @@ const defaultState: SearchState = {
[SEARCH_OPTIONS.CLAIM_TYPE]: SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS,
[SEARCH_OPTIONS.MEDIA_AUDIO]: true,
[SEARCH_OPTIONS.MEDIA_VIDEO]: true,
[SEARCH_OPTIONS.MEDIA_TEXT]: true,
[SEARCH_OPTIONS.MEDIA_IMAGE]: true,
[SEARCH_OPTIONS.MEDIA_APPLICATION]: true,
[SEARCH_OPTIONS.MEDIA_TEXT]: false,
[SEARCH_OPTIONS.MEDIA_IMAGE]: false,
[SEARCH_OPTIONS.MEDIA_APPLICATION]: false,
},
urisByQuery: {},
hasReachedMaxResultsLength: {},

View file

@ -8,7 +8,7 @@ import { UNSYNCED_SETTINGS } from 'config';
const { CLIENT_SYNC_KEYS } = SHARED_PREFERENCES;
const settingsToIgnore = (UNSYNCED_SETTINGS && UNSYNCED_SETTINGS.trim().split(' ')) || [];
const clientSyncKeys = settingsToIgnore.length
? CLIENT_SYNC_KEYS.filter(k => !settingsToIgnore.includes(k))
? CLIENT_SYNC_KEYS.filter((k) => !settingsToIgnore.includes(k))
: CLIENT_SYNC_KEYS;
const reducers = {};
@ -70,7 +70,7 @@ const defaultState = {
[SETTINGS.AUTOPLAY_NEXT]: true,
[SETTINGS.FLOATING_PLAYER]: true,
[SETTINGS.AUTO_DOWNLOAD]: true,
[SETTINGS.HIDE_REPOSTS]: false,
[SETTINGS.HIDE_REPOSTS]: true,
// OS
[SETTINGS.AUTO_LAUNCH]: true,
@ -89,12 +89,12 @@ reducers[ACTIONS.REHYDRATE] = (state, action) => {
return Object.assign({}, state, { clientSettings });
};
reducers[ACTIONS.FINDING_FFMPEG_STARTED] = state =>
reducers[ACTIONS.FINDING_FFMPEG_STARTED] = (state) =>
Object.assign({}, state, {
findingFFmpeg: true,
});
reducers[ACTIONS.FINDING_FFMPEG_COMPLETED] = state =>
reducers[ACTIONS.FINDING_FFMPEG_COMPLETED] = (state) =>
Object.assign({}, state, {
findingFFmpeg: false,
});
@ -120,7 +120,7 @@ reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => {
});
};
reducers[ACTIONS.UPDATE_IS_NIGHT] = state => {
reducers[ACTIONS.UPDATE_IS_NIGHT] = (state) => {
const { from, to } = state.clientSettings[SETTINGS.DARK_MODE_TIMES];
const momentNow = moment();
const startNightMoment = moment(from.formattedTime, 'HH:mm');
@ -155,7 +155,7 @@ reducers[LBRY_REDUX_ACTIONS.SHARED_PREFERENCE_SET] = (state, action) => {
});
};
reducers[ACTIONS.SYNC_CLIENT_SETTINGS] = state => {
reducers[ACTIONS.SYNC_CLIENT_SETTINGS] = (state) => {
const { clientSettings } = state;
const sharedPreferences = Object.assign({}, state.sharedPreferences);
const selectedClientSettings = getSubsetFromKeysArray(clientSettings, clientSyncKeys);

View file

@ -620,6 +620,12 @@ svg + .button__label {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.button--file-action {
&:first-child {
margin-right: var(--spacing-s);
}
}
}
.button--file-action {

View file

@ -221,13 +221,28 @@
}
.file-viewer__overlay-logo {
color: var(--color-white);
font-weight: bold;
height: 3.5rem;
width: 12rem;
display: flex;
align-items: center;
.icon {
height: 30px;
stroke-width: 5px;
&:hover {
filter: drop-shadow(1px 2px 10px var(--color-gray-3));
}
@media (max-width: $breakpoint-small) {
margin-right: var(--spacing-m);
width: 2.5rem;
.button__label {
display: none;
}
}
}
.file-viewer__overlay-logo--videoend {
height: 3.5rem;
width: 12rem;
}
.file-viewer--is-playing:not(:hover) .file-viewer__embedded-header {
@ -237,11 +252,15 @@
.file-viewer__embedded-header {
position: absolute;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
top: 0;
opacity: 1;
z-index: 2;
height: 4rem;
padding-left: var(--spacing-m);
padding-right: var(--spacing-s);
font-size: var(--font-large);
overflow-x: hidden;
overflow-y: hidden;
@ -251,7 +270,6 @@
border-top-right-radius: var(--border-radius);
.button {
padding: var(--spacing-s);
color: var(--color-white);
z-index: 2;

View file

@ -203,7 +203,7 @@ input-submit {
height: var(--height-checkbox);
width: var(--height-checkbox);
border: 1px solid var(--color-input-border);
border-radius: var(--border-radius);
border-radius: 3px;
left: 0px;
top: -1px;
}

View file

@ -58,7 +58,6 @@
justify-content: center;
align-items: center;
border-radius: var(--border-radius);
color: var(--color-text);
position: relative;
font-weight: var(--font-weight-bold);

View file

@ -281,8 +281,8 @@ $discussion-header__height: 3rem;
}
.livestream-superchat__banner {
border-top-right-radius: var(--border-radius);
border-bottom-right-radius: var(--border-radius);
border-top-left-radius: 0;
border-bottom-left-radius: 0;
padding: 0.25rem var(--spacing-s);
display: inline-block;
position: relative;
@ -298,7 +298,7 @@ $discussion-header__height: 3rem;
background-color: var(--color-superchat);
bottom: 0;
left: 0;
transform: translateX(25%) translateY(50%);
transform: translateX(0) translateY(50%);
&::after {
content: '';
@ -316,6 +316,11 @@ $discussion-header__height: 3rem;
.livestream-comment__text {
padding-right: var(--spacing-xxs);
padding-bottom: var(--spacing-xxs);
.markdown-preview {
p {
word-break: break-all;
}
}
}
.livestream-superchat__tooltip-amount {

View file

@ -39,6 +39,10 @@
overflow-y: auto;
}
}
@media (min-width: $breakpoint-small) {
justify-content: space-between;
}
}
.navigation--mac {

View file

@ -58,7 +58,7 @@
.section__title {
text-align: left;
font-size: var(--font-title);
font-size: var(--font-large);
font-weight: var(--font-weight-light);
}

View file

@ -1,57 +0,0 @@
:root {
// Generic colors
--color-primary: #257761;
--color-primary-alt: #e4f4ef;
--color-primary-alt-2: #4b8576;
--color-secondary: #295284;
--color-secondary-alt: #d9eaff;
--color-tertiary: #552470;
--color-tertiary-alt: #f7e8ff;
--color-danger: #9b2023;
--color-danger-alt: #fccdce;
--color-warning: #fff58c;
--color-cost: #ffd580;
--color-focus: #93cff2;
--color-notification: #f02849;
--color-live: #cc190f;
--color-black: #111;
--color-white: #fdfdfd;
--color-white-alt: #fafafa;
--color-gray-1: #eff1f4;
--color-gray-2: #d8dde1;
--color-gray-3: #ced4da;
--color-gray-4: #abb1b7;
--color-gray-5: #666a6d;
// Text
--color-text: var(--color-black);
--color-text-subtitle: var(--color-gray-5);
--color-text-inverse: #fdfdfd;
// Components
// Button
--color-button-primary-bg: var(--color-primary);
--color-button-primary-text: var(--color-primary-alt);
--color-button-primary-bg-hover: var(--color-primary-alt-2);
--color-button-primary-hover-text: var(--color-primary-alt);
--color-button-secondary-bg: var(--color-secondary-alt);
--color-button-secondary-border: var(--color-secondary-alt);
--color-button-secondary-text: var(--color-secondary);
--color-button-secondary-bg-hover: #b9d0e9;
--color-button-alt-bg: var(--color-gray-1);
--color-button-alt-text: var(--color-text);
--color-button-alt-bg-hover: var(--color-gray-2);
--color-link: var(--color-primary);
--color-link-hover: var(--color-black);
// Table
--color-table-highlight: var(--color-white-alt);
// Tag
--color-tag: var(--color-gray-5);
--color-tag-bg: var(--color-button-alt-bg);
--color-tag-hover: var(--color-button-alt-text);
--color-tag-bg-hover: var(--color-button-alt-bg-hover);
}

View file

@ -60,8 +60,12 @@ ol {
position: relative;
list-style-position: outside;
margin: var(--spacing-xs) 0;
margin-left: var(--spacing-xl);
margin-left: var(--spacing-s);
margin-bottom: 0;
@media (min-width: $breakpoint-small) {
margin-left: var(--spacing-xl);
}
}
}
@ -267,10 +271,10 @@ textarea {
margin-top: var(--spacing-s);
&:not(:last-child) {
margin-bottom: var(--spacing-s);
margin-bottom: var(--spacing-m);
}
.button--link ~ .button--link {
.button--link + .button--link {
margin-left: var(--spacing-s);
}
@ -282,7 +286,6 @@ textarea {
.help--warning {
@extend .help;
padding: var(--spacing-s);
color: var(--color-black);
border-radius: var(--border-radius);
background-color: var(--color-help-warning-bg);
color: var(--color-help-warning-text);
@ -499,3 +502,16 @@ textarea {
height: 4rem;
}
}
.home__meme {
text-align: center;
font-weight: bold;
line-height: 1;
font-size: 1rem;
margin-bottom: var(--spacing-m);
@media (min-width: $breakpoint-small) {
font-size: 1.2rem;
margin-bottom: var(--spacing-l);
}
}

View file

@ -9,7 +9,7 @@ $breakpoint-medium: 1150px;
$breakpoint-large: 1600px;
:root {
--border-radius: 5px;
--border-radius: 10px;
--height-input: 2.5rem;
--height-button: 2.5rem;
--height-checkbox: 24px;

View file

@ -1,30 +1,30 @@
[theme='dark'] {
// Color overrides
--color-primary: #2bbb90;
--color-primary-alt: #3e675d;
--color-primary-alt-2: #065f46;
--color-primary-alt-3: #34e5b0;
--color-secondary: #204166;
--color-secondary-alt: #dbeafe;
--color-secondary-alt-2: #bfdbfe;
--color-secondary-alt-3: #2c5c8c;
--color-primary: #e50054;
--color-primary-alt: #66001880;
--color-fire: #ff6635;
--color-fire-outside: #ff9b20;
// Structure
--color-background: var(--color-gray-9);
--color-background-overlay: #21252999;
--color-border: #333338;
--color-card-background: var(--color-gray-8);
--color-card-background-highlighted: var(--color-gray-7);
--color-background: #140e1b;
--color-background-overlay: #0c0d0e95;
--color-border: #30243d;
--color-card-background: #181021;
--color-card-background-highlighted: #241c30;
// Text
--color-text: var(--color-white);
--color-text: var(--color-gray-1);
--color-text-subtitle: var(--color-gray-4);
--color-text-empty: var(--color-text-subtitle);
--color-text-help: #bbbbbb;
--color-text-warning: #212529;
--color-text-warning--background: var(--lbry-yellow-1);
--color-text-error: #f87171;
--color-error: #61373f;
--color-text-error: var(--color-danger);
--color-error: var(--color-danger-alt);
--color-blockquote: var(--color-gray-5);
--color-blockquote-bg: var(--color-card-background-highlighted);
--color-help-warning-text: var(--color-white-alt);
--color-help-warning-bg: #fbbf2450;
// Tags (words)
--color-tag-words: var(--color-text);
@ -33,87 +33,73 @@
--color-tag-words-bg-hover: var(--color-gray-4);
// Header
--color-header-background: var(--color-gray-8);
--color-header-button: var(--color-gray-6);
--color-header-button-hover: var(--color-gray-6);
--color-header-button-active: var(--color-gray-6);
--color-header-button: #38274c;
--color-header-background: #231830;
// Button
--color-button-primary-bg: var(--color-primary-alt);
--color-button-primary-bg-hover: var(--color-primary-alt-2);
--color-button-primary-text: var(--color-gray-2);
--color-button-primary-text: white;
--color-button-primary-hover-text: var(--color-primary-alt);
--color-button-secondary-bg: var(--color-secondary);
--color-button-secondary-border: var(--color-secondary);
--color-button-secondary-bg-hover: var(--color-secondary-alt-3);
--color-button-secondary-text: var(--color-gray-2);
--color-button-alt-bg: var(--color-gray-7);
--color-button-alt-bg-hover: var(--color-gray-6);
--color-button-alt-text: var(--color-gray-1);
--color-button-border: var(--color-gray-5);
--color-button-toggle-text: var(--color-gray-1);
--color-link: var(--color-primary-alt-3);
--color-link-hover: var(--color-text);
--color-link-focus-bg: var(--color-gray-7);
--color-button-secondary-bg: #2c1543;
--color-button-secondary-border: #4f1c82;
--color-button-secondary-bg-hover: #3b1c5b;
--color-button-secondary-text: #efefef;
--color-button-alt-bg: var(--color-header-button);
--color-button-alt-bg-hover: #2b2037;
--color-button-toggle-text: var(--color-text);
--color-button-toggle-bg: var(--color-primary-alt);
--color-button-toggle-bg-hover: var(--color-primary-alt);
--color-button-alt-text: #e2e9f0;
--color-button-border: #5b4475;
--color-link: var(--color-primary);
--color-link-hover: #d75673;
--color-link-active: #ec1d4c;
--color-link-focus-bg: #3d2d4e;
// Input
--color-input: var(--color-white);
--color-input-label: var(--color-gray-3);
--color-input-placeholder: var(--color-gray-1);
--color-input: #f4f4f5;
--color-input-label: #a7a7a7;
--color-input-placeholder: #f4f4f5;
--color-input-bg: var(--color-header-button);
--color-input-bg-copyable: var(--color-gray-6);
--color-input-bg-copyable: #4c3861;
--color-input-border: var(--color-border);
--color-input-border-active: var(--color-secondary);
--color-input-toggle: var(--color-primary-alt-3);
--color-input-toggle-bg: var(--color-input-bg);
--color-input-toggle-bg-hover: var(--color-secondary);
--color-input-bg-selected: var(--color-primary-alt);
--color-input-prefix-bg: var(--color-gray-5);
--color-input-prefix-bg: var(--color-input-bg-copyable);
--color-input-prefix-border: var(--color-gray-4);
--select-toggle-background: url("data:image/svg+xml,%3Csvg viewBox='0 0 96 96' xmlns='http://www.w3.org/2000/svg' fill='%23ffffff'%3E%3Cpath d='M17.172, 31.172c1.562, -1.562 4.095, -1.562 5.656, 0l25.172, 25.171l25.172, -25.171c1.562, -1.562 4.095, -1.562 5.656, 0c1.562, 1.562 1.562, 4.095 0, 5.656l-28, 28c-1.562, 1.562 -4.095, 1.562 -5.656, 0l-28, -28c-0.781, -0.781 -1.172, -1.805 -1.172, -2.828c0, -1.023 0.391, -2.047 1.172, -2.828Z'/%3E%3C/svg%3E%0A");
// Navigation
--color-navigation-icon: var(--color-gray-4);
--color-navigation-link: var(--color-gray-4);
--color-navigation-active: var(--color-gray-7);
--color-navigation-active-text: var(--color-gray-3);
--color-navigation-hover: var(--color-gray-6);
--color-navigation-hover-text: var(--color-gray-3);
--color-navigation-icon: #76808a;
--color-navigation-link: #b9c3ce;
--color-navigation-active: #2b2037;
--color-navigation-active-text: #c6bcd2;
--color-navigation-hover: #21182a;
--color-navigation-hover-text: #c6bcd2;
// Tags
--color-tag: var(--color-primary-alt-3);
--color-tag-bg: var(--color-gray-7);
--color-tag: #ff85b1;
--color-tag-bg: var(--color-navigation-hover);
--color-tag-hover: var(--color-white);
--color-tag-bg-hover: var(--color-primary-alt);
--color-tag-bg-hover: var(--color-primary-alt-2);
--color-tag-mature-bg: var(--color-primary-alt-2);
// Menu
--color-menu-background: var(--color-header-background);
--color-menu-background--active: var(--color-gray-7);
--color-menu-icon: var(--color-gray-4);
--color-menu-background--active: var(--color-primary-alt);
--color-menu-icon: #928b9b;
--color-menu-icon-active: #d6d6d6;
// Comments
--color-comment-menu: var(--color-gray-5);
--color-comment-menu-hovering: var(--color-gray-2);
--color-comment-threadline: #434b54;
--color-comment-threadline-hover: var(--color-gray-4);
--color-comment-menu: #6a6a6a;
--color-comment-menu-hovering: #e0e0e0;
--color-comment-highlighted: #484734;
// Snack
--color-snack-bg: var(--color-secondary);
// Superchat
--color-superchat-text: var(--color-black);
--color-superchat-text__light: var(--color-text);
--color-superchat: #fcd34d;
--color-superchat__light: #ef4e1647;
--color-superchat-2: #fde68a;
--color-superchat-3: #fef3c7;
--color-superchat-3__light: #58066087;
--color-superchat-4: #fffbeb;
--color-comment-threadline: #24192f;
--color-comment-threadline-hover: var(--color-gray-4);
// Other
--color-focus: #93c5fd50;
--color-nag: var(--color-orange);
--color-tab-text: var(--color-white);
--color-tabs-background: var(--color-card-background);
--color-tab-divider: var(--color-white);
@ -121,14 +107,12 @@
--color-notice: #58563b;
--color-purchased: #ffd580;
--color-purchased-alt: var(--color-purchased);
--color-purchased-text: var(--color-gray-5);
--color-purchased-text: black;
--color-thumbnail-background: var(--color-gray-5);
--color-tooltip-bg: #2f3337;
--color-help-warning-bg: #d97706;
--color-help-warning-text: white;
--color-blockquote: var(--color-gray-5);
--color-placeholder-background: #4e5862;
--color-spinner-light: #5a6570;
--color-focus: #e91e6329;
--color-placeholder-background: #261a35;
--color-spinner-light: white;
--color-spinner-dark: #212529;
--color-login-graphic-background: var(--color-background);

View file

@ -1,2 +1,155 @@
:root {
// Color overrides
--color-primary: #fa6165;
--color-primary-alt: #fef1f6;
--color-primary-alt-2: #fb7e82;
--color-primary-alt-3: #fbcbdd;
--color-secondary: #f9902a;
--color-secondary-alt: #fee8d2;
--color-secondary-alt-2: #fefcf6;
// Structure
--color-border: #ededed;
--color-background: #fafafa;
--color-background-overlay: #21252980;
--color-card-background: #ffffff;
--color-card-background-highlighted: #fff5f5;
// Text
--color-text-selection-bg: var(--color-primary-alt);
--color-text-selection: var(--color-primary);
--color-text-error: var(--color-danger);
--color-text-empty: #999999;
--color-text-help: #999999;
--color-text-subtitle: #767676;
--color-text-warning: #212529;
--color-help-warning-bg: #fef3c7;
--color-text-warning--background: var(--lbry-yellow-1);
--color-blockquote: var(--color-gray-3);
--color-blockquote-bg: var(--color-gray-1);
--color-tooltip-bg: #222;
--color-tooltip-text: #fafafa;
// Header
--color-header-button: var(--color-button-alt-bg);
--color-header-background: #ffffff;
// Button
--color-button-alt-bg: var(--color-gray-1);
--color-button-alt-bg-hover: var(--color-gray-2);
--color-button-alt-text: black;
--color-button-primary-bg: var(--color-primary);
--color-button-primary-bg-hover: var(--color-primary-alt-2);
--color-button-primary-text: var(--color-primary-alt);
--color-button-primary-hover-text: var(--color-white);
--color-button-secondary-bg: var(--color-primary-alt);
--color-button-secondary-border: var(--color-primary-alt-3);
--color-button-secondary-text: var(--color-primary);
--color-button-secondary-bg-hover: var(--color-primary-alt-3);
--color-button-toggle-text: var(--color-primary);
--color-button-toggle-bg: var(--color-primary-alt);
--color-button-toggle-bg-hover: var(--color-primary-alt);
--color-button-border: var(--color-gray-3);
--color-link-active: var(--color-primary);
--color-link-focus-bg: #f1f1f1;
--color-link: var(--color-primary);
// Input
--color-input-bg-selected: var(--color-primary-alt);
--color-input-color: #111111;
--color-input-label: var(--color-gray-5);
--color-input-placeholder: #212529;
--color-input-bg: var(--color-gray-1);
--color-input-border: var(--color-border);
--color-input-border-active: var(--color-secondary);
--color-input-toggle: var(--color-secondary);
--color-input-toggle-bg: var(--color-gray-1);
--color-input-toggle-bg-hover: var(--color-secondary-alt);
--color-input-prefix-bg: var(--color-gray-2);
--color-input-prefix-border: var(--color-gray-5);
--select-toggle-background: url("data:image/svg+xml,%3Csvg viewBox='0 0 96 96' xmlns='http://www.w3.org/2000/svg' fill='%23212529'%3E%3Cpath d='M17.172, 31.172c1.562, -1.562 4.095, -1.562 5.656, 0l25.172, 25.171l25.172, -25.171c1.562, -1.562 4.095, -1.562 5.656, 0c1.562, 1.562 1.562, 4.095 0, 5.656l-28, 28c-1.562, 1.562 -4.095, 1.562 -5.656, 0l-28, -28c-0.781, -0.781 -1.172, -1.805 -1.172, -2.828c0, -1.023 0.391, -2.047 1.172, -2.828Z'/%3E%3C/svg%3E%0A");
// Navigation
--color-navigation-icon: var(--color-gray-5);
--color-navigation-link: var(--color-gray-5);
--color-navigation-active: var(--color-primary-alt);
--color-navigation-active-text: var(--color-primary);
--color-navigation-hover: var(--color-gray-1);
--color-navigation-hover-text: #3f3f3f;
// Tags
--color-tag: var(--color-primary-alt-2);
--color-tag-bg: #f9f6f7;
--color-tag-hover: var(--color-button-alt-text);
--color-tag-bg-hover: var(--color-button-alt-bg-hover);
// Menu
--color-menu-background: var(--color-header-background);
--color-menu-icon: var(--color-navigation-link);
--color-menu-icon-active: var(--color-navigation-link);
--color-menu-background--selected: var(--color-secondary-alt);
--color-menu-background--active: var(--color-primary-alt);
// Comments
--color-comment-menu: #e0e0e0;
--color-comment-menu-hovering: #6a6a6a;
--color-comment-highlighted: #fff2d9;
--color-comment-threadline: var(--color-gray-1);
--color-comment-threadline-hover: var(--color-gray-4);
// Superchat
--color-superchat-text: var(--color-black);
--color-superchat: #fcd34d;
--color-superchat__light: #fcd34d50;
--color-superchat-2: #fde68a;
--color-superchat-3: #fef3c7;
--color-superchat-3__light: #fef3c750;
--color-superchat-4: #fffbeb;
// Color
--color-focus: #8dbff0;
--color-nag: #fa8700;
--color-error: #fcafca;
--color-notice: #fef3ca;
--color-purchased: var(--color-cost);
--color-purchased-alt: #ffebc2;
--color-purchased-text: black;
--color-thumbnail-background: var(--color-gray-1);
--color-spinner-light: #ffffff;
--color-spinner-dark: #212529;
--color-placeholder-background: #f0f0f0;
--color-file-viewer-background: var(--color-card-background);
--color-tabs-background: var(--color-card-background);
--color-tab-divider: var(--color-primary);
--color-modal-background: var(--color-card-background);
// Icons
--color-follow-bg: #ffd4da;
--color-follow-icon: #e2495e;
--color-view-bg: var(--color-secondary-alt);
--color-view-icon: var(--color-secondary);
// Editor
--color-editor-cursor: var(--color-text);
--color-editor-quote: #707070;
--color-editor-tag: #ea9400;
--color-editor-attr: #04b0f4;
--color-editor-string: #ff7451;
--color-editor-inline-code-fg: var(--color-text);
--color-editor-inline-code-fg-preview: #2e3439;
--color-editor-inline-code-bg: rgba(157, 161, 165, 0.3);
--color-editor-inline-code-bg-preview: #d0e8ff;
--color-editor-selected: #add6ff;
--color-editor-link: var(--color-link);
--color-editor-url: var(--color-editor-string);
--color-editor-hr: var(--color-editor-tag);
--color-editor-hr-preview: #cccccc;
// Ads
--color-ads-background: #fae5ff;
--color-ads-link: var(--color-link);
// Scrollbar
--color-scrollbar-thumb-bg: rgba(0, 0, 0, 0.2);
--color-scrollbar-track-bg: transparent;
}

View file

@ -38,9 +38,13 @@ export const getSearchQueryString = (query: string, options: any = {}) => {
const encodedQuery = encodeURIComponent(query);
const queryParams = [
options.exact && !isSurroundedByQuotes(encodedQuery) ? `s="${encodedQuery}"` : `s=${encodedQuery}`,
`free_only=true`,
`size=${options.size || DEFAULT_SEARCH_SIZE}`,
`from=${options.from || DEFAULT_SEARCH_RESULT_FROM}`,
// `mediaType=${SEARCH_OPTIONS.MEDIA_VIDEO}`,
// `claimType=${SEARCH_OPTIONS.INCLUDE_FILES}`,
];
const { isBackgroundSearch } = options;
const includeUserOptions = typeof isBackgroundSearch === 'undefined' ? false : !isBackgroundSearch;

View file

@ -150,6 +150,6 @@ export const generateShareUrl = (
export const generateRssUrl = (domain, lbryUrl) => {
const { channelName, channelClaimId } = parseURI(lbryUrl);
const url = `${domain}/$/rss/@${channelName}/${channelClaimId.slice(0, 2)}`;
const url = `${domain}/$/rss/@${channelName}${channelClaimId ? `/${channelClaimId.slice(0, 2)}` : ''}`;
return url;
};

View file

@ -4,7 +4,7 @@ import Button from 'component/button';
import { formatLbryUrlForWeb } from 'util/url';
import { withRouter } from 'react-router';
import { URL, SITE_NAME } from 'config';
import * as ICONS from 'constants/icons';
import OdyseeLogoWithText from 'component/header/odysee_white.png';
type Props = {
uri: string,
@ -37,7 +37,9 @@ function FileViewerEmbeddedEnded(props: Props) {
return (
<div className="file-viewer__overlay">
<div className="file-viewer__overlay-secondary">
<Button className="file-viewer__overlay-logo" label="LBRY" icon={ICONS.LBRY} href={URL} />
<Button className="file-viewer__overlay-logo--videoend" href={URL}>
<img src={OdyseeLogoWithText} />
</Button>
</div>
<div className="file-viewer__overlay-title">{prompt}</div>
<div className="file-viewer__overlay-actions">

View file

@ -1,101 +1,34 @@
import * as PAGES from 'constants/pages';
import React from 'react';
import Button from 'component/button';
const sections = [
{
name: 'Community',
links: [
{
label: 'Twitter',
link: 'https://twitter.com/lbrycom',
},
{
label: 'Reddit',
link: 'https://reddit.com/r/lbry',
},
{
label: 'Chat (Discord)',
link: 'https://chat.lbry.org/',
},
{
label: 'Telegram',
link: 'https://t.me/lbryofficial',
},
{
label: 'Facebook',
link: 'https://www.facebook.com/lbryio',
},
],
},
{
name: 'Resources',
links: [
{
label: 'FAQ',
link: 'https://lbry.com/faq',
},
{
label: 'Support --[used in footer; general help/support]--',
link: 'https://lbry.com/faq/support',
},
{
label: 'YouTube Partner Program',
link: 'https://lbry.com/youtube',
},
{
label: 'lbry.com',
link: 'https://lbry.com',
},
{
label: 'lbry.tech',
link: 'https://lbry.tech',
},
{
label: 'GitHub',
link: 'https://github.com/lbryio',
},
],
},
{
name: 'Policies',
links: [
{
label: 'Terms of Service',
link: 'https://www.lbry.com/termsofservice',
},
{
label: 'Privacy Policy',
link: 'https://lbry.com/privacypolicy',
},
{
label: '2257',
navigate: `/$/${PAGES.CODE_2257}`,
},
],
},
];
import I18nMessage from 'component/i18nMessage';
export default function Footer() {
return (
<footer className="footer">
<ul className="navigation__tertiary footer__links ul--no-style">
{sections.map(({ name, links }) => {
return (
<li key={name} className="footer__section">
<ul className="ul--no-style">
<div className="footer__section-title">{__(name)}</div>
{links.map(({ label, link, navigate }) => {
return (
<li key={label}>
<Button className="footer__link" label={__(label)} href={link} navigate={navigate} />
</li>
);
})}
</ul>
</li>
);
})}
<span className="footer__section-title">
<I18nMessage tokens={{ lbry_link: <Button button="link" label={'LBRY'} href="https://lbry.com" /> }}>
POWERED BY %lbry_link%
</I18nMessage>
</span>
<ul className="navigation__tertiary footer__links">
<li className="footer__link">
<Button label={__('About --[link title in Sidebar or Footer]--')} href="https://lbry.com/about" />
</li>
<li className="footer__link">
<Button label={__('Community Guidelines')} href="https://odysee.com/@OdyseeHelp:b/Community-Guidelines:c" />
</li>
<li className="footer__link">
<Button label={__('FAQ')} href="https://odysee.com/@OdyseeHelp:b" />
</li>
<li className="footer__link">
<Button label={__('Support --[used in footer; general help/support]--')} href="https://lbry.com/support" />
</li>
<li className="footer__link">
<Button label={__('Terms')} href="https://lbry.com/termsofservice" />
</li>
<li className="footer__link">
<Button label={__('Privacy Policy')} href="https://lbry.com/privacy" />
</li>
</ul>
</footer>
);