From 032e17cecd4ffeaa1d92e784245bae93baae1298 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Wed, 21 Jul 2021 21:34:46 +0800 Subject: [PATCH 01/48] Improve CLS on Posts ## Issue 6068 Fix "Cumulative Layout Shift" for Core Web Vitals In Posts, the Comments section appears first while we fetch the MD file. When the MD is fetched, Comments get pushed to the bottom (or shifted up for short posts), hence the red CLS scores. ## Approach There are too many layers between `` and `` to pass the `loading` state around to hide the Comments section, so just make Comments fade in after a 2s delay. ## Changes - Posts: Add 2s fade-in delay to Comments. - Posts: remove the gray placeholder. This improves the score a bit more, and reduces flicker as well. There's already a spinner from `FileRenderInline` to tell the user to be patient. - Posts: add a minimum 30vh height so that short posts don't get collapsed too much, causing the `FileDetails` and Comments to shift. Small shifts are fine as long as CLS is below 0.1. --- ui/component/postViewer/view.jsx | 6 ++++-- ui/component/viewers/documentViewer.jsx | 3 +-- ui/scss/component/_file-render.scss | 4 ++++ ui/scss/component/_main.scss | 14 ++++++++++++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/ui/component/postViewer/view.jsx b/ui/component/postViewer/view.jsx index 5cb3fe111..02e280fb3 100644 --- a/ui/component/postViewer/view.jsx +++ b/ui/component/postViewer/view.jsx @@ -104,8 +104,10 @@ function PostViewer(props: Props) { - - +
+ + +
); diff --git a/ui/component/viewers/documentViewer.jsx b/ui/component/viewers/documentViewer.jsx index 8bd17f153..90b3ef1ab 100644 --- a/ui/component/viewers/documentViewer.jsx +++ b/ui/component/viewers/documentViewer.jsx @@ -86,13 +86,12 @@ class DocumentViewer extends React.PureComponent { } render() { - const { error, loading, content } = this.state; + const { error, content } = this.state; const isReady = content && !error; const errorMessage = __("Sorry, looks like we can't load the document."); return (
- {loading && !error &&
} {error && } {isReady && this.renderDocument()}
diff --git a/ui/scss/component/_file-render.scss b/ui/scss/component/_file-render.scss index 14226fba5..60d64bc99 100644 --- a/ui/scss/component/_file-render.scss +++ b/ui/scss/component/_file-render.scss @@ -105,6 +105,10 @@ aspect-ratio: 16 / 9; } +.file-render--post-container { + min-height: 30vh; +} + .file-render__header { display: flex; justify-content: space-between; diff --git a/ui/scss/component/_main.scss b/ui/scss/component/_main.scss index 698fef3f2..e4814d29a 100644 --- a/ui/scss/component/_main.scss +++ b/ui/scss/component/_main.scss @@ -95,9 +95,23 @@ } } + @keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } + } + .file-page__post-comments { margin-top: var(--spacing-l); + opacity: 0; + animation: fadeIn 2s; + animation-delay: 2s; + animation-fill-mode: forwards; + @media (min-width: $breakpoint-small) { padding: var(--spacing-m); } From 8919182c0c1adbea931dbe65b5e1846a7003d547 Mon Sep 17 00:00:00 2001 From: zeppi Date: Wed, 21 Jul 2021 17:31:00 -0400 Subject: [PATCH 02/48] default avatar config --- config.js | 1 + ui/component/channelThumbnail/view.jsx | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/config.js b/config.js index 36b982ff6..cd68045b2 100644 --- a/config.js +++ b/config.js @@ -63,6 +63,7 @@ const config = { ENABLE_MATURE: process.env.ENABLE_MATURE === 'true', CUSTOM_HOMEPAGE: process.env.CUSTOM_HOMEPAGE === 'true', SHOW_TAGS_INTRO: process.env.SHOW_TAGS_INTRO === 'true', + AVATAR_DEFAULT: process.env.AVATAR_DEFAULT, }; config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`; diff --git a/ui/component/channelThumbnail/view.jsx b/ui/component/channelThumbnail/view.jsx index 19c15fc2e..b09846840 100644 --- a/ui/component/channelThumbnail/view.jsx +++ b/ui/component/channelThumbnail/view.jsx @@ -6,6 +6,7 @@ import Gerbil from './gerbil.png'; import FreezeframeWrapper from 'component/fileThumbnail/FreezeframeWrapper'; import ChannelStakedIndicator from 'component/channelStakedIndicator'; import OptimizedImage from 'component/optimizedImage'; +import { AVATAR_DEFAULT } from 'config'; type Props = { thumbnail: ?string, @@ -48,6 +49,7 @@ function ChannelThumbnail(props: Props) { const channelThumbnail = thumbnail || thumbnailPreview; const isGif = channelThumbnail && channelThumbnail.endsWith('gif'); const showThumb = (!obscure && !!thumbnail) || thumbnailPreview; + const defaultAvater = AVATAR_DEFAULT || Gerbil; // Generate a random color class based on the first letter of the channel name const { channelName } = parseURI(uri); @@ -86,7 +88,7 @@ function ChannelThumbnail(props: Props) { setThumbError(true)} // if thumb fails (including due to https replace, show gerbil. /> @@ -99,7 +101,7 @@ function ChannelThumbnail(props: Props) { setThumbError(true)} // if thumb fails (including due to https replace, show gerbil. /> From f4559c1ccef86ba0eed58603689c3cd73c779e6f Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 22 Jul 2021 12:01:35 -0400 Subject: [PATCH 03/48] fileSubtitle recon --- ui/component/fileSubtitle/view.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/component/fileSubtitle/view.jsx b/ui/component/fileSubtitle/view.jsx index 2c80c0539..60f9c489c 100644 --- a/ui/component/fileSubtitle/view.jsx +++ b/ui/component/fileSubtitle/view.jsx @@ -22,7 +22,7 @@ function FileSubtitle(props: Props) {
- + ); } From ecb14be8712adfc91a561de9622bda2e51d8fd2d Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Thu, 22 Jul 2021 22:39:10 +0800 Subject: [PATCH 04/48] Fix broken embeds in incognito ## Issue Closes 6490 Embeds in https://lbry.com/news/2002dtf was crashing in incognito ## Change Ensure localStorage is available before using it. Jessop warned me before... --- ui/util/lazyImport.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/ui/util/lazyImport.js b/ui/util/lazyImport.js index d5f05f60a..da3e64b04 100644 --- a/ui/util/lazyImport.js +++ b/ui/util/lazyImport.js @@ -1,19 +1,30 @@ import React from 'react'; +let localStorageAvailable; +try { + localStorageAvailable = Boolean(window.localStorage); +} catch (e) { + localStorageAvailable = false; +} + export const lazyImport = (componentImport) => React.lazy(async () => { - const pageHasAlreadyBeenForceRefreshed = JSON.parse( - window.localStorage.getItem('page-has-been-force-refreshed') || 'false' - ); + const pageHasAlreadyBeenForceRefreshed = localStorageAvailable + ? JSON.parse(window.localStorage.getItem('page-has-been-force-refreshed') || 'false') + : false; try { const component = await componentImport(); - window.localStorage.setItem('page-has-been-force-refreshed', 'false'); + if (localStorageAvailable) { + window.localStorage.setItem('page-has-been-force-refreshed', 'false'); + } return component; } catch (error) { if (!pageHasAlreadyBeenForceRefreshed) { // It's highly likely that the user's session is old. Try reloading once. - window.localStorage.setItem('page-has-been-force-refreshed', 'true'); + if (localStorageAvailable) { + window.localStorage.setItem('page-has-been-force-refreshed', 'true'); + } return window.location.reload(); } From 713dc69ed7742e4f531dbb2b2a8d0ee7ae632d8c Mon Sep 17 00:00:00 2001 From: Anthony Date: Thu, 22 Jul 2021 18:44:30 +0200 Subject: [PATCH 05/48] add check for two decimals and fix showing error for fiat tip --- ui/component/walletSendTip/view.jsx | 17 +++++++++++++---- ui/component/walletTipAmountSelector/view.jsx | 17 +++++++++++++---- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/ui/component/walletSendTip/view.jsx b/ui/component/walletSendTip/view.jsx index 981833ffe..8d035fdea 100644 --- a/ui/component/walletSendTip/view.jsx +++ b/ui/component/walletSendTip/view.jsx @@ -186,8 +186,7 @@ function WalletSendTip(props: Props) { React.useEffect(() => { // Regex for number up to 8 decimal places - const regexp = RegExp(/^(\d*([.]\d{0,8})?)$/); - const validTipInput = regexp.test(String(tipAmount)); + let regexp; let tipError; if (tipAmount === 0) { @@ -198,8 +197,13 @@ function WalletSendTip(props: Props) { // if it's not fiat, aka it's boost or lbc tip else if (activeTab !== TAB_FIAT) { + regexp = RegExp(/^(\d*([.]\d{0,8})?)$/); + const validTipInput = regexp.test(String(tipAmount)); + if (!validTipInput) { tipError = __('Amount must have no more than 8 decimal places'); + } else if (!validTipInput) { + tipError = __('Amount must have no more than 8 decimal places'); } else if (tipAmount === balance) { tipError = __('Please decrease the amount to account for transaction fees'); } else if (tipAmount > balance) { @@ -209,7 +213,12 @@ function WalletSendTip(props: Props) { } // if tip fiat tab } else { - if (tipAmount < 1) { + regexp = RegExp(/^(\d*([.]\d{0,2})?)$/); + const validTipInput = regexp.test(String(tipAmount)); + + if (!validTipInput) { + tipError = __('Amount must have no more than 2 decimal places'); + } else if (tipAmount < 1) { tipError = __('Amount must be at least one dollar'); } else if (tipAmount > 1000) { tipError = __('Amount cannot be over 1000 dollars'); @@ -544,7 +553,7 @@ function WalletSendTip(props: Props) { } className="form-field--price-amount" - error={tipError && activeTab !== TAB_FIAT} + error={tipError} min="0" step="any" type="number" diff --git a/ui/component/walletTipAmountSelector/view.jsx b/ui/component/walletTipAmountSelector/view.jsx index a0246ca47..98006abe7 100644 --- a/ui/component/walletTipAmountSelector/view.jsx +++ b/ui/component/walletTipAmountSelector/view.jsx @@ -120,9 +120,7 @@ function WalletTipAmountSelector(props: Props) { // setHasSavedCard(false); // setCanReceiveFiatTip(true); - const regexp = RegExp(/^(\d*([.]\d{0,8})?)$/); - const validTipInput = regexp.test(String(amount)); - let tipError = ''; + let regexp, tipError; if (amount === 0) { tipError = __('Amount must be a positive number'); @@ -132,6 +130,9 @@ function WalletTipAmountSelector(props: Props) { // if it's not fiat, aka it's boost or lbc tip else if (activeTab !== TAB_FIAT) { + regexp = RegExp(/^(\d*([.]\d{0,8})?)$/); + const validTipInput = regexp.test(String(amount)); + if (!validTipInput) { tipError = __('Amount must have no more than 8 decimal places'); } else if (amount === balance) { @@ -143,7 +144,12 @@ function WalletTipAmountSelector(props: Props) { } // if tip fiat tab } else { - if (amount < 1) { + regexp = RegExp(/^(\d*([.]\d{0,2})?)$/); + const validTipInput = regexp.test(String(amount)); + + if (!validTipInput) { + tipError = __('Amount must have no more than 2 decimal places'); + } else if (amount < 1) { tipError = __('Amount must be at least one dollar'); } else if (amount > 1000) { tipError = __('Amount cannot be over 1000 dollars'); @@ -154,8 +160,10 @@ function WalletTipAmountSelector(props: Props) { onTipErrorChange(tipError); }, [amount, balance, setTipError, activeTab]); + // parse number as float and sets it in the parent component function handleCustomPriceChange(amount: number) { const tipAmount = parseFloat(amount); + onChange(tipAmount); } @@ -229,6 +237,7 @@ function WalletTipAmountSelector(props: Props) { )} + {/* custom number input form */} {useCustomTip && (
Date: Thu, 22 Jul 2021 18:47:41 +0200 Subject: [PATCH 06/48] disable button if theres a fiat tip error --- ui/component/walletSendTip/view.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/component/walletSendTip/view.jsx b/ui/component/walletSendTip/view.jsx index 8d035fdea..a6b67ff84 100644 --- a/ui/component/walletSendTip/view.jsx +++ b/ui/component/walletSendTip/view.jsx @@ -574,7 +574,7 @@ function WalletSendTip(props: Props) { disabled={ fetchingChannels || isPending || - (tipError && activeTab !== TAB_FIAT) || + tipError || !tipAmount || (activeTab === TAB_FIAT && (!hasCardSaved || !canReceiveFiatTip)) } From 78b4fa05b3984c94880d6a0cf37c87cab9ede8ea Mon Sep 17 00:00:00 2001 From: Anthony Date: Thu, 22 Jul 2021 20:05:46 +0200 Subject: [PATCH 07/48] pull out variable for max and min fiat amounts --- ui/component/walletSendTip/view.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/component/walletSendTip/view.jsx b/ui/component/walletSendTip/view.jsx index a6b67ff84..97fe1186e 100644 --- a/ui/component/walletSendTip/view.jsx +++ b/ui/component/walletSendTip/view.jsx @@ -25,6 +25,8 @@ if (STRIPE_PUBLIC_KEY.indexOf('pk_live') > -1) { } const DEFAULT_TIP_AMOUNTS = [1, 5, 25, 100]; +const MINIMUM_FIAT_TIP = 1; +const MAXIMUM_FIAT_TIP = 1000; const TAB_BOOST = 'TabBoost'; const TAB_FIAT = 'TabFiat'; @@ -218,9 +220,9 @@ function WalletSendTip(props: Props) { if (!validTipInput) { tipError = __('Amount must have no more than 2 decimal places'); - } else if (tipAmount < 1) { + } else if (tipAmount < MINIMUM_FIAT_TIP) { tipError = __('Amount must be at least one dollar'); - } else if (tipAmount > 1000) { + } else if (tipAmount > MAXIMUM_FIAT_TIP) { tipError = __('Amount cannot be over 1000 dollars'); } } From e920738cd169c15d69149944208e64f06e4339e5 Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 22 Jul 2021 14:21:31 -0400 Subject: [PATCH 08/48] file page recon --- ui/page/file/view.jsx | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ui/page/file/view.jsx b/ui/page/file/view.jsx index a75d497da..987b6bcac 100644 --- a/ui/page/file/view.jsx +++ b/ui/page/file/view.jsx @@ -1,4 +1,5 @@ // @flow +import * as PAGES from 'constants/pages'; import * as React from 'react'; import classnames from 'classnames'; import { lazyImport } from 'util/lazyImport'; @@ -11,6 +12,9 @@ import FileRenderDownload from 'component/fileRenderDownload'; import RecommendedContent from 'component/recommendedContent'; import CollectionContent from 'component/collectionContentSidebar'; import CommentsList from 'component/commentsList'; +import { Redirect } from 'react-router'; +import Button from 'component/button'; +import I18nMessage from 'component/i18nMessage'; import Empty from 'component/common/empty'; const PostViewer = lazyImport(() => import('component/postViewer' /* webpackChunkName: "postViewer" */)); @@ -32,7 +36,9 @@ type Props = { collection?: Collection, collectionId: string, videoTheaterMode: boolean, + claimIsMine: boolean, commentsDisabled: boolean, + isLivestream: boolean, }; function FilePage(props: Props) { @@ -49,9 +55,12 @@ function FilePage(props: Props) { linkedCommentId, setPrimaryUri, videoTheaterMode, + + claimIsMine, commentsDisabled, collection, collectionId, + isLivestream, } = props; const cost = costInfo ? costInfo.cost : null; const hasFileInfo = fileInfo !== undefined; @@ -136,6 +145,10 @@ function FilePage(props: Props) { ); } + if (!claimIsMine && isLivestream) { + return ; + } + if (obscureNsfw && isMature) { return ( @@ -156,6 +169,18 @@ function FilePage(props: Props) { {!isMarkdown && (
+ {claimIsMine && isLivestream && ( +
+

{__('Only visible to you')}

+ + People who view this link will be redirected to your livestream. Make sure to use this for sharing + so your title and thumbnail are displayed properly. + +
+
+
+ )} {RENDER_MODES.FLOATING_MODES.includes(renderMode) && } {commentsDisabled && } {!commentsDisabled && } From 085ea15247133ec16b8c13312c96df7a4a191644 Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 22 Jul 2021 14:41:08 -0400 Subject: [PATCH 09/48] settings page recon --- ui/page/settings/view.jsx | 142 +++++++++++++++++++++----------------- 1 file changed, 77 insertions(+), 65 deletions(-) diff --git a/ui/page/settings/view.jsx b/ui/page/settings/view.jsx index f0cf63325..034a2ee28 100644 --- a/ui/page/settings/view.jsx +++ b/ui/page/settings/view.jsx @@ -15,6 +15,7 @@ import Card from 'component/common/card'; import SettingAccountPassword from 'component/settingAccountPassword'; import classnames from 'classnames'; import { getPasswordFromCookie } from 'util/saved-passwords'; +import { SIMPLE_SITE } from 'config'; // $FlowFixMe import homepages from 'homepages'; import { Lbryio } from 'lbryinc'; @@ -208,37 +209,41 @@ class SettingsPage extends React.PureComponent { className="card-stack" > {/* @if TARGET='web' */} - {user && user.fiat_enabled && -
- } - />} + {user && user.fiat_enabled && ( + +
+ } + /> + )} {/* @endif */} {/* @if TARGET='web' */} - -
- } - /> + {isAuthenticated && ( + + ); diff --git a/webpack.base.config.js b/webpack.base.config.js index 5fca49380..eca42f75d 100644 --- a/webpack.base.config.js +++ b/webpack.base.config.js @@ -77,6 +77,7 @@ let baseConfig = { config: path.resolve(__dirname, 'config.js'), homepage: 'util/homepage.js', homepages: process.env.CUSTOM_HOMEPAGE === 'true' ? path.resolve(__dirname, 'custom/homepages/v2/index.js') : ('homepages/index.js'), + memes: process.env.CUSTOM_HOMEPAGE === 'true' ? path.resolve(__dirname, 'custom/homepages/meme/index.js') : path.resolve(__dirname, 'homepages/meme/index.js'), lbryinc: 'lbryinc/dist/bundle.es.js', // Build optimizations for 'redux-persist-transform-filter' 'redux-persist-transform-filter': 'redux-persist-transform-filter/index.js', From e3006a0edbdce9b117cd1b0ce7f742bd8c4afb72 Mon Sep 17 00:00:00 2001 From: zeppi Date: Fri, 23 Jul 2021 15:44:16 -0400 Subject: [PATCH 26/48] exempt news from hp --- ui/util/buildHomepage.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/util/buildHomepage.js b/ui/util/buildHomepage.js index 362dec55f..63a4a82bd 100644 --- a/ui/util/buildHomepage.js +++ b/ui/util/buildHomepage.js @@ -337,6 +337,9 @@ export function GetLinksData( rowData.push(LATEST_FROM_LBRY); if (!showPersonalizedChannels) rowData.push(TOP_CHANNELS); } - (Object.values(all): any).map((row) => rowData.push(getHomepageRowForCat(row))); + // TODO: provide better method for exempting from homepage + (Object.values(all): any) + .filter((row) => !(isHomepage && row.name === 'news')) + .map((row) => rowData.push(getHomepageRowForCat(row))); return rowData; } From aed3e98c7951754a2ba2db5edc02f2f778ff1822 Mon Sep 17 00:00:00 2001 From: zeppi Date: Fri, 23 Jul 2021 16:18:28 -0400 Subject: [PATCH 27/48] footer recon --- web/component/footer.jsx | 121 ++++++++++----------------------------- 1 file changed, 29 insertions(+), 92 deletions(-) diff --git a/web/component/footer.jsx b/web/component/footer.jsx index ad16140a5..07951e372 100644 --- a/web/component/footer.jsx +++ b/web/component/footer.jsx @@ -1,101 +1,38 @@ -import * as PAGES from 'constants/pages'; import React from 'react'; import Button from 'component/button'; - -const sections = [ - { - name: 'Community', - links: [ - { - label: 'Twitter', - link: 'https://twitter.com/lbrycom', - }, - { - label: 'Reddit', - link: 'https://reddit.com/r/lbry', - }, - { - label: 'Chat (Discord)', - link: 'https://chat.lbry.org/', - }, - { - label: 'Telegram', - link: 'https://t.me/lbryofficial', - }, - { - label: 'Facebook', - link: 'https://www.facebook.com/lbryio', - }, - ], - }, - { - name: 'Resources', - links: [ - { - label: 'FAQ', - link: 'https://lbry.com/faq', - }, - { - label: 'Support --[used in footer; general help/support]--', - link: 'https://lbry.com/faq/support', - }, - { - label: 'YouTube Partner Program', - link: 'https://lbry.com/youtube', - }, - { - label: 'lbry.com', - link: 'https://lbry.com', - }, - { - label: 'lbry.tech', - link: 'https://lbry.tech', - }, - { - label: 'GitHub', - link: 'https://github.com/lbryio', - }, - ], - }, - { - name: 'Policies', - links: [ - { - label: 'Terms of Service', - link: 'https://www.lbry.com/termsofservice', - }, - { - label: 'Privacy Policy', - link: 'https://lbry.com/privacypolicy', - }, - { - label: '2257', - navigate: `/$/${PAGES.CODE_2257}`, - }, - ], - }, -]; +import I18nMessage from 'component/i18nMessage'; +import { SIMPLE_SITE } from 'config'; export default function Footer() { + if (!SIMPLE_SITE) { + return null; + } return (
-
    - {sections.map(({ name, links }) => { - return ( -
  • -
      -
      {__(name)}
      - {links.map(({ label, link, navigate }) => { - return ( -
    • -
    • - ); - })} -
    -
  • - ); - })} + + }}> + POWERED BY %lbry_link% + + +
      +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
); From 1e9dabe6e20e1a8dda2944525b38bab074dba700 Mon Sep 17 00:00:00 2001 From: zeppi Date: Fri, 23 Jul 2021 11:34:11 -0400 Subject: [PATCH 28/48] favicon custom html fav tag remove basic meta favi missing favicon recon --- static/index-web.html | 1 - web/src/html.js | 19 ++++++++++++++++--- web/src/rss.js | 4 ++-- web/src/xml.js | 6 +++--- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/static/index-web.html b/static/index-web.html index f34303615..248dcd0e6 100644 --- a/static/index-web.html +++ b/static/index-web.html @@ -5,7 +5,6 @@ - diff --git a/web/src/html.js b/web/src/html.js index ed764b9f1..8463180a2 100644 --- a/web/src/html.js +++ b/web/src/html.js @@ -8,6 +8,7 @@ const { OG_IMAGE_URL, SITE_DESCRIPTION, SITE_NAME, + FAVICON, } = require('../../config.js'); const { generateEmbedUrl, generateStreamUrl, generateDirectUrl } = require('../../ui/util/web'); const PAGES = require('../../ui/constants/pages'); @@ -82,20 +83,31 @@ function buildOgMetadata(overrideOptions = {}) { function conditionallyAddPWA() { let head = ''; if (DOMAIN === 'odysee.com') { - head += ''; + head += ''; head += ''; head += ''; } return head; } +function addFavicon() { + let head = ''; + head += ``; + return head; +} + function buildHead() { - const head = '' + conditionallyAddPWA() + buildOgMetadata() + ''; + const head = + '' + + addFavicon() + + conditionallyAddPWA() + + buildOgMetadata() + + ''; return head; } function buildBasicOgMetadata() { - const head = '' + buildOgMetadata() + ''; + const head = '' + addFavicon() + buildOgMetadata() + ''; return head; } @@ -128,6 +140,7 @@ function buildClaimOgMetadata(uri, claim, overrideOptions = {}) { let head = ''; + head += `${addFavicon()}`; head += ''; head += `${title}`; head += ``; diff --git a/web/src/rss.js b/web/src/rss.js index aba49f644..98684ab89 100644 --- a/web/src/rss.js +++ b/web/src/rss.js @@ -1,5 +1,5 @@ const { generateDownloadUrl } = require('../../ui/util/web'); -const { URL, SITE_NAME, LBRY_WEB_API } = require('../../config.js'); +const { URL, SITE_NAME, LBRY_WEB_API, FAVICON } = require('../../config.js'); const { Lbry } = require('lbry-redux'); const Feed = require('feed').Feed; @@ -82,7 +82,7 @@ async function getFeed(channelClaim, feedLink) { const title = value ? value.title : channelClaim.name; const options = { - favicon: URL + '/public/favicon.png', + favicon: FAVICON || URL + '/public/favicon.png', generator: SITE_NAME + ' RSS Feed', title: title + ' on ' + SITE_NAME, description: fmtDescription(value && value.description ? value.description : ''), diff --git a/web/src/xml.js b/web/src/xml.js index bad950406..9cd48fe44 100644 --- a/web/src/xml.js +++ b/web/src/xml.js @@ -1,11 +1,11 @@ -const { URL, SITE_TITLE } = require('../../config.js'); - +const { URL, SITE_TITLE, FAVICON } = require('../../config.js'); +const favicon = FAVICON || `${URL}/public/favicon.png`; function getOpenSearchXml() { return ( `${SITE_TITLE}` + `Search ${SITE_TITLE}` + 'UTF-8' + - `${URL}/public/favicon.png` + + `${favicon}` + `` + `${URL}` ); From 8fef6c6160eda755e261725bcbd4adfa15f7aa98 Mon Sep 17 00:00:00 2001 From: zeppi Date: Fri, 23 Jul 2021 16:32:19 -0400 Subject: [PATCH 29/48] ugly discover recon --- ui/page/discover/view.jsx | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/ui/page/discover/view.jsx b/ui/page/discover/view.jsx index 59a7a49d3..1783756a3 100644 --- a/ui/page/discover/view.jsx +++ b/ui/page/discover/view.jsx @@ -2,6 +2,7 @@ import { SHOW_ADS, DOMAIN, SIMPLE_SITE, ENABLE_NO_SOURCE_CLAIMS } from 'config'; import * as ICONS from 'constants/icons'; import * as PAGES from 'constants/pages'; +import * as CS from 'constants/claim_search'; import React, { useRef } from 'react'; import Page from 'component/page'; import ClaimListDiscover from 'component/claimListDiscover'; @@ -11,11 +12,11 @@ import { useIsMobile } from 'effects/use-screensize'; import analytics from 'analytics'; import HiddenNsfw from 'component/common/hidden-nsfw'; import Icon from 'component/common/icon'; -import * as CS from 'constants/claim_search'; import Ads from 'web/component/ads'; import LbcSymbol from 'component/common/lbc-symbol'; import I18nMessage from 'component/i18nMessage'; import useGetLivestreams from 'effects/use-get-livestreams'; +import moment from 'moment'; type Props = { location: { search: string }, @@ -52,6 +53,8 @@ function DiscoverPage(props: Props) { const tags = tagsQuery ? tagsQuery.split(',') : null; const repostedClaimIsResolved = repostedUri && repostedClaim; + const discoverIcon = SIMPLE_SITE ? ICONS.WILD_WEST : ICONS.DISCOVER; + const discoverLabel = SIMPLE_SITE ? __('Wild West') : __('All Content'); // Eventually allow more than one tag on this page // Restricting to one to make follow/unfollow simpler const tag = (tags && tags[0]) || null; @@ -97,8 +100,8 @@ function DiscoverPage(props: Props) { } else { headerLabel = ( - - {(dynamicRouteProps && dynamicRouteProps.title) || __('All Content')} + + {(dynamicRouteProps && dynamicRouteProps.title) || discoverLabel} ); } @@ -106,9 +109,11 @@ function DiscoverPage(props: Props) { return ( : undefined} tileLayout={repostedUri ? false : tileLayout} + defaultOrderBy={SIMPLE_SITE ? (dynamicRouteProps ? undefined : CS.ORDER_BY_TRENDING) : undefined} claimType={claimType ? [claimType] : undefined} headerLabel={headerLabel} tags={tags} @@ -117,9 +122,24 @@ function DiscoverPage(props: Props) { injectedItem={ SHOW_ADS && IS_WEB ? (SIMPLE_SITE ? false : !isAuthenticated && ) : false } + // Assume wild west page if no dynamicRouteProps + // Not a very good solution, but just doing it for now + // until we are sure this page will stay around + releaseTime={ + SIMPLE_SITE + ? !dynamicRouteProps && `>${Math.floor(moment().subtract(1, 'day').startOf('week').unix())}` + : undefined + } + feeAmount={SIMPLE_SITE ? !dynamicRouteProps && CS.FEE_AMOUNT_ANY : undefined} channelIds={ (dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.channelIds) || undefined } + limitClaimsPerChannel={ + SIMPLE_SITE + ? (dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.limitClaimsPerChannel) || + undefined + : 3 + } meta={ !dynamicRouteProps ? ( Date: Mon, 26 Jul 2021 12:29:29 +0800 Subject: [PATCH 30/48] Fix split (concat) string usage Concatenated strings are hard to translate. --- static/app-strings.json | 2 ++ ui/component/claimMenuList/view.jsx | 11 +++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/static/app-strings.json b/static/app-strings.json index 665dd3884..d4ad7eb37 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -375,6 +375,8 @@ "Got it": "Got it", "View your channels": "View your channels", "Unfollow": "Unfollow", + "Follow @%channelName%": "Follow @%channelName%", + "Unfollow @%channelName%": "Unfollow @%channelName%", "These LBRY Credits remain yours. It is a deposit to reserve the name and can be undone at any time.": "These LBRY Credits remain yours. It is a deposit to reserve the name and can be undone at any time.", "Create channel": "Create channel", "Uh oh. The flux in our Retro Encabulator must be out of whack. Try refreshing to fix it.": "Uh oh. The flux in our Retro Encabulator must be out of whack. Try refreshing to fix it.", diff --git a/ui/component/claimMenuList/view.jsx b/ui/component/claimMenuList/view.jsx index 6220cc783..66535b73d 100644 --- a/ui/component/claimMenuList/view.jsx +++ b/ui/component/claimMenuList/view.jsx @@ -98,10 +98,13 @@ function ClaimMenuList(props: Props) { const isChannel = !incognitoClaim && !contentSigningChannel; const { channelName } = parseURI(contentChannelUri); const showDelete = claimIsMine || (fileInfo && (fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0)); - const subscriptionLabel = __('%action%' + '%user%', { - action: isSubscribed ? __('Unfollow') : __('Follow'), - user: repostedClaim ? __(' @' + channelName) : '', - }); + const subscriptionLabel = repostedClaim + ? isSubscribed + ? __('Unfollow @%channelName%', { channelName }) + : __('Follow @%channelName%', { channelName }) + : isSubscribed + ? __('Unfollow') + : __('Follow'); const lastCollectionName = 'Favorites'; const lastCollectionId = COLLECTIONS_CONSTS.FAVORITES_ID; From f6e648222ef4cdda9b5646963861924f9c7ceb27 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Fri, 23 Jul 2021 14:36:39 +0800 Subject: [PATCH 31/48] Change constants to object for IDE auto complete No functional change; just thought this is cleaner (group up the constants) and easier to type via IDE auto-complete, at the expense of creating an extra object. --- ui/page/channel/view.jsx | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/ui/page/channel/view.jsx b/ui/page/channel/view.jsx index 1bd03b613..236a0b3f7 100644 --- a/ui/page/channel/view.jsx +++ b/ui/page/channel/view.jsx @@ -28,11 +28,15 @@ import I18nMessage from 'component/i18nMessage'; import PlaceholderTx from 'static/img/placeholderTx.gif'; export const PAGE_VIEW_QUERY = `view`; -const CONTENT_PAGE = 'content'; -const LISTS_PAGE = 'lists'; -const ABOUT_PAGE = `about`; export const DISCUSSION_PAGE = `discussion`; -const EDIT_PAGE = 'edit'; + +const PAGE = { + CONTENT: 'content', + LISTS: 'lists', + ABOUT: 'about', + DISCUSSION: DISCUSSION_PAGE, + EDIT: 'edit', +}; type Props = { uri: string, @@ -85,7 +89,7 @@ function ChannelPage(props: Props) { const urlParams = new URLSearchParams(search); const currentView = urlParams.get(PAGE_VIEW_QUERY) || undefined; const [discussionWasMounted, setDiscussionWasMounted] = React.useState(false); - const editing = urlParams.get(PAGE_VIEW_QUERY) === EDIT_PAGE; + const editing = urlParams.get(PAGE_VIEW_QUERY) === PAGE.EDIT; const { channelName } = parseURI(uri); const { permanent_url: permanentUrl } = claim; const claimId = claim.claim_id; @@ -143,16 +147,16 @@ function ChannelPage(props: Props) { // would alter the Tab label's role attribute, which should stay role="tab" to work with keyboards/screen readers. let tabIndex; switch (currentView) { - case CONTENT_PAGE: + case PAGE.CONTENT: tabIndex = 0; break; - case LISTS_PAGE: + case PAGE.LISTS: tabIndex = 1; break; - case ABOUT_PAGE: + case PAGE.ABOUT: tabIndex = 2; break; - case DISCUSSION_PAGE: + case PAGE.DISCUSSION: tabIndex = 3; break; default: @@ -165,20 +169,20 @@ function ChannelPage(props: Props) { let search = '?'; if (newTabIndex === 0) { - search += `${PAGE_VIEW_QUERY}=${CONTENT_PAGE}`; + search += `${PAGE_VIEW_QUERY}=${PAGE.CONTENT}`; } else if (newTabIndex === 1) { - search += `${PAGE_VIEW_QUERY}=${LISTS_PAGE}`; + search += `${PAGE_VIEW_QUERY}=${PAGE.LISTS}`; } else if (newTabIndex === 2) { - search += `${PAGE_VIEW_QUERY}=${ABOUT_PAGE}`; + search += `${PAGE_VIEW_QUERY}=${PAGE.ABOUT}`; } else { - search += `${PAGE_VIEW_QUERY}=${DISCUSSION_PAGE}`; + search += `${PAGE_VIEW_QUERY}=${PAGE.DISCUSSION}`; } push(`${url}${search}`); } React.useEffect(() => { - if (currentView === DISCUSSION_PAGE) { + if (currentView === PAGE.DISCUSSION) { setDiscussionWasMounted(true); } }, [currentView]); @@ -241,7 +245,7 @@ function ChannelPage(props: Props) { {!authHeader && (
{/* @if TARGET='app' */} diff --git a/ui/component/logo/index.js b/ui/component/logo/index.js new file mode 100644 index 000000000..6d0f96f4b --- /dev/null +++ b/ui/component/logo/index.js @@ -0,0 +1,10 @@ +import { connect } from 'react-redux'; +import Logo from './view'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; +import { SETTINGS } from 'lbry-redux'; + +const select = (state, props) => ({ + currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state), +}); + +export default connect(select)(Logo); diff --git a/ui/component/logo/view.jsx b/ui/component/logo/view.jsx new file mode 100644 index 000000000..7d1ddd30a --- /dev/null +++ b/ui/component/logo/view.jsx @@ -0,0 +1,29 @@ +// @flow +import React from 'react'; +import * as ICONS from 'constants/icons'; +import { LOGO, LOGO_TEXT_LIGHT, LOGO_TEXT_DARK } from 'config'; +import Icon from 'component/common/icon'; + +type Props = { + type: string, + currentTheme: string, +}; + +export default function Logo(props: Props) { + const { type, currentTheme } = props; + if (type === 'small') { + return LOGO ? : ; + } else { + if (LOGO_TEXT_LIGHT && LOGO_TEXT_DARK) { + return ( + <> + {/**/} + + + ); + } else { + return ; + } + } +} +//mobile-hidden From 3f4c601428c64fa532af71c4382abcd74f4e0172 Mon Sep 17 00:00:00 2001 From: zeppi Date: Sun, 25 Jul 2021 18:03:48 -0400 Subject: [PATCH 37/48] logo component on embeds/embeds ended --- ui/component/fileViewerEmbeddedTitle/view.jsx | 6 ++-- ui/component/header/view.jsx | 5 +--- ui/component/logo/view.jsx | 29 +++++++++++++++---- .../fileViewerEmbeddedEnded/view.jsx | 6 ++-- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/ui/component/fileViewerEmbeddedTitle/view.jsx b/ui/component/fileViewerEmbeddedTitle/view.jsx index e97b56e73..39dfe4d4c 100644 --- a/ui/component/fileViewerEmbeddedTitle/view.jsx +++ b/ui/component/fileViewerEmbeddedTitle/view.jsx @@ -5,7 +5,7 @@ import FilePrice from 'component/filePrice'; import { formatLbryUrlForWeb } from 'util/url'; import { withRouter } from 'react-router'; import { URL } from 'config'; -import * as ICONS from 'constants/icons'; +import Logo from 'component/logo'; type Props = { uri: string, @@ -36,7 +36,9 @@ function FileViewerEmbeddedTitle(props: Props) { {...contentLinkProps} />
- {isInApp && }
diff --git a/ui/component/header/view.jsx b/ui/component/header/view.jsx index 7b961664c..775d4a12f 100644 --- a/ui/component/header/view.jsx +++ b/ui/component/header/view.jsx @@ -1,5 +1,5 @@ // @flow -import { LOGO_TITLE, ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM, ENABLE_UI_NOTIFICATIONS } from 'config'; +import { ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM, ENABLE_UI_NOTIFICATIONS } from 'config'; import * as ICONS from 'constants/icons'; import { SETTINGS } from 'lbry-redux'; import * as PAGES from 'constants/pages'; @@ -256,9 +256,6 @@ const Header = (props: Props) => { // @if TARGET='app' label={'LBRY'} // @endif - // @if TARGET='web' - label={LOGO_TITLE} // eslint-disable-line - // @endif onClick={() => { if (history.location.pathname === '/') window.location.reload(); }} diff --git a/ui/component/logo/view.jsx b/ui/component/logo/view.jsx index 7d1ddd30a..21bfe28d9 100644 --- a/ui/component/logo/view.jsx +++ b/ui/component/logo/view.jsx @@ -1,8 +1,9 @@ // @flow import React from 'react'; import * as ICONS from 'constants/icons'; -import { LOGO, LOGO_TEXT_LIGHT, LOGO_TEXT_DARK } from 'config'; +import { LOGO_TITLE, LOGO, LOGO_TEXT_LIGHT, LOGO_TEXT_DARK } from 'config'; import Icon from 'component/common/icon'; +import { useIsMobile } from 'effects/use-screensize'; type Props = { type: string, @@ -11,19 +12,35 @@ type Props = { export default function Logo(props: Props) { const { type, currentTheme } = props; - if (type === 'small') { - return LOGO ? : ; + const isMobile = useIsMobile(); + const defaultWithLabel = ( + <> + + + + ); + + if (type === 'small' || (isMobile && type !== 'embed')) { + return LOGO ? : ; + } else if (type === 'embed') { + if (LOGO_TEXT_LIGHT) { + return ( + <> + + + ); + } else { + return defaultWithLabel; + } } else { if (LOGO_TEXT_LIGHT && LOGO_TEXT_DARK) { return ( <> - {/**/} ); } else { - return ; + return defaultWithLabel; } } } -//mobile-hidden diff --git a/web/component/fileViewerEmbeddedEnded/view.jsx b/web/component/fileViewerEmbeddedEnded/view.jsx index eaf70ee30..86bb1803f 100644 --- a/web/component/fileViewerEmbeddedEnded/view.jsx +++ b/web/component/fileViewerEmbeddedEnded/view.jsx @@ -4,7 +4,7 @@ import Button from 'component/button'; import { formatLbryUrlForWeb } from 'util/url'; import { withRouter } from 'react-router'; import { URL, SITE_NAME } from 'config'; -import * as ICONS from 'constants/icons'; +import Logo from 'component/logo'; type Props = { uri: string, @@ -37,7 +37,9 @@ function FileViewerEmbeddedEnded(props: Props) { return (
-
{prompt}
From 71d9b0d973fdaccc5b2a4fa230a1275eb486ca95 Mon Sep 17 00:00:00 2001 From: zeppi Date: Sun, 25 Jul 2021 18:40:53 -0400 Subject: [PATCH 38/48] default logo --- ui/component/logo/view.jsx | 2 +- ui/scss/component/_header.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/component/logo/view.jsx b/ui/component/logo/view.jsx index 21bfe28d9..597723350 100644 --- a/ui/component/logo/view.jsx +++ b/ui/component/logo/view.jsx @@ -15,8 +15,8 @@ export default function Logo(props: Props) { const isMobile = useIsMobile(); const defaultWithLabel = ( <> - +
{LOGO_TITLE}
); diff --git a/ui/scss/component/_header.scss b/ui/scss/component/_header.scss index 0c1d0fbd8..c7fbb3591 100644 --- a/ui/scss/component/_header.scss +++ b/ui/scss/component/_header.scss @@ -58,7 +58,6 @@ justify-content: center; align-items: center; border-radius: var(--border-radius); - color: var(--color-text); position: relative; font-weight: var(--font-weight-bold); @@ -132,6 +131,7 @@ align-items: center; margin-left: var(--spacing-m); margin-right: var(--spacing-m); + color: var(--color-text); // move to lbry theme? .lbry-icon { height: var(--height-button); From ef77a5cd008a6fd559c89b4e9400919b5cc27fc0 Mon Sep 17 00:00:00 2001 From: zeppi Date: Sun, 25 Jul 2021 18:46:43 -0400 Subject: [PATCH 39/48] optimizedImage --- ui/component/logo/view.jsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/component/logo/view.jsx b/ui/component/logo/view.jsx index 597723350..ca8745712 100644 --- a/ui/component/logo/view.jsx +++ b/ui/component/logo/view.jsx @@ -4,6 +4,7 @@ import * as ICONS from 'constants/icons'; import { LOGO_TITLE, LOGO, LOGO_TEXT_LIGHT, LOGO_TEXT_DARK } from 'config'; import Icon from 'component/common/icon'; import { useIsMobile } from 'effects/use-screensize'; +import OptimizedImage from 'component/optimizedImage'; type Props = { type: string, @@ -21,12 +22,12 @@ export default function Logo(props: Props) { ); if (type === 'small' || (isMobile && type !== 'embed')) { - return LOGO ? : ; + return LOGO ? : ; } else if (type === 'embed') { if (LOGO_TEXT_LIGHT) { return ( <> - + ); } else { @@ -36,7 +37,7 @@ export default function Logo(props: Props) { if (LOGO_TEXT_LIGHT && LOGO_TEXT_DARK) { return ( <> - + ); } else { From b1e8d2d6db43d3834c6dac6a98c9dab11036bbca Mon Sep 17 00:00:00 2001 From: zeppi Date: Mon, 26 Jul 2021 08:41:10 -0400 Subject: [PATCH 40/48] desktop logo --- ui/component/header/view.jsx | 3 --- ui/component/logo/view.jsx | 5 +++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ui/component/header/view.jsx b/ui/component/header/view.jsx index 775d4a12f..e712c50e5 100644 --- a/ui/component/header/view.jsx +++ b/ui/component/header/view.jsx @@ -253,9 +253,6 @@ const Header = (props: Props) => { )}