bring in ody styles; modify; cleanup

This commit is contained in:
zeppi 2022-04-14 17:27:16 -04:00
parent 50ae6e2869
commit 0fa424c78f
136 changed files with 8135 additions and 1818 deletions

View file

@ -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,20 @@
"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.",
"--end--": "--end--"
}

BIN
static/img/freespch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -118,7 +118,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

@ -212,6 +212,7 @@ function ChannelForm(props: Props) {
function handleSubmit() {
if (uri) {
console.log('Params A: ', params);
updateChannel(params).then((success) => {
if (success) {
onDone();
@ -269,9 +270,10 @@ function ChannelForm(props: Props) {
}
// TODO clear and bail after submit
// <div className={classnames('main--contained', { 'card--disabled': disabled })}></div>
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 +334,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 {
@ -27,8 +28,20 @@ function getChannelIcon(level: number): string {
return icons[level] || ICONS.CHANNEL_LEVEL_1;
}
// function getChannelIconB(level: number): string {
// const icons = {
// '1': ICONS.CHANNEL_LEVEL_1_B,
// '2': ICONS.CHANNEL_LEVEL_2_B,
// '3': ICONS.CHANNEL_LEVEL_3_B,
// '4': ICONS.CHANNEL_LEVEL_4_B,
// '5': ICONS.CHANNEL_LEVEL_5_B,
// };
//
// return icons[level] || ICONS.CHANNEL_LEVEL_1_B;
// }
function ChannelStakedIndicator(props: Props) {
const { channelClaim, amount, level, large = false, inline = false } = props;
const { channelClaim, amount, level, large = false, inline = false, hideTooltip = false } = props;
if (!channelClaim || !channelClaim.meta) {
return null;
@ -36,7 +49,9 @@ function ChannelStakedIndicator(props: Props) {
const isControlling = channelClaim && channelClaim.meta.is_controlling;
const icon = getChannelIcon(level);
// const icon_b = getChannelIconB(level);
if (!hideTooltip) {
return (
<Tooltip
title={
@ -64,6 +79,18 @@ function ChannelStakedIndicator(props: Props) {
</div>
</Tooltip>
);
} else {
return (
<div
className={classnames('channel-staked__wrapper', {
'channel-staked__wrapper--large': large,
'channel-staked__wrapper--inline': inline,
})}
>
<LevelIcon icon={icon} large={large} isControlling={isControlling} />
</div>
);
}
}
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">
<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,10 +386,19 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
</NavLink>
)}
</div>
<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">
{!pending && (
@ -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">
<div className="claim-preview__repost-ribbon">
<Icon icon={ICONS.REPOST} size={12} />
<br />
<span>{repostUrl}</span>
</div>
</span>
);
}
@ -47,11 +50,14 @@ function ClaimRepostAuthor(props: Props) {
return (
<div className="claim-preview__repost-author">
<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% reposted
%repost_channel_link%
</I18nMessage>
</div>
</div>
);
}

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,29 @@
// @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,
};
// 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 +66,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 +80,10 @@ type Props = {
function ClaimTilesDiscover(props: Props) {
const {
doClaimSearch,
claimSearchByQuery,
claimSearchResults,
claimsByUri,
fetchViewCount,
fetchingClaimSearchByQuery,
fetchingClaimSearch,
hasNoSource,
renderProperties,
// pinUrls,
@ -93,16 +91,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 +121,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 +162,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;
// --- Deep-compare ---
// These are props that are hard to memoize from where it is passed.
const prevSearchKey = createNormalizedClaimSearchKey(prevOptions);
const nextSearchKey = createNormalizedClaimSearchKey(nextOptions);
if (prevSearchKey !== nextSearchKey) {
debug_trace('search key');
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;
}
// --- Deep-compare ---
if (!urisEqual(prev.claimSearchByQuery[prevSearchKey], next.claimSearchByQuery[nextSearchKey])) {
debug_trace('claimSearchByQuery');
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 +198,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,10 +58,11 @@ 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">
<a href={`/$/${PAGES.LIST}/${id}`}>
<span className="file-page__playlist-collection__row">
<Icon
icon={
(id === COLLECTIONS_CONSTS.WATCH_LATER_ID && ICONS.TIME) ||
@ -72,7 +73,8 @@ export default function CollectionContent(props: Props) {
/>
{collectionName}
</span>
<span className="file-page__recommended-collection__row">
</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 && (
isMyCollection && (
<Button
title={__('Edit')}
className={classnames('button-toggle', { 'button-toggle--active': showEdit })}
icon={ICONS.EDIT}
onClick={() => setShowEdit(!showEdit)}
/>
)}
</>
)
}
body={
<DragDropContext onDragEnd={handleOnDragEnd}>

View file

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

View file

@ -0,0 +1,63 @@
// @flow
'use strict';
import React, { useState } from 'react';
import reactCSS from 'reactcss';
import { SketchPicker } from 'react-color';
import classNames from 'classnames';
import { changeColor, getPrimaryColor } from 'util/theme';
type Props = {
disabled?: boolean,
};
function ColorPicker(props: Props) {
const { disabled } = props;
const [displayColorPicker, toggleDisplayColorPicker] = useState(false);
let dynamic = getPrimaryColor();
var rgb = dynamic.replace(/\s/g, '').match(/^rgba?\((\d+),(\d+),(\d+),?([^,\s)]+)?/i);
var hex = rgb
? (rgb[1] | (1 << 8)).toString(16).slice(1) +
(rgb[2] | (1 << 8)).toString(16).slice(1) +
(rgb[3] | (1 << 8)).toString(16).slice(1)
: dynamic;
const [color, setColor] = useState({
hex: '#' + hex,
rgb: { r: parseInt(rgb[1]), g: parseInt(rgb[2]), b: parseInt(rgb[3]), a: 1 },
});
const styles = reactCSS({
default: {
color: {
background: `rgba(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b}, ${color.rgb.a})`,
},
},
});
function handleChange(color) {
console.log('Color: ', color);
changeColor(color.rgb);
setColor(color);
}
return (
<div
className={classNames('color-picker', {
disabled: disabled,
})}
>
<input value={color.hex} />
<div className="swatch" onClick={() => toggleDisplayColorPicker(!displayColorPicker)}>
<div className="color" style={styles.color} />
</div>
{displayColorPicker ? (
<div className="popover">
<div className="cover" onClick={() => toggleDisplayColorPicker(false)} />
<SketchPicker color={color} onChange={handleChange} disableAlpha />
</div>
) : null}
</div>
);
}
export default ColorPicker;

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(
[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(
[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" />
@ -256,6 +285,12 @@ export const icons = {
<line x1="1" y1="10" x2="23" y2="10" />
</g>
),
[ICONS.WALLET2]: buildIcon(
<g>
<path d="M1 4c0 1 1 2 2 2h17M1 4c0-1 1-2 2-2h15c1 0 2 1 2 2v2M1 4v16c0 1 1 2 2 2h18c1 0 2-1 2-2V8c0-1-1-2-2-2h-1" />
<path d="m14 11 2 2v2l-4 4-4-4v-2l4-4 2 2Zm0 0-3 3M9 16l3-3" />
</g>
),
[ICONS.COIN_SWAP]: buildIcon(
<g>
<path d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
@ -586,12 +621,24 @@ export const icons = {
<path d="M21 13v2a4 4 0 0 1-4 4H3" />
</g>
),
[ICONS.MORE_VERTICAL]: buildIcon(
[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 +1021,6 @@ export const icons = {
width={props.size || '16'}
height={props.size || '18'}
fill="none"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
>
@ -1124,13 +1170,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

@ -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),
}
: {}
}

View file

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

View file

@ -130,12 +130,19 @@ const Header = (props: Props) => {
}
>
<div>
{hideBalance ? (
<Button
navigate={`/$/${PAGES.WALLET}`}
className="header__navigationItem--icon header__navigationItem--balance"
label={!(hideBalance || Number(roundedBalance) === 0) && roundedBalance}
icon={ICONS.WALLET2}
iconSize={18}
onDoubleClick={(e) => {
e.stopPropagation();
}}
/>
) : (
<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}
@ -144,6 +151,7 @@ const Header = (props: Props) => {
e.stopPropagation();
}}
/>
)}
</div>
</Tooltip>
@ -181,7 +189,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';
@ -9,6 +8,7 @@ import classnames from 'classnames';
import HeaderMenuLink from 'component/common/header-menu-link';
import Icon from 'component/common/icon';
import React from 'react';
import Skeleton from '@mui/material/Skeleton';
type HeaderMenuButtonProps = {
activeChannelClaim: ?ChannelClaim,
@ -25,6 +25,9 @@ export default function HeaderProfileMenuButton(props: HeaderMenuButtonProps) {
return (
<div className="header__buttons">
<Menu>
{activeChannelUrl === undefined ? (
<Skeleton variant="circular" animation="wave" className="header__navigationItem--iconSkeleton" />
) : (
<MenuButton
aria-label={__('Your account')}
title={__('Your account')}
@ -39,6 +42,7 @@ export default function HeaderProfileMenuButton(props: HeaderMenuButtonProps) {
<Icon size={18} icon={ICONS.ACCOUNT} aria-hidden />
)}
</MenuButton>
)}
<MenuList className="menu__list--header">
<HeaderMenuLink page={PAGES.UPLOADS} icon={ICONS.PUBLISH} name={__('Uploads')} />

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,8 +95,27 @@ 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}
/>
)
))}
<div
className={classnames({
'sidebar--pusher': fullWidthPage,
'sidebar--pusher--open': sidebarOpen && fullWidthPage,
'sidebar--pusher--filepage': !fullWidthPage,
})}
>
<main
id={'main-content'}
className={classnames(MAIN_CLASS, className, {
@ -124,18 +124,17 @@ function Page(props: Props) {
'main--file-page': filePage,
'main--settings-page': settingsPage,
'main--markdown': isMarkdown,
'main--theater-mode': isOnFilePage && videoTheaterMode,
'main--theater-mode': isOnFilePage && videoTheaterMode && !isMarkdown,
})}
>
{children}
{!isMobile && rightSide && <div className="main__right-side">{rightSide}</div>}
</main>
{/* @if TARGET='app' */}
<StatusBar />
{/* @endif */}
</div>
</Fragment>
</div>
</>
);
}

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,6 +14,8 @@ function PublishPrice(props: Props) {
const { contentIsFree, fee, updatePublishForm, disabled } = props;
return (
<>
<label>{__('Price')}</label>
<Card
actions={
<React.Fragment>
@ -39,7 +41,7 @@ function PublishPrice(props: Props) {
name="content_cost_amount"
min={0}
price={fee}
onChange={newFee => updatePublishForm({ fee: newFee })}
onChange={(newFee) => updatePublishForm({ fee: newFee })}
/>
)}
{fee && fee.currency !== 'LBC' && (
@ -52,6 +54,7 @@ function PublishPrice(props: Props) {
</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,6 +123,8 @@ function SelectThumbnail(props: Props) {
return (
<>
{status !== THUMBNAIL_STATUSES.IN_PROGRESS && (
<>
<label>{__('Thumbnail')}</label>
<div className="column">
{thumbPreview}
{publishForm && thumbUploaded ? (
@ -179,6 +183,7 @@ function SelectThumbnail(props: Props) {
</div>
)}
</div>
</>
)}
{status === THUMBNAIL_STATUSES.IN_PROGRESS && <p>{__('Uploading thumbnail')}...</p>}

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

@ -8,11 +8,38 @@ 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 FOLLOWED_ITEM_INITIAL_LIMIT = 10;
const touch = isTouch();
const {
location: { pathname },
} = useHistory();
type SideNavLink = {
title: string,
link?: string,
route?: string,
onClick?: () => any,
icon: string,
extra?: Node,
hideForUnauth?: boolean,
};
const HOME = {
title: 'Home',
link: `/`,
icon: ICONS.HOME,
onClick: () => {
if (pathname === '/') window.location.reload();
},
};
const RECENT_FROM_FOLLOWING = {
title: 'Following --[sidebar button]--',
@ -20,6 +47,57 @@ const RECENT_FROM_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 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,
},
];
// ****************************************************************************
// ****************************************************************************
type Props = {
subscriptions: Array<Subscription>,
followedTags: Array<Tag>,
@ -35,16 +113,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) {
@ -63,46 +132,7 @@ function SideNavigation(props: Props) {
followedTags,
} = props;
const {
location: { pathname },
} = useHistory();
const HOME = {
title: 'Home',
link: `/`,
icon: ICONS.HOME,
onClick: () => {
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 MOBILE_LINKS: Array<SideNavLink> = [
{
title: 'Notifications',
link: `/$/${PAGES.NOTIFICATIONS}`,
icon: ICONS.NOTIFICATION,
extra: <NotificationBubble inline />,
hideForUnauth: true,
},
{
title: 'Upload',
link: `/$/${PAGES.UPLOAD}`,
@ -171,56 +201,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 [expandSubscriptions, setExpandSubscriptions] = React.useState(false);
const [expandTags, setExpandTags] = 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 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);
}
return true;
})
: UNAUTH_LINKS;
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 +415,57 @@ 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,
'navigation--micro': showMicroMenu,
'navigation--push': showPushMenu,
'navigation-file-page-and-mobile': hideMenuFromView,
'navigation-touch': touch,
// @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>
);
})}
</ul>
{(!canDisposeMenu || sidebarOpen) && (
<div className="navigation-inner-container">
<ul className="navigation-links--absolute mobile-only">{notificationsEnabled && getLink(NOTIFICATIONS)}</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 && sidebarOpen && unAuthNudge}
</div>
{sidebarOpen && helpLinks}
</nav>
)}
{(isOnFilePage || isMediumScreen) && sidebarOpen && (
<>
<nav
className={classnames('navigation--absolute', {
// @if TARGET='app'
<ul
className={classnames('navigation-links', {
'navigation-links--micro': showMicroMenu,
'navigation-links--absolute': shouldRenderLargeMenu,
'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>
);
})}
{getLink(HOME)}
{getLink(RECENT_FROM_FOLLOWING)}
{getLink(DISCOVER)}
{getLink(LIBRARY)}
{getLink(PLAYLISTS)}
</ul>
<ul className="navigation-links--absolute mobile-only">
{subLinks.map((linkProps) => {
const { hideForUnauth, ...passedProps } = linkProps;
{email && MOBILE_LINKS.map((linkProps) => getLink(linkProps))}
{!email && UNAUTH_LINKS.map((linkProps) => getLink(linkProps))}
</ul>
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}
{getSubscriptionSection()}
{getFollowedTagsSection()}
{!isAuthenticated && sidebarOpen && unAuthNudge}
</div>
)}
{(!canDisposeMenu || sidebarOpen) && shouldRenderLargeMenu && helpLinks}
</nav>
<div
className={classnames('navigation__overlay', {
// @if TARGET='app'
'navigation__overlay--mac': IS_MAC,
// @endif
'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,9 +120,11 @@ export default function SubscribeButton(props: Props) {
}}
/>
{isSubscribed && uiNotificationsEnabled && (
<>
<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;
@ -145,6 +148,7 @@ export default function SubscribeButton(props: Props) {
});
}}
/>
</>
)}
</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';
@ -181,3 +186,4 @@ export const MYSTERIES = 'Mysteries';
export const TECHNOLOGY = 'Technology';
export const EMOJI = 'Emoji';
export const STICKER = 'Sticker';
export const WALLET2 = 'Wallet2';

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}

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

@ -0,0 +1,12 @@
import { connect } from 'react-redux';
import { selectTotalBalance } from 'redux/selectors/wallet';
import { doOpenModal } from 'redux/actions/app';
import Elements from './view';
const select = (state) => ({
totalBalance: selectTotalBalance(state),
});
export default connect(select, {
doOpenModal,
})(Elements);

42
ui/page/elements/view.jsx Normal file
View file

@ -0,0 +1,42 @@
// @flow
import React from 'react';
import { useHistory } from 'react-router';
import TxoList from 'component/txoList';
import Page from 'component/page';
import WalletBalance from 'component/walletBalance';
import ClaimList from 'component/claimList';
type Props = {
history: { action: string, push: (string) => void, replace: (string) => void },
location: { search: string, pathname: string },
};
const Elements = (props: Props) => {
const {
location: { search },
} = useHistory();
return (
<Page>
<div className="card-stack">
<label>claims</label>
<ClaimList uris={'lbry://@Odysee#8/Odysee-Android-App#1'} showUnresolvedClaims showHiddenByUser hideMenu />
<ClaimList
uris={'lbry://@Odysee#8/Odysee-Android-App#1'}
showUnresolvedClaims
showHiddenByUser
hideMenu
tileLayout
/>
<label>channels</label>
<ClaimList uris={'lbry://@Odysee#8'} showUnresolvedClaims showHiddenByUser hideMenu />
<ClaimList uris={'lbry://@Odysee#8'} showUnresolvedClaims showHiddenByUser hideMenu tileLayout />
<WalletBalance />
<TxoList search={search} />
</div>
</Page>
);
};
export default Elements;

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) => {
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,7 +1,19 @@
.block-list {
.claim-preview__wrapper--channel {
.button--no-style {
.button__content {
align-items: unset;
}
}
}
}
.block-list--moderator {
.button--no-style {
.button__content {
align-items: flex-start;
}
}
.section__actions {
flex-wrap: wrap;
@ -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;
}

File diff suppressed because it is too large Load diff

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;
@ -143,8 +195,12 @@
.card-stack {
.card:not(:last-of-type) {
margin-bottom: var(--spacing-xxl);
@media (max-width: $breakpoint-small) {
margin-bottom: var(--spacing-l);
}
}
}
.card ~ .card-stack {
@ -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,19 @@ $actions-z-index: 2;
margin-top: var(--spacing-l);
box-shadow: var(--card-box-shadow);
.channel-staked__wrapper {
height: var(--height-button);
background-color: var(--color-card-background);
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 +258,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 +290,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 +301,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 +343,7 @@ $actions-z-index: 2;
align-items: flex-end;
.button {
height: auto;
// height: auto;
}
}
@ -205,6 +359,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 +396,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,31 +448,25 @@ $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);
background-color: var(--color-primary);
.claim-preview__title {
color: var(--color-primary-contrast);
}
}
&: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);
}
}
&:last-child {
@ -305,8 +478,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 +500,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 +521,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,15 +566,42 @@ $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: 5;
z-index: 10;
display: flex;
position: absolute;
//text-align: center;
//width: 116%;
//left: -8%;
//bottom: -14%;
//
//svg {
// overflow: visible;
// width: 100%;
// height: 100%;
//}
padding: 0.2rem;
bottom: -0.75rem;
left: -0.8rem;
bottom: -0.5rem;
right: -0.8rem;
right: -0.5rem;
//background-color: white;
background-color: var(--color-card-background);
//box-shadow: 0px 0px 8px -3px rgba(255,255,255,1);
border-radius: 50%;
}
@ -395,13 +627,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 +646,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,25 +153,36 @@ $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 {
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 {
@ -75,20 +96,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 +158,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 +170,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 +183,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 +219,68 @@ $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: rgba(var(--color-secondary-dynamic), 1);
}
}
}
.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;
@media (max-width: $breakpoint-small) {
width: 90%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.comment__badge--global-mod {
.st0 {
// @see: ICONS.BADGE_MOD
fill: #fe7500;
}
}
.comment__badge--mod {
.st0 {
// @see: ICONS.BADGE_MOD
fill: #ff3850;
}
}
//.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;
// }
//}
.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 +288,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 +337,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 +364,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 +453,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 +523,7 @@ $thumbnailWidthSmall: 1rem;
max-width: 10rem;
white-space: pre-line;
margin-right: var(--spacing-s);
color: var(--color-text);
}
.comment--blocked {
@ -436,11 +547,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 +575,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 +600,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 +619,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,21 @@
.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;
background-color: rgba(var(--color-primary-dynamic), 0.95) !important;
.icon {
width: 24px;
height: 24px;
}
&:hover {
background-color: rgba(var(--color-primary-dynamic), 1) !important;
}
}
.content__floating-link {
@ -93,12 +145,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 +160,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;
margin-bottom: var(--spacing-s);
> :first-child {
margin-bottom: var(--spacing-s);
}
@media (max-width: $breakpoint-medium) {
flex-direction: row;
justify-content: start;
flex-direction: row;
margin-bottom: var(--spacing-s);
> :first-child {
margin-bottom: 0;
margin-right: 1rem;
}
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,10 +338,8 @@ input[type='number'] {
fieldset-group {
+ fieldset-group {
&:not(.fieldset-group--row) {
margin-top: var(--spacing-s);
}
}
&.fieldset-group--smushed {
justify-content: flex-start;
@ -349,6 +377,13 @@ fieldset-group {
margin-top: var(--spacing-l);
align-items: flex-end;
justify-content: center;
fieldset-section {
input {
margin-bottom: 5px !important;
margin-left: var(--spacing-s);
}
}
}
&.fieldgroup--paginate-top {
@ -356,9 +391,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 +419,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 +449,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 +468,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 +498,7 @@ fieldset-group {
.form-field__help {
@extend .help;
color: var(--color-text);
}
.form-field__help + .checkbox,
@ -465,19 +514,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,7 +558,6 @@ fieldset-section {
@media (min-width: $breakpoint-small) {
max-width: none;
}
select {
max-height: 1.5rem !important;
@ -504,6 +566,19 @@ fieldset-section {
}
}
select {
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 {
.icon--help {
vertical-align: middle;
@ -526,6 +601,7 @@ fieldset-section {
.form-field-date-picker {
margin-bottom: var(--spacing-l);
font-size: var(--font-base);
label {
display: block;
@ -598,6 +674,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 +757,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) !important;
}
&:hover {
.button__label {
color: var(--color-primary) !important;
}
.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,90 @@
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 {
background-color: var(--color-brand);
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 +234,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 {
@ -124,8 +286,28 @@
stroke: var(--color-text);
}
&[aria-expanded='true'] {
background-color: var(--color-header-button-active);
&[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);
}
}
}
@media (max-width: $breakpoint-small) {
height: var(--height-button-mobile);
}
&:hover {
.button__label {
color: var(--color-brand) !important;
}
.icon {
stroke: var(--color-brand);
}
}
}
@ -139,17 +321,16 @@
margin-right: var(--spacing-s);
&: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 +341,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 +471,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;
@media (min-width: $breakpoint-small) {
min-height: calc(100vh - var(--header-height));
padding: 0 var(--spacing-m);
}
@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 !important;
}
}
}
}
.claim-preview--collection-mine {
@ -217,6 +416,44 @@
}
}
@media (max-width: $breakpoint-small) {
padding: var(--spacing-xs);
flex-direction: column;
padding-top: 0;
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 +485,6 @@
}
.file-page__recommended {
width: 25rem;
@media (max-width: $breakpoint-medium) {
width: 100%;
}
@ -263,6 +498,10 @@
flex-direction: column;
}
}
.file-page__recommended {
margin-top: 10px;
}
}
.main--full-width {
@ -270,6 +509,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 +538,109 @@
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);
background-color: var(--color-card-background);
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 +651,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 +858,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 +921,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 +940,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 +974,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,168 @@
@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);
}
}
}
// CUSTOM LIKE COLORS
//.button-like {
// &:hover {
// .button__label {
// color: var(--color-fire) !important;
// }
// svg {
// stroke: var(--color-fire);
// }
// }
//}
//
//.button-dislike {
// &:hover {
// .button__label {
// //color: var(--color-slime) !important;
// }
// svg {
// //stroke: var(--color-slime);
// }
// }
//}
.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) {
padding-top: var(--spacing-s);
margin-right: 0px;
.ratio-bar {
height: 1px;
bottom: -1px;
}
}
}
@media (max-width: $breakpoint-small) {
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 +311,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

@ -5,8 +5,8 @@
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,36 @@
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);
.card {
.card__main-actions {
border-top: unset;
}
input {
background: var(--color-header-button) !important;
&:focus {
box-shadow: none;
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 +96,53 @@
.card {
margin: 0;
border: none;
padding: var(--spacing-l);
border: 2px solid black;
border-radius: var(--border-radius);
.form-field--copyable {
background: rgba(var(--color-primary-dynamic), 0.1);
}
.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 {
background-color: rgba(var(--color-header-button-base), 0.9) !important;
}
.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) {
.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 {
background-color: var(--color-card-background-highlighted);
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