diff --git a/package.json b/package.json index 34daad47f..177ceb1e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lbry", - "version": "0.52.6", + "version": "0.52.6-alpha.teststyles.3", "description": "A browser for the LBRY network, a digital marketplace controlled by its users.", "keywords": [ "lbry" @@ -63,6 +63,7 @@ "proxy-polyfill": "0.1.6", "re-reselect": "^4.0.0", "react-beautiful-dnd": "^13.1.0", + "react-color": "^2.19.3", "react-datetime-picker": "^3.4.3", "remove-markdown": "^0.3.0", "rss": "^1.2.2", @@ -89,7 +90,7 @@ "@meetfranz/electron-cookies": "^3.0.2", "@reach/auto-id": "^0.13.0", "@reach/combobox": "^0.12.1", - "@reach/menu-button": "0.7.4", + "@reach/menu-button": "0.8.6", "@reach/rect": "^0.16.0", "@reach/tabs": "^0.1.5", "@reach/tooltip": "^0.12.1", diff --git a/static/app-strings.json b/static/app-strings.json index 649979674..0b7f246ca 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -2308,5 +2308,21 @@ "Yes, share with LBRY": "Yes, share with LBRY", "Search Uploads": "Search Uploads", "This refundable boost will improve the discoverability of this %claimTypeText% while active. ": "This refundable boost will improve the discoverability of this %claimTypeText% while active. ", + "%repost_channel_link%": "%repost_channel_link%", + "Show less": "Show less", + "Channel \"realporno\" blocked.": "Channel \"realporno\" blocked.", + "Elements": "Elements", + "Icons": "Icons", + "You followed @MinutePhysics!": "You followed @MinutePhysics!", + "Unfollowed @samtime.": "Unfollowed @samtime.", + "You followed @samtime!": "You followed @samtime!", + "Unfollowed @gatogalactico.": "Unfollowed @gatogalactico.", + "You followed @gatogalactico!": "You followed @gatogalactico!", + "Unfollowed @Odysee.": "Unfollowed @Odysee.", + "Unfollowed @rossmanngroup.": "Unfollowed @rossmanngroup.", + "You followed @rossmanngroup!": "You followed @rossmanngroup!", + "%repost% %publish%": "%repost% %publish%", + "Failed to view lbry://@MicheL-PDF#7/LaDameAuPain#f, please try again. If this problem persists, visit https://lbry.com/faq/support for support.": "Failed to view lbry://@MicheL-PDF#7/LaDameAuPain#f, please try again. If this problem persists, visit https://lbry.com/faq/support for support.", + "Go to": "Go to", "--end--": "--end--" } diff --git a/static/img/freespch.png b/static/img/freespch.png new file mode 100644 index 000000000..559067192 Binary files /dev/null and b/static/img/freespch.png differ diff --git a/ui/component/blockList/view.jsx b/ui/component/blockList/view.jsx index 4a45f8f95..f8637f418 100644 --- a/ui/component/blockList/view.jsx +++ b/ui/component/blockList/view.jsx @@ -1,6 +1,5 @@ // @flow import { Combobox, ComboboxInput, ComboboxPopover, ComboboxList, ComboboxOption } from '@reach/combobox'; -// import '@reach/combobox/styles.css'; --> 'scss/third-party.scss' import { matchSorter } from 'match-sorter'; import React from 'react'; import classnames from 'classnames'; @@ -118,7 +117,7 @@ export default function BlockList(props: Props) { return ( <>
{help}
-
+
-
+
- + {__('General')} {__('Credit Details')} diff --git a/ui/component/channelStakedIndicator/view.jsx b/ui/component/channelStakedIndicator/view.jsx index 2103938d9..b3350e53b 100644 --- a/ui/component/channelStakedIndicator/view.jsx +++ b/ui/component/channelStakedIndicator/view.jsx @@ -13,6 +13,7 @@ type Props = { level: number, large?: boolean, inline?: boolean, + hideTooltip?: Boolean, }; function getChannelIcon(level: number): string { @@ -28,7 +29,7 @@ function getChannelIcon(level: number): string { } function ChannelStakedIndicator(props: Props) { - const { channelClaim, amount, level, large = false, inline = false } = props; + const { channelClaim, amount, level, large = false, inline = false, hideTooltip } = props; if (!channelClaim || !channelClaim.meta) { return null; @@ -37,23 +38,36 @@ function ChannelStakedIndicator(props: Props) { const isControlling = channelClaim && channelClaim.meta.is_controlling; const icon = getChannelIcon(level); - return ( - -
- -
+ if (!hideTooltip) { + return ( + +
+ +
-
- {__('Level %current_level%', { current_level: level })} -
- } size={14} /> +
+ {__('Level %current_level%', { current_level: level })} +
+ } size={14} /> +
+ } + > +
+
- } - > + + ); + } else { + return (
- - ); + ); + } } type LevelIconProps = { diff --git a/ui/component/channelThumbnail/view.jsx b/ui/component/channelThumbnail/view.jsx index c5bc3dd02..e24c58608 100644 --- a/ui/component/channelThumbnail/view.jsx +++ b/ui/component/channelThumbnail/view.jsx @@ -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 ( - {!hideStakedIndicator && } + {!hideStakedIndicator && } ); } @@ -91,6 +93,7 @@ function ChannelThumbnail(props: Props) { 'channel-thumbnail--resolving': isResolving, })} > + {/* show delay necessary? */} {showDelayedMessage ? (
{__('This will be visible in a few minutes.')}
) : ( diff --git a/ui/component/claimList/view.jsx b/ui/component/claimList/view.jsx index 891f926b8..01a935759 100644 --- a/ui/component/claimList/view.jsx +++ b/ui/component/claimList/view.jsx @@ -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; diff --git a/ui/component/claimMenuList/view.jsx b/ui/component/claimMenuList/view.jsx index e128c1303..f1f57787d 100644 --- a/ui/component/claimMenuList/view.jsx +++ b/ui/component/claimMenuList/view.jsx @@ -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); } } diff --git a/ui/component/claimPreview/claim-preview-loading.jsx b/ui/component/claimPreview/claim-preview-loading.jsx index e7d313d7f..47c8e3665 100644 --- a/ui/component/claimPreview/claim-preview-loading.jsx +++ b/ui/component/claimPreview/claim-preview-loading.jsx @@ -11,17 +11,24 @@ function ClaimPreviewLoading(props: Props) { const { isChannel, type } = props; return (
  • -
    +
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
    +
  • diff --git a/ui/component/claimPreview/view.jsx b/ui/component/claimPreview/view.jsx index 67d05d74d..5664655af 100644 --- a/ui/component/claimPreview/view.jsx +++ b/ui/component/claimPreview/view.jsx @@ -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((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((props: Props, ref: any) => { return ; } const formattedSubCount = toCompactNotation(channelSubCount, lang, 10000); + const formattedSubCountLocale = Number(channelSubCount).toLocaleString(); return ( - - - {channelSubCount === 1 ? __('1 Follower') : __('%formattedSubCount% Followers', { formattedSubCount })} - - +
    + + + {channelSubCount === 1 ? __('1 Follower') : __('%formattedSubCount% Followers', { formattedSubCount })} + + +
    ); }, [channelSubCount]); - const isValid = uri && isURIValid(uri); + const isValid = uri && isURIValid(uri, false); // $FlowFixMe const isPlayable = @@ -359,7 +365,7 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => {
    {/* @endif */}
    - +
    @@ -380,9 +386,18 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { )}
    - - {(pending || !!reflectingProgress) && } - {channelSubscribers} +
    + {!isChannelUri && signingChannel && ( +
    + + + +
    + )} + + {(pending || !!reflectingProgress) && } + {channelSubscribers} +
    {type !== 'small' && (
    @@ -393,11 +408,6 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { actions ) : (
    - {!isChannelUri && signingChannel && ( -
    - -
    - )} {isChannelUri && !banState.muted && !claimIsMine && ( ((props: Props, ref: any) => { )} {claim && ( - {typeof properties === 'function' ? ( - properties(claim) - ) : properties !== undefined ? ( - properties - ) : ( - - )} + {typeof properties === 'function' + ? properties(claim) + : properties !== undefined + ? properties + : !isMobile && } )}
    diff --git a/ui/component/claimPreviewTile/view.jsx b/ui/component/claimPreviewTile/view.jsx index 52ee6d1e9..aea7bd313 100644 --- a/ui/component/claimPreviewTile/view.jsx +++ b/ui/component/claimPreviewTile/view.jsx @@ -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 ( -
  • -
    +
  • +
    Placeholder
    -
    +
    +
    + > +
    +
    +
    +
    +
    +
  • ); @@ -220,11 +224,7 @@ function ClaimPreviewTile(props: Props) { contains_view_count: shouldShowViewCount, })} > - {isChannel ? ( -
    - -
    - ) : ( + {!isChannel && ( diff --git a/ui/component/claimRepostAuthor/view.jsx b/ui/component/claimRepostAuthor/view.jsx index 4525560b0..c4daeba81 100644 --- a/ui/component/claimRepostAuthor/view.jsx +++ b/ui/component/claimRepostAuthor/view.jsx @@ -19,8 +19,11 @@ function ClaimRepostAuthor(props: Props) { if (short && repostUrl) { return ( - - {repostUrl} +
    + +
    + {repostUrl} +
    ); } @@ -47,10 +50,13 @@ function ClaimRepostAuthor(props: Props) { return (
    - - }}> - %repost_channel_link% reposted - +
    + +
    + }}> + %repost_channel_link% + +
    ); } diff --git a/ui/component/claimSupportButton/view.jsx b/ui/component/claimSupportButton/view.jsx index 5d6e94c88..e8a37baca 100644 --- a/ui/component/claimSupportButton/view.jsx +++ b/ui/component/claimSupportButton/view.jsx @@ -23,7 +23,7 @@ export default function ClaimSupportButton(props: Props) { return (
    - - {isMyCollection && ( -
    @@ -157,11 +165,9 @@ const Header = (props: Props) => { 'header--minimal': authHeader, 'header--mac': IS_MAC, })} - // @if TARGET='app' onDoubleClick={(e) => { remote.getCurrentWindow().maximize(); }} - // @endif >
    {!authHeader && canBackout ? ( @@ -181,7 +187,7 @@ const Header = (props: Props) => {
    - + ); } diff --git a/ui/component/postViewer/view.jsx b/ui/component/postViewer/view.jsx index 84eb408b5..85c32415c 100644 --- a/ui/component/postViewer/view.jsx +++ b/ui/component/postViewer/view.jsx @@ -52,17 +52,16 @@ function PostViewer(props: Props) { return (
    - - - - - - +
    + + + +
    -
    {expand === EXPAND.CREDIT_DETAILS && ( diff --git a/ui/component/publishForm/view.jsx b/ui/component/publishForm/view.jsx index 811e3bf46..8042975e8 100644 --- a/ui/component/publishForm/view.jsx +++ b/ui/component/publishForm/view.jsx @@ -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 = ; } else { if (isStillEditing) { submitLabel = __('Save'); @@ -498,6 +499,7 @@ function PublishForm(props: Props) {
    {mode !== PUBLISH_MODES.POST && } } /> + { return {__('Uploading (%progress%%) ', { progress: progress })}; } else { return ( - +
    {__('Confirming...')} - +
    ); } }; diff --git a/ui/component/publishPrice/view.jsx b/ui/component/publishPrice/view.jsx index e21195cc0..16d7a49dd 100644 --- a/ui/component/publishPrice/view.jsx +++ b/ui/component/publishPrice/view.jsx @@ -14,44 +14,47 @@ function PublishPrice(props: Props) { const { contentIsFree, fee, updatePublishForm, disabled } = props; return ( - - updatePublishForm({ contentIsFree: true })} - /> - - updatePublishForm({ contentIsFree: false })} - /> - {!contentIsFree && ( - updatePublishForm({ fee: newFee })} + <> + + + updatePublishForm({ contentIsFree: true })} /> - )} - {fee && fee.currency !== 'LBC' && ( -

    - {__( - 'All content fees are charged in LBRY Credits. For alternative payment methods, the number of LBRY Credits charged will be adjusted based on the value of LBRY Credits at the time of purchase.' - )} -

    - )} - - } - /> + + updatePublishForm({ contentIsFree: false })} + /> + {!contentIsFree && ( + updatePublishForm({ fee: newFee })} + /> + )} + {fee && fee.currency !== 'LBC' && ( +

    + {__( + 'All content fees are charged in LBRY Credits. For alternative payment methods, the number of LBRY Credits charged will be adjusted based on the value of LBRY Credits at the time of purchase.' + )} +

    + )} + + } + /> + ); } diff --git a/ui/component/ratioBar/index.js b/ui/component/ratioBar/index.js new file mode 100644 index 000000000..738ce081c --- /dev/null +++ b/ui/component/ratioBar/index.js @@ -0,0 +1,6 @@ +import { connect } from 'react-redux'; +import RatioBar from './view'; + +const select = (state, props) => ({}); + +export default connect(select)(RatioBar); diff --git a/ui/component/ratioBar/view.jsx b/ui/component/ratioBar/view.jsx new file mode 100644 index 000000000..350c5f7cd --- /dev/null +++ b/ui/component/ratioBar/view.jsx @@ -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 ( +
    +
    +
    +
    + ); + } else { + return
    ; + } +}; + +export default RatioBar; diff --git a/ui/component/recommendedContent/view.jsx b/ui/component/recommendedContent/view.jsx index a0cc00226..c067a763b 100644 --- a/ui/component/recommendedContent/view.jsx +++ b/ui/component/recommendedContent/view.jsx @@ -68,18 +68,18 @@ export default React.memo(function RecommendedContent(props: Props) { title={__('Related')} titleActions={ signingChannel && ( -
    +
    -
    - ) : ( -
    - {manualInput ? ( - - ) : ( - - openModal(MODALS.CONFIRM_THUMBNAIL_UPLOAD, { - file, - cb: (url) => !publishForm && updateThumbnailParams({ thumbnail_url: url }), - }) - } - /> - )} -
    -
    -
    - )} -
    + )} +
    + )} {status === THUMBNAIL_STATUSES.IN_PROGRESS &&

    {__('Uploading thumbnail')}...

    } diff --git a/ui/component/settingSystem/view.jsx b/ui/component/settingSystem/view.jsx index f461faa47..19ad493a7 100644 --- a/ui/component/settingSystem/view.jsx +++ b/ui/component/settingSystem/view.jsx @@ -400,7 +400,7 @@ export default function SettingSystem(props: Props) { subtitle={__('This might fix issues that you are having. Your wallet will not be affected.')} >
    - - {sidebarOpen && helpLinks} - - )} - - {(isOnFilePage || isMediumScreen) && sidebarOpen && ( - <> - -
    setSidebarOpen(false)} - /> - - )} + )} + {(!canDisposeMenu || sidebarOpen) && shouldRenderLargeMenu && helpLinks} + +
    setSidebarOpen(false)} + />
    ); } diff --git a/ui/component/subscribeButton/view.jsx b/ui/component/subscribeButton/view.jsx index adc1c5be2..dda3fa588 100644 --- a/ui/component/subscribeButton/view.jsx +++ b/ui/component/subscribeButton/view.jsx @@ -69,7 +69,7 @@ export default function SubscribeButton(props: Props) { if (isSubscribed && !permanentUrl && rawChannelName) { return ( -
    +
    ) : null; diff --git a/ui/component/transactionListTable/view.jsx b/ui/component/transactionListTable/view.jsx index 6239d6589..8e86c3e4d 100644 --- a/ui/component/transactionListTable/view.jsx +++ b/ui/component/transactionListTable/view.jsx @@ -33,10 +33,10 @@ function TransactionListTable(props: Props) { - - + + - + diff --git a/ui/component/viewers/videoViewer/internal/videojs-events.jsx b/ui/component/viewers/videoViewer/internal/videojs-events.jsx index 1c665a962..914477c72 100644 --- a/ui/component/viewers/videoViewer/internal/videojs-events.jsx +++ b/ui/component/viewers/videoViewer/internal/videojs-events.jsx @@ -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); } diff --git a/ui/component/wallpaper/index.js b/ui/component/wallpaper/index.js new file mode 100644 index 000000000..61c65f06d --- /dev/null +++ b/ui/component/wallpaper/index.js @@ -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); diff --git a/ui/component/wallpaper/view.jsx b/ui/component/wallpaper/view.jsx new file mode 100644 index 000000000..3b21a735f --- /dev/null +++ b/ui/component/wallpaper/view.jsx @@ -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 && ( + <> +
    +
    + + ) + ); + } else { */ + /* +
    + */ + return ( + <> +
    +
    + + ); + // } +}; + +export default Wallpaper; diff --git a/ui/component/wunderbarSuggestions/view.jsx b/ui/component/wunderbarSuggestions/view.jsx index cdb0bbd61..c897e1347 100644 --- a/ui/component/wunderbarSuggestions/view.jsx +++ b/ui/component/wunderbarSuggestions/view.jsx @@ -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)} > - + { + const handler = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + return () => { + clearTimeout(handler); + }; + }, [value, delay]); + + return debouncedValue; +} diff --git a/ui/effects/use-persisted-state.js b/ui/effects/use-persisted-state.js index c45838688..6272dc3d3 100644 --- a/ui/effects/use-persisted-state.js +++ b/ui/effects/use-persisted-state.js @@ -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]); diff --git a/ui/effects/use-screensize.js b/ui/effects/use-screensize.js index f0b315f5c..b7404c3ee 100644 --- a/ui/effects/use-screensize.js +++ b/ui/effects/use-screensize.js @@ -34,3 +34,7 @@ export function useIsLargeScreen() { const windowSize = useWindowSize(); return windowSize > 1600; } + +export function isTouch() { + return 'ontouchstart' in window || 'onmsgesturechange' in window; +} diff --git a/ui/page/channel/view.jsx b/ui/page/channel/view.jsx index efba3b151..d263e948e 100644 --- a/ui/page/channel/view.jsx +++ b/ui/page/channel/view.jsx @@ -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 ( - +
    {isMyYouTubeChannel && ( @@ -228,12 +227,11 @@ function ChannelPage(props: Props) { {cover && } {cover && }
    - +

    {title || (channelName && '@' + channelName)} -

    diff --git a/ui/page/channels/view.jsx b/ui/page/channels/view.jsx index 785e6e1b9..4d850d810 100644 --- a/ui/page/channels/view.jsx +++ b/ui/page/channels/view.jsx @@ -45,7 +45,7 @@ export default function ChannelsPage(props: Props) { }, [setRewardData]); return ( - +
    {hasYoutubeChannels && } diff --git a/ui/page/channelsFollowingDiscover/view.jsx b/ui/page/channelsFollowingDiscover/view.jsx index 86f04770f..cd4c9ba6d 100644 --- a/ui/page/channelsFollowingDiscover/view.jsx +++ b/ui/page/channelsFollowingDiscover/view.jsx @@ -98,7 +98,7 @@ function ChannelsFollowingDiscover(props: Props) { }); return ( - + {rowDataWithGenericOptions.map(({ title, link, help, options = {} }) => (

    diff --git a/ui/page/collection/view.jsx b/ui/page/collection/view.jsx index 0e33f1e68..83983a27e 100644 --- a/ui/page/collection/view.jsx +++ b/ui/page/collection/view.jsx @@ -269,7 +269,8 @@ export default function CollectionPage(props: Props) { if (urlsReady) { return ( - + + {editing}
    {info} diff --git a/ui/page/fileListPublished/view.jsx b/ui/page/fileListPublished/view.jsx index 02aa73dbc..ab3c2b158 100644 --- a/ui/page/fileListPublished/view.jsx +++ b/ui/page/fileListPublished/view.jsx @@ -166,12 +166,19 @@ function FileListPublished(props: Props) { headerAltControls={

    {__('Date')}{<>{__('Type')}}{__('Date')}{<>{__('Type')}} {__('Details')} {__('Transaction')}{__('Transaction')}