bring in styles (#7542)

* bring in ody styles; modify; cleanup

* workflow

* workflow

* v0.52.6-alpha.teststyles.1

* fix hook

* v0.52.6-alpha.teststyles.2

* style fixes

* fix pagination styling

* v0.52.6-alpha.teststyles.3

* wallet icon was bad

* restore deploy script

* fixes

* fix player close button

* modal inputs

* cleanup

* cleanup

* fix staked indicator

* fix profile menu button skel delay

* fix view-all-playlists hover

* fix overlay buttons on collection page

* fix header buttons
This commit is contained in:
jessopb 2022-04-17 13:04:56 -04:00 committed by GitHub
parent 50ae6e2869
commit 3034f4ce6c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
136 changed files with 7502 additions and 1841 deletions

View file

@ -1,6 +1,6 @@
{
"name": "lbry",
"version": "0.52.6",
"version": "0.52.6-alpha.teststyles.3",
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
"keywords": [
"lbry"
@ -63,6 +63,7 @@
"proxy-polyfill": "0.1.6",
"re-reselect": "^4.0.0",
"react-beautiful-dnd": "^13.1.0",
"react-color": "^2.19.3",
"react-datetime-picker": "^3.4.3",
"remove-markdown": "^0.3.0",
"rss": "^1.2.2",
@ -89,7 +90,7 @@
"@meetfranz/electron-cookies": "^3.0.2",
"@reach/auto-id": "^0.13.0",
"@reach/combobox": "^0.12.1",
"@reach/menu-button": "0.7.4",
"@reach/menu-button": "0.8.6",
"@reach/rect": "^0.16.0",
"@reach/tabs": "^0.1.5",
"@reach/tooltip": "^0.12.1",

View file

@ -2308,5 +2308,21 @@
"Yes, share with LBRY": "Yes, share with LBRY",
"Search Uploads": "Search Uploads",
"This refundable boost will improve the discoverability of this %claimTypeText% while active. ": "This refundable boost will improve the discoverability of this %claimTypeText% while active. ",
"%repost_channel_link%": "%repost_channel_link%",
"Show less": "Show less",
"Channel \"realporno\" blocked.": "Channel \"realporno\" blocked.",
"Elements": "Elements",
"Icons": "Icons",
"You followed @MinutePhysics!": "You followed @MinutePhysics!",
"Unfollowed @samtime.": "Unfollowed @samtime.",
"You followed @samtime!": "You followed @samtime!",
"Unfollowed @gatogalactico.": "Unfollowed @gatogalactico.",
"You followed @gatogalactico!": "You followed @gatogalactico!",
"Unfollowed @Odysee.": "Unfollowed @Odysee.",
"Unfollowed @rossmanngroup.": "Unfollowed @rossmanngroup.",
"You followed @rossmanngroup!": "You followed @rossmanngroup!",
"%repost% %publish%": "%repost% %publish%",
"Failed to view lbry://@MicheL-PDF#7/LaDameAuPain#f, please try again. If this problem persists, visit https://lbry.com/faq/support for support.": "Failed to view lbry://@MicheL-PDF#7/LaDameAuPain#f, please try again. If this problem persists, visit https://lbry.com/faq/support for support.",
"Go to": "Go to",
"--end--": "--end--"
}

BIN
static/img/freespch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -1,6 +1,5 @@
// @flow
import { Combobox, ComboboxInput, ComboboxPopover, ComboboxList, ComboboxOption } from '@reach/combobox';
// import '@reach/combobox/styles.css'; --> 'scss/third-party.scss'
import { matchSorter } from 'match-sorter';
import React from 'react';
import classnames from 'classnames';
@ -118,7 +117,7 @@ export default function BlockList(props: Props) {
return (
<>
<div className="help--notice">{help}</div>
<div className="section">
<div className="section" style={{ zIndex: '4' }}>
<SearchList
list={localList}
placeholder={__('e.g. odysee')}

View file

@ -271,7 +271,7 @@ function ChannelForm(props: Props) {
// TODO clear and bail after submit
return (
<>
<div className={classnames('main--contained', { 'card--disabled': disabled })}>
<div className={classnames({ 'card--disabled': disabled })}>
<header className="channel-cover">
<div className="channel__quick-actions">
<Button
@ -332,7 +332,7 @@ function ChannelForm(props: Props) {
<div className="channel-cover__gradient" />
</header>
<Tabs>
<Tabs className="channelPage-wrapper">
<TabList className="tabs__list--channel-page">
<Tab>{__('General')}</Tab>
<Tab>{__('Credit Details')}</Tab>

View file

@ -13,6 +13,7 @@ type Props = {
level: number,
large?: boolean,
inline?: boolean,
hideTooltip?: Boolean,
};
function getChannelIcon(level: number): string {
@ -28,7 +29,7 @@ function getChannelIcon(level: number): string {
}
function ChannelStakedIndicator(props: Props) {
const { channelClaim, amount, level, large = false, inline = false } = props;
const { channelClaim, amount, level, large = false, inline = false, hideTooltip } = props;
if (!channelClaim || !channelClaim.meta) {
return null;
@ -37,23 +38,36 @@ function ChannelStakedIndicator(props: Props) {
const isControlling = channelClaim && channelClaim.meta.is_controlling;
const icon = getChannelIcon(level);
return (
<Tooltip
title={
<div className="channel-staked__tooltip">
<div className="channel-staked__tooltip-icons">
<LevelIcon icon={icon} isControlling={isControlling} size={isControlling ? 14 : 10} />
</div>
if (!hideTooltip) {
return (
<Tooltip
title={
<div className="channel-staked__tooltip">
<div className="channel-staked__tooltip-icons">
<LevelIcon icon={icon} isControlling={isControlling} size={isControlling ? 14 : 10} />
</div>
<div className="channel-staked__tooltip-text">
<span>{__('Level %current_level%', { current_level: level })}</span>
<div className="channel-staked__amount">
<LbcSymbol postfix={<CreditAmount amount={amount} showLBC={false} />} size={14} />
<div className="channel-staked__tooltip-text">
<span>{__('Level %current_level%', { current_level: level })}</span>
<div className="channel-staked__amount">
<LbcSymbol postfix={<CreditAmount amount={amount} showLBC={false} />} size={14} />
</div>
</div>
</div>
}
>
<div
className={classnames('channel-staked__wrapper', {
'channel-staked__wrapper--large': large,
'channel-staked__wrapper--inline': inline,
})}
>
<LevelIcon icon={icon} large={large} isControlling={isControlling} />
</div>
}
>
</Tooltip>
);
} else {
return (
<div
className={classnames('channel-staked__wrapper', {
'channel-staked__wrapper--large': large,
@ -62,8 +76,8 @@ function ChannelStakedIndicator(props: Props) {
>
<LevelIcon icon={icon} large={large} isControlling={isControlling} />
</div>
</Tooltip>
);
);
}
}
type LevelIconProps = {

View file

@ -23,6 +23,7 @@ type Props = {
showDelayedMessage?: boolean,
noLazyLoad?: boolean,
hideStakedIndicator?: boolean,
hideTooltip?: boolean,
xsmall?: boolean,
noOptimization?: boolean,
setThumbUploadError: (boolean) => void,
@ -45,11 +46,12 @@ function ChannelThumbnail(props: Props) {
showDelayedMessage = false,
noLazyLoad,
hideStakedIndicator = false,
hideTooltip,
setThumbUploadError,
ThumbUploadError,
} = props;
const [thumbLoadError, setThumbLoadError] = React.useState(ThumbUploadError);
const shouldResolve = claim === undefined;
const shouldResolve = !isResolving && claim === undefined;
const thumbnail = rawThumbnail && rawThumbnail.trim().replace(/^http:\/\//i, 'https://');
const thumbnailPreview = rawThumbnailPreview && rawThumbnailPreview.trim().replace(/^http:\/\//i, 'https://');
const defaultAvatar = AVATAR_DEFAULT || Gerbil;
@ -77,7 +79,7 @@ function ChannelThumbnail(props: Props) {
if (isGif && !allowGifs) {
return (
<FreezeframeWrapper src={channelThumbnail} className={classnames('channel-thumbnail', className)}>
{!hideStakedIndicator && <ChannelStakedIndicator uri={uri} claim={claim} />}
{!hideStakedIndicator && <ChannelStakedIndicator uri={uri} claim={claim} hideTooltip={hideTooltip} />}
</FreezeframeWrapper>
);
}
@ -91,6 +93,7 @@ function ChannelThumbnail(props: Props) {
'channel-thumbnail--resolving': isResolving,
})}
>
{/* show delay necessary? */}
{showDelayedMessage ? (
<div className="channel-thumbnail--waiting">{__('This will be visible in a few minutes.')}</div>
) : (

View file

@ -102,6 +102,7 @@ export default function ClaimList(props: Props) {
let tileUris = (prefixUris || []).concat(uris || []);
tileUris = tileUris.filter((uri) => !excludeUris.includes(uri));
if (prefixUris && prefixUris.length) tileUris.splice(prefixUris.length * -1, prefixUris.length);
const totalLength = tileUris.length;

View file

@ -39,7 +39,7 @@ type Props = {
doChannelUnmute: (string) => void,
doCommentModBlock: (string) => void,
doCommentModUnBlock: (string) => void,
doCommentModBlockAsAdmin: (string, string) => void,
doCommentModBlockAsAdmin: (string, ?string, ?string) => void,
doCommentModUnBlockAsAdmin: (string, string) => void,
doCollectionEdit: (string, any) => void,
hasClaimInWatchLater: boolean,
@ -232,7 +232,7 @@ function ClaimMenuList(props: Props) {
if (channelIsAdminBlocked) {
doCommentModUnBlockAsAdmin(contentChannelUri, '');
} else {
doCommentModBlockAsAdmin(contentChannelUri, '');
doCommentModBlockAsAdmin(contentChannelUri, undefined, undefined);
}
}

View file

@ -11,17 +11,24 @@ function ClaimPreviewLoading(props: Props) {
const { isChannel, type } = props;
return (
<li
className={classnames('claim-preview__wrapper', {
className={classnames('placeholder claim-preview__wrapper', {
'claim-preview__wrapper--channel': isChannel && type !== 'inline',
'claim-preview__wrapper--inline': type === 'inline',
'claim-preview__wrapper--small': type === 'small',
})}
>
<div className={classnames('claim-preview', { 'claim-preview--large': type === 'large' })}>
<div className="placeholder media__thumb" />
<div className="media__thumb" />
<div className="placeholder__wrapper">
<div className="placeholder claim-preview__title" />
<div className="placeholder media__subtitle" />
<div className="claim-preview__title" />
<div className="claim-preview__title_b" />
<div className="claim-tile__info">
<div className="channel-thumbnail" />
<div className="claim-tile__about">
<div className="media__subtitle" />
<div className="media__subtitle_b" />
</div>
</div>
</div>
</div>
</li>

View file

@ -30,6 +30,7 @@ import ClaimPreviewLoading from './claim-preview-loading';
import ClaimPreviewHidden from './claim-preview-no-mature';
import ClaimPreviewNoContent from './claim-preview-no-content';
import CollectionEditButtons from 'component/collectionEditButtons';
import { useIsMobile } from 'effects/use-screensize';
import AbandonedChannelPreview from 'component/abandonedChannelPreview';
// preview images used on the landing page and on the channel page
@ -143,6 +144,8 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
unavailableUris,
} = props;
const isMobile = useIsMobile();
const isCollection = claim && claim.value_type === 'collection';
const collectionClaimId = isCollection && claim && claim.claim_id;
const listId = collectionId || collectionClaimId;
@ -160,15 +163,18 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
return <span />;
}
const formattedSubCount = toCompactNotation(channelSubCount, lang, 10000);
const formattedSubCountLocale = Number(channelSubCount).toLocaleString();
return (
<Tooltip title={channelSubCount} followCursor placement="top">
<span className="claim-preview__channel-sub-count">
{channelSubCount === 1 ? __('1 Follower') : __('%formattedSubCount% Followers', { formattedSubCount })}
</span>
</Tooltip>
<div className="media__subtitle">
<Tooltip title={formattedSubCountLocale} followCursor placement="top">
<span className="claim-preview__channel-sub-count">
{channelSubCount === 1 ? __('1 Follower') : __('%formattedSubCount% Followers', { formattedSubCount })}
</span>
</Tooltip>
</div>
);
}, [channelSubCount]);
const isValid = uri && isURIValid(uri);
const isValid = uri && isURIValid(uri, false);
// $FlowFixMe
const isPlayable =
@ -359,7 +365,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
</div>
{/* @endif */}
<div className="claim-preview__file-property-overlay">
<PreviewOverlayProperties uri={uri} />
<PreviewOverlayProperties uri={uri} small={type === 'small'} />
</div>
</FileThumbnail>
</NavLink>
@ -380,9 +386,18 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
</NavLink>
)}
</div>
<ClaimPreviewSubtitle uri={uri} type={type} />
{(pending || !!reflectingProgress) && <PublishPending uri={uri} />}
{channelSubscribers}
<div className="claim-tile__info" uri={uri}>
{!isChannelUri && signingChannel && (
<div className="claim-preview__channel-staked">
<UriIndicator focusable={false} uri={uri} link hideAnonymous>
<ChannelThumbnail uri={signingChannel.permanent_url} xsmall />
</UriIndicator>
</div>
)}
<ClaimPreviewSubtitle uri={uri} type={type} />
{(pending || !!reflectingProgress) && <PublishPending uri={uri} />}
{channelSubscribers}
</div>
</div>
{type !== 'small' && (
<div className="claim-preview__actions">
@ -393,11 +408,6 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
actions
) : (
<div className="claim-preview__primary-actions">
{!isChannelUri && signingChannel && (
<div className="claim-preview__channel-staked">
<ChannelThumbnail uri={signingChannel.permanent_url} xsmall />
</div>
)}
{isChannelUri && !banState.muted && !claimIsMine && (
<SubscribeButton
uri={repostedChannelUri || (uri.startsWith('lbry://') ? uri : `lbry://${uri}`)}
@ -411,13 +421,11 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
)}
{claim && (
<React.Fragment>
{typeof properties === 'function' ? (
properties(claim)
) : properties !== undefined ? (
properties
) : (
<ClaimTags uri={uri} type={type} />
)}
{typeof properties === 'function'
? properties(claim)
: properties !== undefined
? properties
: !isMobile && <ClaimTags uri={uri} type={type} />}
</React.Fragment>
)}
</div>

View file

@ -8,7 +8,6 @@ import TruncatedText from 'component/common/truncated-text';
import DateTime from 'component/dateTime';
import ChannelThumbnail from 'component/channelThumbnail';
import FileViewCountInline from 'component/fileViewCountInline';
import SubscribeButton from 'component/subscribeButton';
import useGetThumbnail from 'effects/use-get-thumbnail';
import { formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url';
import { formatClaimPreviewTitle } from 'util/formatAriaLabel';
@ -85,7 +84,6 @@ function ClaimPreviewTile(props: Props) {
const shouldFetch = claim === undefined;
const thumbnailUrl = useGetThumbnail(uri, claim, streamingUrl, getFile, placeholder) || thumbnail;
const canonicalUrl = claim && claim.canonical_url;
const permanentUrl = claim && claim.permanent_url;
const repostedContentUri = claim && (claim.reposted_claim ? claim.reposted_claim.permanent_url : claim.permanent_url);
const listId = collectionId || collectionClaimId;
const navigateUrl =
@ -110,7 +108,6 @@ function ClaimPreviewTile(props: Props) {
const isChannel = claim && claim.value_type === 'channel';
const channelUri = !isChannel ? signingChannel && signingChannel.permanent_url : claim && claim.permanent_url;
const channelTitle = signingChannel && ((signingChannel.value && signingChannel.value.title) || signingChannel.name);
const repostedChannelUri = isRepost && isChannel ? permanentUrl || canonicalUrl : undefined;
// Aria-label value for claim preview
let ariaLabelData = isChannel ? title : formatClaimPreviewTitle(title, channelTitle, date, mediaDuration);
@ -148,17 +145,24 @@ function ClaimPreviewTile(props: Props) {
if (placeholder || (!claim && isResolvingUri)) {
return (
<li className={classnames('claim-preview--tile', {})}>
<div className="placeholder media__thumb">
<li className={classnames('placeholder claim-preview--tile', {})}>
<div className="media__thumb">
<img src={PlaceholderTx} alt="Placeholder" />
</div>
<div className="placeholder__wrapper">
<div className="placeholder claim-tile__title" />
<div className="claim-tile__title" />
<div className="claim-tile__title_b" />
<div
className={classnames('claim-tile__info placeholder', {
className={classnames('claim-tile__info', {
contains_view_count: shouldShowViewCount,
})}
/>
>
<div className="channel-thumbnail" />
<div className="claim-tile__about">
<div className="button__content" />
<div className="claim-tile__about--counts" />
</div>
</div>
</div>
</li>
);
@ -220,11 +224,7 @@ function ClaimPreviewTile(props: Props) {
contains_view_count: shouldShowViewCount,
})}
>
{isChannel ? (
<div className="claim-tile__about--channel">
<SubscribeButton uri={repostedChannelUri || uri} />
</div>
) : (
{!isChannel && (
<React.Fragment>
<UriIndicator focusable={false} uri={uri} link hideAnonymous>
<ChannelThumbnail uri={channelUri} xsmall />

View file

@ -19,8 +19,11 @@ function ClaimRepostAuthor(props: Props) {
if (short && repostUrl) {
return (
<span className="claim-preview__repost-author">
<Icon icon={ICONS.REPOST} size={12} />
<span>{repostUrl}</span>
<div className="claim-preview__repost-ribbon">
<Icon icon={ICONS.REPOST} size={12} />
<br />
<span>{repostUrl}</span>
</div>
</span>
);
}
@ -47,10 +50,13 @@ function ClaimRepostAuthor(props: Props) {
return (
<div className="claim-preview__repost-author">
<Icon icon={ICONS.REPOST} size={10} className="claim-preview__repost-icon" />
<I18nMessage tokens={{ repost_channel_link: <UriIndicator link uri={repostChannelUrl} /> }}>
%repost_channel_link% reposted
</I18nMessage>
<div className="claim-preview__repost-ribbon">
<Icon icon={ICONS.REPOST} size={10} className="claim-preview__repost-icon" />
<br />
<I18nMessage tokens={{ repost_channel_link: <UriIndicator link uri={repostChannelUrl} /> }}>
%repost_channel_link%
</I18nMessage>
</div>
</div>
);
}

View file

@ -23,7 +23,7 @@ export default function ClaimSupportButton(props: Props) {
return (
<Button
button={fileAction ? undefined : 'alt'}
button={fileAction ? undefined : 'secondary'}
className={classnames({ 'button--file-action': fileAction })}
icon={ICONS.LBC}
iconSize={fileAction ? 22 : undefined}

View file

@ -9,6 +9,7 @@ import { doToggleTagFollowDesktop } from 'redux/actions/tags';
import { makeSelectClientSetting, selectShowMatureContent } from 'redux/selectors/settings';
import { selectMutedAndBlockedChannelIds } from 'redux/selectors/blocked';
import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
import { createNormalizedClaimSearchKey } from 'util/claim';
import ClaimListDiscover from './view';
@ -17,13 +18,22 @@ const select = (state, props) => {
const hideReposts = makeSelectClientSetting(SETTINGS.HIDE_REPOSTS)(state);
const mutedAndBlockedChannelIds = selectMutedAndBlockedChannelIds(state);
return {
claimSearchByQuery: selectClaimSearchByQuery(state),
claimsByUri: selectClaimsByUri(state),
fetchingClaimSearchByQuery: selectFetchingClaimSearchByQuery(state),
const options = resolveSearchOptions({
showNsfw,
hideReposts,
options: resolveSearchOptions({ showNsfw, hideReposts, mutedAndBlockedChannelIds, pageSize: 8, ...props }),
mutedAndBlockedChannelIds,
pageSize: 8,
...props,
});
const searchKey = createNormalizedClaimSearchKey(options);
return {
claimSearchResults: selectClaimSearchByQuery(state)[searchKey],
claimsByUri: selectClaimsByUri(state),
fetchingClaimSearch: selectFetchingClaimSearchByQuery(state)[searchKey],
showNsfw,
hideReposts,
optionsStringified: JSON.stringify(options),
};
};

View file

@ -1,31 +1,8 @@
// @flow
import type { Node } from 'react';
import React from 'react';
import { createNormalizedClaimSearchKey } from 'util/claim';
import ClaimPreviewTile from 'component/claimPreviewTile';
import useFetchViewCount from 'effects/use-fetch-view-count';
import usePrevious from 'effects/use-previous';
type SearchOptions = {
page_size: number,
page: number,
no_totals: boolean,
any_tags: Array<string>,
channel_ids: Array<string>,
claim_ids?: Array<string>,
not_channel_ids: Array<string>,
not_tags: Array<string>,
order_by: Array<string>,
languages?: Array<string>,
release_time?: string,
claim_type?: string | Array<string>,
timestamp?: string,
fee_amount?: string,
limit_claims_per_channel?: number,
stream_types?: Array<string>,
has_source?: boolean,
has_no_source?: boolean,
};
function urisEqual(prev: ?Array<string>, next: ?Array<string>) {
if (!prev || !next) {
@ -68,12 +45,12 @@ type Props = {
hasNoSource?: boolean,
// --- select ---
location: { search: string },
claimSearchByQuery: { [string]: Array<string> },
claimSearchResults: Array<string>,
claimsByUri: { [string]: any },
fetchingClaimSearchByQuery: { [string]: boolean },
fetchingClaimSearch: boolean,
showNsfw: boolean,
hideReposts: boolean,
options: SearchOptions,
optionsStringified: string,
// --- perform ---
doClaimSearch: ({}) => void,
doFetchViewCount: (claimIdCsv: string) => void,
@ -82,10 +59,10 @@ type Props = {
function ClaimTilesDiscover(props: Props) {
const {
doClaimSearch,
claimSearchByQuery,
claimSearchResults,
claimsByUri,
fetchViewCount,
fetchingClaimSearchByQuery,
fetchingClaimSearch,
hasNoSource,
renderProperties,
// pinUrls,
@ -93,16 +70,15 @@ function ClaimTilesDiscover(props: Props) {
showNoSourceClaims,
doFetchViewCount,
pageSize = 8,
options,
optionsStringified,
} = props;
const searchKey = createNormalizedClaimSearchKey(options);
const fetchingClaimSearch = fetchingClaimSearchByQuery[searchKey];
const claimSearchUris = claimSearchByQuery[searchKey] || [];
const isUnfetchedClaimSearch = claimSearchByQuery[searchKey] === undefined;
const prevUris = React.useRef();
const claimSearchUris = claimSearchResults || [];
const isUnfetchedClaimSearch = claimSearchResults === undefined;
// Don't use the query from createNormalizedClaimSearchKey for the effect since that doesn't include page & release_time
const optionsStringForEffect = JSON.stringify(options);
const shouldPerformSearch = !fetchingClaimSearch && claimSearchUris.length === 0;
const uris = (prefixUris || []).concat(claimSearchUris);
@ -124,21 +100,19 @@ function ClaimTilesDiscover(props: Props) {
uris.push(...Array(pageSize - uris.length).fill(''));
}
const prevUris = usePrevious(uris);
useFetchViewCount(fetchViewCount, uris, claimsByUri, doFetchViewCount);
const finalUris = isUnfetchedClaimSearch && prevUris.current ? prevUris.current : uris;
prevUris.current = finalUris;
// Run `doClaimSearch`
React.useEffect(() => {
if (shouldPerformSearch) {
const searchOptions = JSON.parse(optionsStringForEffect);
const searchOptions = JSON.parse(optionsStringified);
doClaimSearch(searchOptions);
}
}, [doClaimSearch, shouldPerformSearch, optionsStringForEffect]);
}, [doClaimSearch, shouldPerformSearch, optionsStringified]);
// Show previous results while we fetch to avoid blinkies and poor CLS.
const finalUris = isUnfetchedClaimSearch && prevUris ? prevUris : uris;
return (
<ul className="claim-grid">
{finalUris && finalUris.length
@ -167,33 +141,33 @@ function ClaimTilesDiscover(props: Props) {
export default React.memo<Props>(ClaimTilesDiscover, areEqual);
function debug_trace(val) {
if (process.env.DEBUG_TRACE) console.log(`Render due to: ${val}`);
// ****************************************************************************
// ****************************************************************************
function trace(key, value) {
// @if process.env.DEBUG_TILE_RENDER
// $FlowFixMe "cannot coerce certain types".
console.log(`[claimTilesDiscover] ${key}: ${value}`); // eslint-disable-line no-console
// @endif
}
function areEqual(prev: Props, next: Props) {
const prevOptions: SearchOptions = prev.options;
const nextOptions: SearchOptions = next.options;
const prevSearchKey = createNormalizedClaimSearchKey(prevOptions);
const nextSearchKey = createNormalizedClaimSearchKey(nextOptions);
if (prevSearchKey !== nextSearchKey) {
debug_trace('search key');
return false;
}
// --- Deep-compare ---
if (!urisEqual(prev.claimSearchByQuery[prevSearchKey], next.claimSearchByQuery[nextSearchKey])) {
debug_trace('claimSearchByQuery');
return false;
// These are props that are hard to memoize from where it is passed.
if (prev.claimType !== next.claimType) {
// Array<string>: confirm the contents are actually different.
if (prev.claimType && next.claimType && JSON.stringify(prev.claimType) !== JSON.stringify(next.claimType)) {
trace('claimType', next.claimType);
return false;
}
}
const ARRAY_KEYS = ['prefixUris', 'channelIds'];
for (let i = 0; i < ARRAY_KEYS.length; ++i) {
const key = ARRAY_KEYS[i];
if (!urisEqual(prev[key], next[key])) {
debug_trace(`${key}`);
trace(key, next[key]);
return false;
}
}
@ -203,22 +177,19 @@ function areEqual(prev: Props, next: Props) {
// to update this function. Better to render more than miss an important one.
const KEYS_TO_IGNORE = [
...ARRAY_KEYS,
'claimSearchByQuery',
'fetchingClaimSearchByQuery', // We are showing previous results while fetching.
'options', // Covered by search-key comparison.
'claimType', // Handled above.
'claimsByUri', // Used for view-count. Just ignore it for now.
'location',
'history',
'match',
'claimsByUri',
'doClaimSearch',
'doToggleTagFollowDesktop',
];
const propKeys = Object.keys(next);
for (let i = 0; i < propKeys.length; ++i) {
const pk = propKeys[i];
if (!KEYS_TO_IGNORE.includes(pk) && prev[pk] !== next[pk]) {
debug_trace(`${pk}`);
trace(pk, next[pk]);
return false;
}
}

View file

@ -177,7 +177,7 @@ function CollectionActions(props: Props) {
if (isMobile) {
return (
<div className="media__actions">
<div className="media__actions stretch">
{lhsSection}
{rhsSection}
{infoButtons}

View file

@ -58,21 +58,23 @@ export default function CollectionContent(props: Props) {
return (
<Card
isBodyList
className="file-page__recommended-collection"
className="file-page__playlist-collection"
title={
<>
<span className="file-page__recommended-collection__row">
<Icon
icon={
(id === COLLECTIONS_CONSTS.WATCH_LATER_ID && ICONS.TIME) ||
(id === COLLECTIONS_CONSTS.FAVORITES_ID && ICONS.STAR) ||
ICONS.STACK
}
className="icon--margin-right"
/>
{collectionName}
</span>
<span className="file-page__recommended-collection__row">
<a href={`/$/${PAGES.LIST}/${id}`}>
<span className="file-page__playlist-collection__row">
<Icon
icon={
(id === COLLECTIONS_CONSTS.WATCH_LATER_ID && ICONS.TIME) ||
(id === COLLECTIONS_CONSTS.FAVORITES_ID && ICONS.STAR) ||
ICONS.STACK
}
className="icon--margin-right"
/>
{collectionName}
</span>
</a>
<span className="file-page__playlist-collection__row">
<Button
button="alt"
title={__('Loop')}
@ -93,21 +95,14 @@ export default function CollectionContent(props: Props) {
</>
}
titleActions={
<>
<div className="card__title-actions--link">
{/* TODO: BUTTON TO SAVE COLLECTION - Probably save/copy modal */}
<Button label={__('View List')} button="link" navigate={`/$/${PAGES.LIST}/${id}`} />
</div>
{isMyCollection && (
<Button
title={__('Edit')}
className={classnames('button-toggle', { 'button-toggle--active': showEdit })}
icon={ICONS.EDIT}
onClick={() => setShowEdit(!showEdit)}
/>
)}
</>
isMyCollection && (
<Button
title={__('Edit')}
className={classnames('button-toggle', { 'button-toggle--active': showEdit })}
icon={ICONS.EDIT}
onClick={() => setShowEdit(!showEdit)}
/>
)
}
body={
<DragDropContext onDragEnd={handleOnDragEnd}>

View file

@ -8,6 +8,7 @@ import classnames from 'classnames';
import Button from 'component/button';
import ChannelThumbnail from 'component/channelThumbnail';
import { useHistory } from 'react-router';
import { useIsMobile } from 'effects/use-screensize';
type Props = {
myReacts: Array<string>,
@ -43,6 +44,8 @@ export default function CommentReactions(props: Props) {
location: { pathname },
} = useHistory();
const isMobile = useIsMobile();
React.useEffect(() => {
if (!claim) {
resolve(uri);
@ -101,7 +104,8 @@ export default function CommentReactions(props: Props) {
<Button
title={__('Upvote')}
icon={likeIcon}
className={classnames('comment__action', {
iconSize={isMobile && 12}
className={classnames('comment__action button-like', {
'comment__action--active': myReacts && myReacts.includes(REACTION_TYPES.LIKE),
})}
onClick={handleCommentLike}
@ -110,7 +114,8 @@ export default function CommentReactions(props: Props) {
<Button
title={__('Downvote')}
icon={dislikeIcon}
className={classnames('comment__action', {
iconSize={isMobile && 12}
className={classnames('comment__action button-dislike', {
'comment__action--active': myReacts && myReacts.includes(REACTION_TYPES.DISLIKE),
})}
onClick={handleCommentDislike}

View file

@ -63,7 +63,7 @@ export default function Card(props: Props) {
}
}}
>
<div>
<div className="card__first-pane">
{(title || subtitle) && (
<div
className={classnames('card__header--between', {
@ -73,7 +73,7 @@ export default function Card(props: Props) {
<div
className={classnames('card__title-section', {
'card__title-section--body-list': isBodyList,
'card__title-section--small': smallTitle,
'card__title-section--smallx': smallTitle,
})}
>
{icon && <Icon sectionIcon icon={icon} />}

View file

@ -0,0 +1,41 @@
// @flow
import React, { useEffect, useState } from 'react';
import { FormField } from 'component/common/form';
import Icon from 'component/common/icon';
import useDebounce from 'effects/use-debounce';
import classnames from 'classnames';
const FILTER_DEBOUNCE_MS = 300;
interface Props {
defaultValue?: string;
icon?: string;
placeholder?: string;
inline?: boolean;
onChange: (newValue: string) => any;
}
export default function DebouncedInput(props: Props) {
const { defaultValue = '', icon, placeholder = '', inline, onChange } = props;
const [rawValue, setRawValue] = useState(defaultValue);
const debouncedValue: string = useDebounce(rawValue, FILTER_DEBOUNCE_MS);
useEffect(() => {
onChange(debouncedValue);
}, [onChange, debouncedValue]);
return (
<div className={classnames({ wunderbar: !inline, 'wunderbar--inline': inline })}>
{icon && <Icon icon={icon} />}
<FormField
className={classnames({ wunderbar__input: !inline, 'wunderbar__input--inline': inline })}
type="text"
name="debounced_search"
spellCheck={false}
placeholder={placeholder}
value={rawValue}
onChange={(e) => setRawValue(e.target.value.trim())}
/>
</div>
);
}

View file

@ -71,7 +71,7 @@ class FileSelector extends React.PureComponent<Props> {
<FormField
label={label}
webkitdirectory="true"
className="form-field--copyable"
className="form-field--with-button"
error={error}
disabled={disabled}
type="text"
@ -80,7 +80,7 @@ class FileSelector extends React.PureComponent<Props> {
inputButton={
<Button
autoFocus={autoFocus}
button="secondary"
button="primary"
disabled={disabled}
onClick={type === 'openDirectory' ? this.handleDirectoryInputSelection : this.fileInputButton}
label={__('Browse')}

View file

@ -67,19 +67,16 @@ export const icons = {
viewBox="0 0 24 24"
width={size}
height={size}
fill="none"
fill="black"
stroke={color}
strokeWidth="0"
strokeLinecap="round"
strokeLinejoin="round"
{...rest}
>
<path d="M1.03125 14.1562V9.84375L12 0L22.9688 9.84375V14.1562L12 24L1.03125 14.1562Z" fill="black" />
<path d="M8.925 10.3688L3.99375 14.8125L7.70625 18.15L12.6375 13.7063L8.925 10.3688Z" fill="black" />
<path
d="M8.925 10.3688L15.1312 4.80005L12 1.98755L2.60625 10.425V13.575L3.99375 14.8125L8.925 10.3688Z"
fill="black"
/>
<path d="M1.03125 14.1562V9.84375L12 0L22.9688 9.84375V14.1562L12 24L1.03125 14.1562Z" />
<path d="M8.925 10.3688L3.99375 14.8125L7.70625 18.15L12.6375 13.7063L8.925 10.3688Z" />
<path d="M8.925 10.3688L15.1312 4.80005L12 1.98755L2.60625 10.425V13.575L3.99375 14.8125L8.925 10.3688Z" />
<path
d="M8.925 10.3688L3.99375 14.8125L7.70625 18.15L12.6375 13.7063L8.925 10.3688Z"
fill={`url(#paint0_linear${randomId})`}
@ -172,7 +169,7 @@ export const icons = {
</g>
),
[ICONS.HOME]: buildIcon(
<g strokeWidth="2" fill="none" fillRule="evenodd" strokeLinecap="round" strokeLinejoin="round">
<g fill="none" fillRule="evenodd" strokeLinecap="round" strokeLinejoin="round">
<path d="M1, 11 L12, 2 C12, 2 22.9999989, 11.0000005 23, 11" />
<path d="M3, 10 C3, 10 3, 10.4453982 3, 10.9968336 L3, 20.0170446 C3, 20.5675806 3.43788135, 21.0138782 4.00292933, 21.0138781 L8.99707067, 21.0138779 C9.55097324, 21.0138779 10, 20.5751284 10, 20.0089602 L10, 15.0049177 C10, 14.449917 10.4433532, 14 11.0093689, 14 L12.9906311, 14 C13.5480902, 14 14, 14.4387495 14, 15.0049177 L14, 20.0089602 C14, 20.5639609 14.4378817, 21.0138779 15.0029302, 21.0138779 L19.9970758, 21.0138781 C20.5509789, 21.0138782 21.000006, 20.56848 21.000006, 20.0170446 L21.0000057, 10" />
</g>
@ -198,9 +195,25 @@ export const icons = {
<path d="M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29" />
</g>
),
[ICONS.SUBSCRIBE]: buildIcon(
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
),
[ICONS.SUBSCRIBE]: (props: IconProps) => {
const { size = 24, color = 'currentColor', ...otherProps } = props;
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
fill={color}
stroke={'#FFFFFF'}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
{...otherProps}
>
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
</svg>
);
},
[ICONS.SUBSCRIBED]: (props: IconProps) => {
const { size = 24, color = 'currentColor', ...otherProps } = props;
return (
@ -210,8 +223,8 @@ export const icons = {
width={size}
height={size}
fill={color}
stroke={color}
strokeWidth="1"
stroke={'#FFFFFF'}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
{...otherProps}
@ -221,9 +234,25 @@ export const icons = {
);
},
[ICONS.UNSUBSCRIBE]: buildIcon(
<path d="M 12,5.67 10.94,4.61 C 5.7533356,-0.57666427 -2.0266644,7.2033357 3.16,12.39 l 1.06,1.06 7.78,7.78 7.78,-7.78 1.06,-1.06 c 2.149101,-2.148092 2.149101,-5.6319078 0,-7.78 -2.148092,-2.1491008 -5.631908,-2.1491008 -7.78,0 L 9.4481298,8.2303201 15.320603,9.2419066 11.772427,13.723825" />
),
[ICONS.UNSUBSCRIBE]: (props: IconProps) => {
const { size = 24, color = 'currentColor', ...otherProps } = props;
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
fill={color}
stroke={'#FFFFFF'}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
{...otherProps}
>
<path d="M 12,5.67 10.94,4.61 C 5.7533356,-0.57666427 -2.0266644,7.2033357 3.16,12.39 l 1.06,1.06 7.78,7.78 7.78,-7.78 1.06,-1.06 c 2.149101,-2.148092 2.149101,-5.6319078 0,-7.78 -2.148092,-2.1491008 -5.631908,-2.1491008 -7.78,0 L 9.4481298,8.2303201 15.320603,9.2419066 11.772427,13.723825" />
</svg>
);
},
[ICONS.SETTINGS]: buildIcon(
<g>
<circle cx="12" cy="12" r="3" />
@ -586,12 +615,24 @@ export const icons = {
<path d="M21 13v2a4 4 0 0 1-4 4H3" />
</g>
),
[ICONS.MORE_VERTICAL]: buildIcon(
<g>
<circle cx="12" cy="5" r="1" />
<circle cx="12" cy="12" r="1" />
<circle cx="12" cy="19" r="1" />
</g>
[ICONS.MORE_VERTICAL]: (props: CustomProps) => (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="20"
height="20"
fill="none"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<g>
<circle cx="12" cy="5" r="1" />
<circle cx="12" cy="12" r="1" />
<circle cx="12" cy="19" r="1" />
</g>
</svg>
),
[ICONS.MORE]: buildIcon(
<g transform="rotate(90 12 12)">
@ -974,7 +1015,6 @@ export const icons = {
width={props.size || '16'}
height={props.size || '18'}
fill="none"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
>
@ -1124,13 +1164,6 @@ export const icons = {
[ICONS.DOWNVOTE]: buildIcon(
<path d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17" />
),
[ICONS.FIRE_ACTIVE]: buildIcon(
<path
d="M11.3969 23.04C11.3969 23.04 18.4903 21.8396 18.9753 16.2795C19.3997 9.89148 14.2161 7.86333 13.2915 4.56586C13.1861 4.2261 13.1051 3.88045 13.049 3.53109C12.9174 2.68094 12.8516 1.82342 12.852 0.964865C12.852 0.964865 5.607 0.426785 4.87947 10.6227C4.34858 10.1469 3.92655 9.57999 3.63777 8.9548C3.349 8.32962 3.19921 7.65853 3.19706 6.98033C3.19706 6.98033 -4.32074 18.7767 8.45649 23.04C7.94555 22.1623 7.67841 21.1842 7.67841 20.1909C7.67841 19.1976 7.94555 18.2195 8.45649 17.3418C9.54778 15.0653 9.97218 13.8788 9.97218 13.8788C9.97218 13.8788 15.5044 18.6525 11.3969 23.04Z"
fill="#FF6635"
strokeWidth="0"
/>
),
[ICONS.SLIME_ACTIVE]: buildIcon(
<path
d="M13.065 4.18508C12.5638 4.47334 11.9699 4.5547 11.4096 4.41183C10.8494 4.26896 10.367 3.91315 10.065 3.42008C9.70126 2.96799 9.52899 2.39146 9.58506 1.81392C9.64113 1.23639 9.92109 0.703759 10.365 0.330081C10.8662 0.0418164 11.4601 -0.0395341 12.0204 0.103332C12.5806 0.246199 13.063 0.602008 13.365 1.09508C13.7287 1.54717 13.901 2.12371 13.8449 2.70124C13.7889 3.27877 13.5089 3.8114 13.065 4.18508ZM2.565 6.76508C1.98518 6.6732 1.39241 6.81157 0.913189 7.15066C0.433971 7.48976 0.106262 8.00272 0 8.58008C0.0118186 9.17159 0.256137 9.73464 0.680058 10.1473C1.10398 10.56 1.67339 10.7891 2.265 10.7851C2.84509 10.8863 3.44175 10.7561 3.92691 10.4224C4.41207 10.0886 4.74707 9.57801 4.86 9.00008C4.85804 8.7046 4.79789 8.41241 4.683 8.14018C4.56811 7.86794 4.40072 7.62101 4.1904 7.41347C3.98007 7.20593 3.73093 7.04185 3.45719 6.9306C3.18345 6.81935 2.89048 6.7631 2.595 6.76508H2.565ZM22.2 15.1951C21.9286 15.0703 21.635 15.0008 21.3364 14.9907C21.0379 14.9806 20.7403 15.0301 20.461 15.1362C20.1818 15.2423 19.9264 15.403 19.7099 15.6088C19.4934 15.8146 19.3201 16.0615 19.2 16.3351C19.1369 16.6299 19.1337 16.9345 19.1906 17.2306C19.2475 17.5267 19.3634 17.8084 19.5313 18.0588C19.6992 18.3093 19.9157 18.5235 20.168 18.6886C20.4203 18.8537 20.7033 18.9665 21 19.0201C21.2714 19.1449 21.565 19.2143 21.8636 19.2244C22.1621 19.2346 22.4597 19.1851 22.739 19.079C23.0182 18.9729 23.2736 18.8122 23.4901 18.6064C23.7066 18.4005 23.8799 18.1536 24 17.8801C24.0634 17.5873 24.0677 17.2849 24.0127 16.9904C23.9577 16.696 23.8444 16.4155 23.6795 16.1654C23.5147 15.9153 23.3015 15.7007 23.0526 15.5341C22.8037 15.3674 22.524 15.2522 22.23 15.1951H22.2ZM20.34 10.2451C20.0073 9.99542 19.6009 9.86349 19.185 9.87008C18.4572 9.93018 17.7485 10.1341 17.1 10.4701C16.7447 10.6341 16.3789 10.7744 16.005 10.8901H15.69C15.5961 10.9108 15.4989 10.9108 15.405 10.8901C15 9.97508 16.5 9.00008 18.285 7.93508C18.8914 7.60883 19.4599 7.21644 19.98 6.76508C20.3961 6.30667 20.646 5.72169 20.6895 5.10413C20.733 4.48658 20.5677 3.87232 20.22 3.36008C19.9329 2.89588 19.5307 2.51381 19.0523 2.25098C18.574 1.98815 18.0358 1.85349 17.49 1.86008C17.2067 1.85969 16.9245 1.89496 16.65 1.96508C16.1585 2.08101 15.7042 2.31914 15.3293 2.65739C14.9543 2.99565 14.6708 3.42308 14.505 3.90008C14.16 4.75508 13.14 7.30508 12.135 7.71008C12.0359 7.72949 11.9341 7.72949 11.835 7.71008C11.6138 7.70259 11.3956 7.65692 11.19 7.57508C9.96 7.12508 9.6 5.62508 9.225 4.03508C9.06457 3.15891 8.79234 2.30695 8.415 1.50008C8.17043 1.04181 7.80465 0.659541 7.3576 0.395014C6.91055 0.130487 6.39941 -0.00612938 5.88 8.05856e-05C5.30686 0.011692 4.74338 0.149999 4.23 0.405081C3.872 0.589131 3.5547 0.843345 3.297 1.15258C3.03931 1.46182 2.84648 1.81976 2.73 2.20508C2.58357 2.66415 2.532 3.1482 2.57841 3.62781C2.62483 4.10743 2.76826 4.57261 3 4.99508C3.63898 5.99088 4.39988 6.90294 5.265 7.71008C5.59239 8.0233 5.90283 8.35377 6.195 8.70008C6.41249 8.94283 6.57687 9.22833 6.67761 9.5383C6.77835 9.84826 6.81322 10.1759 6.78 10.5001C6.68279 10.762 6.52008 10.9947 6.30737 11.1759C6.09467 11.3571 5.83908 11.4808 5.565 11.5351H5.19C4.89755 11.5247 4.60651 11.4896 4.32 11.4301C3.94485 11.3508 3.56329 11.3056 3.18 11.2951H3C2.50224 11.3269 2.02675 11.513 1.63964 11.8275C1.25253 12.142 0.973032 12.5694 0.84 13.0501C0.685221 13.5092 0.678705 14.0053 0.821373 14.4683C0.964041 14.9313 1.24867 15.3377 1.635 15.6301C1.97288 15.8809 2.38429 16.0127 2.805 16.0051C3.4891 15.9504 4.15377 15.751 4.755 15.4201C5.18104 15.1991 5.64344 15.0568 6.12 15.0001H6.285C6.32317 15.0086 6.35846 15.0269 6.38739 15.0532C6.41632 15.0795 6.4379 15.1129 6.45 15.1501C6.52858 15.4213 6.49621 15.7127 6.36 15.9601C5.80418 16.8088 4.95508 17.4229 3.975 17.6851C3.38444 17.8608 2.85799 18.205 2.46025 18.6756C2.06252 19.1462 1.81078 19.7226 1.73592 20.3342C1.66107 20.9458 1.76635 21.5659 2.03886 22.1185C2.31136 22.6711 2.73924 23.1321 3.27 23.4451C3.81477 23.8292 4.46349 24.0384 5.13 24.0451C6.1389 23.9485 7.08103 23.4979 7.7894 22.773C8.49778 22.0482 8.92665 21.0959 9 20.0851V19.9501C9.135 19.0351 9.33 17.7751 10.05 17.3401C10.2442 17.2216 10.4675 17.1593 10.695 17.1601C11.0828 17.1781 11.4558 17.3142 11.7641 17.5501C12.0724 17.786 12.3012 18.1105 12.42 18.4801C13.155 21.2251 13.725 23.4001 16.14 23.4001C16.4527 23.3961 16.7643 23.361 17.07 23.2951C17.8256 23.2158 18.5231 22.8527 19.0214 22.2792C19.5198 21.7057 19.7819 20.9644 19.755 20.2051C19.6664 19.6213 19.4389 19.0673 19.0918 18.5896C18.7446 18.112 18.2879 17.7246 17.76 17.4601C17.4534 17.2574 17.1625 17.0317 16.89 16.7851C16.005 15.9301 15.855 15.4051 15.885 15.1051C15.9198 14.8698 16.0313 14.6526 16.2021 14.4871C16.373 14.3217 16.5937 14.2173 16.83 14.1901H17.055C17.31 14.1901 17.61 14.1901 17.895 14.1901C18.18 14.1901 18.57 14.1901 18.84 14.1901H19.14C19.6172 14.1642 20.0748 13.9919 20.4505 13.6967C20.8263 13.4014 21.102 12.9976 21.24 12.5401C21.3316 12.1166 21.2981 11.6757 21.1436 11.2709C20.9892 10.8661 20.7204 10.5149 20.37 10.2601L20.34 10.2451Z"

View file

@ -81,8 +81,9 @@ function Paginate(props: Props) {
<FormField
value={textValue}
onChange={(e) => setTextValue(e.target.value)}
className="paginate-channel"
label={__('Go to page:')}
className="paginate-goto"
aria-label={__('Go to page:')}
placeholder={__('Go to')}
type="text"
name="paginate-file"
/>

View file

@ -118,7 +118,7 @@ function FileActions(props: Props) {
{!claimIsMine && (
<Menu>
<MenuButton
className="button--file-action"
className="button--file-action--menu"
onClick={(e) => {
e.stopPropagation();
e.preventDefault();

View file

@ -6,7 +6,6 @@ import classnames from 'classnames';
import Button from 'component/button';
import { formatNumberWithCommas } from 'util/number';
import NudgeFloating from 'component/nudgeFloating';
type Props = {
claim: StreamClaim,
doFetchReactions: (string) => void,
@ -57,26 +56,10 @@ function FileReactions(props: Props) {
<Button
title={__('I like this')}
authSrc="filereaction_like"
className={classnames('button--file-action', {
className={classnames('button--file-action button-like', {
'button--file-action-active': myReaction === REACTION_TYPES.LIKE,
})}
label={
<>
{/* Be nice to have animated Likes */}
{/* {myReaction === REACTION_TYPES.LIKE && SIMPLE_SITE && ( */}
{/* <> */}
{/* <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)}
</>
}
label={<>{formatNumberWithCommas(likeCount, 0)}</>}
iconSize={18}
icon={likeIcon}
onClick={() => doReactionLike(uri)}
@ -84,7 +67,7 @@ function FileReactions(props: Props) {
<Button
authSrc={'filereaction_dislike'}
title={__('I dislike this')}
className={classnames('button--file-action', {
className={classnames('button--file-action button-dislike', {
'button--file-action-active': myReaction === REACTION_TYPES.DISLIKE,
})}
label={<>{formatNumberWithCommas(dislikeCount, 0)}</>}

View file

@ -12,6 +12,7 @@ import { PRIMARY_PLAYER_WRAPPER_CLASS } from 'page/file/view';
import Draggable from 'react-draggable';
import { onFullscreenChange } from 'util/full-screen';
import { generateListSearchUrlParams, formatLbryUrlForWeb } from 'util/url';
import { useIsMobile } from 'effects/use-screensize';
import debounce from 'util/debounce';
import { useHistory } from 'react-router';
import { isURIEqual } from 'util/lbryURI';
@ -19,7 +20,8 @@ import AutoplayCountdown from 'component/autoplayCountdown';
// scss/init/vars.scss
// --header-height
const HEADER_HEIGHT = 64;
const HEADER_HEIGHT = 60;
const HEADER_HEIGHT_MOBILE = 60;
const IS_DESKTOP_MAC = typeof process === 'object' ? process.platform === 'darwin' : false;
const DEBOUNCE_WINDOW_RESIZE_HANDLER_MS = 100;
@ -130,6 +132,7 @@ export default function FileRenderFloating(props: Props) {
const hideFloatingPlayer = location.state && location.state.hideFloatingPlayer;
const playingUriSource = playingUri && playingUri.source;
const isComment = playingUriSource === 'comment';
const isMobile = useIsMobile();
const mainFilePlaying = !isFloating && primaryUri && isURIEqual(uri, primaryUri);
const [fileViewerRect, setFileViewerRect] = useState();
@ -245,14 +248,10 @@ export default function FileRenderFloating(props: Props) {
}, [handleResize]);
useEffect(() => {
// @if TARGET='app'
setDesktopPlayStartTime(Date.now());
// @endif
return () => {
// @if TARGET='app'
setDesktopPlayStartTime(undefined);
// @endif
};
}, [uri]);
@ -293,7 +292,7 @@ export default function FileRenderFloating(props: Props) {
if (
!isPlayable ||
!uri ||
(isFloating && (!floatingPlayerEnabled || hideFloatingPlayer)) ||
(isFloating && (isMobile || !floatingPlayerEnabled || hideFloatingPlayer)) ||
(collectionId && !isFloating && ((!canViewFile && !nextListUri) || countdownCanceled))
) {
return null;
@ -317,7 +316,6 @@ export default function FileRenderFloating(props: Props) {
function handleDragStop(e, ui) {
if (wasDragging) {
// e.stopPropagation();
setWasDragging(false);
}
@ -346,7 +344,7 @@ export default function FileRenderFloating(props: Props) {
'content__viewer--floating': isFloating,
'content__viewer--inline': !isFloating,
'content__viewer--secondary': isComment,
'content__viewer--theater-mode': !isFloating && videoTheaterMode,
'content__viewer--theater-mode': !isFloating && videoTheaterMode && playingUri?.uri === primaryUri,
'content__viewer--disable-click': wasDragging,
})}
style={
@ -355,7 +353,11 @@ export default function FileRenderFloating(props: Props) {
width: fileViewerRect.width,
height: fileViewerRect.height,
left: fileViewerRect.x,
top: fileViewerRect.windowOffset + fileViewerRect.top - HEADER_HEIGHT - (IS_DESKTOP_MAC ? 24 : 0),
top:
fileViewerRect.windowOffset +
fileViewerRect.top -
(isMobile ? HEADER_HEIGHT_MOBILE : HEADER_HEIGHT) -
(IS_DESKTOP_MAC ? 24 : 0),
}
: {}
}
@ -370,7 +372,7 @@ export default function FileRenderFloating(props: Props) {
title={__('Close')}
onClick={closeFloatingPlayer}
icon={ICONS.REMOVE}
button="primary"
button="alt"
className="content__floating-close"
/>
)}

View file

@ -57,7 +57,7 @@ $transition-duration: 300ms;
}
&.ff-responsive {
width: 100%;
max-width: 100%;
.ff-image,
.ff-canvas {

View file

@ -130,20 +130,28 @@ const Header = (props: Props) => {
}
>
<div>
<Button
// title={
// balance > 0
// ? __('Immediately spendable: %spendable_balance%', { spendable_balance: roundedSpendableBalance })
// : __('Your Wallet')
// }
navigate={`/$/${PAGES.WALLET}`}
className="button--file-action header__navigationItem--balance"
label={hideBalance || Number(roundedBalance) === 0 ? __('Your Wallet') : roundedBalance}
icon={ICONS.LBC}
onDoubleClick={(e) => {
e.stopPropagation();
}}
/>
{hideBalance ? (
<Button
navigate={`/$/${PAGES.WALLET}`}
className="header__navigationItem--icon header__navigationItem--balance"
label={!(hideBalance || Number(roundedBalance) === 0) && roundedBalance}
icon={ICONS.LBC}
iconSize={18}
onDoubleClick={(e) => {
e.stopPropagation();
}}
/>
) : (
<Button
navigate={`/$/${PAGES.WALLET}`}
className="button--file-action header__navigationItem--balance"
label={hideBalance || Number(roundedBalance) === 0 ? __('Your Wallet') : roundedBalance}
icon={ICONS.LBC}
onDoubleClick={(e) => {
e.stopPropagation();
}}
/>
)}
</div>
</Tooltip>
@ -157,11 +165,9 @@ const Header = (props: Props) => {
'header--minimal': authHeader,
'header--mac': IS_MAC,
})}
// @if TARGET='app'
onDoubleClick={(e) => {
remote.getCurrentWindow().maximize();
}}
// @endif
>
<div className="card__actions--between header__contents">
{!authHeader && canBackout ? (
@ -181,7 +187,7 @@ const Header = (props: Props) => {
<span style={{ position: 'relative' }}>
<Button
aria-label={sidebarLabel}
className="header__navigationItem--icon"
className="header__navigationItem--icon button-rotate"
icon={ICONS.MENU}
aria-expanded={sidebarOpen}
onClick={() => setSidebarOpen(!sidebarOpen)}

View file

@ -1,5 +1,4 @@
// @flow
// import 'scss/component/_header.scss'; // REMOVE!
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
import * as ICONS from 'constants/icons';

View file

@ -1,104 +1,85 @@
// @flow
import type { Node } from 'react';
import React, { Fragment } from 'react';
import classnames from 'classnames';
import SideNavigation from 'component/sideNavigation';
import SettingsSideNavigation from 'component/settingsSideNavigation';
import Header from 'component/header';
/* @if TARGET='app' */
import StatusBar from 'component/common/status-bar';
/* @endif */
import usePersistedState from 'effects/use-persisted-state';
import { MAIN_CLASS } from 'constants/classnames';
import { parseURI } from 'util/lbryURI';
import { useHistory } from 'react-router';
import { useIsMobile, useIsMediumScreen } from 'effects/use-screensize';
import { parseURI } from 'util/lbryURI';
import classnames from 'classnames';
import Header from 'component/header';
import React from 'react';
import Wallpaper from 'component/wallpaper';
import SettingsSideNavigation from 'component/settingsSideNavigation';
import SideNavigation from 'component/sideNavigation';
import StatusBar from 'component/common/status-bar';
import usePersistedState from 'effects/use-persisted-state';
import type { Element, Node } from 'react';
import { MAIN_CLASS } from 'constants/classnames';
type Props = {
children: Node | Array<Node>,
className: ?string,
autoUpdateDownloaded: boolean,
isUpgradeAvailable: boolean,
authPage: boolean,
filePage: boolean,
settingsPage?: boolean,
noHeader: boolean,
noFooter: boolean,
noSideNavigation: boolean,
fullWidthPage: boolean,
videoTheaterMode: boolean,
isMarkdown?: boolean,
chatDisabled: boolean,
rightSide?: Node,
backout: {
backLabel?: string,
backNavDefault?: string,
title: string,
simpleTitle: string, // Just use the same value as `title` if `title` is already short (~< 10 chars), unless you have a better idea for title overlfow on mobile
},
children: Node | Array<Node>,
className: ?string,
filePage: boolean,
fullWidthPage: boolean,
isMarkdown?: boolean,
noHeader: boolean,
noSideNavigation: boolean,
rightSide?: Element<any>,
settingsPage?: boolean,
videoTheaterMode: boolean,
};
function Page(props: Props) {
const {
authPage = false,
backout,
children,
className,
filePage = false,
settingsPage,
authPage = false,
fullWidthPage = false,
isMarkdown = false,
noHeader = false,
noSideNavigation = false,
backout,
videoTheaterMode,
isMarkdown = false,
rightSide,
settingsPage,
videoTheaterMode,
} = props;
const {
location: { pathname },
} = useHistory();
const [sidebarOpen, setSidebarOpen] = usePersistedState('sidebar', false);
const isMediumScreen = useIsMediumScreen();
const isMobile = useIsMobile();
const [sidebarOpen, setSidebarOpen] = usePersistedState('sidebar', false);
const url = pathname.slice(1).replace(/:/g, '#');
let isOnFilePage = false;
try {
const url = pathname.slice(1).replace(/:/g, '#');
const { isChannel } = parseURI(url);
if (!isChannel) {
isOnFilePage = true;
}
if (!isChannel) isOnFilePage = true;
} catch (e) {}
const isAbsoluteSideNavHidden = (isOnFilePage || isMobile) && !sidebarOpen;
function getSideNavElem() {
if (!authPage) {
if (settingsPage) {
return <SettingsSideNavigation />;
} else if (!noSideNavigation) {
return (
<SideNavigation
sidebarOpen={sidebarOpen}
setSidebarOpen={setSidebarOpen}
isMediumScreen={isMediumScreen}
isOnFilePage={isOnFilePage}
/>
);
}
}
return null;
}
React.useEffect(() => {
if (isOnFilePage || isMediumScreen) {
setSidebarOpen(false);
}
if (isOnFilePage || isMediumScreen) setSidebarOpen(false);
// TODO: make sure setState callback for usePersistedState uses useCallback to it doesn't cause effect to re-run
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isOnFilePage, isMediumScreen]);
return (
<Fragment>
<>
<Wallpaper uri={url} />
{!noHeader && (
<Header
authHeader={authPage}
@ -114,28 +95,46 @@ function Page(props: Props) {
'main-wrapper__inner--theater-mode': isOnFilePage && videoTheaterMode,
})}
>
{getSideNavElem()}
{!authPage &&
(settingsPage ? (
<SettingsSideNavigation />
) : (
!noSideNavigation && (
<SideNavigation
sidebarOpen={sidebarOpen}
setSidebarOpen={setSidebarOpen}
isMediumScreen={isMediumScreen}
isOnFilePage={isOnFilePage}
/>
)
))}
<main
id={'main-content'}
className={classnames(MAIN_CLASS, className, {
'main--full-width': fullWidthPage,
'main--auth-page': authPage,
'main--file-page': filePage,
'main--settings-page': settingsPage,
'main--markdown': isMarkdown,
'main--theater-mode': isOnFilePage && videoTheaterMode,
<div
className={classnames({
'sidebar--pusher': fullWidthPage,
'sidebar--pusher--open': sidebarOpen && fullWidthPage,
'sidebar--pusher--filepage': !fullWidthPage,
})}
>
{children}
<main
id={'main-content'}
className={classnames(MAIN_CLASS, className, {
'main--full-width': fullWidthPage,
'main--auth-page': authPage,
'main--file-page': filePage,
'main--settings-page': settingsPage,
'main--markdown': isMarkdown,
'main--theater-mode': isOnFilePage && videoTheaterMode && !isMarkdown,
})}
>
{children}
{!isMobile && rightSide && <div className="main__right-side">{rightSide}</div>}
</main>
{/* @if TARGET='app' */}
<StatusBar />
{/* @endif */}
{!isMobile && rightSide && <div className="main__right-side">{rightSide}</div>}
</main>
<StatusBar />
</div>
</div>
</Fragment>
</>
);
}

View file

@ -52,17 +52,16 @@ function PostViewer(props: Props) {
return (
<div className="post">
<FileTitle uri={uri} className="post__title">
<span className="post__date">
<DateTime uri={uri} show={DateTime.SHOW_DATE} />
</span>
</FileTitle>
<FileTitle uri={uri} className="post__title" />
<div
className={classnames('post__info', {
'post__info--expanded': expand !== EXPAND.NONE,
})}
>
<span className="post__date">
<DateTime uri={uri} type="date" />
<FileViewCount uri={uri} />
</span>
<div className="post__info--grouped">
<Button
button="link"
@ -86,7 +85,6 @@ function PostViewer(props: Props) {
/>
)}
</div>
<FileViewCount uri={uri} />
</div>
{expand === EXPAND.CREDIT_DETAILS && (

View file

@ -129,6 +129,7 @@ function PublishForm(props: Props) {
hasClaimedInitialRewards,
} = props;
const inEditMode = Boolean(editingURI);
const { replace, location } = useHistory();
const urlParams = new URLSearchParams(location.search);
const TYPE_PARAM = 'type';
@ -137,7 +138,7 @@ function PublishForm(props: Props) {
// $FlowFixMe
const AVAILABLE_MODES = Object.values(PUBLISH_MODES).filter((mode) => {
// $FlowFixMe
if (editingURI) {
if (inEditMode) {
if (isPostClaim) {
return mode === PUBLISH_MODES.POST;
} else {
@ -248,7 +249,7 @@ function PublishForm(props: Props) {
submitLabel = __('Uploading...');
}
} else if (previewing) {
submitLabel = __('Preparing...');
submitLabel = <Spinner type="small" />;
} else {
if (isStillEditing) {
submitLabel = __('Save');
@ -498,6 +499,7 @@ function PublishForm(props: Props) {
<div className={classnames({ 'card--disabled': formDisabled })}>
{mode !== PUBLISH_MODES.POST && <PublishDescription disabled={formDisabled} />}
<Card actions={<SelectThumbnail />} />
<label>{__('Tags')}</label>
<TagsSelect
suggestMature
disableAutoFocus

View file

@ -27,9 +27,9 @@ const PublishPending = (props: Props) => {
return <span>{__('Uploading (%progress%%) ', { progress: progress })}</span>;
} else {
return (
<span>
<div className="confirming-change">
{__('Confirming...')} <Spinner type="small" />
</span>
</div>
);
}
};

View file

@ -14,44 +14,47 @@ function PublishPrice(props: Props) {
const { contentIsFree, fee, updatePublishForm, disabled } = props;
return (
<Card
actions={
<React.Fragment>
<FormField
type="radio"
name="content_free"
label={__('Free')}
checked={contentIsFree}
disabled={disabled}
onChange={() => updatePublishForm({ contentIsFree: true })}
/>
<FormField
type="radio"
name="content_cost"
label={__('Add a price to this file')}
checked={!contentIsFree}
disabled={disabled}
onChange={() => updatePublishForm({ contentIsFree: false })}
/>
{!contentIsFree && (
<FormFieldPrice
name="content_cost_amount"
min={0}
price={fee}
onChange={newFee => updatePublishForm({ fee: newFee })}
<>
<label>{__('Price')}</label>
<Card
actions={
<React.Fragment>
<FormField
type="radio"
name="content_free"
label={__('Free')}
checked={contentIsFree}
disabled={disabled}
onChange={() => updatePublishForm({ contentIsFree: true })}
/>
)}
{fee && fee.currency !== 'LBC' && (
<p className="form-field__help">
{__(
'All content fees are charged in LBRY Credits. For alternative payment methods, the number of LBRY Credits charged will be adjusted based on the value of LBRY Credits at the time of purchase.'
)}
</p>
)}
</React.Fragment>
}
/>
<FormField
type="radio"
name="content_cost"
label={__('Add a price to this file')}
checked={!contentIsFree}
disabled={disabled}
onChange={() => updatePublishForm({ contentIsFree: false })}
/>
{!contentIsFree && (
<FormFieldPrice
name="content_cost_amount"
min={0}
price={fee}
onChange={(newFee) => updatePublishForm({ fee: newFee })}
/>
)}
{fee && fee.currency !== 'LBC' && (
<p className="form-field__help">
{__(
'All content fees are charged in LBRY Credits. For alternative payment methods, the number of LBRY Credits charged will be adjusted based on the value of LBRY Credits at the time of purchase.'
)}
</p>
)}
</React.Fragment>
}
/>
</>
);
}

View file

@ -0,0 +1,6 @@
import { connect } from 'react-redux';
import RatioBar from './view';
const select = (state, props) => ({});
export default connect(select)(RatioBar);

View file

@ -0,0 +1,25 @@
// @flow
import React from 'react';
type Props = {
likeCount: number,
dislikeCount: number,
};
const RatioBar = (props: Props) => {
const { likeCount, dislikeCount } = props;
const like = (1 / (likeCount + dislikeCount)) * likeCount;
if (like || dislikeCount) {
return (
<div className={'ratio-bar'}>
<div className={'ratio-bar-like'} style={{ flex: like }} />
<div className={'ratio-bar-dislike'} style={{ flex: 1 - like }} />
</div>
);
} else {
return <div className={'ratio-bar'} />;
}
};
export default RatioBar;

View file

@ -68,18 +68,18 @@ export default React.memo<Props>(function RecommendedContent(props: Props) {
title={__('Related')}
titleActions={
signingChannel && (
<div className="recommended-content__toggles">
<div className="recommended-content__bubble">
<Button
className={classnames('button-toggle', {
'button-toggle--active': viewMode === VIEW_ALL_RELATED,
className={classnames('button-bubble', {
'button-bubble--active': viewMode === VIEW_ALL_RELATED,
})}
label={__('All')}
label={__('Related')}
onClick={() => setViewMode(VIEW_ALL_RELATED)}
/>
<Button
className={classnames('button-toggle', {
'button-toggle--active': viewMode === VIEW_MORE_FROM,
className={classnames('button-bubble', {
'button-bubble--active': viewMode === VIEW_MORE_FROM,
})}
label={__('More from %claim_name%', { claim_name: channelName })}
onClick={() => setViewMode(VIEW_MORE_FROM)}

View file

@ -326,6 +326,7 @@ function RepostCreate(props: Props) {
return (
<>
<Card
className="repost-wrapper"
actions={
<div>
<ChannelSelector />

View file

@ -99,7 +99,9 @@ function SelectThumbnail(props: Props) {
*/
const thumbPreview = (
<div className="column__item thumbnail-picker__preview" style={{ backgroundImage: `url(${String(thumbnailSrc)})` }}>
{thumbUploaded && thumbnailError !== false && __('This will be visible in a few minutes.')}
{thumbUploaded &&
thumbnailError !== false &&
__('This will be visible in a few minutes after you submit this form.')}
<img
style={{ display: 'none' }}
src={thumbnail}
@ -121,64 +123,67 @@ function SelectThumbnail(props: Props) {
return (
<>
{status !== THUMBNAIL_STATUSES.IN_PROGRESS && (
<div className="column">
{thumbPreview}
{publishForm && thumbUploaded ? (
<div className="column__item">
<p>{__('Upload complete.')}</p>
<div className="section__actions">
<Button button="link" label={__('New thumbnail')} onClick={resetThumbnailStatus} />
<>
<label>{__('Thumbnail')}</label>
<div className="column">
{thumbPreview}
{publishForm && thumbUploaded ? (
<div className="column__item">
<p>{__('Upload complete.')}</p>
<div className="section__actions">
<Button button="link" label={__('New thumbnail')} onClick={resetThumbnailStatus} />
</div>
</div>
</div>
) : (
<div className="column__item">
{manualInput ? (
<FormField
type="text"
name="content_thumbnail"
label="URL"
placeholder="https://images.fbi.gov/alien"
value={thumbnail}
disabled={formDisabled}
onChange={handleThumbnailChange}
/>
) : (
<FileSelector
currentPath={thumbnailPath}
label={__('Thumbnail')}
placeholder={__('Choose an enticing thumbnail')}
accept={accept}
onFileChosen={(file) =>
openModal(MODALS.CONFIRM_THUMBNAIL_UPLOAD, {
file,
cb: (url) => !publishForm && updateThumbnailParams({ thumbnail_url: url }),
})
}
/>
)}
<div className="card__actions">
<Button
button="link"
label={manualInput ? __('Use thumbnail upload tool') : __('Enter a thumbnail URL')}
onClick={() =>
updatePublishForm({
uploadThumbnailStatus: manualInput ? THUMBNAIL_STATUSES.READY : THUMBNAIL_STATUSES.MANUAL,
})
}
/>
{status === THUMBNAIL_STATUSES.READY && isSupportedVideo && (
// Disabled on desktop until this is resolved
// https://github.com/electron/electron/issues/20750#issuecomment-709505902
<Button
button="link"
label={__('Take a snapshot from your video')}
onClick={() => openModal(MODALS.AUTO_GENERATE_THUMBNAIL, { filePath: actualFilePath })}
) : (
<div className="column__item">
{manualInput ? (
<FormField
type="text"
name="content_thumbnail"
label="URL"
placeholder="https://images.fbi.gov/alien"
value={thumbnail}
disabled={formDisabled}
onChange={handleThumbnailChange}
/>
) : (
<FileSelector
currentPath={thumbnailPath}
label={__('Thumbnail')}
placeholder={__('Choose an enticing thumbnail')}
accept={accept}
onFileChosen={(file) =>
openModal(MODALS.CONFIRM_THUMBNAIL_UPLOAD, {
file,
cb: (url) => !publishForm && updateThumbnailParams({ thumbnail_url: url }),
})
}
/>
)}
<div className="card__actions">
<Button
button="link"
label={manualInput ? __('Use thumbnail upload tool') : __('Enter a thumbnail URL')}
onClick={() =>
updatePublishForm({
uploadThumbnailStatus: manualInput ? THUMBNAIL_STATUSES.READY : THUMBNAIL_STATUSES.MANUAL,
})
}
/>
{status === THUMBNAIL_STATUSES.READY && isSupportedVideo && (
// Disabled on desktop until this is resolved
// https://github.com/electron/electron/issues/20750#issuecomment-709505902
<Button
button="link"
label={__('Take a snapshot from your video')}
onClick={() => openModal(MODALS.AUTO_GENERATE_THUMBNAIL, { filePath: actualFilePath })}
/>
)}
</div>
</div>
</div>
)}
</div>
)}
</div>
</>
)}
{status === THUMBNAIL_STATUSES.IN_PROGRESS && <p>{__('Uploading thumbnail')}...</p>}

View file

@ -400,7 +400,7 @@ export default function SettingSystem(props: Props) {
subtitle={__('This might fix issues that you are having. Your wallet will not be affected.')}
>
<Button
button="secondary"
button="primary"
icon={ALERT}
label={clearingCache ? __('Clearing') : __('Clear Cache')}
onClick={() => {

View file

@ -7,16 +7,17 @@ type Props = {
subtitle?: string,
multirow?: boolean, // Displays the Value widget(s) below the Label instead of on the right.
useVerticalSeparator?: boolean, // Show a separator line between Label and Value. Useful when there are multiple Values.
disabled?: boolean,
children?: React$Node,
};
export default function SettingsRow(props: Props) {
const { title, subtitle, multirow, useVerticalSeparator, children } = props;
const { title, subtitle, multirow, useVerticalSeparator, disabled, children } = props;
return (
<div
className={classnames('card__main-actions settings__row', {
'section__actions--between': !multirow,
'opacity-30': disabled,
})}
>
<div className="settings__row--title">

View file

@ -14,7 +14,7 @@ export default function ShareButton(props: Props) {
return (
<Button
button="alt"
button="secondary"
icon={ICONS.SHARE}
label={__('Share')}
title={__('Share this channel')}

View file

@ -8,18 +8,29 @@ import Button from 'component/button';
import classnames from 'classnames';
import Icon from 'component/common/icon';
import NotificationBubble from 'component/notificationBubble';
import DebouncedInput from 'component/common/debounced-input';
import I18nMessage from 'component/i18nMessage';
import ChannelThumbnail from 'component/channelThumbnail';
import { DOMAIN, ENABLE_UI_NOTIFICATIONS } from 'config';
import { useIsMobile, isTouch } from 'effects/use-screensize';
import { IS_MAC } from 'component/app/view';
import { useHistory } from 'react-router';
import { DOMAIN, ENABLE_UI_NOTIFICATIONS } from 'config';
const RECENT_FROM_FOLLOWING = {
title: 'Following --[sidebar button]--',
link: `/$/${PAGES.CHANNELS_FOLLOWING}`,
icon: ICONS.SUBSCRIBE,
const FOLLOWED_ITEM_INITIAL_LIMIT = 10;
const touch = isTouch();
type SideNavLink = {
title: string,
link?: string,
route?: string,
onClick?: () => any,
icon: string,
extra?: Node,
hideForUnauth?: boolean,
};
// ****************************************************************************
// ****************************************************************************
type Props = {
subscriptions: Array<Subscription>,
followedTags: Array<Tag>,
@ -35,16 +46,7 @@ type Props = {
doClearPurchasedUriSuccess: () => void,
user: ?User,
homepageData: any,
};
type SideNavLink = {
title: string,
link?: string,
route?: string,
onClick?: () => any,
icon: string,
extra?: Node,
hideForUnauth?: boolean,
activeChannelStakedLevel: number,
};
function SideNavigation(props: Props) {
@ -75,34 +77,39 @@ function SideNavigation(props: Props) {
if (pathname === '/') window.location.reload();
},
};
const FULL_LINKS: Array<SideNavLink> = [
{
title: 'Your Tags',
link: `/$/${PAGES.TAGS_FOLLOWING}`,
icon: ICONS.TAG,
hideForUnauth: true,
},
{
title: 'Discover',
link: `/$/${PAGES.DISCOVER}`,
icon: ICONS.DISCOVER,
},
{
title: 'Library',
link: `/$/${PAGES.LIBRARY}`,
icon: ICONS.PURCHASED,
hideForUnauth: true,
},
];
const RECENT_FROM_FOLLOWING = {
title: 'Following --[sidebar button]--',
link: `/$/${PAGES.CHANNELS_FOLLOWING}`,
icon: ICONS.SUBSCRIBE,
};
const DISCOVER = {
title: 'Discover',
link: `/$/${PAGES.DISCOVER}`,
icon: ICONS.DISCOVER,
};
const LIBRARY = {
title: 'Library',
link: `/$/${PAGES.LIBRARY}`,
icon: ICONS.PURCHASED,
};
const NOTIFICATIONS = {
title: 'Notifications',
link: `/$/${PAGES.NOTIFICATIONS}`,
icon: ICONS.NOTIFICATION,
extra: <NotificationBubble inline />,
};
const PLAYLISTS = {
title: 'Lists',
link: `/$/${PAGES.LISTS}`,
icon: ICONS.STACK,
};
const MOBILE_LINKS: Array<SideNavLink> = [
{
title: 'Notifications',
link: `/$/${PAGES.NOTIFICATIONS}`,
icon: ICONS.NOTIFICATION,
extra: <NotificationBubble inline />,
hideForUnauth: true,
},
{
title: 'Upload',
link: `/$/${PAGES.UPLOAD}`,
@ -171,56 +178,149 @@ function SideNavigation(props: Props) {
},
];
const UNAUTH_LINKS: Array<SideNavLink> = [
{
title: 'Log In',
link: `/$/${PAGES.AUTH_SIGNIN}`,
icon: ICONS.SIGN_IN,
},
{
title: 'Sign Up',
link: `/$/${PAGES.AUTH}`,
icon: ICONS.SIGN_UP,
},
{
title: 'Settings',
link: `/$/${PAGES.SETTINGS}`,
icon: ICONS.SETTINGS,
},
{
title: 'Help',
link: `/$/${PAGES.HELP}`,
icon: ICONS.HELP,
},
];
const notificationsEnabled = ENABLE_UI_NOTIFICATIONS || (user && user.experimental_ui);
const isAuthenticated = Boolean(email);
// SIDE LINKS: FOLLOWING, HOME, [FULL,] [EXTRA]
let SIDE_LINKS: Array<SideNavLink> = [];
SIDE_LINKS.push(HOME);
SIDE_LINKS.push(RECENT_FROM_FOLLOWING);
FULL_LINKS.push({
title: 'Lists',
link: `/$/${PAGES.LISTS}`,
icon: ICONS.STACK,
hideForUnauth: true,
});
SIDE_LINKS.push(...FULL_LINKS);
const [pulseLibrary, setPulseLibrary] = React.useState(false);
const isAbsolute = isOnFilePage || isMediumScreen;
const microNavigation = !sidebarOpen || isMediumScreen;
const subLinks = email
? MOBILE_LINKS.filter((link) => {
if (!notificationsEnabled && link.icon === ICONS.NOTIFICATION) {
return false;
}
const [expandSubscriptions, setExpandSubscriptions] = React.useState(false);
const [expandTags, setExpandTags] = React.useState(false);
return true;
})
: UNAUTH_LINKS;
const isAbsolute = isOnFilePage || isMediumScreen;
const isMobile = useIsMobile();
const [menuInitialized, setMenuInitialized] = React.useState(false);
const menuCanCloseCompletely = (isOnFilePage && !isMobile) || (isMobile && menuInitialized);
const hideMenuFromView = menuCanCloseCompletely && !sidebarOpen;
const [canDisposeMenu, setCanDisposeMenu] = React.useState(false);
React.useEffect(() => {
if (hideMenuFromView || !menuInitialized) {
const handler = setTimeout(() => {
setMenuInitialized(true);
setCanDisposeMenu(true);
}, 250);
return () => {
clearTimeout(handler);
};
} else {
setCanDisposeMenu(false);
}
}, [hideMenuFromView, menuInitialized]);
const shouldRenderLargeMenu = menuCanCloseCompletely || sidebarOpen;
const showMicroMenu = !sidebarOpen && !menuCanCloseCompletely;
const showPushMenu = sidebarOpen && !menuCanCloseCompletely;
const showSubscriptionSection = shouldRenderLargeMenu && subscriptions && subscriptions.length > 0;
const showTagSection = sidebarOpen && followedTags && followedTags.length;
const [subscriptionFilter, setSubscriptionFilter] = React.useState('');
const filteredSubscriptions = subscriptions.filter(
(sub) => !subscriptionFilter || sub.channelName.toLowerCase().includes(subscriptionFilter.toLowerCase())
);
let displayedSubscriptions = filteredSubscriptions;
if (
showSubscriptionSection &&
!subscriptionFilter &&
subscriptions.length > FOLLOWED_ITEM_INITIAL_LIMIT &&
!expandSubscriptions
) {
displayedSubscriptions = subscriptions.slice(0, FOLLOWED_ITEM_INITIAL_LIMIT);
}
let displayedFollowedTags = followedTags;
if (showTagSection && followedTags.length > FOLLOWED_ITEM_INITIAL_LIMIT && !expandTags) {
displayedFollowedTags = followedTags.slice(0, FOLLOWED_ITEM_INITIAL_LIMIT);
}
function getLink(props: SideNavLink) {
const { hideForUnauth, route, link, ...passedProps } = props;
const { title, icon, extra } = passedProps;
if (hideForUnauth && !email) {
return null;
}
return (
<li key={route || link || title}>
<Button
{...passedProps}
icon={icon}
navigate={route || link}
label={__(title)}
title={__(title)}
className={classnames('navigation-link', {
'navigation-link--pulse': icon === ICONS.LIBRARY && pulseLibrary,
'navigation-link--highlighted': icon === ICONS.NOTIFICATION && unseenCount > 0,
})}
activeClass="navigation-link--active"
/>
{extra && extra}
</li>
);
}
function getSubscriptionSection() {
if (showSubscriptionSection) {
return (
<>
<ul className="navigation__secondary navigation-links">
{subscriptions.length > FOLLOWED_ITEM_INITIAL_LIMIT && (
<li className="navigation-item">
<DebouncedInput icon={ICONS.SEARCH} placeholder={__('Filter')} onChange={setSubscriptionFilter} />
</li>
)}
{displayedSubscriptions.map((subscription) => (
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
))}
{!!subscriptionFilter && !displayedSubscriptions.length && (
<li>
<div className="navigation-item">
<div className="empty empty--centered">{__('No results')}</div>
</div>
</li>
)}
{!subscriptionFilter && subscriptions.length > FOLLOWED_ITEM_INITIAL_LIMIT && (
<Button
key="showMore"
label={expandSubscriptions ? __('Show less') : __('Show more')}
className="navigation-link"
onClick={() => setExpandSubscriptions(!expandSubscriptions)}
/>
)}
</ul>
</>
);
}
return null;
}
function getFollowedTagsSection() {
if (showTagSection) {
return (
<>
<ul className="navigation__secondary navigation-links">
{displayedFollowedTags.map(({ name }, key) => (
<li key={name} className="navigation-link__wrapper">
<Button navigate={`/$/discover?t=${name}`} label={`#${name}`} className="navigation-link" />
</li>
))}
{followedTags.length > FOLLOWED_ITEM_INITIAL_LIMIT && (
<Button
key="showMore"
label={expandTags ? __('Show less') : __('Show more')}
className="navigation-link"
onClick={() => setExpandTags(!expandTags)}
/>
)}
</ul>
</>
);
}
return null;
}
React.useEffect(() => {
if (purchaseSuccess) {
@ -292,151 +392,56 @@ function SideNavigation(props: Props) {
return (
<div
className={classnames('navigation__wrapper', {
'navigation__wrapper--micro': microNavigation && !isOnFilePage,
'navigation__wrapper--micro': showMicroMenu,
'navigation__wrapper--absolute': isAbsolute,
})}
>
{!isOnFilePage && (
<nav
aria-label={'Sidebar'}
className={classnames('navigation', {
'navigation--micro': microNavigation,
// @if TARGET='app'
'navigation--mac': IS_MAC,
// @endif
})}
>
<div>
<ul className={classnames('navigation-links', { 'navigation-links--micro': !sidebarOpen })}>
{SIDE_LINKS.map((linkProps) => {
// $FlowFixMe
const { hideForUnauth, ...passedProps } = linkProps;
return (
<li key={linkProps.route || linkProps.link}>
<Button
{...passedProps}
label={__(linkProps.title)}
title={__(linkProps.title)}
// $FlowFixMe
navigate={linkProps.route || linkProps.link}
icon={pulseLibrary && linkProps.icon === ICONS.LIBRARY ? ICONS.PURCHASED : linkProps.icon}
className={classnames('navigation-link', {
'navigation-link--pulse': linkProps.icon === ICONS.LIBRARY && pulseLibrary,
'navigation-link--highlighted': linkProps.icon === ICONS.NOTIFICATION && unseenCount > 0,
})}
activeClass="navigation-link--active"
/>
{linkProps.extra && linkProps.extra}
</li>
);
<nav
aria-label={'Sidebar'}
className={classnames('navigation', {
'navigation--micro': showMicroMenu,
'navigation--push': showPushMenu,
'navigation-file-page-and-mobile': hideMenuFromView,
'navigation-touch': touch,
// @if TARGET='app'
'navigation--mac': IS_MAC,
// @endif
})}
>
{(!canDisposeMenu || sidebarOpen) && (
<div className="navigation-inner-container">
<ul className="navigation-links--absolute mobile-only">{notificationsEnabled && getLink(NOTIFICATIONS)}</ul>
<ul
className={classnames('navigation-links', {
'navigation-links--micro': showMicroMenu,
'navigation-links--absolute': shouldRenderLargeMenu,
'navigation--mac': IS_MAC,
})}
>
{getLink(HOME)}
{getLink(RECENT_FROM_FOLLOWING)}
{getLink(DISCOVER)}
{getLink(LIBRARY)}
{getLink(PLAYLISTS)}
</ul>
<ul className="navigation-links--absolute mobile-only">
{email && MOBILE_LINKS.map((linkProps) => getLink(linkProps))}
</ul>
{sidebarOpen && subscriptions && subscriptions.length > 0 && (
<ul className="navigation__secondary navigation-links">
{subscriptions.map((subscription) => (
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
))}
</ul>
)}
{sidebarOpen && followedTags && followedTags.length > 0 && (
<ul className="navigation__secondary navigation-links navigation-links--small">
{followedTags.map(({ name }, key) => (
<li key={name} className="navigation-link__wrapper">
<Button navigate={`/$/discover?t=${name}`} label={`#${name}`} className="navigation-link" />
</li>
))}
</ul>
)}
{getSubscriptionSection()}
{getFollowedTagsSection()}
{!isAuthenticated && sidebarOpen && unAuthNudge}
</div>
{sidebarOpen && helpLinks}
</nav>
)}
{(isOnFilePage || isMediumScreen) && sidebarOpen && (
<>
<nav
className={classnames('navigation--absolute', {
// @if TARGET='app'
'navigation--mac': IS_MAC,
// @endif
})}
>
<div>
<ul className="navigation-links--absolute">
{SIDE_LINKS.map((linkProps) => {
// $FlowFixMe
const { hideForUnauth, link, route, ...passedProps } = linkProps;
return (
<li key={route || link}>
<Button
{...passedProps}
navigate={route || link}
label={__(linkProps.title)}
title={__(linkProps.title)}
icon={pulseLibrary && linkProps.icon === ICONS.LIBRARY ? ICONS.PURCHASED : linkProps.icon}
className={classnames('navigation-link', {
'navigation-link--pulse': linkProps.icon === ICONS.LIBRARY && pulseLibrary,
'navigation-link--highlighted': linkProps.icon === ICONS.NOTIFICATION && unseenCount > 0,
})}
activeClass="navigation-link--active"
/>
{linkProps.extra && linkProps.extra}
</li>
);
})}
</ul>
<ul className="navigation-links--absolute mobile-only">
{subLinks.map((linkProps) => {
const { hideForUnauth, ...passedProps } = linkProps;
return (
<li key={linkProps.title} className="mobile-only">
<Button
{...passedProps}
navigate={linkProps.link}
label={__(linkProps.title)}
title={__(linkProps.title)}
className="navigation-link"
activeClass="navigation-link--active"
/>
{linkProps.extra}
</li>
);
})}
</ul>
{sidebarOpen && subscriptions && subscriptions.length > 0 && (
<ul className="navigation__secondary navigation-links">
{subscriptions.map((subscription) => (
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
))}
</ul>
)}
{sidebarOpen && followedTags && followedTags.length > 0 && (
<ul className="navigation__secondary navigation-links navigation-links--small">
{followedTags.map(({ name }, key) => (
<li key={name} className="navigation-link__wrapper">
<Button navigate={`/$/discover?t=${name}`} label={`#${name}`} className="navigation-link" />
</li>
))}
</ul>
)}
{!isAuthenticated && unAuthNudge}
</div>
</nav>
<div
className={classnames('navigation__overlay', {
// @if TARGET='app'
'navigation__overlay--mac': IS_MAC,
// @endif
})}
onClick={() => setSidebarOpen(false)}
/>
</>
)}
)}
{(!canDisposeMenu || sidebarOpen) && shouldRenderLargeMenu && helpLinks}
</nav>
<div
className={classnames('navigation__overlay', {
'navigation__overlay--active': isAbsolute && sidebarOpen,
})}
onClick={() => setSidebarOpen(false)}
/>
</div>
);
}

View file

@ -69,7 +69,7 @@ export default function SubscribeButton(props: Props) {
if (isSubscribed && !permanentUrl && rawChannelName) {
return (
<div className="button-group">
<div className="button-group button-group-subscribed">
<Button
ref={buttonRef}
iconColor="red"
@ -100,6 +100,7 @@ export default function SubscribeButton(props: Props) {
<Button
ref={buttonRef}
iconColor="red"
className={isSubscribed ? 'button-following' : ''}
largestLabel={isMobile && shrinkOnMobile ? '' : subscriptionLabel}
icon={unfollowOverride ? ICONS.UNSUBSCRIBE : isSubscribed ? ICONS.SUBSCRIBED : ICONS.SUBSCRIBE}
button={'alt'}
@ -119,32 +120,35 @@ export default function SubscribeButton(props: Props) {
}}
/>
{isSubscribed && uiNotificationsEnabled && (
<Button
button="alt"
icon={notificationsDisabled ? ICONS.BELL : ICONS.BELL_ON}
aria-label={notificationsDisabled ? __('Turn on notifications') : __('Turn off notifications')}
onClick={() => {
const newNotificationsDisabled = !notificationsDisabled;
<>
<Button
button="alt"
icon={notificationsDisabled ? ICONS.BELL : ICONS.BELL_ON}
className={isSubscribed ? 'button-following' : ''}
aria-label={notificationsDisabled ? __('Turn on notifications') : __('Turn off notifications')}
onClick={() => {
const newNotificationsDisabled = !notificationsDisabled;
doChannelSubscribe(
{
channelName: claimName,
uri: permanentUrl,
notificationsDisabled: newNotificationsDisabled,
},
false
);
doChannelSubscribe(
{
channelName: claimName,
uri: permanentUrl,
notificationsDisabled: newNotificationsDisabled,
},
false
);
doToast({
message: __(
newNotificationsDisabled
? 'Notifications turned off for %channel%'
: 'Notifications turned on for %channel%!',
{ channel: claimName }
),
});
}}
/>
doToast({
message: __(
newNotificationsDisabled
? 'Notifications turned off for %channel%'
: 'Notifications turned on for %channel%!',
{ channel: claimName }
),
});
}}
/>
</>
)}
</div>
) : null;

View file

@ -33,10 +33,10 @@ function TransactionListTable(props: Props) {
<table className="table table--transactions">
<thead>
<tr>
<th>{__('Date')}</th>
<th>{<>{__('Type')}</>}</th>
<th className="table-column-lbc-date">{__('Date')}</th>
<th className="table-column-lbc-type">{<>{__('Type')}</>}</th>
<th>{__('Details')} </th>
<th>{__('Transaction')}</th>
<th className="table-column-lbc-transaction">{__('Transaction')}</th>
<th className="table__item--align-right">
<LbcSymbol size={18} />
</th>

View file

@ -25,6 +25,14 @@ const VideoJsEvents = ({
playerRef,
autoplaySetting,
replay,
claimId,
userId,
claimValues,
embedded,
uri,
doAnalyticsView,
claimRewards,
playerServerRef,
}: {
tapToUnmuteRef: any, // DOM element
tapToRetryRef: any, // DOM element
@ -33,6 +41,15 @@ const VideoJsEvents = ({
playerRef: any, // DOM element
autoplaySetting: boolean,
replay: boolean,
claimId?: ?string,
userId?: ?number,
claimValues?: any,
embedded?: boolean,
clearPosition?: (string) => void,
uri?: string,
doAnalyticsView?: (string, number) => any,
claimRewards?: () => void,
playerServerRef?: any,
}) => {
// Override the player's control text. We override to:
// 1. Add keyboard shortcut to the tool-tip.
@ -93,6 +110,10 @@ const VideoJsEvents = ({
function onInitialPlay() {
const player = playerRef.current;
const bigPlayButton = document.querySelector('.vjs-big-play-button');
if (bigPlayButton) bigPlayButton.style.setProperty('display', 'none');
if (player && (player.muted() || player.volume() === 0)) {
// The css starts as "hidden". We make it visible here without
// re-rendering the whole thing.
@ -223,6 +244,19 @@ const VideoJsEvents = ({
player.on('volumechange', resolveCtrlText);
player.on('volumechange', onVolumeChange);
player.on('error', onError);
// custom tracking plugin, event used for watchman data, and marking view/getting rewards
// hide forcing control bar show
player.on('canplaythrough', function () {
setTimeout(function () {
// $FlowFixMe
const vjsControlBar = document.querySelector('.vjs-control-bar');
if (vjsControlBar) vjsControlBar.style.removeProperty('opacity');
}, 1000 * 3); // wait 3 seconds to hit control bar
});
player.on('playing', function () {
// $FlowFixMe
document.querySelector('.vjs-big-play-button').style.setProperty('display', 'none', 'important');
});
// player.on('ended', onEnded);
}

View file

@ -0,0 +1,16 @@
import { connect } from 'react-redux';
// import { makeSelectCoverForUri, makeSelectAvatarForUri } from 'redux/selectors/claims';
import Wallpaper from './view';
/*
const select = (state, props) => {
if (props.uri && (props.uri.indexOf('@') !== -1 || props.uri.indexOf('#') !== -1)) {
return {
cover: makeSelectCoverForUri(props.uri)(state),
avatar: makeSelectAvatarForUri(props.uri)(state),
};
} else return {};
};
*/
export default connect()(Wallpaper);

View file

@ -0,0 +1,244 @@
// @flow
import React from 'react';
// import { resetColors } from 'util/theme';
// $FlowFixMe cannot resolve ...
import freeezepeach from 'static/img/freespch.png';
type Props = {
// uri: ?string,
// cover: ?string,
// avatar: ?string,
reset: ?boolean,
};
const Wallpaper = (props: Props) => {
// const { cover, avatar } = props;
/*
if (avatar) {
toDataUrl(avatar, function (image) {
if (image) {
let threshold = 155;
getAverageRGB(image, function (rgb) {
let brightness = Math.round((parseInt(rgb.r) * 299 + parseInt(rgb.g) * 587 + parseInt(rgb.b) * 114) / 1000);
if (colorCompare(rgb) < 15) {
rgb = colorMixer(rgb, brightness > threshold ? { r: 0, g: 0, b: 0 } : { r: 255, g: 255, b: 255 }, 0.7);
}
// Tune link color in light theme
if (document.documentElement !== null) {
if (getComputedStyle(document.documentElement).getPropertyValue('--color-text') === ' #000000') {
let link = colorMixer(
rgb,
brightness > threshold ? { r: 0, g: 0, b: 0 } : { r: 255, g: 255, b: 255 },
0.8
);
document.documentElement !== null &&
document.documentElement.style.setProperty(
'--color-link',
'rgba(' + link.r + ',' + link.g + ',' + link.b + ', 1)'
);
} else {
document.documentElement !== null &&
document.documentElement.style.setProperty('--color-link', 'var(--color-primary)');
}
}
document.documentElement !== null &&
document.documentElement.style.setProperty('--color-primary-dynamic', rgb.r + ',' + rgb.g + ',' + rgb.b);
document.documentElement !== null &&
document.documentElement.style.setProperty(
'--color-primary-contrast',
brightness > 155 ? 'black' : 'white'
);
if (document.documentElement !== null) {
threshold =
getComputedStyle(document.documentElement).getPropertyValue('--color-text') === ' #000000' ? 70 : 155;
}
let rgbs = colorMixer(rgb, brightness > threshold ? { r: 0, g: 0, b: 0 } : { r: 255, g: 255, b: 255 }, 0.6);
let brightnesss = Math.round(
(parseInt(rgbs.r) * 299 + parseInt(rgbs.g) * 587 + parseInt(rgbs.b) * 114) / 1000
);
document.documentElement !== null &&
document.documentElement.style.setProperty(
'--color-secondary-dynamic',
rgbs.r + ',' + rgbs.g + ',' + rgbs.b
);
document.documentElement !== null &&
document.documentElement.style.setProperty(
'--color-secondary-contrast',
brightnesss > 155 ? 'black' : 'white'
);
});
}
});
} else {
resetColors(true);
}
function toDataUrl(url, callback) {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
const reader = new FileReader();
reader.onloadend = function () {
const image = new Image();
image.src = reader.result.toString();
image.onload = () => callback(image);
};
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
}
function getAverageRGB(img, callback) {
const blockSize = 5;
const defaultRGB = { r: 0, g: 0, b: 0 };
const canvas = document.createElement('canvas');
const context = canvas.getContext && canvas.getContext('2d');
const rgb = { r: 0, g: 0, b: 0 };
const rgb_gray = { r: 0, g: 0, b: 0 };
const blackwhite = { r: 0, g: 0, b: 0 };
let count = 0;
let count_gray = 0;
let count_off = 0;
let i = -4;
let data;
let length;
if (!context) {
return defaultRGB;
}
const height = (canvas.height = img.naturalHeight || img.offsetHeight || img.height);
const width = (canvas.width = img.naturalWidth || img.offsetWidth || img.width);
context.drawImage(img, 0, 0);
try {
data = context.getImageData(0, 0, width, height);
} catch (e) {
return defaultRGB;
}
length = data.data.length;
while ((i += blockSize * 4) < length) {
if (shadeCheck(data.data, i, 75)) {
++count;
rgb.r += data.data[i];
rgb.g += data.data[i + 1];
rgb.b += data.data[i + 2];
} else if (shadeCheck(data.data, i, 25)) {
++count_gray;
rgb_gray.r += data.data[i];
rgb_gray.g += data.data[i + 1];
rgb_gray.b += data.data[i + 2];
} else {
++count_off;
blackwhite.r += data.data[i];
blackwhite.g += data.data[i + 1];
blackwhite.b += data.data[i + 2];
}
}
if ((100 / (count + count_gray + count_off)) * count > 3) {
rgb.r = ~~(rgb.r / count);
rgb.g = ~~(rgb.g / count);
rgb.b = ~~(rgb.b / count);
} else if (count_gray > count_off) {
rgb.r = ~~(rgb_gray.r / count_gray);
rgb.g = ~~(rgb_gray.g / count_gray);
rgb.b = ~~(rgb_gray.b / count_gray);
} else {
let shade = 255;
if (document.documentElement !== null) {
shade = getComputedStyle(document.documentElement).getPropertyValue('--color-text') === ' #000000' ? 0 : 255;
}
rgb.r = shade;
rgb.g = shade;
rgb.b = shade;
}
callback(rgb);
}
function shadeCheck(data, i, threshold) {
let white = 0;
if (data[i] > 255 - threshold) white = white + 1;
if (data[i + 1] > 255 - threshold) white = white + 1;
if (data[i + 2] > 255 - threshold) white = white + 1;
let black = 0;
if (data[i] < threshold) black = black + 1;
if (data[i + 1] < threshold) black = black + 1;
if (data[i + 2] < threshold) black = black + 1;
if (white > 2 || black > 2) return false;
else return true;
}
function colorChannelMixer(a, b, mix) {
let channelA = a * mix;
let channelB = b * (1 - mix);
return parseInt(channelA + channelB);
}
function colorMixer(rgbA, rgbB, mix) {
let r = colorChannelMixer(rgbA.r, rgbB.r, mix);
let g = colorChannelMixer(rgbA.g, rgbB.g, mix);
let b = colorChannelMixer(rgbA.b, rgbB.b, mix);
return { r: r, g: g, b: b };
}
function colorCompare(rgb) {
let bg = 0;
if (document.documentElement !== null) {
bg = getComputedStyle(document.documentElement).getPropertyValue('--color-text') === ' #000000' ? 221 : 32;
}
let r = Math.abs(rgb.r - bg);
let g = Math.abs(rgb.g - bg);
let b = Math.abs(rgb.b - bg);
r = r / 255;
g = g / 255;
b = b / 255;
return ((r + g + b) / 3) * 100;
}
*/
/*
if (cover) {
return (
cover && (
<>
<div className={'background-image'} style={{ backgroundImage: 'url("' + cover + '")' }} />
<div className={'theme'} />
</>
)
);
} else { */
/*
<div
className={'background-image'}
style={{
backgroundImage:
'url("https://thumbnails.odysee.com/optimize/plain/https://cdn.lbryplayer.xyz/speech/2e9a7dc6c99f0fb9.jpg")',
}}
/>
*/
return (
<>
<div
className={'background-image'}
style={{
backgroundImage: `url(${freeezepeach})`,
}}
/>
<div className={'theme'} />
</>
);
// }
};
export default Wallpaper;

View file

@ -8,7 +8,6 @@ import classnames from 'classnames';
import Icon from 'component/common/icon';
import { isURIValid, normalizeURI, parseURI } from 'util/lbryURI';
import { Combobox, ComboboxInput, ComboboxPopover, ComboboxList, ComboboxOption } from '@reach/combobox';
// import '@reach/combobox/styles.css'; --> 'scss/third-party.scss'
import useLighthouse from 'effects/use-lighthouse';
import { Form } from 'component/common/form';
import Button from 'component/button';
@ -279,11 +278,9 @@ export default function WunderBarSuggestions(props: Props) {
return () => {
window.removeEventListener('keydown', handleKeyDown);
// @if TARGET='app'
if (inputRef.current) {
inputRef.current.removeEventListener('dblclick', handleDoubleClick);
}
// @endif
};
}, [inputRef]);
@ -309,7 +306,7 @@ export default function WunderBarSuggestions(props: Props) {
className={classnames('wunderbar__wrapper', { 'wunderbar__wrapper--mobile': isMobile })}
onSubmit={() => handleSelect(term)}
>
<Combobox className="wunderbar" onSelect={handleSelect}>
<Combobox className="wunderbar" onSelect={handleSelect} openOnFocus>
<Icon icon={ICONS.SEARCH} />
<ComboboxInput
ref={inputRef}

View file

@ -33,7 +33,12 @@ export const ORDER_BY_TOP = 'top';
export const ORDER_BY_TOP_VALUE = ['effective_amount'];
export const ORDER_BY_NEW = 'new';
export const ORDER_BY_NEW_VALUE = ['release_time'];
export const ORDER_BY_TYPES = [ORDER_BY_TRENDING, ORDER_BY_NEW, ORDER_BY_TOP];
export const ORDER_BY_NEW_ASC = 'new_asc';
export const ORDER_BY_NEW_ASC_VALUE = ['^release_time'];
// @note: These are used to build the default controls available on claim listings.
export const ORDER_BY_TYPES = [ORDER_BY_NEW, ORDER_BY_TRENDING, ORDER_BY_TOP];
export const DURATION_SHORT = 'short';
export const DURATION_MEDIUM = 'medium';

View file

@ -150,10 +150,15 @@ export const CREATOR_LIKE = 'CreatorLike';
export const CHEF = 'Chef';
export const ANONYMOUS = 'Anonymous';
export const CHANNEL_LEVEL_1 = 'ChannelLevel1';
export const CHANNEL_LEVEL_1_B = 'ChannelLevel1B';
export const CHANNEL_LEVEL_2 = 'ChannelLevel2';
export const CHANNEL_LEVEL_2_B = 'ChannelLevel2B';
export const CHANNEL_LEVEL_3 = 'ChannelLevel3';
export const CHANNEL_LEVEL_3_B = 'ChannelLevel3B';
export const CHANNEL_LEVEL_4 = 'ChannelLevel4';
export const CHANNEL_LEVEL_4_B = 'ChannelLevel4B';
export const CHANNEL_LEVEL_5 = 'ChannelLevel5';
export const CHANNEL_LEVEL_5_B = 'ChannelLevel5B';
export const MOVIES = 'Movies';
export const WILD_WEST = 'WildWest';
export const UNIVERSE = 'Universe';

View file

@ -5,6 +5,7 @@ export const RULE = {
FIAT_TIP: 'fiat_tip',
NEW_CONTENT: 'new_content',
NEW_LIVESTREAM: 'new_livestream',
WEEKLY_WATCH_REMINDER: 'weekly_watch_reminder',
DAILY_WATCH_AVAILABLE: 'daily_watch_available',
DAILY_WATCH_REMIND: 'daily_watch_remind',
MISSED_OUT: 'missed_out',

View file

@ -0,0 +1,18 @@
// @flow
import { useEffect, useState } from 'react';
export default function useDebounce(value: string, delay: number) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
}

View file

@ -7,7 +7,7 @@ function getSetAllValues(key, setValue) {
// If no key just return the normal setValue function
return setValue;
}
return value => listeners[key].forEach(fn => fn(value));
return (value) => listeners[key].forEach((fn) => fn(value));
}
export default function usePersistedState(key, firstTimeDefault) {
@ -58,7 +58,7 @@ export default function usePersistedState(key, firstTimeDefault) {
return () => {
if (key) {
// remove hook on unmount
listeners[key] = listeners[key].filter(listener => listener !== setValue);
listeners[key] = listeners[key].filter((listener) => listener !== setValue);
}
};
}, [key, value, localStorageAvailable]);

View file

@ -34,3 +34,7 @@ export function useIsLargeScreen() {
const windowSize = useWindowSize();
return windowSize > 1600;
}
export function isTouch() {
return 'ontouchstart' in window || 'onmsgesturechange' in window;
}

View file

@ -19,7 +19,6 @@ import ChannelForm from 'component/channelForm';
import classnames from 'classnames';
import HelpLink from 'component/common/help-link';
import ClaimSupportButton from 'component/claimSupportButton';
import ChannelStakedIndicator from 'component/channelStakedIndicator';
import ClaimMenuList from 'component/claimMenuList';
import OptimizedImage from 'component/optimizedImage';
import Yrbl from 'component/yrbl';
@ -208,7 +207,7 @@ function ChannelPage(props: Props) {
}
return (
<Page noFooter>
<Page className="channelPage-wrapper" noFooter>
<header className="channel-cover">
<div className="channel__quick-actions">
{isMyYouTubeChannel && (
@ -228,12 +227,11 @@ function ChannelPage(props: Props) {
{cover && <img className={classnames('channel-cover__custom')} src={PlaceholderTx} />}
{cover && <OptimizedImage className={classnames('channel-cover__custom')} src={cover} objectFit="cover" />}
<div className="channel__primary-info">
<ChannelThumbnail className="channel__thumbnail--channel-page" uri={uri} allowGifs hideStakedIndicator />
<ChannelThumbnail className="channel__thumbnail--channel-page" uri={uri} allowGifs />
<h1 className="channel__title">
<TruncatedText lines={2} showTooltip>
{title || (channelName && '@' + channelName)}
</TruncatedText>
<ChannelStakedIndicator uri={uri} large />
</h1>
<div className="channel__meta">
<span>

View file

@ -45,7 +45,7 @@ export default function ChannelsPage(props: Props) {
}, [setRewardData]);
return (
<Page>
<Page className="channelsPage-wrapper">
<div className="card-stack">
{hasYoutubeChannels && <YoutubeTransferStatus hideChannelLink />}

View file

@ -98,7 +98,7 @@ function ChannelsFollowingDiscover(props: Props) {
});
return (
<Page>
<Page className="discoverPage-wrapper">
{rowDataWithGenericOptions.map(({ title, link, help, options = {} }) => (
<div key={title} className="claim-grid__wrapper">
<h1 className="section__actions">

View file

@ -269,7 +269,8 @@ export default function CollectionPage(props: Props) {
if (urlsReady) {
return (
<Page>
<Page className="playlistPage-wrapper">
{editing}
<div className={classnames('section card-stack')}>
{info}

View file

@ -166,12 +166,19 @@ function FileListPublished(props: Props) {
headerAltControls={
<div className="card__actions--inline">
<Button
button="alt"
button="secondary"
label={__('Refresh')}
icon={ICONS.REFRESH}
disabled={fetching}
onClick={fetchAllMyClaims}
/>
<Button
icon={ICONS.PUBLISH}
button="primary"
label={__('Upload')}
navigate={`/$/${PAGES.UPLOAD}`}
onClick={() => clearPublish()}
/>
<Form onSubmit={() => {}} className="wunderbar--inline">
<Icon icon={ICONS.SEARCH} />
<FormField

View file

@ -9,7 +9,7 @@ import ClaimTilesDiscover from 'component/claimTilesDiscover';
import ClaimPreviewTile from 'component/claimPreviewTile';
import Icon from 'component/common/icon';
import WaitUntilOnPage from 'component/common/wait-until-on-page';
import { useIsLargeScreen } from 'effects/use-screensize'; // have this?
import { useIsLargeScreen } from 'effects/use-screensize';
import { GetLinksData } from 'util/buildHomepage';
type Props = {

View file

@ -7,7 +7,7 @@ import Icon from 'component/common/icon';
function ListsPage() {
return (
<Page>
<Page className="playlistPage-wrapper">
<label className="claim-list__header-label">
<span>
<Icon icon={ICONS.STACK} size={10} />

View file

@ -80,7 +80,7 @@ export default function SearchPage(props: Props) {
}
return (
<Page>
<Page className="searchPage-wrapper">
<section className="search">
{urlQuery && (
<>

View file

@ -5,7 +5,7 @@ import Page from 'component/page';
export default function SignInPage() {
return (
<Page authPage>
<Page authPage noFooter>
<UserSignIn />
</Page>
);

View file

@ -87,7 +87,7 @@ function SignInVerifyPage(props: Props) {
}
return (
<Page authPage>
<Page authPage noFooter>
<div className="main__sign-up">
<Card
title={isAuthenticationSuccess ? __('Log in success!') : __('Log in')}

View file

@ -5,7 +5,7 @@ import Page from 'component/page';
export default function SignUpPage() {
return (
<Page authPage>
<Page authPage noFooter>
<UserSignUp />
</Page>
);

View file

@ -21,7 +21,7 @@ function TopPage(props: Props) {
// if the query was actually '@name', still offer repost for 'name'
const queryName = name[0] === '@' ? name.slice(1) : name;
return (
<Page>
<Page className="topPage-wrapper">
<SearchTopClaim query={name} hideLink setChannelActive={setChannelActive} />
<ClaimListDiscover
name={channelActive ? `@${queryName}` : queryName}

View file

@ -31,8 +31,8 @@ const defaultState = {
// UI
[SETTINGS.LANGUAGE]: null,
[SETTINGS.SEARCH_IN_LANGUAGE]: false,
[SETTINGS.THEME]: __('light'),
[SETTINGS.THEMES]: [__('light'), __('dark')],
[SETTINGS.THEME]: __('dark'),
[SETTINGS.THEMES]: [__('dark'), __('light')],
[SETTINGS.HOMEPAGE]: null,
[SETTINGS.HIDE_SPLASH_ANIMATION]: false,
[SETTINGS.HIDE_BALANCE]: false,

View file

@ -402,8 +402,29 @@ export const selectThumbnailForUri = createCachedSelector(selectClaimForUri, (cl
export const makeSelectCoverForUri = (uri: string) =>
createSelector(makeSelectClaimForUri(uri), (claim) => {
const cover = claim && claim.value && claim.value.cover;
return cover && cover.url ? cover.url.trim().replace(/^http:\/\//i, 'https://') : undefined;
if (claim && claim.value.cover) {
const cover = claim && claim.value && claim.value.cover;
return cover && cover.url ? cover.url.trim().replace(/^http:\/\//i, 'https://') : undefined;
} else {
const cover = claim && claim.signing_channel && claim.signing_channel.value && claim.signing_channel.value.cover;
return cover && cover.url ? cover.url.trim().replace(/^http:\/\//i, 'https://') : undefined;
}
});
export const makeSelectAvatarForUri = (uri: string) =>
createSelector(makeSelectClaimForUri(uri), (claim) => {
if (claim && claim.value.cover) {
const avatar = claim && claim.value && claim.value.thumbnail && claim.value.thumbnail;
return avatar && avatar.url ? avatar.url.trim().replace(/^http:\/\//i, 'https://') : undefined;
} else {
const avatar =
claim &&
claim.signing_channel &&
claim.signing_channel.value &&
claim.signing_channel.value.thumbnail &&
claim.signing_channel.value.thumbnail;
return avatar && avatar.url ? avatar.url.trim().replace(/^http:\/\//i, 'https://') : false;
}
});
export const selectIsFetchingClaimListMine = (state: State) => selectState(state).isFetchingClaimListMine;

View file

@ -17,6 +17,7 @@
@import 'component/_textarea-suggestions';
@import 'component/claim-list';
@import 'component/collection';
@import 'component/color-picker';
@import 'component/comments';
@import 'component/content';
@import 'component/dat-gui';

View file

@ -70,11 +70,11 @@
@keyframes menu-animate-in {
0% {
transform: scaleY(0);
opacity: 0;
transform: scale(1, 0);
opacity: 1;
}
100% {
transform: scaleY(1);
transform: scaleZ(1);
opacity: 1;
}
}

View file

@ -1,6 +1,18 @@
.block-list {
.claim-preview__wrapper--channel {
.button--no-style {
.button__content {
align-items: unset;
}
}
}
}
.block-list--moderator {
.button__content {
align-items: flex-start;
.button--no-style {
.button__content {
align-items: flex-start;
}
}
.section__actions {
@ -10,6 +22,9 @@
.block-list--delegator {
padding: var(--spacing-s);
background-color: rgba(var(--color-background-base), 0.6);
border-radius: var(--border-radius);
border: 1px solid var(--color-border);
.button--alt,
.button--secondary {
@ -35,10 +50,6 @@
font-size: var(--font-xsmall);
}
.section {
margin-left: var(--spacing-m);
}
label {
font-style: italic;
}

View file

@ -10,10 +10,7 @@
.button--secondary,
.button--alt,
.button--link {
border-radius: var(--border-radius);
&:focus {
@include focus;
z-index: 2; // Ensure focus box-shadow is always visible on every button side
}
}
@ -23,64 +20,108 @@
.button--alt {
height: var(--height-button);
border-radius: var(--border-radius);
padding: var(--spacing-s) var(--spacing-m);
line-height: 1.2;
padding: 0 var(--spacing-m);
line-height: 1.2em;
font-weight: var(--font-weight-bold);
.button__label {
margin-top: 2px;
}
@media (max-width: $breakpoint-small) {
font-size: var(--font-small);
}
}
.button--primary {
background-color: var(--color-button-primary-bg);
background-color: var(--color-primary) !important;
.button__label {
color: var(--color-button-primary-text);
color: var(--color-primary-contrast);
}
.icon {
stroke: var(--color-button-primary-text);
}
&:hover {
color: var(--color-button-primary-hover-text);
background-color: var(--color-button-primary-bg-hover);
color: var(--color-primary-contrast);
}
.credit-amount {
color: var(--color-button-primary-text);
color: var(--color-primary-contrast);
.icon {
margin-left: 3px;
margin-right: 2px;
margin-right: 3px;
}
}
&:hover {
.icon {
stroke: var(--color-primary-contrast) !important;
}
}
&:focus-visible {
background-color: rgba(var(--color-primary-dynamic), 0.2) !important;
box-shadow: 0px 0px 0px 2px var(--color-primary) inset;
.button__label {
color: var(--color-text) !important;
}
.icon {
stroke: var(--color-text) !important;
}
}
}
.button--secondary {
background-color: var(--color-button-secondary-bg);
border: 1px solid var(--color-button-secondary-border);
background-color: var(--color-button-secondary-bg) !important;
.button__label {
color: var(--color-button-secondary-text);
color: var(--color-button-secondary-text) !important;
}
.icon {
stroke: var(--color-button-secondary-text);
stroke: var(--color-button-secondary-text) !important;
}
&:hover {
background-color: var(--color-button-secondary-bg-hover);
background-color: var(--color-button-secondary-bg-hover) !important;
.button__label {
color: var(--color-button-secondary-text-hover) !important;
}
.icon {
stroke: var(--color-button-secondary-text-hover) !important;
}
}
&:focus-visible {
background-color: rgba(var(--color-primary-dynamic), 0.2) !important;
box-shadow: 0px 0px 0px 2px var(--color-primary) inset;
.button__label {
color: var(--color-text) !important;
}
.icon {
stroke: var(--color-text) !important;
}
}
}
.button--alt {
background-color: var(--color-button-alt-bg);
color: var(--color-button-alt-text);
&:hover {
background-color: var(--color-button-alt-bg-hover);
color: var(--color-button-alt-text-hover);
}
}
a.button--alt {
@media (max-width: $breakpoint-small) {
.button__label {
div:first-of-type {
top: 23% !important;
}
}
}
}
@ -94,12 +135,23 @@
background-color: var(--color-primary);
&:hover {
background-color: var(--color-button-primary-bg-hover);
background-color: var(--color-button-secondary-bg-hover);
&.button--play {
background-color: var(--color-primary);
opacity: 1;
}
}
&.button--play {
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E %3Cg stroke='white' stroke-width='2' fill='white' fill-rule='evenodd' stroke-linejoin='round'%3E %3Cpolygon points='5 21 5 3 21 12'/%3E %3C/g%3E %3C/svg%3E");
background-position: calc(50% + 0.1rem) center;
opacity: 0.95;
transition: opacity 0.2s;
&:hover {
opacity: 1;
transition: opacity 0s;
}
}
&.button--view {
@ -198,7 +250,7 @@
width: 14px;
background: var(--color-white);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.25);
border-radius: var(--border-radius);
border-radius: 50%;
transition: transform 0.2s;
}
@ -208,12 +260,10 @@
.button--link {
color: var(--color-link);
transition: color 0.2s;
word-break: break-word;
font-weight: var(--font-weight-bold);
&:hover {
text-decoration: underline;
color: var(--color-link-hover);
}
}
@ -225,21 +275,30 @@
.button--uri-indicator {
@extend .button--link;
color: var(--color-text-subtitle);
color: var(--color-text);
max-width: 100%;
text-align: left;
transition: color 0.2s;
.channel-name {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
font-size: var(--font-xsmall);
color: rgba(var(--color-text-base), 0.6);
}
.markdown-preview & {
height: initial;
vertical-align: initial;
}
&:hover {
color: var(--color-primary);
.channel-name {
color: var(--color-text);
}
}
}
.button--close {
@ -259,21 +318,22 @@
}
&:hover {
color: var(--color-button-primary-text);
background-color: var(--color-button-primary-bg);
}
&:focus {
@include focus;
color: var(--color-primary-contrast);
background-color: var(--color-primary);
}
@media (max-width: $breakpoint-small) {
padding: 0.8rem 0.8rem;
padding: 0.7rem 0.2rem;
top: var(--spacing-s);
right: var(--spacing-xxs);
&:hover {
background-color: unset;
}
}
}
.button--header-close {
background-color: var(--color-primary-alt);
background-color: var(--color-secondary);
padding: var(--spacing-s);
}
@ -286,6 +346,7 @@
.button--file-action {
@extend .button--alt;
color: var(--color-text);
background-color: transparent;
margin-right: var(--spacing-m);
padding: 0 var(--spacing-xxs);
@ -297,9 +358,14 @@
color: var(--color-primary);
}
}
@media (max-width: $breakpoint-small) {
padding: 0 0;
}
.icon {
&:not(.color-override) {
stroke: var(--color-text-subtitle);
stroke: var(--color-text);
}
}
@ -312,12 +378,19 @@
}
&:hover {
background-color: var(--color-button-alt-bg);
.icon {
stroke: var(--color-link);
}
.button__label {
color: var(--color-link);
}
}
}
&:focus {
box-shadow: none;
background-color: var(--color-button-alt-bg);
[aria-expanded='true'].button--file-action {
background-color: var(--color-header-background);
.icon {
stroke: var(--color-primary);
}
}
@ -328,206 +401,11 @@
}
}
.button--fire {
color: var(--color-fire);
position: relative;
path {
stroke: var(--color-fire-outside);
}
.button--file-action--menu {
@extend .button--file-action;
}
.button__fire-particle {
position: absolute;
top: 60%;
left: 20%;
width: 2px;
height: 2px;
background-color: #ef5a00;
border-radius: 50%;
filter: drop-shadow(0 0 10px #d43322);
animation-iteration-count: 2;
animation-fill-mode: both;
}
.button__fire-glow {
width: 1px;
height: 1px;
left: var(--spacing-s);
bottom: var(--spacing-m);
position: absolute;
box-shadow: 4px 0px 10px 10px var(--color-glow);
animation: glowDecay 2.5s ease-out;
opacity: 0;
}
.button__fire-particle1 {
@extend .button__fire-particle;
right: 10%;
top: 40%;
animation: particleUp 1.5s ease-out 0;
animation-iteration-count: 2;
animation-fill-mode: both;
}
.button__fire-particle2 {
@extend .button__fire-particle;
animation: particleUp2 2s ease-out 0;
animation-iteration-count: 2;
animation-fill-mode: both;
}
.button__fire-particle3 {
@extend .button__fire-particle;
animation: particleUp3 2.2s ease-out 0;
animation-iteration-count: 2;
animation-fill-mode: both;
}
.button__fire-particle4 {
@extend .button__fire-particle1;
animation-delay: 0.5s;
}
.button__fire-particle5 {
@extend .button__fire-particle2;
animation-delay: 0.75s;
}
.button__fire-particle6 {
@extend .button__fire-particle3;
animation-delay: 0.25s;
}
@keyframes glowDecay {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes particleUp {
0% {
opacity: 0;
left: 0;
}
20% {
opacity: 1;
right: 10%;
}
50% {
right: 20%;
}
50% {
left: 10%;
}
80% {
opacity: 1;
right: 40%;
}
100% {
opacity: 0;
top: -50%;
transform: scale(0.5);
}
}
@keyframes particleUp2 {
0% {
opacity: 0;
right: 0;
}
20% {
opacity: 1;
left: 10%;
}
50% {
left: 20%;
}
50% {
right: 10%;
}
80% {
opacity: 1;
left: 40%;
}
100% {
opacity: 0;
top: -50%;
transform: scale(0.5);
}
}
@keyframes particleUp3 {
0% {
opacity: 0;
left: 30%;
}
20% {
opacity: 1;
left: 60%;
}
40% {
left: 50%;
}
80% {
opacity: 1;
right: 80%;
}
100% {
opacity: 0;
top: -50%;
transform: scale(0.5);
}
}
.button--slime {
color: var(--color-slime);
}
.button__slime-drop {
position: absolute;
top: 60%;
left: 15%;
width: 5px;
height: 5px;
background-color: #81c554;
border-radius: 50%;
filter: drop-shadow(0 0 10px #d43322);
animation-iteration-count: 2;
animation-fill-mode: both;
}
.button__slime-drop1 {
@extend .button__slime-drop;
top: 40%;
animation: dropDown 1.5s ease-out 0;
animation-iteration-count: 1;
animation-fill-mode: both;
}
.button__slime-drop2 {
@extend .button__slime-drop;
left: 35%;
top: 40%;
animation: dropDown2 1.5s ease-out 0;
animation-iteration-count: 1;
animation-fill-mode: both;
}
.button__slime-stain {
width: 1px;
height: 1px;
left: var(--spacing-s);
bottom: var(--spacing-m);
position: absolute;
box-shadow: 4px 0px 10px 10px var(--color-slime);
animation: glowDecay 2.5s ease-out;
opacity: 0;
[aria-expanded='true'].button--file-action--menu {
background-color: var(--color-header-background) !important;
}
@keyframes dropDown {
@ -593,12 +471,24 @@ svg + .button__label {
padding: 0 var(--spacing-m);
height: var(--height-button);
font-size: var(--font-base);
border: 1px solid var(--color-border);
border-left-width: 0;
border-radius: 0;
margin: 0;
background-color: var(--color-card-background);
color: var(--color-text);
color: var(--color-button-toggle-text) !important;
background-color: var(--color-button-toggle-bg) !important;
-webkit-user-select: none;
user-select: none;
&:hover:not(.button-toggle--active) {
background-color: var(--color-button-toggle-bg-hover) !important;
.button__label {
color: var(--color-button-toggle-text-hover);
}
.icon {
stroke: var(--color-button-toggle-text-hover) !important;
}
}
@media (max-width: $breakpoint-small) {
padding: var(--spacing-m) var(--spacing-s);
@ -616,6 +506,81 @@ svg + .button__label {
}
}
.button-toggle--expandformobile {
@media (max-width: $breakpoint-small) {
display: block;
width: 100%;
text-align: center;
border-radius: var(--border-radius);
border: 1px solid var(--color-border);
&:not(:first-of-type) {
margin-top: var(--spacing-s);
}
}
}
.button-toggle--active {
// color: var(--color-button-toggle-text) !important;
//box-shadow: 0px 0px 0px 1px var(--color-primary) inset;
color: var(--color-button-toggle-text-active) !important;
background-color: var(--color-button-toggle-bg-active) !important;
.icon {
opacity: 1;
stroke: var(--color-button-toggle-text-active) !important;
}
&:hover {
cursor: default;
text-decoration: none;
background-color: var(--color-button-toggle-bg-active);
.icon {
stroke: var(--color-button-toggle-text-active) !important;
}
}
&:focus-visible {
background-color: rgba(var(--color-primary-dynamic), 0.2) !important;
box-shadow: 0px 0px 0px 2px var(--color-primary) inset !important;
.icon {
stroke: var(--color-button-toggle-text) !important;
}
}
}
.button-toggle--custom {
color: var(--color-toggle-custom) !important;
.button__content {
.icon {
stroke: var(--color-toggle-custom) !important;
}
}
svg {
opacity: 1;
}
}
.button-toggle__label {
@extend label;
display: inline-block;
margin-top: -4px;
}
.button-toggle-group-action {
position: absolute; // Centers the button along toggle buttons
margin-left: var(--spacing-xs);
@media (max-width: $breakpoint-small) {
position: relative;
top: var(--spacing-s);
margin-bottom: var(--spacing-s);
margin-left: unset;
}
}
.button-collection-manage {
font-size: var(--font-base);
border-left-width: 0;
@ -636,7 +601,11 @@ svg + .button__label {
text-align: center;
&:hover {
background-color: var(--color-button-alt-bg-hover);
background-color: var(--color-primary);
color: var(--color-primary-contrast);
.icon {
stroke: var(--color-primary-contrast);
}
}
@media (max-width: $breakpoint-small) {
@ -678,48 +647,6 @@ svg + .button__label {
}
}
.button-toggle--expandformobile {
@media (max-width: $breakpoint-small) {
display: block;
width: 100%;
text-align: center;
border-radius: var(--border-radius);
border: 1px solid var(--color-border);
&:not(:first-of-type) {
margin-top: var(--spacing-s);
}
}
}
.button-toggle--active {
color: var(--color-button-toggle-text);
background-color: var(--color-button-toggle-bg);
svg {
opacity: 1;
}
&:hover {
cursor: default;
text-decoration: none;
background-color: var(--color-button-toggle-bg);
}
}
.button-toggle--custom {
color: var(--color-primary);
svg {
opacity: 1;
}
}
.button-toggle__label {
@extend label;
display: inline-block;
margin-top: -4px;
}
.button-tab-group {
margin-bottom: var(--spacing-l);
}
@ -731,12 +658,16 @@ svg + .button__label {
.button:first-child:not(:only-child) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: 1px solid var(--color-button-border);
margin-right: 1px;
}
.button:nth-child(2) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
margin-left: 1px;
&:hover {
fill: var(--color-text) !important;
}
}
.button--file-action {
@ -752,17 +683,83 @@ svg + .button__label {
}
}
.button-toggle-group-action {
position: absolute; // Centers the button along toggle buttons
margin-left: var(--spacing-xs);
@media (max-width: $breakpoint-small) {
position: relative;
top: var(--spacing-s);
margin-left: unset;
}
}
.button--hash-id {
@include font-mono;
}
.button-rotate {
transform: rotate(90deg);
transition: transform 0.2s;
margin-right: var(--spacing-s) !important;
}
.button-like.comment__action--active {
.comment__reaction-count {
color: var(--color-fire) !important;
}
}
.button-dislike.comment__action--active {
.comment__reaction-count {
color: var(--color-slime);
}
}
.button-following {
color: var(--color-primary-contrast) !important;
//background-color: rgba(var(--color-primary-dynamic),0.5) !important;
background-color: rgba(125, 125, 125, 0.5) !important;
.icon {
stroke: var(--color-primary-contrast) !important;
}
}
.recommended-content__bubble {
// margin-top: var(--spacing-xs);
display: flex;
.button-toggle:nth-child(2) {
margin-left: 2px;
@media (min-width: $breakpoint-small) {
margin-right: var(--spacing-xs);
}
}
.button-bubble {
border-radius: 1rem;
padding-left: var(--spacing-m);
padding-right: var(--spacing-m);
margin-right: var(--spacing-xxs);
background-color: var(--color-button-toggle-bg) !important;
color: var(--color-button-toggle-text);
font-size: var(--font-base);
padding: 0 var(--spacing-xs);
height: 2rem;
max-width: 15rem;
.button__content {
height: unset;
}
&:hover:not(.button-bubble--active) {
background-color: var(--color-button-toggle-bg-hover) !important;
.button__label {
color: var(--color-button-toggle-text-hover) !important;
}
}
}
.button-bubble:first-of-type {
margin-left: 0;
}
.button-bubble--active {
color: var(--color-button-toggle-text-active) !important;
background-color: var(--color-button-toggle-bg-active) !important;
box-shadow: unset;
&:hover {
cursor: default;
}
}
}
.file-reaction__tooltip-inner {
margin: 0px !important;
}

View file

@ -0,0 +1,28 @@
.schedule-counter {
position: absolute;
top: 19px;
left: 15px;
width: 10px;
height: 10px;
color: var(--color-text);
z-index: 99999;
font-size: 7px;
}
.test {
svg {
stroke: var(--color-text);
fill: var(--color-text);
}
&:hover {
svg {
stroke: var(--color-primary-contrast);
fill: var(--color-primary-contrast);
}
.schedule-counter {
color: var(--color-primary-contrast);
}
}
}

View file

@ -1,9 +1,7 @@
.card {
background-color: var(--color-card-background);
position: relative;
border-radius: var(--card-radius);
overflow: hidden;
border: 1px solid var(--color-border);
~ .card {
margin-bottom: var(--spacing-m);
@ -13,6 +11,54 @@
.card--enable-overflow {
overflow: visible;
margin-bottom: var(--spacing-m);
@media (max-width: $breakpoint-small) {
overflow-y: scroll;
height: 100%;
border-top: 1px solid var(--color-border);
.card__main-actions {
margin-top: 0px !important;
.comment__sort {
margin: 0px !important;
display: inline;
button {
padding: var(--spacing-xxs);
span {
font-size: var(--font-xxsmall);
}
}
}
> .button--alt {
padding: var(--spacing-xxs) var(--spacing-s);
}
.comment__sort + button {
margin: 0px var(--spacing-xxs);
}
.button + .commentCreate {
margin-top: var(--spacing-xxs);
}
}
}
}
.card--comments-list {
@extend .card--enable-overflow;
@media (max-width: $breakpoint-small) {
overflow-y: scroll;
height: 100%;
.card__main-actions {
margin-top: 0px !important;
}
}
}
.card--disabled {
@ -22,7 +68,7 @@
.card--section {
position: relative;
padding: var(--spacing-m);
// padding: var(--spacing-m);
}
.card--reward-total {
@ -34,13 +80,19 @@
}
.card--inline {
border: 1px solid var(--color-border);
border-radius: var(--card-radius);
margin-bottom: var(--spacing-m);
&:last-of-type {
margin-bottom: 0;
}
.claim-preview__wrapper {
background: rgba(var(--color-header-background-base), 0.6);
&:hover {
background: rgba(var(--color-header-background-base), 0.9);
}
}
}
.card-collection-selector {
@ -87,9 +139,10 @@
}
@media (max-width: $breakpoint-small) {
> * {
padding-bottom: var(--spacing-m);
> *:not(:last-child) {
margin-right: var(--spacing-s);
}
flex-flow: wrap;
justify-content: space-between;
}
@ -98,22 +151,14 @@
.card__title-section {
@extend .section__flex;
//@media (min-width: $breakpoint-small) {
// padding: var(--spacing-s) var(--spacing-m);
//}
}
.card__title-section--body-list {
// this is superfluous
//padding-left: var(--spacing-s);
//
//@media (min-width: $breakpoint-small) {
// padding: var(--spacing-m);
//}
@media (min-width: $breakpoint-small) {
padding: var(--spacing-s) 0px;
}
}
.card__title-section--small {
padding: var(--spacing-s);
padding-left: 0px;
}
.card__actions--inline {
@ -121,6 +166,13 @@
margin-top: 0;
@media (max-width: $breakpoint-small) {
padding-bottom: 0;
&:last-of-type {
.button--alt {
padding-bottom: 0;
margin-top: 6px;
}
}
.button__content {
svg + .button__label {
display: none;
@ -131,7 +183,7 @@
.card__actions--between {
@include between;
align-items: center;
align-items: end;
width: 100%;
}
@ -143,7 +195,11 @@
.card-stack {
.card:not(:last-of-type) {
margin-bottom: var(--spacing-l);
margin-bottom: var(--spacing-xxl);
@media (max-width: $breakpoint-small) {
margin-bottom: var(--spacing-l);
}
}
}
@ -217,19 +273,61 @@
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
.card--enable-overflow {
.card__header--between {
@media (max-width: $breakpoint-small) {
margin-bottom: 0;
.card__title-section {
width: 60%;
}
}
}
.card__title-actions-container {
@media (max-width: $breakpoint-small) {
flex-grow: 1;
min-height: 47px;
.card__title-actions {
width: 100%;
flex-grow: 1;
margin-right: auto;
.button--alt {
flex-grow: 1;
}
.button-toggle {
padding: 0 var(--spacing-s) 0 var(--spacing-xxxs);
}
}
.comment__sort {
.button {
float: left;
}
}
.button {
float: right;
}
}
}
}
.card__title-actions {
align-self: flex-start;
@media (min-width: $breakpoint-small) {
padding: var(--spacing-s);
.button--alt {
padding-top: 2px;
}
.comment__sort {
.button--alt {
padding-top: 0;
}
}
}
.card__title-actions--link {
margin-top: var(--spacing-xs);
margin-right: var(--spacing-xs);
}
.card__title-actions--small {
@ -277,30 +375,93 @@
.card__header--between {
@extend .card__header;
justify-content: space-between;
align-items: flex-start;
align-items: center;
flex-wrap: wrap;
padding: var(--spacing-m) var(--spacing-m) var(--spacing-m) var(--spacing-m);
@media (max-width: $breakpoint-small) {
padding: var(--spacing-m);
padding-bottom: 0;
margin: 0;
margin-bottom: var(--spacing-s);
.card__title-section {
padding: 0px;
}
h1 {
font-size: 1.2rem;
font-weight: var(--font-weight-bold);
line-height: 1.25;
}
h2 {
font-size: 1.2rem;
line-height: 1.25;
}
.recommended-content__toggles {
button {
height: unset;
padding: 2px var(--spacing-xxs);
.button__content {
height: unset;
span {
font-size: var(--font-small);
line-height: 1.25;
}
}
}
}
}
.button--alt {
color: var(--color-button-alt-text);
background-color: var(--color-button-alt-bg);
&:hover {
color: var(--color-primary-contrast);
background-color: var(--color-primary);
.icon {
stroke: var(--color-primary-contrast);
}
}
}
}
.card__header--nowrap {
@extend .card__header--between;
flex-wrap: nowrap;
@media (max-width: $breakpoint-small) {
margin-bottom: var(--spacing-s);
.card__title-section {
.card__title {
margin-bottom: calc(var(--spacing-s) * -1);
}
}
.card__title-actions-container {
.card__title-actions {
.filePrice {
padding: 0;
.credit-amount {
margin-top: var(--spacing-xs);
padding: var(--spacing-xxxs);
}
}
}
}
}
}
.card__subtitle {
color: var(--color-text-subtitle);
margin: var(--spacing-s) 0;
margin-top: var(--spacing-s);
margin-bottom: var(--spacing-s) 0;
font-size: var(--font-body);
}
.card__body {
padding: var(--spacing-m);
padding-left: 0px;
&:not(.card__body--no-title) {
padding-top: 0;
@ -313,7 +474,25 @@
}
@media (max-width: $breakpoint-small) {
padding: var(--spacing-l);
padding: 0 !important;
padding-left: 0px;
padding-right: 0px;
.file__viewdate {
.date_time {
font-size: var(--font-small);
}
span {
font-size: var(--font-small);
margin: 0;
}
span + .media__subtitle--centered::before {
content: '';
margin: 0 5px;
}
}
}
}
@ -323,20 +502,38 @@
}
.card__main-actions {
//margin-bottom: var(--spacing-s);
padding: var(--spacing-m);
padding-bottom: 0;
margin-bottom: var(--spacing-s);
border-top: 1px solid var(--color-border);
height: 100%;
&:only-child {
border-top: none;
}
.form-field__help {
color: var(--color-text);
}
.help {
color: var(--color-text);
}
}
.card__body-actions {
padding: var(--spacing-s);
padding-left: 0px;
padding-right: 0px;
h3 {
padding-left: var(--spacing-s);
}
@media (min-width: $breakpoint-small) {
padding: var(--spacing-m);
padding-left: 0px;
padding-right: 0px;
}
}
@ -363,12 +560,22 @@
.card__body,
.card__main-actions {
padding: var(--spacing-m);
@media (min-width: $breakpoint-small) {
padding: var(--spacing-m);
}
padding-left: 0;
padding-right: 0;
padding-bottom: 0;
margin: 0;
//margin-bottom: var(--spacing-m);
margin-bottom: 0px;
@media (max-width: $breakpoint-small) {
margin-bottom: 0px;
padding-bottom: var(--spacing-xxs);
}
}
@media (max-width: $breakpoint-small) {
.card__main-actions:nth-child(1) {
margin-top: var(--spacing-l);
}
}
.card__bottom-gutter {
@ -391,6 +598,16 @@
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--color-border);
@media (max-width: $breakpoint-small) {
font-size: var(--font-small);
.button--link {
font-size: var(--font-xsmall);
margin: 0px;
}
}
}
.card__bottom-actions--comments {
@ -419,3 +636,12 @@
}
}
}
@media (max-width: $breakpoint-small) {
.ReactModalPortal {
.button--close {
top: 0;
right: 0;
}
}
}

View file

@ -0,0 +1,126 @@
.channel-mention {
display: flex;
align-items: center;
position: absolute;
bottom: calc(100% - 1.8rem);
z-index: 3;
font-size: var(--font-small);
padding-left: var(--spacing-s);
> .icon {
top: 0;
left: var(--spacing-m);
height: 100%;
position: absolute;
z-index: 1;
stroke: var(--color-input-placeholder);
}
@media (min-width: $breakpoint-small) {
padding: 0;
}
}
.channel-mention__suggestions {
@extend .card;
display: flex;
flex-direction: column;
overflow-y: auto;
max-height: 30vh;
position: absolute;
text-overflow: ellipsis;
width: 22rem;
z-index: 3;
left: 0;
right: 0;
bottom: 0;
box-shadow: var(--card-box-shadow);
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
border-bottom: none;
background-color: var(--color-background);
.channel-mention__label:first-of-type {
margin-top: var(--spacing-xs);
}
}
.channel-mention__suggestions[flow-bottom] {
top: 4rem;
bottom: auto;
border-top-right-radius: 0;
border-top-left-radius: 0;
border-top: none;
border-bottom-right-radius: var(--border-radius);
border-bottom-left-radius: var(--border-radius);
border-bottom: auto;
}
.channel-mention__input--none {
opacity: 0;
width: 0;
height: 0;
}
.channel-mention__label {
@extend .wunderbar__label;
}
.channel-mention__top-separator {
@extend .wunderbar__top-separator;
}
.channel-mention__suggestion {
display: flex;
align-items: center;
padding: 0 var(--spacing-xxs);
//margin-left: var(--spacing-xxs);
overflow: hidden;
text-overflow: ellipsis;
.channel-thumbnail {
@include handleChannelGif(2.1rem);
position: absolute;
@media (min-width: $breakpoint-small) {
@include handleChannelGif(2.1rem);
}
}
}
.channel-mention__suggestion-label {
@extend .wunderbar__suggestion-label;
margin-left: var(--spacing-m);
display: block;
position: relative;
}
.channel-mention__suggestion-name {
@extend .wunderbar__suggestion-name;
margin-left: calc(var(--spacing-l) - var(--spacing-xxs));
}
.channel-mention__suggestion-title {
@extend .wunderbar__suggestion-title;
margin-left: calc(var(--spacing-l) - var(--spacing-xxs));
}
.channel-mention__placeholder-suggestion {
@extend .wunderbar__placeholder-suggestion;
padding: 0 var(--spacing-xxs);
margin-left: var(--spacing-xxs);
}
.channel-mention__placeholder-label {
@extend .wunderbar__placeholder-label;
margin-left: var(--spacing-m);
}
.channel-mention__placeholder-thumbnail {
@extend .wunderbar__placeholder-thumbnail;
margin-left: var(--spacing-m);
}
.channel-mention__placeholder-info {
@extend .wunderbar__placeholder-info;
margin-left: var(--spacing-m);
}

View file

@ -2,6 +2,115 @@ $cover-z-index: 0;
$metadata-z-index: 1;
$actions-z-index: 2;
.channelPage-wrapper {
.button-group {
.button__content {
.icon {
stroke: var(--color-text);
}
}
.button-following {
color: var(--color-text) !important;
background-color: var(--color-button-alt-bg) !important;
.icon {
stroke: var(--color-text) !important;
}
&:hover {
color: var(--color-primary) !important;
}
}
.button-following:last-of-type {
margin-left: 2px;
&:hover {
color: var(--color-text) !important;
}
}
}
.claim-preview__live {
margin-bottom: 0;
.card__title-section {
padding-top: 0;
padding-bottom: 0;
}
}
fieldset-group {
fieldset-section:last-of-type {
label {
text-align: right;
margin-left: unset !important;
}
}
}
.claim-preview__wrapper--channel {
.menu__button {
right: var(--spacing-s);
}
.claim-tile__info {
margin-top: 0;
padding-bottom: var(--spacing-xxxs);
.claim-preview-metadata-sub-upload {
margin-top: 3px;
}
}
}
.mb-xl {
// Temporary fix for upcoming livestreams on channel page
margin-bottom: 0px;
background: rgba(var(--color-primary-dynamic), 0.1);
border-radius: var(--border-radius);
padding: var(--spacing-m);
.section__header--actions {
margin-top: 0px !important;
padding-top: 0px !important;
}
.claim-preview--tile {
margin-bottom: 0px;
}
.claim-tile__title {
margin-bottom: 0px;
min-height: unset;
}
.claim-tile__info {
padding-bottom: var(--spacing-s);
}
}
.media__info-text {
.claim__tags {
.tag {
margin-top: var(--spacing-xxxs);
display: inline-block;
}
}
}
label {
margin-top: var(--spacing-s);
font-size: var(--font-medium);
font-weight: var(--font-weight-bold);
}
.media__info-text,
.media__info-text--constrained {
font-size: var(--font-base) !important;
opacity: 0.8;
.date_time {
font-size: var(--font-base);
opacity: 0.8;
}
}
.media__info-text:first-of-type {
opacity: 1;
}
}
.channel-cover {
position: relative;
background-image: linear-gradient(to right, #637ad2, #318794 80%);
@ -9,6 +118,14 @@ $actions-z-index: 2;
align-items: flex-end;
box-sizing: content-box;
color: #fff;
.channel-cover__customm,
.channel__quick-actions {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
}
.channel-cover__custom {
@ -33,6 +150,11 @@ $actions-z-index: 2;
// I, Sean Yesmunt, take full responsibility for this monster
min-height: calc(var(--cover-photo-height) + 2 * var(--spacing-xl) + var(--spacing-m));
}
.menu__button {
opacity: 1;
justify-content: center;
}
}
.channel-cover__custom--waiting {
@ -101,6 +223,18 @@ $actions-z-index: 2;
margin-top: var(--spacing-l);
box-shadow: var(--card-box-shadow);
.channel-staked__wrapper {
height: var(--height-button);
margin: auto;
text-align: center;
svg {
margin: auto;
overflow: visible;
width: 90%;
height: 90%;
}
}
@media (max-width: $breakpoint-small) {
top: 0;
margin-top: var(--spacing-xl);
@ -123,7 +257,14 @@ $actions-z-index: 2;
.channel-thumbnail,
.channel-thumbnail__custom {
border-radius: var(--card-radius);
border-radius: 50%;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.channel-thumbnail__default--0 {
@ -148,7 +289,8 @@ $actions-z-index: 2;
.channel__primary-info {
// Ensure the profile pic/title sit ontop of the default cover background
z-index: $metadata-z-index;
//z-index: $metadata-z-index;
z-index: 5;
// Jump over the thumbnail photo because it is absolutely positioned
// Then add normal page spacing, _then_ add the actual padding
padding-left: calc(var(--channel-thumbnail-width) + var(--spacing-xl));
@ -158,6 +300,17 @@ $actions-z-index: 2;
min-width: 0;
width: 100%;
.channel__edit-thumb {
z-index: 5;
.button--alt {
border: 1px solid rgba(var(--color-primary-dynamic), 0.1);
&:hover {
background-color: var(--color-button-alt-bg);
color: var(--color-primary);
}
}
}
@media (max-width: $breakpoint-small) {
padding-left: var(--spacing-m);
margin-top: calc(var(--channel-thumbnail-width) + var(--spacing-l));
@ -189,7 +342,7 @@ $actions-z-index: 2;
align-items: flex-end;
.button {
height: auto;
// height: auto;
}
}
@ -205,6 +358,11 @@ $actions-z-index: 2;
flex-wrap: wrap;
font-size: var(--font-base);
.button,
.menu__button {
border: 1px solid rgba(var(--color-primary-dynamic), 0.1);
}
> .button,
> .button-group .button {
padding: 0 var(--spacing-s);
@ -237,6 +395,26 @@ $actions-z-index: 2;
margin-right: 0;
}
}
.claim__menu-button--inline {
z-index: 10;
.icon {
padding: 1rem;
margin: -1rem;
}
}
}
.button,
.menu__button {
&:hover {
color: var(--color-link);
background-color: rgba(var(--color-header-background-base), 0.95);
.icon {
stroke: var(--color-link);
}
}
}
}
@ -269,30 +447,23 @@ $actions-z-index: 2;
}
.menu__list.channel__list {
margin-top: var(--spacing-xs);
margin-left: 0;
padding: 0;
border-radius: var(--border-radius);
background: transparent;
max-height: 15rem;
overflow-y: scroll;
overflow-y: auto;
[role='menuitem'] {
margin: 0;
&[data-selected] {
background: transparent;
// background: transparent;
.channel__list-item,
.channel-staked__wrapper {
background-color: var(--color-card-background-highlighted);
}
}
&:first-child {
.channel__list-item {
border-top: 1px solid var(--color-border);
border-top-left-radius: var(--border-radius);
border-top-right-radius: var(--border-radius);
.claim-preview__title {
color: var(--color-primary-contrast);
}
}
}
@ -305,8 +476,21 @@ $actions-z-index: 2;
.channel__list-item {
padding-right: calc(var(--spacing-xl) + var(--spacing-s) * 2);
border-left: 1px solid var(--color-border);
border-right: 1px solid var(--color-border);
.icon__wrapper {
background-color: var(--color-primary);
.icon {
stroke: var(--color-primary-contrast);
}
}
&:hover {
.icon__wrapper {
.icon {
stroke: var(--color-primary-contrast);
}
}
}
}
}
}
@ -314,9 +498,8 @@ $actions-z-index: 2;
.channel__list-item {
display: flex;
align-items: center;
background-color: var(--color-card-background);
background-color: var(--color-header-background);
padding: var(--spacing-s);
border-bottom: 1px solid var(--color-border);
overflow: hidden;
.channel-thumbnail {
@ -336,23 +519,43 @@ $actions-z-index: 2;
border-radius: var(--border-radius);
}
.ff-container {
canvas {
border-radius: 50%;
}
.freezeframe-img {
width: 2rem !important;
height: 2rem !important;
border-radius: 50%;
}
}
&:hover {
background-color: var(--color-card-background-highlighted);
background-color: var(--color-primary);
.channel__list-text {
color: var(--color-menu-icon-active);
}
}
}
.channel__list-item--selected {
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
.icon--ChevronDown {
margin-left: var(--spacing-l);
}
&:hover {
.claim-preview__title {
color: white;
}
}
}
.channel__list-text {
font-weight: var(--font-weight-bold);
color: var(--color-text);
color: var(--color-menu-icon);
}
.channel__selector {
@ -361,16 +564,31 @@ $actions-z-index: 2;
@media (min-width: $breakpoint-small) {
margin-bottom: var(--spacing-l);
}
.ff-container {
canvas {
border-radius: 50%;
}
.freezeframe-img {
width: 2rem !important;
height: 2rem !important;
border-radius: 50%;
}
}
}
.channel-staked__wrapper {
z-index: 10;
display: flex;
position: absolute;
padding: 0.2rem;
bottom: -0.75rem;
left: -0.8rem;
background-color: var(--color-card-background);
bottom: -0.5rem;
right: -0.5rem;
border-radius: 50%;
svg {
fill: var(--color-brand-blue);
}
}
.channel-staked__wrapper--large {
@ -395,13 +613,14 @@ $actions-z-index: 2;
}
.channel-staked__indicator {
margin-left: 1px;
//margin-left: 1px;
z-index: 3;
fill: var(--color-gray-3);
}
.channel-staked__indicator--controlling {
fill: #00eaff;
fill: var(--color-primary);
}
.channel-staked__amount {
@ -413,3 +632,67 @@ $actions-z-index: 2;
color: var(--color-gray-3);
}
}
.channelsPage-wrapper {
.claim-preview__wrapper--channel {
position: relative;
border-radius: var(--border-radius);
background: rgba(var(--color-header-background-base), 0.6);
padding: var(--spacing-m) !important;
.claim__menu-button {
right: calc(var(--spacing-m) - 8px) !important;
margin-top: var(--spacing-xxs);
.icon {
stroke: var(--color-text);
}
&:hover {
.icon {
stroke: var(--color-primary);
}
}
}
.help--inline {
color: var(--color-text);
}
.claim-tile__info {
display: unset;
margin-top: 0;
margin-bottom: 0;
padding-bottom: 0;
}
.media__subtitle {
.claim-preview-metadata-sub-upload {
margin-top: 2px;
font-size: var(--font-small) !important;
}
}
@media (max-width: $breakpoint-small) {
.claim-preview--channel {
a:first-of-type {
.button__content {
align-items: unset;
}
}
.claim-preview__actions {
flex-flow: row;
.section__actions {
.button--alt {
margin-bottom: 0;
}
}
.claim-preview__custom-properties {
justify-content: unset;
}
}
}
.claim-preview__actions {
margin-top: var(--spacing-s) !important;
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -11,10 +11,9 @@
flex-direction: column;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
padding: var(--spacing-m);
padding-left: 0;
padding-bottom: 0;
padding-left: 0px;
padding-bottom: var(--spacing-s);
margin-top: var(--spacing-m);
margin-bottom: var(--spacing-m);
color: var(--color-text-subtitle);
@ -23,18 +22,20 @@
@media (min-width: $breakpoint-small) {
flex-direction: row;
}
@media (max-width: $breakpoint-small) {
padding: unset;
}
}
.claim-search__dropdown {
padding: 0 var(--spacing-m);
padding-right: var(--spacing-xl);
font-size: var(--font-body);
background-color: var(--color-card-background);
background-position: right var(--spacing-m) center;
}
.claim-search__dropdown--selected {
background-color: var(--color-input-bg-selected);
color: var(--color-primary-contrast);
background-color: var(--color-brand-blue);
}
.claim-search__input-container {
@ -42,18 +43,28 @@
flex-direction: column;
font-size: var(--font-body);
width: 100%;
margin-bottom: var(--spacing-m);
&:not(:first-of-type) {
margin-top: var(--spacing-s);
}
@media (min-width: $breakpoint-small) {
width: auto;
margin-top: 0;
&:not(:last-of-type) {
padding-right: var(--spacing-m);
&:not(:first-of-type) {
margin-top: 0;
padding-left: var(--spacing-m);
}
}
}
.claim-search__dropdown,
.claim-search__input-container {
@media (max-width: $breakpoint-small) {
padding-right: 0;
}
}
.claim-search__filter-button {
display: flex;
justify-content: center;
@ -78,6 +89,10 @@
@media (min-width: $breakpoint-small) {
justify-content: flex-start;
}
.claim-search__menu-group:last-of-type {
margin-right: unset;
}
}
.claim-search__top > div {
@ -90,6 +105,13 @@
display: flex;
flex-wrap: nowrap;
margin-right: var(--spacing-s);
@media (max-width: $breakpoint-small) {
margin-right: 0;
.button-toggle {
padding: 0 var(--spacing-s) 0 var(--spacing-xs);
}
}
}
.claim-search__menu-group--between {

View file

@ -88,14 +88,19 @@
.collection-preview__edit-buttons {
position: absolute;
left: 0;
top: calc(-1 * var(--spacing-m));
bottom: calc(-1 * var(--spacing-m));
top: calc(var(--spacing-m) * -1);
bottom: calc(var(--spacing-m) * -1);
padding-left: 0;
padding-top: var(--spacing-m);
padding-bottom: var(--spacing-m);
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
align-items: center;
@media (max-width: $breakpoint-small) {
margin-right: var(--spacing-s);
}
}
.collection-preview__edit-group {
@ -103,13 +108,15 @@
display: flex;
flex-direction: column;
width: 2rem;
align-items: center;
justify-content: center;
align-items: stretch;
flex-grow: 4;
@media (max-width: $breakpoint-small) {
width: 1.5rem;
margin-right: 0;
button {
padding: var(--spacing-xs) var(--spacing-xs);
}
}
}

View file

@ -0,0 +1,70 @@
.color-picker {
position: relative;
height: var(--height-input);
//background-color:#ff0000;
border-radius: var(--border-radius);
max-width: 220px;
margin-top: var(--spacing-s);
.swatch {
position: absolute;
left: 0;
margin: 5px;
background: var(--color-header-background);
border-radius: var(--border-radius);
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
display: inline-block;
cursor: pointer;
width: calc(var(--height-input) - (2 * 5px));
height: calc(var(--height-input) - (2 * 5px));
box-sizing: border-box;
}
.color {
width: 100%;
height: 100%;
border-radius: calc(var(--border-radius) - 2px);
}
.popover {
position: absolute;
z-index: 2;
}
.cover {
position: fixed;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
}
.sketch-picker {
background-color: var(--color-header-background) !important;
margin-bottom: var(--spacing-l);
.flexbox-fix {
input {
box-shadow: unset !important;
background-color: var(--color-header-button) !important;
text-align: center;
}
label {
color: var(--color-text) !important;
}
}
.flexbox-fix:nth-child(3) {
display: none !important;
}
.flexbox-fix:last-of-type {
display: none !important;
}
}
input {
width: 220px;
display: inline-block;
padding-left: calc(var(--height-input) + var(--spacing-xxs));
}
}

View file

@ -1,9 +1,9 @@
@import '../init/vars';
@import '../init/breakpoints';
$thumbnailWidth: 1.5rem;
$thumbnailWidthSmall: 1rem;
.create__comment {
.content_comment {
position: relative;
}
@ -11,6 +11,59 @@ $thumbnailWidthSmall: 1rem;
font-size: var(--font-small);
position: relative;
.section {
margin-top: var(--spacing-xs);
}
.button--file-action {
&:hover {
background-color: var(--color-primary) !important;
color: var(--color-primary-contrast);
}
}
.section__actions {
.button,
.button--link {
background-color: var(--color-header-background);
color: var(--color-text);
border-radius: var(--border-radius);
&:hover {
background-color: var(--color-primary);
color: var(--color-primary-contrast);
}
}
.button--link {
// flex: auto;
margin-top: -2px;
height: var(--height-button);
.button__content {
justify-content: center;
}
.button__label {
margin-top: 1px;
line-height: 18px;
}
}
.button--alt {
margin-top: -2px;
}
@media (max-width: $breakpoint-small) {
margin-top: var(--spacing-s);
.button--alt {
flex: auto;
.button__content {
justify-content: center;
}
}
.button--link {
flex: auto;
height: 2rem;
}
}
}
fieldset-section,
.form-field--SimpleMDE {
margin-top: 0;
@ -20,6 +73,65 @@ $thumbnailWidthSmall: 1rem;
display: flex;
justify-content: space-between;
align-items: flex-end;
.comment__char-count-mde {
margin-left: auto;
min-width: 40px;
text-align: center;
margin-bottom: 8px;
padding-left: 4px;
padding-right: 4px;
padding-top: 5px;
border-radius: var(--border-radius);
height: var(--height-input-slim);
}
.button--file-action {
padding: 0px;
height: var(--height-input-slim);
background: var(--color-header-background);
margin-bottom: 8px;
.button__content {
.icon {
width: var(--height-input-slim);
height: var(--height-input-slim);
padding: 4px;
border-radius: var(--border-radius);
}
}
&:hover {
background-color: var(--color-primary) !important;
.button__content {
.icon {
stroke: var(--color-primary-contrast);
}
}
}
}
}
@media (min-width: $breakpoint-small) {
fieldset-section + .section {
margin-top: var(--spacing-m);
}
}
}
@media (max-width: $breakpoint-small) {
.empty__wrap {
p {
font-size: var(--font-small);
text-align: center;
}
}
}
.comment-create--drawer {
.MuiPaper-root {
span {
color: var(--color-text);
}
}
}
@ -41,24 +153,35 @@ $thumbnailWidthSmall: 1rem;
padding-bottom: 0;
}
.commentCreate__labelWrapper {
.comment-create__label-wrapper {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: baseline;
flex-wrap: wrap;
width: 100%;
max-width: 50%;
.commentCreate__label {
.comment-create__label {
white-space: nowrap;
margin-right: var(--spacing-xs);
}
@media (min-width: $breakpoint-small) {
fieldset-section {
max-width: 10rem;
}
@media (max-width: $breakpoint-small) {
fieldset-section {
max-width: 10rem;
font-size: var(--font-xxsmall);
}
span {
font-size: var(--font-xxsmall);
}
select {
height: 1rem;
margin: var(--spacing-xxs) 0px;
}
}
}
@ -75,18 +198,35 @@ $thumbnailWidthSmall: 1rem;
margin-right: var(--spacing-m);
font-size: var(--font-large);
}
@media (max-width: $breakpoint-small) {
padding: var(--spacing-xs);
span {
font-size: var(--font-xsmall);
}
}
}
.commentCreate__minAmountNotice {
.comment-create__min-amount-notice {
margin-top: calc(var(--spacing-xxs) - 2px);
padding-top: calc(var(--spacing-xs) + 1px);
height: var(--height-button);
.icon {
margin-bottom: -3px; // TODO fix few instances of these (find "-2px")
}
@media (max-width: $breakpoint-small) {
margin: 0px;
padding-top: calc(var(--spacing-xs) + 3px);
font-size: var(--font-xsmall);
}
}
.commentCreate__stickerPreview {
@extend .commentCreate;
display: flex;
border: 1px solid var(--color-border);
background-color: var(--color-header-background);
border-radius: var(--border-radius);
padding: var(--spacing-s);
margin: var(--spacing-s) 0;
@ -120,4 +260,13 @@ $thumbnailWidthSmall: 1rem;
margin-left: var(--spacing-xxs);
}
}
@media (max-width: $breakpoint-small) {
padding: var(--spacing-xs);
height: 7rem;
span {
font-size: var(--font-xsmall);
}
}
}

View file

@ -0,0 +1,125 @@
@import '../init/breakpoints';
$emote-item-size--small: 2.5rem;
$emote-item-size--big: 3rem;
$sticker-item-size: 5rem;
// -- EMOJIS --
.selector-menu {
overflow-y: scroll;
overflow-x: hidden;
@media (min-width: $breakpoint-small) {
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
max-height: 25vh;
padding: var(--spacing-xs);
}
@media (max-width: $breakpoint-small) {
max-height: 30vh;
padding-top: var(--spacing-s);
&::-webkit-scrollbar {
width: 0 !important;
}
}
}
.emote-selector__items {
display: grid;
grid-template-columns: repeat(auto-fit, $emote-item-size--small);
justify-items: center;
justify-content: space-evenly;
button {
margin: 0px !important;
padding: var(--spacing-xs);
height: unset;
&:first-child {
margin-right: 0px;
}
@media (max-width: $breakpoint-small) {
&:focus,
&:hover {
background-color: transparent !important;
}
}
@media (min-width: $breakpoint-small) {
padding: var(--spacing-s);
}
}
@media (min-width: $breakpoint-small) {
grid-template-columns: repeat(auto-fit, $emote-item-size--big);
}
}
// -- STICKERS --
.selector-menu--stickers {
@extend .selector-menu;
padding-top: 0px;
@media (min-width: $breakpoint-small) {
border: 0;
}
}
.sticker-selector__items {
@extend .emote-selector__items;
grid-template-columns: repeat(auto-fit, $sticker-item-size);
.button--file-action {
overflow: hidden;
margin: unset;
padding: var(--spacing-xs);
height: unset;
.sticker-item--priced {
display: flex;
flex-direction: column;
align-items: center;
img {
margin-bottom: var(--spacing-s);
}
.superChat--light {
position: absolute;
display: inline;
bottom: 0;
.credit-amount {
color: var(--color-primary-contrast) !important;
}
}
}
img {
margin: 0px;
}
}
}
.sticker-selector__row-title {
font-size: var(--font-small);
padding-left: var(--spacing-xxs);
width: 100%;
text-align: center;
position: sticky;
top: 0px;
background-color: var(--color-tabs-background);
border-radius: var(--border-radius);
font-weight: 900;
z-index: 1;
@media (min-width: $breakpoint-small) {
padding-top: var(--spacing-xs);
}
@media (max-width: $breakpoint-small) {
font-size: var(--font-xsmall);
}
}

View file

@ -1,10 +1,26 @@
$thumbnailWidth: 1.5rem;
$thumbnailWidth: 2.5rem;
$thumbnailWidthSmall: 1rem;
.comments {
list-style-type: none;
font-size: var(--font-small);
margin-top: var(--spacing-l);
@media (max-width: $breakpoint-small) {
margin-top: var(--spacing-s);
div {
font-size: var(--font-xsmall) !important;
}
.channel-name {
font-size: var(--font-xsmall);
}
span {
font-size: var(--font-xxsmall);
}
}
}
.comments--contracted {
@ -12,7 +28,6 @@ $thumbnailWidthSmall: 1rem;
max-height: 5rem;
overflow: hidden;
-webkit-mask-image: -webkit-gradient(linear, left 30%, left bottom, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
overflow-wrap: anywhere;
}
.comments--replies {
@ -22,14 +37,16 @@ $thumbnailWidthSmall: 1rem;
}
.comment__sort {
margin: var(--spacing-s) 0;
margin-right: var(--spacing-s);
display: block;
display: inline-block;
@media (min-width: $breakpoint-small) {
margin-top: 0;
display: inline;
}
@media (max-width: $breakpoint-small) {
margin-right: 0;
}
}
.comment {
@ -42,6 +59,10 @@ $thumbnailWidthSmall: 1rem;
&:not(:first-child) {
margin-top: var(--spacing-l);
@media (max-width: $breakpoint-small) {
margin-top: var(--spacing-m) !important;
}
}
.comment__author-thumbnail {
@ -54,7 +75,6 @@ $thumbnailWidthSmall: 1rem;
.channel-staked__wrapper {
padding: 0;
left: calc(#{$thumbnailWidthSmall} / 4);
bottom: -1rem;
padding: -1rem;
margin-left: 0;
@ -75,20 +95,35 @@ $thumbnailWidthSmall: 1rem;
.comment__content {
display: flex;
flex-direction: row;
&:hover {
.ff-canvas {
opacity: 0 !important;
transition: opacity 1s !important;
}
.ff-image {
opacity: 1 !important;
}
}
}
.comment__replies-container {
margin: 0;
overflow-x: hidden;
}
.comment__replies {
display: flex;
margin-top: var(--spacing-m);
margin-left: calc(#{$thumbnailWidthSmall} + var(--spacing-xs));
margin-left: #{$thumbnailWidthSmall};
@media (min-width: $breakpoint-small) {
margin-left: calc(#{$thumbnailWidth} + var(--spacing-m));
}
@media (max-width: $breakpoint-small) {
margin-top: var(--spacing-s);
}
}
.comment--reply {
@ -122,7 +157,6 @@ $thumbnailWidthSmall: 1rem;
background-color: var(--color-comment-threadline);
&:hover {
box-shadow: 0 0 0 1px var(--color-comment-threadline-hover);
background-color: var(--color-comment-threadline-hover);
border-color: var(--color-comment-threadline-hover);
}
@ -135,7 +169,7 @@ $thumbnailWidthSmall: 1rem;
.comment--highlighted {
background: var(--color-comment-highlighted);
box-shadow: 0 0 0 5px var(--color-comment-highlighted);
border-radius: 4px;
border-radius: 2px;
}
.comment__body-container {
@ -148,6 +182,21 @@ $thumbnailWidthSmall: 1rem;
@media (min-width: $breakpoint-small) {
margin-left: var(--spacing-s);
}
&:hover {
.menu__button {
opacity: 1;
}
}
[aria-expanded='true'].menu__button {
opacity: 1;
background: var(--color-header-background);
border-radius: var(--border-radius);
.icon {
stroke: var(--color-primary);
}
}
}
.comment__dead {
@ -169,47 +218,46 @@ $thumbnailWidthSmall: 1rem;
justify-content: flex-start;
align-items: center;
height: 100%;
width: calc(100% - var(--spacing-m) - var(--spacing-s));
.channel-name {
color: var(--color-link);
&:hover {
color: var(--color-secondary);
}
}
}
.comment__pin {
margin-left: var(--spacing-s);
display: inline-block;
margin: 0 var(--spacing-s);
margin-right: 0;
font-size: var(--font-xsmall);
.icon {
padding-top: 1px;
}
}
.comment__badge {
padding-right: var(--spacing-xxs);
.icon {
margin-bottom: -3px;
}
}
.comment__badge--global-mod {
.st0 {
// @see: ICONS.BADGE_MOD
fill: #fe7500;
}
}
.comment__badge--mod {
.st0 {
// @see: ICONS.BADGE_MOD
fill: #ff3850;
@media (max-width: $breakpoint-small) {
width: 90%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.comment__message {
word-break: break-word;
max-width: 35rem;
padding-right: var(--spacing-xl);
color: var(--color-text);
ul li,
ol li {
list-style-position: inside;
ul li {
list-style-type: disc;
ul li {
list-style-type: circle;
}
}
p {
@ -217,28 +265,43 @@ $thumbnailWidthSmall: 1rem;
margin-top: var(--spacing-xxs);
}
}
@media (max-width: $breakpoint-small) {
padding-right: var(--spacing-l);
}
}
.comment__author {
max-width: 10rem;
text-overflow: ellipsis;
margin-right: var(--spacing-xs);
height: 100%;
.button__content {
max-width: 10rem;
overflow: hidden;
text-overflow: ellipsis;
}
}
.comment__author--creator {
padding: 0 3px;
background-color: var(--color-primary-alt);
background-color: var(--color-primary);
border-radius: var(--border-radius);
.button__content {
color: var(--color-primary-contrast);
}
.channel-name {
color: var(--color-primary-contrast);
}
&.button--uri-indicator {
color: var(--color-link);
color: var(--color-primary-contrast);
}
}
.comment__time {
@extend .button--uri-indicator;
opacity: 0.5;
opacity: 0.6;
white-space: nowrap;
height: 100%;
margin-right: var(--spacing-xs);
@ -251,6 +314,12 @@ $thumbnailWidthSmall: 1rem;
.comment__menu {
align-self: flex-end;
line-height: 1;
@media (max-width: $breakpoint-small) {
.menu__button {
opacity: 1;
}
}
}
.comment__char-count {
@ -272,8 +341,21 @@ $thumbnailWidthSmall: 1rem;
font-size: var(--font-xsmall);
.menu__link {
color: var(--color-text);
padding: 0;
color: var(--color-text);
}
.comment__menu-help {
color: var(--color-text);
.icon--ExternalLink {
margin-top: unset;
}
}
&:hover {
.comment__menu-help {
color: var(--color-primary-contrast);
}
}
}
@ -348,18 +430,23 @@ $thumbnailWidthSmall: 1rem;
&:disabled {
opacity: 1;
}
}
.comment__action,
.comment__author {
&:focus {
@include linkFocus;
.button__content {
.icon {
stroke: var(--color-text);
fill: transparent;
}
}
&:hover {
.button__content {
.icon {
fill: var(--color-primary);
}
}
}
}
.comment__action--active {
.icon {
fill: var(--color-primary-alt);
stroke: var(--color-primary);
}
}
@ -413,6 +500,7 @@ $thumbnailWidthSmall: 1rem;
max-width: 10rem;
white-space: pre-line;
margin-right: var(--spacing-s);
color: var(--color-text);
}
.comment--blocked {
@ -436,11 +524,17 @@ $thumbnailWidthSmall: 1rem;
.media__thumb {
flex-shrink: 0;
overflow: hidden;
$width: 5rem;
$width: 6rem;
@include handleClaimListGifThumbnail($width);
width: $width;
width: $width !important;
height: calc(#{$width} * (9 / 16));
margin-right: var(--spacing-s);
@media (max-width: $breakpoint-small) {
$width: 10rem;
width: $width !important;
height: calc(#{$width} * (9 / 16));
}
}
.channel-thumbnail {
@ -458,9 +552,19 @@ $thumbnailWidthSmall: 1rem;
margin: 0 0;
padding: 0;
&:hover {
.claim-preview__hover-actions {
display: none;
}
}
@media (min-width: $breakpoint-medium) {
margin: 0 var(--spacing-xs);
}
@media (max-width: $breakpoint-medium) {
padding-bottom: 0 !important;
}
}
.comment {
@ -473,6 +577,13 @@ $thumbnailWidthSmall: 1rem;
margin-top: 0;
margin-left: var(--spacing-s);
}
@media (max-width: $breakpoint-medium) {
margin-left: var(--spacing-s);
}
}
@media (max-width: $breakpoint-small) {
border-bottom: 1px solid var(--color-border);
}
}
@ -485,9 +596,18 @@ $thumbnailWidthSmall: 1rem;
max-width: 100%;
max-height: 100%;
}
@media (max-width: $breakpoint-small) {
height: 5rem;
}
}
.emote {
max-width: 1.5rem;
max-height: 1.5rem;
@media (max-width: $breakpoint-small) {
max-width: 1.25rem;
max-height: 1.25rem;
}
}

View file

@ -2,6 +2,7 @@
@extend .card;
position: absolute;
top: var(--spacing-s);
border-radius: var(--border-radius);
}
.content__viewer--disable-click {
@ -27,7 +28,16 @@
left: calc(var(--spacing-l) + var(--spacing-s));
z-index: 9999;
border: 2px solid black;
.file-render--video {
border-radius: unset;
}
&:hover {
.video-js--tap-to-unmute {
max-width: calc(var(--floating-viewer-width) - (var(--spacing-xs) * 3) - 42px);
}
.content__floating-close {
visibility: visible;
z-index: 9999;
@ -39,6 +49,12 @@
top: 0;
border-radius: 0;
border: none;
right: 0;
// Next line is fixing the player width
width: unset !important;
.file-render--video {
border-radius: 0;
}
}
.content__wrapper {
@ -46,6 +62,7 @@
width: 100%;
height: 100%;
background-color: black;
border-radius: var(--border-radius);
}
.content__wrapper--floating {
@ -55,6 +72,30 @@
.vjs-button--theater-mode {
display: none;
}
.video-js--tap-to-unmute {
max-width: calc(var(--floating-viewer-width) - (var(--spacing-xs) * 2));
.icon {
width: 24px;
height: 24px;
min-width: 24px;
}
}
.content__info {
.claim-preview__title {
.button {
width: 100%;
.button__label {
display: inline-block;
}
&:hover {
color: var(--color-primary);
}
}
}
}
}
.content__actions {
@ -77,10 +118,16 @@
.content__floating-close {
visibility: hidden;
position: absolute;
top: var(--spacing-s);
right: var(--spacing-s);
width: 3rem;
height: 3rem;
top: 8px;
right: 8px;
width: 42px;
height: 42px;
padding: 10px;
.icon {
width: 24px;
height: 24px;
}
}
.content__floating-link {
@ -93,12 +140,14 @@
.content__info {
cursor: grab;
height: var(--floating-viewer-info-height);
padding: var(--spacing-m);
padding: var(--spacing-s);
display: flex;
flex-direction: column;
align-items: flex-start;
white-space: nowrap;
background-color: var(--color-header-background-transparent);
-webkit-backdrop-filter: blur(4px);
backdrop-filter: blur(4px);
}
.content__cover {
@ -106,8 +155,7 @@
position: relative;
display: flex;
align-items: center;
border-radius: var(--card-radius);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
justify-content: center;
background-position: 50% 50%;
background-repeat: no-repeat;

View file

@ -1,4 +1,4 @@
@import '../init/vars';
@import '../init/breakpoints';
.emoteSelector {
animation: menu-animate-in var(--animation-duration) var(--animation-style);
@ -14,6 +14,8 @@
overflow-x: hidden;
max-height: 25vh;
padding: var(--spacing-s);
background-color: rgba(var(--color-primary-dynamic), 0.01);
border-radius: var(--border-radius);
.emoteSelector__listRowItems {
display: flex;
@ -30,11 +32,18 @@
width: 1.5rem;
height: 1.5rem;
.button__label {
line-height: normal;
}
span {
margin: auto;
font-size: var(--font-large);
}
}
&:hover {
background-color: rgba(var(--color-primary-dynamic), 0.2) !important;
}
}
}
}

View file

@ -11,7 +11,7 @@
position: relative;
margin-left: var(--spacing-m);
white-space: nowrap;
color: var(--color-purchased-text);
color: var(--color-primary-contrast);
}
&::before {
@ -21,9 +21,7 @@
width: 250%;
height: 160%;
transform: skew(15deg);
border-radius: var(--border-radius);
background-color: var(--color-purchased-alt);
border: 2px solid var(--color-purchased);
background-color: rgba(var(--color-primary-dynamic), 1);
}
}
@ -31,10 +29,12 @@
font-size: var(--font-body);
top: calc(var(--spacing-xxs) * -1);
margin-left: var(--spacing-m);
margin-right: var(--spacing-m);
height: 2.4rem;
.credit-amount {
margin: 0 var(--spacing-m);
margin-bottom: -0.5rem;
margin-bottom: -0.9rem;
}
&::before {

View file

@ -1,4 +1,29 @@
.file-page {
.card-stack {
.claim-preview {
&:hover {
.claim-preview__title {
color: var(--color-text);
}
}
.claim-preview__title {
&:hover {
color: var(--color-link);
}
}
}
}
.file-page__recommended {
.claim-preview__wrapper {
&:hover {
.claim-preview__title {
color: var(--color-link);
}
}
}
}
.file-page__video-container + .card,
.file-render + .card,
.content__cover + .card,
@ -16,10 +41,6 @@
.file-viewer--document {
margin-top: var(--spacing-l);
@media (min-width: $breakpoint-small) {
margin-top: var(--spacing-xl);
}
.button {
display: inline;
@ -50,6 +71,24 @@
}
}
// Temporary fix
.card__main-actions {
.claim-tile__info {
display: unset;
margin-top: -2px;
padding-bottom: 0;
.media__subtitle {
padding-bottom: 3px;
.claim-preview__channel-sub-count {
font-size: var(--font-xsmall) !important;
@media (max-width: $breakpoint-small) {
font-size: var(--font-xxsmall) !important;
}
}
}
}
}
> * {
width: 100%;
}
@ -57,6 +96,85 @@
@media (max-width: $breakpoint-medium) {
flex-direction: column;
}
@media (max-width: $breakpoint-small) {
.card__main-actions {
// padding: var(--spacing-s) var(--spacing-xxs) !important;
}
.claim-preview--inline {
align-items: flex-start;
line-height: 1.3;
.button--no-style {
align-self: center;
.channel-thumbnail {
margin: var(--spacing-xxs);
margin-top: 0px;
width: 2.5rem;
height: 2.5rem;
.ff-container {
width: 2.5rem;
height: 2.5rem;
overflow: hidden;
border-radius: var(--border-radius);
}
}
}
.claim-preview-info {
justify-content: flex-start;
.claim-preview__title {
margin: unset;
}
}
.media__subtitle {
height: unset;
display: flex;
max-width: 100%;
}
.claim-preview__channel-sub-count {
font-size: var(--font-xxsmall);
}
.claim-preview-metadata {
flex: 1;
overflow: hidden;
span {
font-size: var(--font-xxsmall);
}
}
.claim-preview__actions {
margin: 0;
align-self: flex-start;
.button-group {
margin: 0;
}
.button--alt {
padding: var(--spacing-xs);
height: unset;
.button__content {
height: unset;
}
}
span {
font-size: var(--font-xsmall);
font-weight: var(--font-weight-bold);
}
}
}
}
}
.file-render {
@ -69,6 +187,7 @@
.file-render--video {
background-color: black;
border-radius: var(--border-radius);
&:after {
content: '';
@ -83,6 +202,18 @@
opacity: 0;
pointer-events: none;
}
@media (max-width: $breakpoint-small) {
border-radius: unset;
.autoplay-countdown {
.file-viewer__overlay-secondary {
margin-bottom: 0 !important;
}
.autoplay-countdown__counter {
margin-top: var(--spacing-xxs) !important;
}
}
}
}
@keyframes fadeInFromBlack {
@ -300,7 +431,6 @@
top: 0;
left: 0;
right: 0;
z-index: 2;
background: linear-gradient(#000000, #00000000 70%);
height: 75px;
z-index: 1;
@ -378,6 +508,12 @@
// Video
// ****************************************************************************
// DRY: we'll soon move vjs items to videojs.scss, so just duplicate these for now.
$control-bar-height: 2.5rem;
$control-bar-font-size: 0.8rem;
$control-bar-popup-font-size: 0.8rem;
$control-bar-icon-size: 0.8rem;
.video-js-parent {
height: 100%;
width: 100%;
@ -399,22 +535,112 @@
pointer-events: none;
}
// control-bar: time
.vjs-control-bar {
// background-color: rgba(0, 0, 0, 0.8);
.vjs-remaining-time {
display: none;
}
.vjs-current-time,
.vjs-time-divider,
.vjs-duration {
.vjs-time-control {
line-height: $control-bar-height;
font-size: $control-bar-font-size;
display: flex;
}
.vjs-current-time {
padding-right: 0;
margin-right: 0.4rem;
@media (max-width: $breakpoint-small) {
margin-right: 0.2rem;
}
}
.vjs-time-divider {
min-width: unset;
padding: 0;
z-index: 0; // solves the grayed-out divider
}
.vjs-duration {
padding-left: 0;
margin-left: 0.4rem;
@media (max-width: $breakpoint-small) {
margin-left: 0.2rem;
}
}
}
// control-bar: menu, button and icon
.vjs-control-bar {
.vjs-menu-button {
font-size: $control-bar-font-size;
line-height: $control-bar-height;
}
.vjs-icon-placeholder {
font-size: $control-bar-icon-size; // videojs icon font
line-height: $control-bar-height;
}
.vjs-icon-placeholder::before {
line-height: $control-bar-height;
}
.vjs-quality-selector {
.vjs-icon-placeholder {
font-size: $control-bar-font-size;
}
}
.vjs-play-control,
.vjs-fullscreen-control {
.vjs-icon-placeholder {
// Compensate: these icons in Font VideoJs are smaller than their peers.
font-size: calc(#{$control-bar-icon-size} * 1.2);
}
}
.vjs-playback-rate {
.vjs-playback-rate-value {
font-size: $control-bar-font-size;
line-height: $control-bar-height;
}
.vjs-menu {
width: 10em; // Extend the width to prevent a potential scrollbar from blocking the text.
left: -3em; // Center the popup on top of the button that invoked it.
}
}
.vjs-chromecast-button {
.vjs-icon-placeholder {
$chromecast-icon-size: 21px;
width: $chromecast-icon-size;
height: $chromecast-icon-size;
}
}
}
// control-bar: general padding
.vjs-control-bar {
.vjs-button--play-previous:first-child,
.vjs-play-control:first-child {
margin-left: var(--spacing-xs);
@media (max-width: $breakpoint-small) {
margin-left: 0;
}
}
.vjs-fullscreen-control {
margin-right: var(--spacing-xs);
@media (max-width: $breakpoint-small) {
margin-right: 0;
}
}
.vjs-button--play-previous,
.vjs-button--play-next,
.vjs-mute-control {
@media (max-width: $breakpoint-small) {
width: 2.25rem;
}
}
}
.vjs-picture-in-picture-control {
@ -494,6 +720,11 @@
}
}
// Note: the '!important' above and below this line was added a quick hack
// to negate a change in vjs without having to increase specificity here.
// It won't be needed in an upcoming version of vjs, as they have updated
// their side https://github.com/videojs/video.js/pull/7098#issuecomment-908438543
&.vjs-layout-small {
.vjs-current-time,
.vjs-time-divider,
@ -503,25 +734,9 @@
}
}
// --- Adjust spacing ---
.vjs-current-time {
padding-right: 0;
}
.vjs-duration {
padding-left: 0;
}
.vjs-playback-rate .vjs-playback-rate-value {
// Reduce the gigantic font a bit. Default was 1.5em.
font-size: 1.25em;
line-height: 2.5;
}
.vjs-playback-rate .vjs-menu {
// Extend the width to prevent a potential scrollbar from blocking the text.
width: 8em;
left: -2em;
// --- Hide unwanted ---
.vjs-remaining-time {
display: none;
}
}
@ -546,10 +761,12 @@
background: black;
border: 1px solid var(--color-gray-4);
opacity: 0.9;
border-radius: var(--border-radius);
&:hover {
opacity: 1;
color: var(--color-white);
color: var(--color-primary);
border: 1px solid var(--color-primary);
}
}
@ -652,6 +869,7 @@
}
.autoplay-countdown__counter {
margin-top: var(--spacing-m);
color: #fff !important;
}
.autoplay-countdown__button {
@ -695,22 +913,13 @@
.file__viewdate {
display: flex;
justify-content: space-between;
flex-direction: column;
justify-content: start;
flex-direction: row;
margin-bottom: var(--spacing-s);
> :first-child {
margin-bottom: var(--spacing-s);
}
@media (max-width: $breakpoint-medium) {
flex-direction: row;
justify-content: start;
> :first-child {
margin-bottom: 0;
margin-right: 1rem;
}
margin-bottom: 0;
margin-right: var(--spacing-s);
}
}

View file

@ -11,6 +11,7 @@
@media (max-width: $breakpoint-small) {
max-width: 100%;
padding: var(--spacing-m);
padding-left: var(--spacing-s);
align-items: flex-start;
}
}
@ -29,6 +30,17 @@
.footer__link {
margin-left: 0;
margin-bottom: 0;
.button {
.button__label {
color: rgba(var(--color-text-base), 0.8);
}
&:hover {
.button__label {
color: rgba(var(--color-text-base), 1);
}
}
}
}
@media (min-width: $breakpoint-small) {

View file

@ -1,22 +1,16 @@
@import '../init/mixins';
input,
textarea,
select,
.date-picker-input {
height: var(--height-input);
border-radius: var(--border-radius);
border: 1px solid;
color: var(--color-input);
border-color: var(--color-input-border);
background-color: var(--color-input-bg);
padding-right: var(--spacing-s);
padding-left: var(--spacing-s);
&:focus {
@include focus;
}
&::placeholder {
color: var(--color-input-placeholder);
opacity: 0.4;
@ -31,12 +25,40 @@ select,
}
&[type='range'] {
height: auto;
height: 0.5rem;
background-color: var(--color-secondary);
}
}
@media (min-width: $breakpoint-small) {
textarea {
height: var(--height-input);
border-radius: var(--border-radius);
color: var(--color-input);
background-color: var(--color-input-bg);
padding-right: var(--spacing-s);
padding-left: var(--spacing-s);
&::placeholder {
color: var(--color-input-placeholder);
opacity: 0.4;
}
&:disabled {
opacity: 0.4;
& + label {
opacity: 0.4;
}
}
&[type='range'] {
height: 0.5rem;
background-color: var(--color-secondary);
}
}
}
checkbox-element,
radio-element,
select {
@ -95,6 +117,20 @@ form,
}
}
fieldset-section {
background-color: unset; // imp
select:focus-visible {
background-color: var(--color-header-background); // ip
}
select {
background-color: var(--color-header-background);
}
option {
background-color: var(--color-header-background);
}
}
fieldset-section,
.checkbox,
.radio {
@ -141,7 +177,7 @@ input-submit {
border-bottom-right-radius: 0;
border-right: none;
}
//
// FIX THIS e.g. copyable text vs editable text
//& > *:nth-child(2) {
// border-top-left-radius: 0;
// border-bottom-left-radius: 0;
@ -174,7 +210,7 @@ input-submit {
display: inline-block;
margin: 0;
font-size: var(--font-base);
padding-left: calc(var(--height-checkbox) + var(--spacing-s));
padding-left: calc(var(--height-checkbox) + 10px);
min-height: var(--height-checkbox);
&::before {
@ -205,11 +241,6 @@ input-submit {
input[type='radio']:checked + label::after {
content: '';
}
input[type='checkbox']:focus + label::before,
input[type='radio']:focus + label::before {
@include focus;
}
}
.checkbox {
@ -217,7 +248,6 @@ input-submit {
label::before {
height: var(--height-checkbox);
width: var(--height-checkbox);
border: 1px solid var(--color-input-border);
border-radius: var(--border-radius);
left: 0px;
top: -1px;
@ -229,8 +259,8 @@ input-submit {
width: 12px;
border-left: 2px solid;
border-bottom: 2px solid;
border-color: var(--color-input-toggle);
border-left-color: var(--color-input-toggle);
border-color: var(--color-primary);
border-left-color: var(--color-primary);
transform: rotate(-45deg);
left: 6px;
top: 6px;
@ -308,9 +338,7 @@ input[type='number'] {
fieldset-group {
+ fieldset-group {
&:not(.fieldset-group--row) {
margin-top: var(--spacing-s);
}
margin-top: var(--spacing-s);
}
&.fieldset-group--smushed {
@ -330,16 +358,13 @@ fieldset-group {
}
&:nth-of-type(2) {
&:not(input.paginate-channel) {
// yuck
input,
select {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
label {
margin-left: var(--spacing-s);
}
input,
select {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
label {
margin-left: var(--spacing-s);
}
}
}
@ -347,8 +372,16 @@ fieldset-group {
&.fieldgroup--paginate {
padding-bottom: var(--spacing-l);
margin-top: var(--spacing-l);
align-items: flex-end;
align-items: center;
justify-content: center;
fieldset-section {
input {
margin-left: var(--spacing-s);
border-radius: calc(var(--height-button) / 2);
height: var(--height-button);
}
}
}
&.fieldgroup--paginate-top {
@ -356,9 +389,6 @@ fieldset-group {
align-items: flex-end;
justify-content: center;
}
&:not(.fieldset-group--row) {
}
}
// This is a special case where the prefix appears "inside" the input
@ -387,7 +417,6 @@ fieldset-group {
overflow: hidden;
padding: 0.5rem;
height: var(--height-input);
border: 1px solid;
border-top-left-radius: var(--border-radius);
border-bottom-left-radius: var(--border-radius);
border-color: var(--color-input-border);
@ -418,6 +447,18 @@ fieldset-group {
}
}
.form-field--with-button {
padding: 0.2rem 0.75rem;
text-overflow: ellipsis;
user-select: text;
cursor: default;
}
.form-field--with-button ~ button {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
}
.form-field--copyable {
padding: 0.2rem 0.75rem;
text-overflow: ellipsis;
@ -425,6 +466,11 @@ fieldset-group {
cursor: default;
}
.form-field--copyable ~ button {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
}
.form-field--short {
width: 100%;
@media (min-width: $breakpoint-small) {
@ -450,6 +496,7 @@ fieldset-group {
.form-field__help {
@extend .help;
color: var(--color-text);
}
.form-field__help + .checkbox,
@ -465,19 +512,33 @@ fieldset-group {
@media (min-width: $breakpoint-small) {
column-count: 2;
}
@media (max-width: $breakpoint-small) {
span {
font-size: var(--font-xxsmall);
}
}
}
.form-field__quick-action {
font-size: var(--font-xsmall);
}
.form-field__hint {
font-size: var(--font-xsmall);
color: var(--color-input-label);
}
.form-field__textarea-info {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
margin-top: var(--spacing-xxs);
margin-bottom: var(--spacing-s);
text-align: right;
span {
display: inline-block;
padding-right: 0px;
}
}
fieldset-section {
@ -495,13 +556,25 @@ fieldset-section {
@media (min-width: $breakpoint-small) {
max-width: none;
select {
max-height: 1.5rem !important;
padding: 0 var(--spacing-xs);
padding-right: var(--spacing-l);
}
}
select {
max-height: 1.5rem !important;
max-height: var(--height-input-slim) !important;
padding: 0 var(--spacing-xs);
padding-right: var(--spacing-l);
}
@media (max-width: $breakpoint-small) {
select {
max-height: 1.25rem !important;
}
}
}
label {
@ -526,6 +599,7 @@ fieldset-section {
.form-field-date-picker {
margin-bottom: var(--spacing-l);
font-size: var(--font-base);
label {
display: block;
@ -598,6 +672,10 @@ fieldset-section {
cursor: pointer;
}
.react-calendar button:disabled {
background-color: rgba(var(--color-header-background-base), 1);
}
.react-calendar__navigation {
height: 44px;
margin-bottom: 1em;
@ -677,6 +755,10 @@ fieldset-section {
background: var(--color-button-alt-bg-hover);
}
.react-calendar__tile:disabled {
background-color: rgba(var(--color-primary-dynamic), 0.4);
}
.react-calendar__tile--now {
background: var(--color-button-secondary-bg);
}

View file

@ -1,4 +1,4 @@
@import '../init/vars';
@import '../init/breakpoints';
@import '../init/mixins';
.header {
@ -7,11 +7,12 @@
top: 0;
width: 100%;
background-color: var(--color-header-background);
box-shadow: var(--card-box-shadow);
font-size: var(--font-body);
user-select: none;
-webkit-user-select: none;
-webkit-app-region: drag;
-webkit-backdrop-filter: blur(4px);
backdrop-filter: blur(4px);
.skip-button {
opacity: 0;
@ -31,20 +32,90 @@
height: unset;
}
}
.header__menu--right {
.header__navigationItem--balance {
.button__label {
margin-left: var(--spacing-xxs);
}
&:hover {
.button__label {
color: var(--color-primary);
}
.icon {
stroke: var(--color-primary);
}
}
}
}
.button--link {
color: var(--color-brand) !important;
&:hover {
color: var(--color-link-hover) !important;
}
}
.button--primary {
background-color: var(--color-brand) !important;
color: var(--color-brand-contrast) !important;
}
@media (max-width: $breakpoint-small) {
.card__actions--between {
.header__menu--left,
.header__menu--right {
width: 5rem;
min-width: 5rem;
}
}
}
*:focus-visible:not(.wunderbar__input):not(.menu__list):not(.menu__list--header):not(.button--secondary):not(.button-like):not(.button-dislike):not(select):not(input):not(textarea):not(video) {
background-color: rgba(var(--color-primary-static), 0.2) !important;
color: var(--color-text) !important;
box-shadow: 0px 0px 0px 2px var(--color-brand) inset;
.icon {
stroke: var(--color-text) !important;
}
}
select:focus-visible,
input:focus-visible:not(.wunderbar__input),
textarea:focus-visible {
box-shadow: 0px 0px 0px 2px var(--color-brand) inset;
}
.ff-container {
canvas {
border-radius: 50%;
}
.freezeframe-img {
width: var(--height-button) !important;
height: var(--height-button) !important;
border-radius: 50%;
}
}
}
.header--minimal {
box-shadow: none;
background-color: var(--color-background);
background-color: var(--color-header-background);
border-bottom: none;
.header__navigation {
padding: var(--spacing-xs) 0;
padding: var(--spacing-xs);
}
.header__navigationItem--logo {
height: 3rem;
}
.header__menu--left,
.header__menu--right {
width: unset;
min-width: unset;
}
}
.header--mac {
@ -60,6 +131,7 @@
@media (max-width: $breakpoint-small) {
padding: var(--spacing-xs);
height: var(--header-height-mobile);
}
}
@ -71,12 +143,89 @@
height: var(--header-height);
padding: var(--spacing-s) 0;
flex-wrap: nowrap;
.wunderbar__wrapper {
.wunderbar__input {
background-color: var(--color-header-button) !important;
}
&:hover {
.wunderbar__input {
outline: 2px solid var(--color-header-button-hover) !important;
}
}
.wunderbar__input:focus-visible {
outline: 2px solid var(--color-primary) !important;
}
}
.button--alt {
background-color: var(--color-header-button);
color: var(--color-text);
&:hover {
color: var(--color-brand-contrast);
}
}
.button__content {
&:hover {
.button__label {
color: var(--color-brand-contrast);
}
}
}
@media (max-width: $breakpoint-small) {
padding: var(--spacing-xs);
height: var(--header-height-mobile);
.button--alt {
display: flex;
align-items: center;
justify-content: center;
padding: 0;
.button__content {
width: unset;
height: 22px;
}
}
.header__navigationItem--logo {
border-radius: 50%;
svg {
width: calc(var(--header-height-mobile) - var(--spacing-m));
height: calc(var(--header-height-mobile) - var(--spacing-m));
}
}
.button,
.header__navigationItem--icon {
width: calc(var(--header-height-mobile) - var(--spacing-m));
height: calc(var(--header-height-mobile) - var(--spacing-m));
background-color: rgba(var(--color-primary-static), 0.6);
.icon {
stroke: var(--color-brand-contrast);
}
}
.channel-thumbnail {
width: calc(var(--header-height-mobile) - var(--spacing-m)) !important;
height: calc(var(--header-height-mobile) - var(--spacing-m)) !important;
}
}
}
.card__actions--between {
.header__menu--left {
@media (max-width: $breakpoint-small) {
max-width: 3rem;
.wunderbar__wrapper--mobile {
border-bottom: unset !important;
.wunderbar__input {
border-radius: var(--border-radius) !important;
background-color: var(--color-header-button) !important;
&:focus-visible,
&:focus {
outline: 2px solid var(--color-brand) !important;
}
}
}
@ -84,31 +233,43 @@
.header__menu {
display: flex;
align-items: center;
@media (min-width: $breakpoint-small) {
width: 15rem;
min-width: 15rem;
}
}
.header__menu--left {
@extend .header__menu;
justify-content: flex-start;
margin-left: var(--spacing-s);
@media (max-width: $breakpoint-small) {
margin-left: unset;
}
}
.header__menu--right {
@extend .header__menu;
justify-content: flex-end;
@media (max-width: $breakpoint-small) {
max-width: 4rem;
}
}
.header__buttons {
display: flex;
}
.header__navigation-logo {
.header__navigation--logo {
height: var(--height-button);
}
// above
.header__logo {
height: var(--height-button);
max-width: -webkit-fit-content;
max-width: -moz-fit-content;
max-width: fit-content;
@media (max-width: $breakpoint-small) {
height: var(--height-button-mobile);
}
}
.header__navigationItem {
@ -120,12 +281,28 @@
position: relative;
font-weight: var(--font-weight-bold);
svg {
stroke: var(--color-text);
&[aria-expanded='true']:not(.header__navigationItem--profilePic) {
transform: rotate(0deg);
&:not(.button-rotate) {
background-color: var(--color-header-button-hover);
.icon {
stroke: var(--color-brand-contrast);
}
}
}
&[aria-expanded='true'] {
background-color: var(--color-header-button-active);
@media (max-width: $breakpoint-small) {
height: var(--height-button-mobile);
}
&:hover {
.button__label {
color: var(--color-brand) !important;
}
.icon {
stroke: var(--color-brand);
}
}
}
@ -137,19 +314,18 @@
background-color: var(--color-header-button);
border-radius: 1.5rem;
margin-right: var(--spacing-s);
color: var(--color-header-button-text);
&:hover {
background-color: var(--color-header-button-hover);
}
@media (min-width: $breakpoint-small) {
&:focus {
@include focus;
.icon {
stroke: var(--color-primary);
color: var(--color-brand);
}
}
@media (max-width: $breakpoint-small) {
margin: 0;
width: calc(var(--header-height-mobile) - var(--spacing-m));
height: calc(var(--header-height-mobile) - var(--spacing-m));
}
span {
@ -160,43 +336,91 @@
}
.header__navigationItem--profilePic {
margin-right: var(--spacing-s);
border-radius: 50%;
.channel-thumbnail {
height: var(--height-button);
width: var(--height-button);
margin-right: 0;
}
.channel-staked__tooltip {
display: none;
}
&:hover {
opacity: 0.7;
.ff-canvas {
opacity: 0 !important;
transition: opacity 1s !important;
}
.ff-image {
opacity: 1 !important;
}
}
@media (max-width: $breakpoint-small) {
margin: 0;
.channel-thumbnail {
height: var(--height-button-mobile);
width: var(--height-button-mobile);
}
}
}
.header__navigationItem--iconSkeleton {
@extend .header__navigationItem--icon;
height: var(--height-button) !important;
width: var(--height-button) !important;
@media (max-width: $breakpoint-small) {
height: calc(var(--header-height-mobile) - var(--spacing-m)) !important;
width: calc(var(--header-height-mobile) - var(--spacing-m)) !important;
}
}
.header__navigationItem--balance {
@extend .header__navigationItem;
margin: 0 var(--spacing-s);
color: var(--color-text);
padding-left: var(--spacing-s);
padding-right: var(--spacing-s);
background-color: var(--color-header-button);
&:hover {
color: var(--color-text);
color: var(--color-primary-contrast);
}
@media (max-width: $breakpoint-small) {
margin: 0 !important;
padding: 0 !important;
width: 5rem;
}
}
.header__navigationItem--balanceLoading {
margin: 0 var(--spacing-s);
width: 4rem;
background-color: var(--color-header-button);
@media (max-width: $breakpoint-small) {
margin: 0 !important;
width: 5rem;
}
}
.header__navigationItem--logo {
@extend .header__navigationItem;
height: 4rem;
display: flex;
align-items: center;
margin-left: var(--spacing-m);
margin-right: var(--spacing-m);
margin: 0 var(--spacing-s);
color: var(--color-text);
// move to lbry theme?
.lbry-icon {
height: var(--height-button);
width: var(--height-button);
}
@media (max-width: $breakpoint-small) {
margin-right: var(--spacing-m);
height: 5rem;
margin: 0;
.button__label {
display: none;
@ -242,6 +466,5 @@
.ReactModal__Overlay {
.button--close {
margin: 0;
margin-top: var(--spacing-xxs);
}
}

View file

@ -1,5 +1,5 @@
.icon__wrapper {
background-color: var(--color-primary-alt);
background-color: var(--color-header-background);
display: flex;
align-items: center;
justify-content: center;
@ -13,7 +13,7 @@
.icon {
position: absolute;
stroke: var(--color-primary);
stroke: var(--color-text);
}
}
@ -22,6 +22,7 @@
.icon {
stroke: var(--color-follow-icon);
fill: var(--color-follow-icon);
}
}

View file

@ -1,3 +1,7 @@
body {
overflow-x: hidden;
}
.main-wrapper {
position: relative;
margin-left: auto;
@ -36,21 +40,21 @@
.main-wrapper__inner--filepage {
padding: 0;
@media (max-width: $breakpoint-small) {
margin-top: 0px;
padding-top: var(--header-height-mobile);
}
}
.main-wrapper__inner--theater-mode {
padding-top: 0;
}
.main-wrapper__inner--auth {
min-height: unset;
padding: 0;
}
.sidebar--pusher {
animation-timing-function: var(--resizing-animation-function);
transition: transform var(--resizing-animation-timing);
transform-origin: left;
transform-origin: top center;
position: absolute;
@media (max-width: $breakpoint-small) {
@ -70,8 +74,16 @@
.sidebar--pusher--open {
@media (min-width: $breakpoint-medium) {
transform: translateX(var(--side-nav-width));
width: calc(100% - var(--side-nav-width));
transform: scaleX(0.9) translateX(calc(5.4 * var(--spacing-l))) scaleY(0.9);
}
}
.main-wrapper__inner--auth {
min-height: calc(100vh - var(--header-height));
padding: 0;
.main--auth-page {
min-height: unset;
}
}
@ -82,12 +94,13 @@
z-index: 0;
margin-right: auto;
margin-left: auto;
min-height: calc(100vh - var(--header-height));
padding: 0 var(--spacing-m);
@media (min-width: $breakpoint-small) {
min-height: calc(100vh - var(--header-height));
}
@media (max-width: $breakpoint-small) {
width: 100%;
min-height: calc(100vh - var(--header-height-mobile));
}
}
@ -109,7 +122,7 @@
.file-page__secondary-content {
display: flex;
flex-direction: row;
flex-direction: column;
justify-content: center;
width: 100%;
margin-top: var(--spacing-m);
@ -122,9 +135,54 @@
max-width: 100%;
}
.claim-preview__wrapper--inline {
.media__subtitle {
padding-bottom: 0;
a.button {
display: inline-block !important;
}
}
}
.date_time {
font-size: var(--font-small);
}
.comment__meta-information {
.date_time {
font-size: var(--font-xsmall) !important;
color: rgba(var(--color-text-base), 0.6);
&:hover {
color: var(--color-text);
}
}
}
@media (min-width: $breakpoint-medium) {
flex-direction: row;
}
@media (max-width: $breakpoint-medium) {
section + .empty__wrap {
margin: var(--spacing-m);
}
}
@media (max-width: $breakpoint-small) {
margin-top: var(--spacing-xs) !important;
.claim-preview__wrapper {
padding: 0 !important;
a {
.button__content {
align-items: unset;
}
}
}
}
}
.media__subtitle--centered::before {
content: '';
margin-right: var(--spacing-s);
}
@keyframes fadeIn {
@ -155,23 +213,81 @@
.file-page__recommended {
height: 0%;
width: 35rem;
margin-left: var(--spacing-m);
width: 32rem;
margin-left: var(--spacing-l);
.card__first-pane {
.card__header--between {
.card__title-section {
display: none !important;
}
}
.card__body.card__body--list {
border-top: unset;
}
}
.card__header--between {
align-items: center;
align-items: unset;
.card__title-section--body-list {
margin-top: auto;
}
}
.claim-preview-metadata {
.claim-tile__info {
margin-top: 0;
.media__subtitle {
.button__content {
margin-top: 0;
.channel-name {
margin-top: 0;
}
}
span,
.date_time {
margin-top: 0px;
}
}
}
.claim-preview__title {
.truncated-text {
-webkit-line-clamp: 2 !important;
}
}
.channel-thumbnail {
display: none;
width: 1.4rem;
height: 1.4rem;
}
}
@media (max-width: $breakpoint-medium) {
width: 100%;
margin-left: 0;
margin-top: var(--spacing-l);
}
@media (max-width: $breakpoint-small) {
.card__header--between {
padding: var(--spacing-xxs);
padding-bottom: var(--spacing-s);
padding-left: 0;
}
}
}
.file-page__recommended-collection {
@extend .file-page__recommended;
flex-direction: column;
overflow-wrap: break-word;
width: 28rem;
@media (max-width: $breakpoint-small) {
width: unset;
}
.card__title-section--body-list {
width: 100%;
}
.card__header--between {
align-items: flex-start !important;
@ -188,20 +304,103 @@
}
}
.file-page__recommended-collection__row {
display: block;
@media (min-width: $breakpoint-medium) {
max-width: 15rem;
.card__title-actions-container {
position: absolute;
top: 0;
right: 0;
height: unset;
display: unset;
flex-direction: unset;
.card__title-actions {
padding: 0;
.button {
height: 2rem;
padding: 0.5rem;
}
}
@media (max-width: $breakpoint-medium) {
max-width: 50rem;
@media (max-width: $breakpoint-small) {
top: calc(var(--spacing-s) * -1);
}
}
.file-page__recommended-collection__row {
display: block;
max-width: unset;
width: 100%;
align-items: center;
color: var(--color-text);
&:hover {
color: var(--color-primary);
}
&:nth-child(2) {
display: flex;
margin-top: calc(var(--spacing-m) * -1 - 10px);
.button {
flex: auto;
.button__content {
flex-direction: column;
justify-content: center;
.color-override {
stroke: var(--color-primary);
}
}
}
}
@media (max-width: $breakpoint-small) {
max-width: unset;
width: 100%;
.button--file-action {
height: unset;
margin-right: var(--spacing-xxxs);
.button__content {
padding: var(--spacing-xxs);
margin: 0;
}
}
.button--file-action:last-of-type {
margin-right: 0;
}
}
}
a {
.file-page__recommended-collection__row {
@media (max-width: $breakpoint-small) {
width: calc(100% - var(--spacing-xl));
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
}
.collection-preview__edit-group {
width: 1.5rem;
//width: 1.5rem;
}
}
.file-page__playlist-collection {
@extend .file-page__recommended-collection;
.card__first-pane {
.card__header--between {
.card__title-section {
display: unset !important;
}
}
}
.file-page__playlist-collection__row {
@extend .file-page__recommended-collection__row;
.button--file-action {
&:hover {
.icon {
stroke: white;
}
}
}
}
.claim-preview--collection-mine {
@ -217,6 +416,42 @@
}
}
@media (max-width: $breakpoint-small) {
flex-direction: column;
margin: 0;
padding: 0;
.file-page__secondary-content {
margin: 0;
padding: 0;
}
.card {
border-radius: 0;
margin-bottom: 0px !important;
padding: var(--spacing-xxs);
}
.file-page__recommended {
margin-top: 0px !important;
}
}
}
.card__title-section--body-list {
display: unset !important;
div {
flex: auto;
}
@media (max-width: $breakpoint-small) {
.card__title {
width: 100%;
}
}
}
.main--upcoming {
@media (max-width: $breakpoint-small) {
padding: var(--spacing-xs);
flex-direction: column;
@ -248,8 +483,6 @@
}
.file-page__recommended {
width: 25rem;
@media (max-width: $breakpoint-medium) {
width: 100%;
}
@ -263,6 +496,10 @@
flex-direction: column;
}
}
.file-page__recommended {
margin-top: 10px;
}
}
.main--full-width {
@ -270,6 +507,14 @@
max-width: none;
}
.main--popout-chat {
@extend .main;
margin: 0 !important;
padding: 0 !important;
width: 100vw !important;
height: 100vh !important;
}
.main--auth-page {
width: 100%;
max-width: 70rem;
@ -291,8 +536,108 @@
margin-top: var(--spacing-m);
padding: 0 var(--spacing-m);
@media (max-width: $breakpoint-small) {
.section__header--actions {
.section__actions--inline:last-of-type {
.button__label {
display: none;
}
}
}
}
.card__body--list {
background-color: rgba(var(--color-header-background-base), 0.4);
border-radius: var(--border-radius);
border-top: unset;
.settings__row {
padding: var(--spacing-s);
border-bottom: 1px solid var(--color-border);
.checkbox {
// Outer box of the fake checkbox
label::before {
height: var(--height-checkbox);
width: var(--height-checkbox);
border: 1px solid var(--color-input-border);
border-radius: var(--border-radius);
left: 0px;
top: -1px;
}
}
.radio {
label::before {
height: var(--height-checkbox);
width: var(--height-checkbox);
border: 1px solid var(--color-input-border);
background-color: var(--color-card-background);
left: 0px;
top: -1px;
}
}
.settings__row--value {
.button__content {
&:hover {
color: var(--color-secondary);
}
}
}
.fieldset-group--smushed {
label {
margin-left: 0;
}
fieldset-section:last-of-type {
margin-left: 2px;
}
}
}
.settings__row:first-of-type {
margin-top: var(--spacing-xxxs);
}
.settings__row:last-of-type {
border-bottom: unset;
}
.card__main-actions {
border-top: unset;
}
}
.button--secondary {
background-color: var(--color-header-button) !important;
.button__content {
.icon {
stroke: var(--color-text) !important;
}
.button__label {
color: var(--color-text) !important;
}
}
&:hover {
background-color: var(--color-primary) !important;
.button__content {
.icon {
stroke: var(--color-primary-contrast) !important;
}
.button__label {
color: var(--color-primary-contrast) !important;
}
}
}
}
@media (max-width: $breakpoint-small) {
padding: 0 0;
.wunderbar__wrapper {
margin-right: 0;
.wunderbar {
padding-left: 0;
.icon {
left: 11px;
}
}
}
}
.card__subtitle {
@ -303,10 +648,141 @@
.button--inverse {
color: var(--color-primary);
}
.card__title-section {
padding-bottom: 0;
}
.card__title-section:not(:first-child) {
padding-top: var(--spacing-l);
}
.section__actions--between:first-child {
margin-top: var(--spacing-s);
}
.section__actions--between {
border-top: unset;
margin-top: 0;
padding-top: var(--spacing-s);
padding-bottom: var(--spacing-s);
margin-left: auto;
position: relative;
.settings__row--value {
align-self: start;
}
.settings__row--title {
color: rgba(var(--color-text-base), 0.9);
}
.settings__row--subtitle {
color: rgba(var(--color-text-base), 0.6);
}
&:hover:not(.opacity-30) {
.settings__row--title {
color: rgba(var(--color-text-base), 1);
}
}
}
.tags--remove {
.button {
background-color: var(--color-header-background);
color: var(--color-text);
}
}
.claim-preview__wrapper--channel {
.menu__button {
right: var(--spacing-s);
right: 0 !important;
}
.claim-tile__info {
margin-top: 0;
padding-bottom: var(--spacing-xxxs);
.claim-preview-metadata-sub-upload {
margin-top: 3px;
}
}
.button--secondary {
background-color: var(--color-header-button) !important;
&:hover {
.button__label {
color: var(--color-text) !important;
}
}
}
.claim__tags {
a.button {
.button__content {
margin-top: -3px;
.button__label {
overflow: unset;
}
}
}
}
}
.claim-preview__wrapper--channel.placeholder {
.media__thumb {
width: 6rem !important;
height: 6rem;
border-radius: 50%;
}
.channel-thumbnail {
display: none;
}
@media (max-width: $breakpoint-small) {
.media__thumb {
width: 4rem !important;
height: 4rem;
}
}
}
}
.main--markdown {
flex-direction: column;
.claim-preview__wrapper {
.claim-tile__info {
margin-top: 0;
padding-bottom: var(--spacing-xxxs);
.claim-preview-metadata-sub-upload {
margin-top: 3px;
}
.channel-name {
margin-top: -8px;
}
}
}
.post__info--grouped {
.button__content {
color: var(--color-primary);
.icon {
color: var(--color-text-subtitle);
}
&:hover {
color: var(--color-secondary);
}
}
}
.markdown-preview {
p {
.button__content {
.channel-name {
font-size: var(--font-large);
color: var(--color-primary);
@media (max-width: $breakpoint-small) {
font-size: var(--font-base);
}
}
}
}
}
@media (max-width: $breakpoint-small) {
padding: var(--spacing-xxxs);
}
}
.main__auth-content {
@ -379,6 +855,15 @@
.main--report-content {
@extend .main--auth-page;
max-width: 40rem;
.form-field__two-column {
display: flex;
.comment__char-count-mde {
margin-left: auto;
padding-bottom: 2px;
padding-right: 0;
}
}
}
.main--empty {
@ -433,6 +918,14 @@
max-width: 27rem;
margin-left: auto;
margin-right: auto;
@media (max-width: $breakpoint-small) {
margin-top: var(--spacing-m);
.card__title {
font-size: var(--font-large) !important;
}
}
}
.main__sign-up--graphic {
@ -444,22 +937,20 @@
width: 100%;
}
}
.card__second-pane {
width: 50%;
@media (max-width: $breakpoint-small) {
width: 100%;
}
border: none;
display: flex;
align-items: center;
justify-content: center;
background: var(--color-login-graphic-background);
@media (max-width: $breakpoint-small) {
width: 100%;
}
.signup-image {
@media (max-width: $breakpoint-small) {
width: 50%;
width: 100%;
}
}
}
@ -480,30 +971,6 @@
max-width: 32rem;
}
// maybe remove all REMOVE
.main-wrapper--scrollbar {
// The W3C future standard; currently supported by Firefox only.
// It'll hopefully auto fallback to this when 'webkit-scrollbar' below is deprecated in the future.
scrollbar-width: auto;
scrollbar-color: var(--color-scrollbar-thumb-bg) var(--color-scrollbar-track-bg);
}
.main-wrapper--scrollbar *::-webkit-scrollbar {
width: 12px;
height: 12px;
}
.main-wrapper--scrollbar *::-webkit-scrollbar-track {
background: var(--color-scrollbar-track-bg);
}
.main-wrapper--scrollbar *::-webkit-scrollbar-thumb {
// Don't set 'border-radius' because Firefox's 'scrollbar-xx'
// standard currently doesn't support it. Stick with square
// scrollbar for all browsers.
background-color: var(--color-scrollbar-thumb-bg);
}
::-webkit-scrollbar {
width: 12px;
height: 12px;

View file

@ -47,6 +47,9 @@
}
&.markdown-preview--description {
padding-top: var(--spacing-s);
margin-bottom: var(--spacing-l);
h1 {
font-size: 1.2em;
}
@ -65,6 +68,29 @@
h6 {
font-size: 0.7em;
}
@media (max-width: $breakpoint-small) {
margin-bottom: 0;
font-size: var(--font-xsmall);
word-wrap: break-word;
overflow: hidden;
a {
.button__content {
display: block;
}
span {
font-size: var(--font-xsmall);
font-weight: var(--font-weight-bold);
}
svg {
margin-left: var(--spacing-xxs);
bottom: 2;
}
}
}
}
dl,
@ -182,10 +208,24 @@
text-align: left;
}
.file-viewer__embedded-header {
.file-viewer__embedded-title {
width: calc(100% - 120px);
.button__label {
display: inline-block;
width: 100%;
}
}
.file-viewer__overlay-logo {
padding-left: 0;
}
}
.preview-link__url {
font-size: var(--font-xxsmall);
margin-top: 0;
padding-left: var(--spacing-xs);
padding-right: var(--spacing-xs);
background-color: black;
color: var(--color-gray-2);
width: 100%;
@ -198,7 +238,9 @@
line-height: 2rem;
.button__label {
display: inline-block;
white-space: nowrap;
width: 100%;
}
&:hover {
@ -221,7 +263,7 @@
padding: 0;
margin: 0;
padding-right: var(--spacing-s);
background-color: var(--color-primary-alt);
background-color: var(--color-secondary);
display: block;
align-items: center;
word-break: break-all;

View file

@ -4,12 +4,13 @@
.media__thumb {
@include thumbnail;
position: relative;
border-radius: var(--border-radius);
border-radius: var(--border-radius-thumbnail);
object-fit: cover;
background-color: var(--color-placeholder-background);
background-position: center;
background-repeat: no-repeat;
background-size: cover;
box-shadow: 0px 0px 0px 1px rgba(var(--color-primary-dynamic), 0.3) inset;
}
// M E D I A
@ -46,6 +47,11 @@
align-self: auto;
align-items: center;
display: flex;
.media__subtitle--centered::before {
content: '';
margin-right: var(--spacing-s);
}
}
.media__subtitle--between {
@ -70,6 +76,7 @@
&.media__info-text--constrained {
max-width: 50rem;
font-size: var(--font-small);
}
}
@ -77,21 +84,44 @@
margin-top: var(--spacing-m);
max-height: 5rem;
overflow: hidden;
font-size: var(--font-small);
}
.media__info-text--expanded {
margin-top: var(--spacing-m);
max-height: auto;
font-size: var(--font-small);
}
.media__info-text--contracted,
.media__info-text--expanded {
margin-top: var(--spacing-m);
max-width: 50rem;
@media (max-width: $breakpoint-small) {
margin-top: 0px;
}
}
.media__info-text--contracted {
@extend .media__info-text--expanded;
overflow: hidden;
.mediaInfo__description {
max-height: 5rem;
}
}
@media (max-width: $breakpoint-small) {
.mediaInfo__description {
margin-top: var(--spacing-s);
}
}
.media__info-text--fade {
//overflow-wrap: anywhere; // safari only
// both needed for compatibility
-webkit-mask-image: -webkit-gradient(linear, left 55%, left bottom, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
overflow-wrap: anywhere;
mask-image: -webkit-gradient(linear, left 55%, left bottom, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
}
.media__info-expand {
@ -110,20 +140,145 @@
@include font-sans;
position: relative;
display: flex;
flex-wrap: wrap;
margin-top: 0;
> *:not(:last-child) {
margin-right: var(--spacing-m);
}
.button--file-action {
background-color: unset;
}
.button {
&:hover {
color: var(--color-link);
.icon {
stroke: var(--color-link);
}
}
}
.ratio-wrapper {
position: relative;
width: 100%;
margin-right: var(--spacing-m);
.ratio-bar {
position: absolute;
display: flex;
left: 0px;
bottom: -2px;
width: 100%;
height: 3px;
background-color: var(--color-text);
z-index: 2;
border-radius: 2px;
overflow: hidden;
.ratio-bar-like {
height: 100%;
background-color: var(--color-fire);
}
.ratio-bar-dislike {
height: 100%;
background-color: var(--color-slime);
}
}
.button-dislike {
margin-right: 0px;
float: right;
}
@media (max-width: $breakpoint-small) {
margin-right: 0px;
.ratio-bar {
height: 1px;
bottom: -1px;
}
}
}
@media (max-width: $breakpoint-small) {
padding-top: var(--spacing-s);
flex-wrap: wrap;
justify-content: flex-end !important;
margin: 0;
padding: 0;
> * {
margin-right: var(--spacing-s);
margin-bottom: var(--spacing-s);
}
.button--file-action--menu {
width: unset;
}
.icon--Plus {
top: -2px;
}
.button--file-action:last-child {
margin-right: 0;
}
.button--file-action {
display: flex;
padding-left: var(--spacing-m);
margin-right: var(--spacing-xxxs);
justify-content: center;
align-items: center;
margin-bottom: var(--spacing-xxs);
.button__content {
justify-content: space-between;
.button__label {
margin: 0;
margin-top: 2px;
margin-left: var(--spacing-xxxs);
font-size: var(--font-small);
}
}
.button__label {
display: none;
}
}
.ratio-wrapper {
.button {
display: inline-block;
background-color: unset;
margin-bottom: 0;
}
}
.ratio-wrapper ~ .button--file-action {
flex: auto;
}
&.stretch {
margin-top: var(--spacing-xxxs);
.button {
flex: auto;
background-color: var(--color-header-background);
margin-right: var(--spacing-xxs);
.button__content {
justify-content: center;
}
}
.section {
margin-right: unset;
margin-left: var(--spacing-xxs);
.button {
margin-right: 0;
}
}
}
}
}
@ -133,6 +288,7 @@
display: flex;
flex-direction: column;
margin-bottom: var(--spacing-s);
color: var(--color-text);
&:not(:last-child) {
margin-bottom: var(--spacing-s);

View file

@ -1,12 +1,12 @@
.home__meme {
text-align: center;
font-weight: bold;
line-height: 1;
font-size: 1rem;
margin-bottom: var(--spacing-m);
text-align: center;
font-weight: bold;
line-height: 1;
font-size: 1rem;
margin-bottom: var(--spacing-m);
@media (min-width: $breakpoint-small) {
@media (min-width: $breakpoint-small) {
font-size: 1.2rem;
margin-bottom: var(--spacing-l);
}
}
}

View file

@ -22,6 +22,11 @@
justify-content: center;
position: fixed;
z-index: 9999;
z-index: 9999;
@media (max-width: $breakpoint-small) {
background-color: rgba(var(--color-header-background-base), 0.95);
}
}
.modal {
@ -33,9 +38,35 @@
overflow: auto;
padding: var(--spacing-l);
word-break: break-word;
background-color: var(--color-modal-background) !important;
border-radius: var(--border-radius);
border: 2px solid #000;
-webkit-backdrop-filter: blur(4px);
backdrop-filter: blur(4px);
&:focus {
box-shadow: none;
.card {
.card__main-actions {
border-top: unset;
}
input {
&:focus {
border: 1px solid var(--color-primary);
box-shadow: unset;
}
}
}
&:focus,
&:focus-visible {
box-shadow: none !important;
background-color: var(--color-modal-background) !important;
}
.claim-preview__wrapper {
&:hover {
background-color: unset;
}
}
@media (max-width: $breakpoint-small) {
@ -64,7 +95,48 @@
.card {
margin: 0;
border: none;
padding: var(--spacing-l);
border: 2px solid black;
border-radius: var(--border-radius);
.button-toggle {
background-color: rgba(var(--color-header-button-base), 0.4) !important;
&:hover {
background-color: rgba(var(--color-header-button-base), 0.9) !important;
}
}
.button-toggle--active,
.channel__list-item,
.button--secondary,
input {
}
.channel__list-item {
&:hover {
background-color: var(--color-primary);
color: var(--color-primary-contrast);
}
}
label {
color: var(--color-text);
font-size: var(--font-medium);
}
[data-reach-menu-button] {
&:hover {
.channel__list-item--selected {
background-color: var(--color-primary) !important;
}
}
}
@media (max-width: $breakpoint-small) {
.card__main-actions {
border-top: unset !important;
}
}
}
}

View file

@ -1,6 +1,27 @@
.navigation__wrapper {
width: var(--side-nav-width);
height: calc(100vh - var(--header-height));
transition: width 0.2s;
@media (max-width: $breakpoint-small) {
height: calc(100vh - var(--header-height-mobile));
}
*:focus-visible:not(.wunderbar__input):not(.menu__list):not(.menu__list--header):not(.button--secondary):not(.button-like):not(.button-dislike):not(select):not(input):not(textarea):not(video) {
background-color: rgba(var(--color-primary-static), 0.2) !important;
color: var(--color-text) !important;
box-shadow: 0px 0px 0px 2px var(--color-brand) inset;
.icon {
stroke: var(--color-text) !important;
}
}
select:focus-visible,
input:focus-visible:not(.wunderbar__input),
textarea:focus-visible {
box-shadow: 0px 0px 0px 2px var(--color-brand) inset;
}
}
.navigation__wrapper--micro {
@ -21,17 +42,35 @@
position: fixed;
left: 0;
overflow-y: auto;
overflow-x: hidden;
top: var(--header-height);
width: var(--side-nav-width);
height: calc(100vh - var(--header-height));
border-right: 1px solid var(--color-border);
padding-top: var(--spacing-l);
padding-bottom: var(--spacing-l);
overflow-y: auto;
display: flex;
flex-direction: column;
background: var(--color-header-background);
-webkit-backdrop-filter: blur(4px);
backdrop-filter: blur(4px);
@media (min-width: $breakpoint-small) {
animation-timing-function: var(--resizing-animation-function);
transition: transform var(--resizing-animation-timing);
z-index: 4;
transform: translateX(0);
transform-origin: left;
.wunderbar__input {
background-color: var(--color-header-button);
}
.empty--centered {
font-size: var(--font-body);
}
.button--secondary {
background-color: var(--color-brand) !important;
color: var(--color-brand-contrast) !important;
}
@media (min-width: $breakpoint-medium) {
overflow-y: hidden;
justify-content: space-between;
@ -39,6 +78,27 @@
overflow-y: auto;
}
}
@media (max-width: $breakpoint-small) {
top: var(--header-height-mobile);
height: calc(100vh - var(--header-height-mobile));
}
ul {
padding-bottom: var(--spacing-s);
}
}
.navigation-touch {
overflow-y: auto !important;
}
.navigation--push-back {
transform: translateX(calc(var(--side-nav-width--micro) - var(--side-nav-width)));
}
.navigation--push {
transform: translateX(0);
}
.navigation--mac {
@ -49,19 +109,28 @@
@extend .navigation;
z-index: 4;
width: var(--side-nav-width);
padding-top: 0;
background-color: var(--color-card-background);
border-top: 1px solid var(--color-border);
background-color: var(--color-header-background-transparent);
box-shadow: var(--card-box-shadow);
padding-top: 0px;
.navigation-link {
padding-left: var(--spacing-m);
padding-left: var(--spacing-s);
}
}
.navigation-file-page-and-mobile {
transform: translateX(calc(-1 * var(--side-nav-width)));
}
.navigation--micro {
@extend .navigation;
width: var(--side-nav-width--micro);
transform: translateX(calc(var(--side-nav-width--micro) - var(--side-nav-width)));
.navigation-inner-container {
ul:nth-child(3) {
border-bottom: unset;
}
}
@media (max-width: $breakpoint-small) {
display: none;
@ -78,6 +147,29 @@
.navigation__tertiary {
margin-top: var(--spacing-m);
.navigation-link {
font-size: var(--font-xxsmall) !important;
.button__content {
padding-top: 0;
padding-bottom: 0;
.button__label {
color: var(--color-navigation-link);
}
}
&:hover {
background-color: var(--color-transparent) !important;
color: var(--color-text) !important;
.button__content {
.button__label {
color: var(--color-text);
}
}
}
}
}
.navigation-link {
@ -89,19 +181,33 @@
width: 100%;
color: var(--color-navigation-link);
padding-left: var(--spacing-s);
font-size: var(--font-body);
font-size: var(--font-small);
font-weight: var(--font-weight-bold);
.icon {
height: 1.5rem;
width: 1.5rem;
height: 1rem;
width: 1rem;
stroke: var(--color-navigation-icon);
stroke-width: 1.5px;
}
.icon--Heart {
color: var(--color-transparent);
}
.button__content {
margin-left: auto;
padding: var(--spacing-s);
padding-top: var(--spacing-xs);
padding-bottom: var(--spacing-xs);
justify-content: flex-start;
flex-direction: column;
.button__label {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
}
&.navigation-link--with-thumbnail .button__content {
@ -125,8 +231,7 @@
}
}
&:hover:not(.navigation-link--active),
&:focus {
&:hover:not(.navigation-link--active) {
@extend .navigation-link--highlighted;
}
@ -135,8 +240,8 @@
margin-bottom: 0;
.icon {
height: 1.5rem;
width: 1.5rem;
height: 1rem;
width: 1rem;
}
.button__content {
@ -144,22 +249,23 @@
}
.button__label {
margin-top: 0;
}
&:focus {
box-shadow: none;
margin-top: 0px;
padding-top: 2px;
}
}
}
.navigation-link--active {
background-color: var(--color-navigation-active);
color: var(--color-navigation-active-text);
color: var(--color-brand-contrast);
.icon {
stroke: var(--color-navigation-active-text);
}
&:hover {
cursor: default;
}
}
.navigation-link--pulse {
@ -171,11 +277,11 @@
}
.navigation-link--highlighted {
background-color: var(--color-navigation-hover);
color: var(--color-navigation-hover-text);
background-color: var(--color-navigation-hover-bg);
color: var(--color-primary-static);
.icon {
stroke: var(--color-navigation-hover-text);
stroke: var(--color-primary-static);
}
}
@ -186,23 +292,37 @@
list-style: none;
}
.navigation-inner-container {
width: var(--side-nav-width);
.navigation-links--micro:first-of-type {
margin-top: var(--spacing-xxxs);
}
}
.navigation-links--micro {
li {
margin-bottom: 0px;
}
.icon {
margin-top: 2px;
height: 1.5rem;
width: 1.5rem;
stroke-width: 1px !important;
}
.button__content {
padding: var(--spacing-s);
justify-content: flex-start;
flex-direction: column;
width: var(--side-nav-width--micro);
}
.button__label {
font-size: var(--font-xsmall);
font-size: var(--font-xxsmall);
font-weight: var(--font-weight-base);
margin-left: 0;
margin-top: var(--spacing-xs);
margin-top: 2px;
//margin-top: var(--spacing-xs); // master
}
.navigation-link {
@ -212,18 +332,35 @@
@media (max-width: $breakpoint-small) {
display: none;
}
@media (min-width: $breakpoint-xlarge) {
.icon {
height: 2.5rem;
width: 2.5rem;
margin-top: 6px;
}
.button__label {
margin-top: 4px;
margin-bottom: 2px;
}
}
}
.navigation-links--absolute {
@extend .navigation-links;
margin-top: 0;
li {
margin-bottom: 0px;
}
.navigation-link {
margin-bottom: 0;
padding-top: 2px;
padding-bottom: 2px;
.icon {
height: 1.5rem;
width: 1.5rem;
height: 1rem;
width: 1rem;
}
.button__content {
@ -232,12 +369,16 @@
.button__label {
margin-top: 0;
font-size: var(--font-body);
font-size: var(--font-small);
font-weight: var(--font-weight-bold);
}
}
&:focus {
box-shadow: none;
@media (max-width: $breakpoint-small) {
.navigation-link {
.button__label {
margin-bottom: -1px;
}
}
}
}
@ -246,22 +387,26 @@
@extend .navigation-links;
margin-right: 0;
padding-right: 0;
margin-top: var(--spacing-xl);
margin-top: var(--spacing-m);
margin-bottom: 0;
.navigation-link {
font-size: var(--font-small);
}
.button__label {
color: var(--color-text-help);
}
.button__content {
align-items: flex-start;
}
}
.navigation-item {
padding: var(--spacing-s);
.empty {
padding: 0;
}
}
.navigation__overlay {
position: fixed;
width: 100vw;
@ -270,19 +415,34 @@
z-index: 3;
left: 0;
top: var(--header-height);
visibility: hidden;
opacity: 0;
animation-timing-function: var(--resizing-animation-function);
transition: visibility var(--resizing-animation-timing), opacity var(--resizing-animation-timing);
&.navigation__overlay--mac {
top: calc(var(--header-height) + var(--mac-titlebar-height));
}
@media (max-width: $breakpoint-small) {
top: var(--header-height-mobile);
}
}
.navigation__overlay--active {
opacity: 1;
visibility: visible;
animation: fadeIn var(--resizing-animation-timing) var(--resizing-animation-function);
}
.navigation__auth-nudge {
@extend .card;
margin: var(--spacing-s);
margin-top: var(--spacing-l);
margin-top: var(--spacing-m);
padding: var(--spacing-xs);
display: flex;
flex-direction: column;
font-size: var(--font-small);
.button {
margin-top: var(--spacing-s);

View file

@ -8,15 +8,75 @@ $contentMaxWidth: 60rem;
.notification_list {
.notification__wrapper {
border-top: 1px solid var(--color-border);
border-radius: var(--border-radius);
margin-bottom: var(--spacing-xxs);
background-color: rgba(var(--color-header-background-base), 0.6);
&:first-of-type {
border-top: none;
}
@media (min-width: $breakpoint-small) {
&:hover {
background-color: var(--color-card-background-highlighted);
.notification__menu {
margin-right: var(--spacing-s);
.icon {
stroke: var(--color-text);
}
[aria-expanded='true'].menu__button {
opacity: 1;
background-color: var(--color-header-background);
border-radius: var(--border-radius);
.icon {
stroke: var(--color-primary);
}
}
}
.commentCreate {
border-top: 1px solid var(--color-border);
padding-top: var(--spacing-s);
.commentCreate__label {
color: var(--color-text);
}
textarea,
select,
.button:not(.button--file-action) {
background-color: var(--color-background);
}
.button {
border-radius: var(--border-radius);
}
.comment__char-count-mde {
padding-right: 0px;
}
.button--file-action {
.button__content {
.icon {
background: var(--color-header-button);
}
}
}
}
&:hover {
cursor: pointer;
background-color: rgba(var(--color-header-background-base), 0.9);
.menu__button {
opacity: 1;
}
.notification__text {
color: var(--color-primary);
}
}
@media (max-width: $breakpoint-small) {
.notification__menu {
margin-right: calc(var(--spacing-xs) * -1);
.menu__button {
opacity: 1;
}
}
}
}
@ -66,6 +126,20 @@ $contentMaxWidth: 60rem;
@include handleChannelGif(3rem);
}
.date_time {
font-size: var(--font-small);
}
.icon__wrapper {
background-color: rgba(var(--color-primary-dynamic), 0.1);
}
&:hover {
.icon__wrapper {
background-color: rgba(var(--color-primary-dynamic), 0.2);
}
}
@media (max-width: $breakpoint-small) {
.channel-thumbnail {
@include handleChannelGif(2rem);
@ -88,16 +162,16 @@ $contentMaxWidth: 60rem;
}
.notification__wrapper--unread {
background-color: var(--color-card-background-highlighted);
box-shadow: 2px 0px 0px 0px rgba(var(--color-primary-dynamic), 0.7) inset;
justify-content: space-between;
&:hover {
background-color: var(--color-button-secondary-bg);
}
@media (max-width: $breakpoint-small) {
padding: var(--spacing-s);
}
&:hover {
box-shadow: 2px 0px 0px 0px rgba(var(--color-primary-dynamic), 1) inset;
}
}
.notificationContent__wrapper {
@ -185,7 +259,7 @@ $contentMaxWidth: 60rem;
.notification__time {
font-size: var(--font-small);
color: var(--color-text-help);
color: var(--color-text);
flex-shrink: 0;
margin-top: var(--spacing-s);
@ -218,20 +292,28 @@ $contentMaxWidth: 60rem;
}
.notification__bubble {
height: 1.5rem;
width: 1.5rem;
height: 1.4rem;
width: 1.4rem;
border-radius: 50%;
background-color: var(--color-notification);
position: absolute;
top: -0.5rem;
right: -0.5rem;
top: -0.4rem;
right: -0.4rem;
color: white;
font-size: var(--font-small);
font-weight: bold;
line-height: 1;
line-height: 1.4rem;
display: flex;
align-items: center;
justify-content: center;
.notification__count {
margin-bottom: -2px;
}
@media (max-width: $breakpoint-small) {
right: 0rem;
}
}
.notification__bubble--small {

Some files were not shown because too many files have changed in this diff Show more