mirror of
https://github.com/LBRYFoundation/lbry-desktop.git
synced 2025-09-03 12:30:10 +00:00
Merge branch 'master' into protocol
This commit is contained in:
commit
d8e92f9d6a
24 changed files with 151 additions and 37 deletions
|
@ -12,6 +12,8 @@ LBRY_WEB_API=https://api.na-backend.odysee.com
|
||||||
LBRY_WEB_STREAMING_API=https://cdn.lbryplayer.xyz
|
LBRY_WEB_STREAMING_API=https://cdn.lbryplayer.xyz
|
||||||
LBRY_WEB_BUFFER_API=https://collector-service.api.lbry.tv/api/v1/events/video
|
LBRY_WEB_BUFFER_API=https://collector-service.api.lbry.tv/api/v1/events/video
|
||||||
COMMENT_SERVER_API=https://comments.odysee.com/api/v2
|
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/
|
THUMBNAIL_CDN_URL=https://image-processor.vanwanet.com/optimize/
|
||||||
WELCOME_VERSION=1.0
|
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_DESCRIPTION=Meet LBRY, an open, free, and community-controlled content wonderland.
|
||||||
SITE_HELP_EMAIL=help@lbry.com
|
SITE_HELP_EMAIL=help@lbry.com
|
||||||
LOGO_TITLE=lbry.tv
|
LOGO_TITLE=lbry.tv
|
||||||
|
## Social media
|
||||||
|
TWITTER_ACCOUNT=LBRYcom
|
||||||
|
|
||||||
## IMAGE ASSETS
|
## IMAGE ASSETS
|
||||||
YRBL_HAPPY_IMG_URL=https://cdn.lbryplayer.xyz/api/v3/streams/free/yrbl-happy/7aa50a7e5adaf48691935d55e45d697547392929/839d9a
|
YRBL_HAPPY_IMG_URL=https://cdn.lbryplayer.xyz/api/v3/streams/free/yrbl-happy/7aa50a7e5adaf48691935d55e45d697547392929/839d9a
|
||||||
|
|
|
@ -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))
|
- 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))
|
- 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))
|
- 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
|
### Changed
|
||||||
- Use Canonical Url for copy link ([#6500](https://github.com/lbryio/lbry-desktop/pull/6500))
|
- 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))
|
- 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))
|
- 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))
|
- 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
|
### Fixed
|
||||||
- App now supports '#' and ':' for claimId separator ([#6496](https://github.com/lbryio/lbry-desktop/pull/6496))
|
- App now supports '#' and ':' for claimId separator ([#6496](https://github.com/lbryio/lbry-desktop/pull/6496))
|
||||||
|
|
|
@ -13,7 +13,9 @@ const config = {
|
||||||
LBRY_API_URL: process.env.LBRY_API_URL, //api.lbry.com',
|
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_STREAMING_API: process.env.LBRY_WEB_STREAMING_API, //cdn.lbryplayer.xyz',
|
||||||
LBRY_WEB_BUFFER_API: process.env.LBRY_WEB_BUFFER_API,
|
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,
|
COMMENT_SERVER_API: process.env.COMMENT_SERVER_API,
|
||||||
|
SOCKETY_SERVER_API: process.env.SOCKETY_SERVER_API,
|
||||||
WELCOME_VERSION: process.env.WELCOME_VERSION,
|
WELCOME_VERSION: process.env.WELCOME_VERSION,
|
||||||
DOMAIN: process.env.DOMAIN,
|
DOMAIN: process.env.DOMAIN,
|
||||||
SHARE_DOMAIN_URL: process.env.SHARE_DOMAIN_URL,
|
SHARE_DOMAIN_URL: process.env.SHARE_DOMAIN_URL,
|
||||||
|
@ -23,6 +25,8 @@ const config = {
|
||||||
SITE_NAME: process.env.SITE_NAME,
|
SITE_NAME: process.env.SITE_NAME,
|
||||||
SITE_DESCRIPTION: process.env.SITE_DESCRIPTION,
|
SITE_DESCRIPTION: process.env.SITE_DESCRIPTION,
|
||||||
SITE_HELP_EMAIL: process.env.SITE_HELP_EMAIL,
|
SITE_HELP_EMAIL: process.env.SITE_HELP_EMAIL,
|
||||||
|
// SOCIAL MEDIA
|
||||||
|
TWITTER_ACCOUNT: process.env.TWITTER_ACCOUNT,
|
||||||
// LOGO
|
// LOGO
|
||||||
LOGO_TITLE: process.env.LOGO_TITLE,
|
LOGO_TITLE: process.env.LOGO_TITLE,
|
||||||
FAVICON: process.env.FAVICON,
|
FAVICON: process.env.FAVICON,
|
||||||
|
@ -69,7 +73,7 @@ const config = {
|
||||||
BRANDED_SITE: process.env.BRANDED_SITE,
|
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_DEV = `http://localhost:${config.WEBPACK_WEB_PORT}`;
|
||||||
|
config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`;
|
||||||
|
|
||||||
module.exports = config;
|
module.exports = config;
|
||||||
|
|
|
@ -2057,17 +2057,14 @@
|
||||||
"Only select creators can receive tips at this time": "Only select creators can receive tips at this time",
|
"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",
|
"The payment will be made from your saved card": "The payment will be made from your saved card",
|
||||||
"Commenting...": "Commenting...",
|
"Commenting...": "Commenting...",
|
||||||
"Show %count% replies": "Show %count% replies",
|
|
||||||
"Show reply": "Show reply",
|
|
||||||
"added to": "added to",
|
"added to": "added to",
|
||||||
"removed from": "removed from",
|
"removed from": "removed from",
|
||||||
"Skip Navigation": "Skip Navigation",
|
"Skip Navigation": "Skip Navigation",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Reset to original (previous) publish date": "Reset to original (previous) publish date",
|
"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...",
|
"Search for something...": "Search for something...",
|
||||||
"Open in Desktop": "Open in Desktop",
|
"Open in Desktop": "Open in Desktop",
|
||||||
|
"Show %count% replies": "Show %count% replies",
|
||||||
|
"Show reply": "Show reply",
|
||||||
"--end--": "--end--"
|
"--end--": "--end--"
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ function ClaimPreviewTile(props: Props) {
|
||||||
const signingChannel = claim && claim.signing_channel;
|
const signingChannel = claim && claim.signing_channel;
|
||||||
const isChannel = claim && claim.value_type === 'channel';
|
const isChannel = claim && claim.value_type === 'channel';
|
||||||
const channelUri = !isChannel ? signingChannel && signingChannel.permanent_url : claim && claim.permanent_url;
|
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
|
// Aria-label value for claim preview
|
||||||
let ariaLabelData = isChannel ? title : formatClaimPreviewTitle(title, channelTitle, date, mediaDuration);
|
let ariaLabelData = isChannel ? title : formatClaimPreviewTitle(title, channelTitle, date, mediaDuration);
|
||||||
|
|
|
@ -270,6 +270,7 @@ function Comment(props: Props) {
|
||||||
authorUri={authorUri}
|
authorUri={authorUri}
|
||||||
commentIsMine={commentIsMine}
|
commentIsMine={commentIsMine}
|
||||||
handleEditComment={handleEditComment}
|
handleEditComment={handleEditComment}
|
||||||
|
supportAmount={supportAmount}
|
||||||
/>
|
/>
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { makeSelectChannelPermUrlForClaimUri, makeSelectClaimIsMine, makeSelectClaimForUri } from 'lbry-redux';
|
import { makeSelectChannelPermUrlForClaimUri, makeSelectClaimIsMine, makeSelectClaimForUri } from 'lbry-redux';
|
||||||
import {
|
import {
|
||||||
doCommentAbandon,
|
|
||||||
doCommentPin,
|
doCommentPin,
|
||||||
doCommentModBlock,
|
doCommentModBlock,
|
||||||
doCommentModBlockAsAdmin,
|
doCommentModBlockAsAdmin,
|
||||||
|
@ -10,6 +9,7 @@ import {
|
||||||
} from 'redux/actions/comments';
|
} from 'redux/actions/comments';
|
||||||
import { doChannelMute } from 'redux/actions/blocked';
|
import { doChannelMute } from 'redux/actions/blocked';
|
||||||
// import { doSetActiveChannel } from 'redux/actions/app';
|
// import { doSetActiveChannel } from 'redux/actions/app';
|
||||||
|
import { doOpenModal } from 'redux/actions/app';
|
||||||
import { doSetPlayingUri } from 'redux/actions/content';
|
import { doSetPlayingUri } from 'redux/actions/content';
|
||||||
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
||||||
import { selectPlayingUri } from 'redux/selectors/content';
|
import { selectPlayingUri } from 'redux/selectors/content';
|
||||||
|
@ -26,8 +26,8 @@ const select = (state, props) => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
|
openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
|
||||||
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
|
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
|
||||||
deleteComment: (commentId, creatorChannelUrl) => dispatch(doCommentAbandon(commentId, creatorChannelUrl)),
|
|
||||||
muteChannel: (channelUri) => dispatch(doChannelMute(channelUri)),
|
muteChannel: (channelUri) => dispatch(doChannelMute(channelUri)),
|
||||||
pinComment: (commentId, claimId, remove) => dispatch(doCommentPin(commentId, claimId, remove)),
|
pinComment: (commentId, claimId, remove) => dispatch(doCommentPin(commentId, claimId, remove)),
|
||||||
// setActiveChannel: channelId => dispatch(doSetActiveChannel(channelId)),
|
// setActiveChannel: channelId => dispatch(doSetActiveChannel(channelId)),
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
|
import * as MODALS from 'constants/modal_types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { MenuList, MenuItem } from '@reach/menu-button';
|
import { MenuList, MenuItem } from '@reach/menu-button';
|
||||||
import ChannelThumbnail from 'component/channelThumbnail';
|
import ChannelThumbnail from 'component/channelThumbnail';
|
||||||
|
@ -12,7 +13,6 @@ type Props = {
|
||||||
authorUri: string, // full LBRY Channel URI: lbry://@channel#123...
|
authorUri: string, // full LBRY Channel URI: lbry://@channel#123...
|
||||||
commentId: string, // sha256 digest identifying the comment
|
commentId: string, // sha256 digest identifying the comment
|
||||||
commentIsMine: boolean, // if this comment was signed by an owned channel
|
commentIsMine: boolean, // if this comment was signed by an owned channel
|
||||||
deleteComment: (string, ?string) => void,
|
|
||||||
isPinned: boolean,
|
isPinned: boolean,
|
||||||
pinComment: (string, string, boolean) => Promise<any>,
|
pinComment: (string, string, boolean) => Promise<any>,
|
||||||
muteChannel: (string) => void,
|
muteChannel: (string) => void,
|
||||||
|
@ -28,6 +28,8 @@ type Props = {
|
||||||
disableEdit?: boolean,
|
disableEdit?: boolean,
|
||||||
disableRemove?: boolean,
|
disableRemove?: boolean,
|
||||||
moderationDelegatorsById: { [string]: { global: boolean, delegators: { name: string, claimId: string } } },
|
moderationDelegatorsById: { [string]: { global: boolean, delegators: { name: string, claimId: string } } },
|
||||||
|
openModal: (id: string, {}) => void,
|
||||||
|
supportAmount?: any,
|
||||||
};
|
};
|
||||||
|
|
||||||
function CommentMenuList(props: Props) {
|
function CommentMenuList(props: Props) {
|
||||||
|
@ -36,7 +38,6 @@ function CommentMenuList(props: Props) {
|
||||||
authorUri,
|
authorUri,
|
||||||
commentIsMine,
|
commentIsMine,
|
||||||
commentId,
|
commentId,
|
||||||
deleteComment,
|
|
||||||
muteChannel,
|
muteChannel,
|
||||||
pinComment,
|
pinComment,
|
||||||
clearPlayingUri,
|
clearPlayingUri,
|
||||||
|
@ -53,6 +54,8 @@ function CommentMenuList(props: Props) {
|
||||||
disableEdit,
|
disableEdit,
|
||||||
disableRemove,
|
disableRemove,
|
||||||
moderationDelegatorsById,
|
moderationDelegatorsById,
|
||||||
|
openModal,
|
||||||
|
supportAmount,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const contentChannelClaim = !claim
|
const contentChannelClaim = !claim
|
||||||
|
@ -80,7 +83,7 @@ function CommentMenuList(props: Props) {
|
||||||
if (playingUri && playingUri.source === 'comment') {
|
if (playingUri && playingUri.source === 'comment') {
|
||||||
clearPlayingUri();
|
clearPlayingUri();
|
||||||
}
|
}
|
||||||
deleteComment(commentId, commentIsMine ? undefined : contentChannelPermanentUrl);
|
openModal(MODALS.CONFIRM_REMOVE_COMMENT, { commentId, commentIsMine, contentChannelPermanentUrl, supportAmount });
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCommentBlock() {
|
function handleCommentBlock() {
|
||||||
|
|
|
@ -18,11 +18,16 @@ export default function LivestreamLink(props: Props) {
|
||||||
const [livestreamClaim, setLivestreamClaim] = React.useState(false);
|
const [livestreamClaim, setLivestreamClaim] = React.useState(false);
|
||||||
const [isLivestreaming, setIsLivestreaming] = React.useState(false);
|
const [isLivestreaming, setIsLivestreaming] = React.useState(false);
|
||||||
const livestreamChannelId = (channelClaim && channelClaim.claim_id) || ''; // TODO: fail in a safer way, probably
|
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(() => {
|
React.useEffect(() => {
|
||||||
if (livestreamChannelId) {
|
// Don't search empty channels
|
||||||
|
if (livestreamChannelId && !isChannelEmpty) {
|
||||||
Lbry.claim_search({
|
Lbry.claim_search({
|
||||||
channel_ids: [livestreamChannelId],
|
channel_ids: [livestreamChannelId],
|
||||||
|
page: 1,
|
||||||
|
page_size: 1,
|
||||||
|
no_totals: true,
|
||||||
has_no_source: true,
|
has_no_source: true,
|
||||||
claim_type: ['stream'],
|
claim_type: ['stream'],
|
||||||
order_by: CS.ORDER_BY_NEW_VALUE,
|
order_by: CS.ORDER_BY_NEW_VALUE,
|
||||||
|
@ -35,7 +40,7 @@ export default function LivestreamLink(props: Props) {
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
}, [livestreamChannelId]);
|
}, [livestreamChannelId, isChannelEmpty]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
function fetchIsStreaming() {
|
function fetchIsStreaming() {
|
||||||
|
@ -53,17 +58,23 @@ export default function LivestreamLink(props: Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let interval;
|
let interval;
|
||||||
if (livestreamChannelId) {
|
// Only call livestream api if channel has livestream claims
|
||||||
|
if (livestreamChannelId && livestreamClaim) {
|
||||||
if (!interval) fetchIsStreaming();
|
if (!interval) fetchIsStreaming();
|
||||||
interval = setInterval(fetchIsStreaming, 10 * 1000);
|
interval = setInterval(fetchIsStreaming, 10 * 1000);
|
||||||
}
|
}
|
||||||
|
// Prevent any more api calls on update
|
||||||
|
if (!livestreamChannelId || !livestreamClaim) {
|
||||||
|
if (interval) {
|
||||||
|
clearInterval(interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
return () => {
|
return () => {
|
||||||
if (interval) {
|
if (interval) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [livestreamChannelId]);
|
}, [livestreamChannelId, livestreamClaim]);
|
||||||
|
|
||||||
if (!livestreamClaim || !isLivestreaming) {
|
if (!livestreamClaim || !isLivestreaming) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -26,12 +26,12 @@ export default function Logo(props: Props) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (type === 'small' || (isMobile && type !== 'embed')) {
|
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') {
|
} else if (type === 'embed') {
|
||||||
if (LOGO_TEXT_LIGHT) {
|
if (LOGO_TEXT_LIGHT) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<img src={LOGO_TEXT_LIGHT} />
|
<img className={'header__navigation-logo'} src={LOGO_TEXT_LIGHT} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -41,7 +41,10 @@ export default function Logo(props: Props) {
|
||||||
if (LOGO_TEXT_LIGHT && LOGO_TEXT_DARK) {
|
if (LOGO_TEXT_LIGHT && LOGO_TEXT_DARK) {
|
||||||
return (
|
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 {
|
} else {
|
||||||
|
|
|
@ -193,7 +193,7 @@ export default function Notification(props: Props) {
|
||||||
|
|
||||||
<div className="notification__menu">
|
<div className="notification__menu">
|
||||||
<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} />
|
<Icon size={18} icon={ICONS.MORE_VERTICAL} />
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
<MenuList className="menu__list">
|
<MenuList className="menu__list">
|
||||||
|
|
|
@ -9,12 +9,15 @@ import { useIsMobile } from 'effects/use-screensize';
|
||||||
import { FormField } from 'component/common/form';
|
import { FormField } from 'component/common/form';
|
||||||
import { hmsToSeconds, secondsToHms } from 'util/time';
|
import { hmsToSeconds, secondsToHms } from 'util/time';
|
||||||
import { generateLbryContentUrl, generateLbryWebUrl, generateEncodedLbryURL, generateShareUrl } from 'util/url';
|
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 SHARE_DOMAIN = SHARE_DOMAIN_URL || URL;
|
||||||
const IOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
|
const IOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
|
||||||
const SUPPORTS_SHARE_API = typeof navigator.share !== 'undefined';
|
const SUPPORTS_SHARE_API = typeof navigator.share !== 'undefined';
|
||||||
|
|
||||||
|
// Twitter share
|
||||||
|
const TWITTER_INTENT_API = 'https://twitter.com/intent/tweet?';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
claim: StreamClaim,
|
claim: StreamClaim,
|
||||||
title: ?string,
|
title: ?string,
|
||||||
|
@ -68,6 +71,21 @@ function SocialShare(props: Props) {
|
||||||
);
|
);
|
||||||
const downloadUrl = `${generateDownloadUrl(name, claimId)}`;
|
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() {
|
function handleWebShareClick() {
|
||||||
if (navigator.share) {
|
if (navigator.share) {
|
||||||
navigator.share({
|
navigator.share({
|
||||||
|
@ -115,7 +133,7 @@ function SocialShare(props: Props) {
|
||||||
iconSize={24}
|
iconSize={24}
|
||||||
icon={ICONS.TWITTER}
|
icon={ICONS.TWITTER}
|
||||||
title={__('Share on Twitter')}
|
title={__('Share on Twitter')}
|
||||||
href={`https://twitter.com/intent/tweet?text=${encodedLbryURL}`}
|
href={tweetIntent}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className="share"
|
className="share"
|
||||||
|
|
|
@ -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_ADD = 'collection_add';
|
||||||
export const COLLECTION_DELETE = 'collection_delete';
|
export const COLLECTION_DELETE = 'collection_delete';
|
||||||
export const CONFIRM_REMOVE_CARD = 'CONFIRM_REMOVE_CARD';
|
export const CONFIRM_REMOVE_CARD = 'CONFIRM_REMOVE_CARD';
|
||||||
|
export const CONFIRM_REMOVE_COMMENT = 'CONFIRM_REMOVE_COMMENT';
|
||||||
|
|
11
ui/modal/modalRemoveComment/index.js
Normal file
11
ui/modal/modalRemoveComment/index.js
Normal 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);
|
51
ui/modal/modalRemoveComment/view.jsx
Normal file
51
ui/modal/modalRemoveComment/view.jsx
Normal 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;
|
|
@ -30,6 +30,7 @@ const ModalPublish = lazyImport(() => import('modal/modalPublish' /* webpackChun
|
||||||
const ModalPublishPreview = lazyImport(() => import('modal/modalPublishPreview' /* webpackChunkName: "modalPublishPreview" */));
|
const ModalPublishPreview = lazyImport(() => import('modal/modalPublishPreview' /* webpackChunkName: "modalPublishPreview" */));
|
||||||
const ModalRemoveBtcSwapAddress = lazyImport(() => import('modal/modalRemoveBtcSwapAddress' /* webpackChunkName: "modalRemoveBtcSwapAddress" */));
|
const ModalRemoveBtcSwapAddress = lazyImport(() => import('modal/modalRemoveBtcSwapAddress' /* webpackChunkName: "modalRemoveBtcSwapAddress" */));
|
||||||
const ModalRemoveCard = lazyImport(() => import('modal/modalRemoveCard' /* webpackChunkName: "modalRemoveCard" */));
|
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 ModalRemoveFile = lazyImport(() => import('modal/modalRemoveFile' /* webpackChunkName: "modalRemoveFile" */));
|
||||||
const ModalRevokeClaim = lazyImport(() => import('modal/modalRevokeClaim' /* webpackChunkName: "modalRevokeClaim" */));
|
const ModalRevokeClaim = lazyImport(() => import('modal/modalRevokeClaim' /* webpackChunkName: "modalRevokeClaim" */));
|
||||||
const ModalRewardCode = lazyImport(() => import('modal/modalRewardCode' /* webpackChunkName: "modalRewardCode" */));
|
const ModalRewardCode = lazyImport(() => import('modal/modalRewardCode' /* webpackChunkName: "modalRewardCode" */));
|
||||||
|
@ -154,6 +155,8 @@ function ModalRouter(props: Props) {
|
||||||
return ModalDeleteCollection;
|
return ModalDeleteCollection;
|
||||||
case MODALS.CONFIRM_REMOVE_CARD:
|
case MODALS.CONFIRM_REMOVE_CARD:
|
||||||
return ModalRemoveCard;
|
return ModalRemoveCard;
|
||||||
|
case MODALS.CONFIRM_REMOVE_COMMENT:
|
||||||
|
return ModalRemoveComment;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { buildURI, doResolveUris, batchActions, isURIValid, makeSelectClaimForUr
|
||||||
import { makeSelectSearchUris, selectSearchValue } from 'redux/selectors/search';
|
import { makeSelectSearchUris, selectSearchValue } from 'redux/selectors/search';
|
||||||
import handleFetchResponse from 'util/handle-fetch';
|
import handleFetchResponse from 'util/handle-fetch';
|
||||||
import { getSearchQueryString } from 'util/query-params';
|
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 Dispatch = (action: any) => any;
|
||||||
type GetState = () => { search: SearchState };
|
type GetState = () => { search: SearchState };
|
||||||
|
@ -19,7 +19,7 @@ type SearchOptions = {
|
||||||
};
|
};
|
||||||
|
|
||||||
let lighthouse = {
|
let lighthouse = {
|
||||||
CONNECTION_STRING: 'https://lighthouse.lbry.com/search',
|
CONNECTION_STRING: SEARCH_SERVER_API,
|
||||||
search: (queryString: string) => fetch(`${lighthouse.CONNECTION_STRING}?${queryString}`).then(handleFetchResponse),
|
search: (queryString: string) => fetch(`${lighthouse.CONNECTION_STRING}?${queryString}`).then(handleFetchResponse),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import { getAuthToken } from 'util/saved-passwords';
|
import { getAuthToken } from 'util/saved-passwords';
|
||||||
import { doNotificationList } from 'redux/actions/notifications';
|
import { doNotificationList } from 'redux/actions/notifications';
|
||||||
|
import { SOCKETY_SERVER_API } from 'config';
|
||||||
|
|
||||||
const NOTIFICATION_WS_URL = 'wss://sockety.lbry.com/ws/internal?id=';
|
const NOTIFICATION_WS_URL = `${SOCKETY_SERVER_API}/internal?id=`;
|
||||||
const COMMENT_WS_URL = 'wss://sockety.lbry.com/ws/commentron?id=';
|
const COMMENT_WS_URL = `${SOCKETY_SERVER_API}/commentron?id=`;
|
||||||
|
|
||||||
let sockets = {};
|
let sockets = {};
|
||||||
let closingSockets = {};
|
let closingSockets = {};
|
||||||
|
|
|
@ -71,6 +71,13 @@
|
||||||
display: flex;
|
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 {
|
.header__navigation-item {
|
||||||
height: var(--height-button);
|
height: var(--height-button);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -51,10 +51,7 @@
|
||||||
padding: 0.3rem;
|
padding: 0.3rem;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
stroke: var(--color-menu);
|
stroke: var(--color-menu-icon);
|
||||||
}
|
|
||||||
|
|
||||||
.comment__menu-icon--hovering {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus,
|
&:focus,
|
||||||
|
@ -62,7 +59,7 @@
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
background-color: var(--color-button-alt-bg);
|
background-color: var(--color-button-alt-bg);
|
||||||
.icon {
|
.icon {
|
||||||
stroke: var(--color-menu-hovering);
|
stroke: var(--color-menu-icon-active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,8 +124,7 @@
|
||||||
--color-menu-background: var(--color-header-background);
|
--color-menu-background: var(--color-header-background);
|
||||||
--color-menu-background--active: var(--color-card-background-highlighted);
|
--color-menu-background--active: var(--color-card-background-highlighted);
|
||||||
--color-menu-icon: var(--color-navigation-link);
|
--color-menu-icon: var(--color-navigation-link);
|
||||||
--color-menu: var(--color-gray-3);
|
--color-menu-icon-active: var(--color-gray-6);
|
||||||
--color-menu-hovering: var(--color-gray-6);
|
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
--color-comment-highlighted: #fff2d9;
|
--color-comment-highlighted: #fff2d9;
|
||||||
|
|
|
@ -90,8 +90,7 @@
|
||||||
--color-menu-background: var(--color-header-background);
|
--color-menu-background: var(--color-header-background);
|
||||||
--color-menu-background--active: var(--color-gray-7);
|
--color-menu-background--active: var(--color-gray-7);
|
||||||
--color-menu-icon: var(--color-gray-4);
|
--color-menu-icon: var(--color-gray-4);
|
||||||
--color-menu: var(--color-gray-5);
|
--color-menu-icon-active: var(--color-gray-2);
|
||||||
--color-menu-hovering: var(--color-gray-2);
|
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
--color-comment-threadline: #434b54;
|
--color-comment-threadline: #434b54;
|
||||||
|
|
|
@ -90,6 +90,7 @@
|
||||||
--color-menu-background: var(--color-header-background);
|
--color-menu-background: var(--color-header-background);
|
||||||
--color-menu-background--active: var(--color-gray-7);
|
--color-menu-background--active: var(--color-gray-7);
|
||||||
--color-menu-icon: var(--color-gray-4);
|
--color-menu-icon: var(--color-gray-4);
|
||||||
|
--color-menu-icon-active: var(--color-gray-2);
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
--color-comment-menu: var(--color-gray-5);
|
--color-comment-menu: var(--color-gray-5);
|
||||||
|
|
|
@ -124,6 +124,7 @@
|
||||||
--color-menu-background: var(--color-header-background);
|
--color-menu-background: var(--color-header-background);
|
||||||
--color-menu-background--active: var(--color-card-background-highlighted);
|
--color-menu-background--active: var(--color-card-background-highlighted);
|
||||||
--color-menu-icon: var(--color-navigation-link);
|
--color-menu-icon: var(--color-navigation-link);
|
||||||
|
--color-menu-icon-active: var(--color-navigation-link);
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
--color-comment-menu: var(--color-gray-3);
|
--color-comment-menu: var(--color-gray-3);
|
||||||
|
|
Loading…
Add table
Reference in a new issue