Merge branch 'master' into protocol

This commit is contained in:
Baltazar Gomez 2021-08-01 13:41:18 -05:00 committed by GitHub
commit d8e92f9d6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 151 additions and 37 deletions

View file

@ -12,6 +12,8 @@ LBRY_WEB_API=https://api.na-backend.odysee.com
LBRY_WEB_STREAMING_API=https://cdn.lbryplayer.xyz
LBRY_WEB_BUFFER_API=https://collector-service.api.lbry.tv/api/v1/events/video
COMMENT_SERVER_API=https://comments.odysee.com/api/v2
SEARCH_SERVER_API=https://lighthouse.odysee.com/search
SOCKETY_SERVER_API=wss://sockety.odysee.com/ws
THUMBNAIL_CDN_URL=https://image-processor.vanwanet.com/optimize/
WELCOME_VERSION=1.0
@ -37,6 +39,8 @@ SITE_NAME=lbry.tv
SITE_DESCRIPTION=Meet LBRY, an open, free, and community-controlled content wonderland.
SITE_HELP_EMAIL=help@lbry.com
LOGO_TITLE=lbry.tv
## Social media
TWITTER_ACCOUNT=LBRYcom
## IMAGE ASSETS
YRBL_HAPPY_IMG_URL=https://cdn.lbryplayer.xyz/api/v3/streams/free/yrbl-happy/7aa50a7e5adaf48691935d55e45d697547392929/839d9a

View file

@ -9,13 +9,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Show currently active playing item on playlist _community pr!_ ([#6453](https://github.com/lbryio/lbry-desktop/pull/6453))
- Add watch later to hover action for last used playlist on popup _community pr!_ ([#6274](https://github.com/lbryio/lbry-desktop/pull/6274))
- Open in desktop (web feature) _community pr!_ ([#6667](https://github.com/lbryio/lbry-desktop/pull/6667))
- Add confirmation on comment removal _community pr!_ ([#6563](https://github.com/lbryio/lbry-desktop/pull/6563))
### Changed
- Use Canonical Url for copy link ([#6500](https://github.com/lbryio/lbry-desktop/pull/6500))
- Use better icon for copy link ([#6485](https://github.com/lbryio/lbry-desktop/pull/6485))
- Comments load paginated ([#6390](https://github.com/lbryio/lbry-desktop/pull/6390))
- Update lighthouse search api _community pr!_ ([#6731](https://github.com/lbryio/lbry-desktop/pull/6731))
- Improve twitter share _community pr!_ ([#6690](https://github.com/lbryio/lbry-desktop/pull/6690))
- Update lighthouse search api _community pr!_ ([#6731](https://github.com/lbryio/lbry-desktop/pull/6731))
- Update sockety api _community pr!_ ([#6747](https://github.com/lbryio/lbry-desktop/pull/6747))
### Fixed
- App now supports '#' and ':' for claimId separator ([#6496](https://github.com/lbryio/lbry-desktop/pull/6496))

View file

@ -13,7 +13,9 @@ const config = {
LBRY_API_URL: process.env.LBRY_API_URL, //api.lbry.com',
LBRY_WEB_STREAMING_API: process.env.LBRY_WEB_STREAMING_API, //cdn.lbryplayer.xyz',
LBRY_WEB_BUFFER_API: process.env.LBRY_WEB_BUFFER_API,
SEARCH_SERVER_API: process.env.SEARCH_SERVER_API,
COMMENT_SERVER_API: process.env.COMMENT_SERVER_API,
SOCKETY_SERVER_API: process.env.SOCKETY_SERVER_API,
WELCOME_VERSION: process.env.WELCOME_VERSION,
DOMAIN: process.env.DOMAIN,
SHARE_DOMAIN_URL: process.env.SHARE_DOMAIN_URL,
@ -23,6 +25,8 @@ const config = {
SITE_NAME: process.env.SITE_NAME,
SITE_DESCRIPTION: process.env.SITE_DESCRIPTION,
SITE_HELP_EMAIL: process.env.SITE_HELP_EMAIL,
// SOCIAL MEDIA
TWITTER_ACCOUNT: process.env.TWITTER_ACCOUNT,
// LOGO
LOGO_TITLE: process.env.LOGO_TITLE,
FAVICON: process.env.FAVICON,
@ -69,7 +73,7 @@ const config = {
BRANDED_SITE: process.env.BRANDED_SITE,
};
config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`;
config.URL_DEV = `http://localhost:${config.WEBPACK_WEB_PORT}`;
config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`;
module.exports = config;

View file

@ -2057,17 +2057,14 @@
"Only select creators can receive tips at this time": "Only select creators can receive tips at this time",
"The payment will be made from your saved card": "The payment will be made from your saved card",
"Commenting...": "Commenting...",
"Show %count% replies": "Show %count% replies",
"Show reply": "Show reply",
"added to": "added to",
"removed from": "removed from",
"Skip Navigation": "Skip Navigation",
"Reset": "Reset",
"Reset to original (previous) publish date": "Reset to original (previous) publish date",
"%title% by %channelTitle%": "%title% by %channelTitle%",
"%title% by %channelTitle% %ariaDate%": "%title% by %channelTitle% %ariaDate%",
"%title% by %channelTitle% %ariaDate%, %mediaDuration%": "%title% by %channelTitle% %ariaDate%, %mediaDuration%",
"Search for something...": "Search for something...",
"Open in Desktop": "Open in Desktop",
"Show %count% replies": "Show %count% replies",
"Show reply": "Show reply",
"--end--": "--end--"
}

View file

@ -120,7 +120,7 @@ function ClaimPreviewTile(props: Props) {
const signingChannel = claim && claim.signing_channel;
const isChannel = claim && claim.value_type === 'channel';
const channelUri = !isChannel ? signingChannel && signingChannel.permanent_url : claim && claim.permanent_url;
const channelTitle = signingChannel && (signingChannel.value.title || signingChannel.name);
const channelTitle = signingChannel && ((signingChannel.value && signingChannel.value.title) || signingChannel.name);
// Aria-label value for claim preview
let ariaLabelData = isChannel ? title : formatClaimPreviewTitle(title, channelTitle, date, mediaDuration);

View file

@ -270,6 +270,7 @@ function Comment(props: Props) {
authorUri={authorUri}
commentIsMine={commentIsMine}
handleEditComment={handleEditComment}
supportAmount={supportAmount}
/>
</Menu>
</div>

View file

@ -1,7 +1,6 @@
import { connect } from 'react-redux';
import { makeSelectChannelPermUrlForClaimUri, makeSelectClaimIsMine, makeSelectClaimForUri } from 'lbry-redux';
import {
doCommentAbandon,
doCommentPin,
doCommentModBlock,
doCommentModBlockAsAdmin,
@ -10,6 +9,7 @@ import {
} from 'redux/actions/comments';
import { doChannelMute } from 'redux/actions/blocked';
// import { doSetActiveChannel } from 'redux/actions/app';
import { doOpenModal } from 'redux/actions/app';
import { doSetPlayingUri } from 'redux/actions/content';
import { selectActiveChannelClaim } from 'redux/selectors/app';
import { selectPlayingUri } from 'redux/selectors/content';
@ -26,8 +26,8 @@ const select = (state, props) => ({
});
const perform = (dispatch) => ({
openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
deleteComment: (commentId, creatorChannelUrl) => dispatch(doCommentAbandon(commentId, creatorChannelUrl)),
muteChannel: (channelUri) => dispatch(doChannelMute(channelUri)),
pinComment: (commentId, claimId, remove) => dispatch(doCommentPin(commentId, claimId, remove)),
// setActiveChannel: channelId => dispatch(doSetActiveChannel(channelId)),

View file

@ -1,5 +1,6 @@
// @flow
import * as ICONS from 'constants/icons';
import * as MODALS from 'constants/modal_types';
import React from 'react';
import { MenuList, MenuItem } from '@reach/menu-button';
import ChannelThumbnail from 'component/channelThumbnail';
@ -12,7 +13,6 @@ type Props = {
authorUri: string, // full LBRY Channel URI: lbry://@channel#123...
commentId: string, // sha256 digest identifying the comment
commentIsMine: boolean, // if this comment was signed by an owned channel
deleteComment: (string, ?string) => void,
isPinned: boolean,
pinComment: (string, string, boolean) => Promise<any>,
muteChannel: (string) => void,
@ -28,6 +28,8 @@ type Props = {
disableEdit?: boolean,
disableRemove?: boolean,
moderationDelegatorsById: { [string]: { global: boolean, delegators: { name: string, claimId: string } } },
openModal: (id: string, {}) => void,
supportAmount?: any,
};
function CommentMenuList(props: Props) {
@ -36,7 +38,6 @@ function CommentMenuList(props: Props) {
authorUri,
commentIsMine,
commentId,
deleteComment,
muteChannel,
pinComment,
clearPlayingUri,
@ -53,6 +54,8 @@ function CommentMenuList(props: Props) {
disableEdit,
disableRemove,
moderationDelegatorsById,
openModal,
supportAmount,
} = props;
const contentChannelClaim = !claim
@ -80,7 +83,7 @@ function CommentMenuList(props: Props) {
if (playingUri && playingUri.source === 'comment') {
clearPlayingUri();
}
deleteComment(commentId, commentIsMine ? undefined : contentChannelPermanentUrl);
openModal(MODALS.CONFIRM_REMOVE_COMMENT, { commentId, commentIsMine, contentChannelPermanentUrl, supportAmount });
}
function handleCommentBlock() {

View file

@ -18,11 +18,16 @@ export default function LivestreamLink(props: Props) {
const [livestreamClaim, setLivestreamClaim] = React.useState(false);
const [isLivestreaming, setIsLivestreaming] = React.useState(false);
const livestreamChannelId = (channelClaim && channelClaim.claim_id) || ''; // TODO: fail in a safer way, probably
const isChannelEmpty = !channelClaim || !channelClaim.meta || !channelClaim.meta.claims_in_channel;
React.useEffect(() => {
if (livestreamChannelId) {
// Don't search empty channels
if (livestreamChannelId && !isChannelEmpty) {
Lbry.claim_search({
channel_ids: [livestreamChannelId],
page: 1,
page_size: 1,
no_totals: true,
has_no_source: true,
claim_type: ['stream'],
order_by: CS.ORDER_BY_NEW_VALUE,
@ -35,7 +40,7 @@ export default function LivestreamLink(props: Props) {
})
.catch(() => {});
}
}, [livestreamChannelId]);
}, [livestreamChannelId, isChannelEmpty]);
React.useEffect(() => {
function fetchIsStreaming() {
@ -53,17 +58,23 @@ export default function LivestreamLink(props: Props) {
}
let interval;
if (livestreamChannelId) {
// Only call livestream api if channel has livestream claims
if (livestreamChannelId && livestreamClaim) {
if (!interval) fetchIsStreaming();
interval = setInterval(fetchIsStreaming, 10 * 1000);
}
// Prevent any more api calls on update
if (!livestreamChannelId || !livestreamClaim) {
if (interval) {
clearInterval(interval);
}
}
return () => {
if (interval) {
clearInterval(interval);
}
};
}, [livestreamChannelId]);
}, [livestreamChannelId, livestreamClaim]);
if (!livestreamClaim || !isLivestreaming) {
return null;

View file

@ -26,12 +26,12 @@ export default function Logo(props: Props) {
);
if (type === 'small' || (isMobile && type !== 'embed')) {
return LOGO ? <img src={LOGO} /> : <Icon icon={ICONS.LBRY} />;
return LOGO ? <img className={'header__navigation-logo'} src={LOGO} /> : <Icon icon={ICONS.LBRY} />;
} else if (type === 'embed') {
if (LOGO_TEXT_LIGHT) {
return (
<>
<img src={LOGO_TEXT_LIGHT} />
<img className={'header__navigation-logo'} src={LOGO_TEXT_LIGHT} />
</>
);
} else {
@ -41,7 +41,10 @@ export default function Logo(props: Props) {
if (LOGO_TEXT_LIGHT && LOGO_TEXT_DARK) {
return (
<>
<img src={currentTheme === 'light' ? LOGO_TEXT_DARK : LOGO_TEXT_LIGHT} />
<img
className={'header__navigation-logo'}
src={currentTheme === 'light' ? LOGO_TEXT_DARK : LOGO_TEXT_LIGHT}
/>
</>
);
} else {

View file

@ -193,7 +193,7 @@ export default function Notification(props: Props) {
<div className="notification__menu">
<Menu>
<MenuButton className={'menu-button notification__menu-button'} onClick={(e) => e.stopPropagation()}>
<MenuButton className={'menu__button notification__menu-button'} onClick={(e) => e.stopPropagation()}>
<Icon size={18} icon={ICONS.MORE_VERTICAL} />
</MenuButton>
<MenuList className="menu__list">

View file

@ -9,12 +9,15 @@ import { useIsMobile } from 'effects/use-screensize';
import { FormField } from 'component/common/form';
import { hmsToSeconds, secondsToHms } from 'util/time';
import { generateLbryContentUrl, generateLbryWebUrl, generateEncodedLbryURL, generateShareUrl } from 'util/url';
import { URL, SHARE_DOMAIN_URL } from 'config';
import { URL, TWITTER_ACCOUNT, SHARE_DOMAIN_URL } from 'config';
const SHARE_DOMAIN = SHARE_DOMAIN_URL || URL;
const IOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
const SUPPORTS_SHARE_API = typeof navigator.share !== 'undefined';
// Twitter share
const TWITTER_INTENT_API = 'https://twitter.com/intent/tweet?';
type Props = {
claim: StreamClaim,
title: ?string,
@ -68,6 +71,21 @@ function SocialShare(props: Props) {
);
const downloadUrl = `${generateDownloadUrl(name, claimId)}`;
// Tweet params
let tweetIntentParams = {
url: shareUrl,
text: title || claim.name,
hashtags: 'LBRY',
};
if (TWITTER_ACCOUNT) {
// $FlowFixMe
tweetIntentParams.via = TWITTER_ACCOUNT;
}
// Generate twitter web intent url
const tweetIntent = TWITTER_INTENT_API + new URLSearchParams(tweetIntentParams).toString();
function handleWebShareClick() {
if (navigator.share) {
navigator.share({
@ -115,7 +133,7 @@ function SocialShare(props: Props) {
iconSize={24}
icon={ICONS.TWITTER}
title={__('Share on Twitter')}
href={`https://twitter.com/intent/tweet?text=${encodedLbryURL}`}
href={tweetIntent}
/>
<Button
className="share"

View file

@ -46,3 +46,4 @@ export const CONFIRM_REMOVE_BTC_SWAP_ADDRESS = 'confirm_remove_btc_swap_address'
export const COLLECTION_ADD = 'collection_add';
export const COLLECTION_DELETE = 'collection_delete';
export const CONFIRM_REMOVE_CARD = 'CONFIRM_REMOVE_CARD';
export const CONFIRM_REMOVE_COMMENT = 'CONFIRM_REMOVE_COMMENT';

View file

@ -0,0 +1,11 @@
import { connect } from 'react-redux';
import { doHideModal } from 'redux/actions/app';
import ModalRemoveComment from './view';
import { doCommentAbandon } from 'redux/actions/comments';
const perform = (dispatch) => ({
closeModal: () => dispatch(doHideModal()),
deleteComment: (commentId, creatorChannelUrl) => dispatch(doCommentAbandon(commentId, creatorChannelUrl)),
});
export default connect(null, perform)(ModalRemoveComment);

View file

@ -0,0 +1,51 @@
// @flow
import React from 'react';
import { Modal } from 'modal/modal';
import Button from 'component/button';
import Card from 'component/common/card';
type Props = {
commentId: string, // sha256 digest identifying the comment
commentIsMine: boolean, // if this comment was signed by an owned channel
contentChannelPermanentUrl: any,
closeModal: () => void,
deleteComment: (string, ?string) => void,
supportAmount?: any,
};
function ModalRemoveComment(props: Props) {
const { commentId, commentIsMine, contentChannelPermanentUrl, closeModal, deleteComment, supportAmount } = props;
return (
<Modal isOpen contentLabel={__('Confirm Comment Deletion')} type="card" onAborted={closeModal}>
<Card
title={__('Remove Comment')}
body={
<React.Fragment>
<p>{__('Are you sure you want to remove this comment?')}</p>
{Boolean(supportAmount) && (
<p className="help error__text"> {__('This comment has a tip associated with it which cannot be reverted.')}</p>
)}
</React.Fragment>
}
actions={
<>
<div className="section__actions">
<Button
button="primary"
label={__('Remove')}
onClick={() => {
deleteComment(commentId, commentIsMine ? undefined : contentChannelPermanentUrl);
closeModal();
}}
/>
<Button button="link" label={__('Cancel')} onClick={closeModal} />
</div>
</>
}
/>
</Modal>
);
}
export default ModalRemoveComment;

View file

@ -30,6 +30,7 @@ const ModalPublish = lazyImport(() => import('modal/modalPublish' /* webpackChun
const ModalPublishPreview = lazyImport(() => import('modal/modalPublishPreview' /* webpackChunkName: "modalPublishPreview" */));
const ModalRemoveBtcSwapAddress = lazyImport(() => import('modal/modalRemoveBtcSwapAddress' /* webpackChunkName: "modalRemoveBtcSwapAddress" */));
const ModalRemoveCard = lazyImport(() => import('modal/modalRemoveCard' /* webpackChunkName: "modalRemoveCard" */));
const ModalRemoveComment = lazyImport(() => import('modal/modalRemoveComment' /* webpackChunkName: "modalRemoveComment" */));
const ModalRemoveFile = lazyImport(() => import('modal/modalRemoveFile' /* webpackChunkName: "modalRemoveFile" */));
const ModalRevokeClaim = lazyImport(() => import('modal/modalRevokeClaim' /* webpackChunkName: "modalRevokeClaim" */));
const ModalRewardCode = lazyImport(() => import('modal/modalRewardCode' /* webpackChunkName: "modalRewardCode" */));
@ -154,6 +155,8 @@ function ModalRouter(props: Props) {
return ModalDeleteCollection;
case MODALS.CONFIRM_REMOVE_CARD:
return ModalRemoveCard;
case MODALS.CONFIRM_REMOVE_COMMENT:
return ModalRemoveComment;
default:
return null;
}

View file

@ -5,7 +5,7 @@ import { buildURI, doResolveUris, batchActions, isURIValid, makeSelectClaimForUr
import { makeSelectSearchUris, selectSearchValue } from 'redux/selectors/search';
import handleFetchResponse from 'util/handle-fetch';
import { getSearchQueryString } from 'util/query-params';
import { SIMPLE_SITE } from 'config';
import { SIMPLE_SITE, SEARCH_SERVER_API } from 'config';
type Dispatch = (action: any) => any;
type GetState = () => { search: SearchState };
@ -19,7 +19,7 @@ type SearchOptions = {
};
let lighthouse = {
CONNECTION_STRING: 'https://lighthouse.lbry.com/search',
CONNECTION_STRING: SEARCH_SERVER_API,
search: (queryString: string) => fetch(`${lighthouse.CONNECTION_STRING}?${queryString}`).then(handleFetchResponse),
};

View file

@ -1,9 +1,10 @@
import * as ACTIONS from 'constants/action_types';
import { getAuthToken } from 'util/saved-passwords';
import { doNotificationList } from 'redux/actions/notifications';
import { SOCKETY_SERVER_API } from 'config';
const NOTIFICATION_WS_URL = 'wss://sockety.lbry.com/ws/internal?id=';
const COMMENT_WS_URL = 'wss://sockety.lbry.com/ws/commentron?id=';
const NOTIFICATION_WS_URL = `${SOCKETY_SERVER_API}/internal?id=`;
const COMMENT_WS_URL = `${SOCKETY_SERVER_API}/commentron?id=`;
let sockets = {};
let closingSockets = {};

View file

@ -71,6 +71,13 @@
display: flex;
}
.header__navigation-logo {
height: var(--height-button);
max-width: -webkit-fit-content;
max-width: -moz-fit-content;
max-width: fit-content;
}
.header__navigation-item {
height: var(--height-button);
display: flex;

View file

@ -51,10 +51,7 @@
padding: 0.3rem;
.icon {
stroke: var(--color-menu);
}
.comment__menu-icon--hovering {
stroke: var(--color-menu-icon);
}
&:focus,
@ -62,7 +59,7 @@
opacity: 1;
background-color: var(--color-button-alt-bg);
.icon {
stroke: var(--color-menu-hovering);
stroke: var(--color-menu-icon-active);
}
}
}

View file

@ -124,8 +124,7 @@
--color-menu-background: var(--color-header-background);
--color-menu-background--active: var(--color-card-background-highlighted);
--color-menu-icon: var(--color-navigation-link);
--color-menu: var(--color-gray-3);
--color-menu-hovering: var(--color-gray-6);
--color-menu-icon-active: var(--color-gray-6);
// Comments
--color-comment-highlighted: #fff2d9;

View file

@ -90,8 +90,7 @@
--color-menu-background: var(--color-header-background);
--color-menu-background--active: var(--color-gray-7);
--color-menu-icon: var(--color-gray-4);
--color-menu: var(--color-gray-5);
--color-menu-hovering: var(--color-gray-2);
--color-menu-icon-active: var(--color-gray-2);
// Comments
--color-comment-threadline: #434b54;

View file

@ -90,6 +90,7 @@
--color-menu-background: var(--color-header-background);
--color-menu-background--active: var(--color-gray-7);
--color-menu-icon: var(--color-gray-4);
--color-menu-icon-active: var(--color-gray-2);
// Comments
--color-comment-menu: var(--color-gray-5);

View file

@ -124,6 +124,7 @@
--color-menu-background: var(--color-header-background);
--color-menu-background--active: var(--color-card-background-highlighted);
--color-menu-icon: var(--color-navigation-link);
--color-menu-icon-active: var(--color-navigation-link);
// Comments
--color-comment-menu: var(--color-gray-3);