diff --git a/ui/component/channelMentionSuggestions/view.jsx b/ui/component/channelMentionSuggestions/view.jsx
index d3fefd1f9..bb04de507 100644
--- a/ui/component/channelMentionSuggestions/view.jsx
+++ b/ui/component/channelMentionSuggestions/view.jsx
@@ -19,11 +19,9 @@ type Props = {
mentionTerm: string,
noTopSuggestion?: boolean,
showMature: boolean,
- isLivestream: boolean,
creatorUri: string,
commentorUris: Array,
subscriptionUris: Array,
- unresolvedCommentors: Array,
unresolvedSubscriptions: Array,
canonicalCreator: string,
canonicalCommentors: Array,
@@ -34,10 +32,8 @@ type Props = {
export default function ChannelMentionSuggestions(props: Props) {
const {
- unresolvedCommentors,
unresolvedSubscriptions,
canonicalCreator,
- isLivestream,
creatorUri,
inputRef,
showMature,
@@ -184,11 +180,6 @@ export default function ChannelMentionSuggestions(props: Props) {
}
}, [doResolveUris, stringifiedResults]);
- // Only resolve commentors on Livestreams when actually mentioning/looking for it
- React.useEffect(() => {
- if (isLivestream && unresolvedCommentors && mentionTerm) doResolveUris(unresolvedCommentors);
- }, [doResolveUris, isLivestream, mentionTerm, unresolvedCommentors]);
-
// Only resolve the subscriptions that match the mention term, instead of all
React.useEffect(() => {
if (isTyping) return;
diff --git a/ui/component/claimPreview/index.js b/ui/component/claimPreview/index.js
index 5e5cdd378..b63696f69 100644
--- a/ui/component/claimPreview/index.js
+++ b/ui/component/claimPreview/index.js
@@ -7,7 +7,6 @@ import {
makeSelectClaimIsNsfw,
makeSelectReflectingClaimForUri,
makeSelectClaimWasPurchased,
- makeSelectClaimIsStreamPlaceholder,
makeSelectTitleForUri,
makeSelectDateForUri,
} from 'redux/selectors/claims';
@@ -23,7 +22,6 @@ import { doCollectionEdit } from 'redux/actions/collections';
import { doFileGet } from 'redux/actions/file';
import { selectMutedChannels, makeSelectChannelIsMuted } from 'redux/selectors/blocked';
import { selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc';
-import { makeSelectIsActiveLivestream } from 'redux/selectors/livestream';
import { selectShowMatureContent } from 'redux/selectors/settings';
import { makeSelectHasVisitedUri } from 'redux/selectors/content';
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
@@ -58,8 +56,6 @@ const select = (state, props) => {
isSubscribed: props.uri && makeSelectIsSubscribed(props.uri, true)(state),
streamingUrl: props.uri && makeSelectStreamingUrlForUri(props.uri)(state),
wasPurchased: props.uri && makeSelectClaimWasPurchased(props.uri)(state),
- isLivestream: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
- isLivestreamActive: makeSelectIsActiveLivestream(props.uri)(state),
isCollectionMine: makeSelectCollectionIsMine(props.collectionId)(state),
collectionUris: makeSelectUrlsForCollectionId(props.collectionId)(state),
collectionIndex: makeSelectIndexForUrlInCollection(props.uri, props.collectionId)(state),
diff --git a/ui/component/claimPreview/view.jsx b/ui/component/claimPreview/view.jsx
index 38ce66c9c..f5735efcd 100644
--- a/ui/component/claimPreview/view.jsx
+++ b/ui/component/claimPreview/view.jsx
@@ -10,7 +10,6 @@ import { formatLbryUrlForWeb } from 'util/url';
import { formatClaimPreviewTitle } from 'util/formatAriaLabel';
import FileThumbnail from 'component/fileThumbnail';
import UriIndicator from 'component/uriIndicator';
-import PreviewOverlayProperties from 'component/previewOverlayProperties';
import ClaimTags from 'component/claimTags';
import SubscribeButton from 'component/subscribeButton';
import ChannelThumbnail from 'component/channelThumbnail';
@@ -26,7 +25,6 @@ import ClaimMenuList from 'component/claimMenuList';
import ClaimPreviewLoading from './claim-preview-loading';
import ClaimPreviewHidden from './claim-preview-no-mature';
import ClaimPreviewNoContent from './claim-preview-no-content';
-import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
import Button from 'component/button';
import * as ICONS from 'constants/icons';
@@ -78,8 +76,6 @@ type Props = {
hideRepostLabel?: boolean,
repostUrl?: string,
hideMenu?: boolean,
- isLivestream?: boolean,
- isLivestreamActive: boolean,
collectionId?: string,
editCollection: (string, CollectionEditParams) => void,
isCollectionMine: boolean,
@@ -144,8 +140,6 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => {
renderActions,
hideMenu = false,
// repostUrl,
- isLivestream, // need both? CHECK
- isLivestreamActive,
collectionId,
collectionIndex,
editCollection,
@@ -296,7 +290,7 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => {
}
}, [isValid, uri, isResolvingUri, shouldFetch, resolveUri]);
- if ((shouldHide && !showNullPlaceholder) || (isLivestream && !ENABLE_NO_SOURCE_CLAIMS)) {
+ if (shouldHide && !showNullPlaceholder) {
return null;
}
@@ -329,11 +323,6 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => {
return null;
}
- let liveProperty = null;
- if (isLivestreamActive === true) {
- liveProperty = (claim) => <>LIVE>;
- }
-
return (
((props: Props, ref: any) => {
'claim-preview__wrapper--channel': isChannelUri && type !== 'inline',
'claim-preview__wrapper--inline': type === 'inline',
'claim-preview__wrapper--small': type === 'small',
- 'claim-preview__live': isLivestreamActive,
'claim-preview__active': active,
})}
>
@@ -380,11 +368,6 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => {
)}
{/* @endif */}
- {(!isLivestream || isLivestreamActive) && (
-
- )}
) : (
diff --git a/ui/component/claimPreviewSubtitle/index.js b/ui/component/claimPreviewSubtitle/index.js
index cf5f1826d..12d608361 100644
--- a/ui/component/claimPreviewSubtitle/index.js
+++ b/ui/component/claimPreviewSubtitle/index.js
@@ -1,10 +1,6 @@
import * as PAGES from 'constants/pages';
import { connect } from 'react-redux';
-import {
- makeSelectClaimForUri,
- makeSelectClaimIsPending,
- makeSelectClaimIsStreamPlaceholder,
-} from 'redux/selectors/claims';
+import { makeSelectClaimForUri, makeSelectClaimIsPending } from 'redux/selectors/claims';
import { doClearPublish, doPrepareEdit } from 'redux/actions/publish';
import { push } from 'connected-react-router';
import ClaimPreviewSubtitle from './view';
@@ -12,7 +8,6 @@ import ClaimPreviewSubtitle from './view';
const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state),
pending: makeSelectClaimIsPending(props.uri)(state),
- isLivestream: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
});
const perform = (dispatch) => ({
diff --git a/ui/component/claimPreviewSubtitle/view.jsx b/ui/component/claimPreviewSubtitle/view.jsx
index 507abf2a7..e2d0afb0d 100644
--- a/ui/component/claimPreviewSubtitle/view.jsx
+++ b/ui/component/claimPreviewSubtitle/view.jsx
@@ -1,5 +1,4 @@
// @flow
-import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
import React from 'react';
import UriIndicator from 'component/uriIndicator';
import DateTime from 'component/dateTime';
@@ -13,12 +12,11 @@ type Props = {
pending?: boolean,
type: string,
beginPublish: (?string) => void,
- isLivestream: boolean,
};
// previews used in channel overview and homepage (and other places?)
function ClaimPreviewSubtitle(props: Props) {
- const { pending, uri, claim, type, beginPublish, isLivestream } = props;
+ const { pending, uri, claim, type, beginPublish } = props;
const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0;
let isChannel;
@@ -38,15 +36,12 @@ function ClaimPreviewSubtitle(props: Props) {
type !== 'inline' &&
`${claimsInChannel} ${claimsInChannel === 1 ? __('upload') : __('uploads')}`}
- {!isChannel &&
- (isLivestream && ENABLE_NO_SOURCE_CLAIMS ? (
- __('Livestream')
- ) : (
- <>
-
-
- >
- ))}
+ {!isChannel && (
+ <>
+
+
+ >
+ )}
>
)}
diff --git a/ui/component/claimPreviewTile/index.js b/ui/component/claimPreviewTile/index.js
index 6209a71ae..b3be8f36d 100644
--- a/ui/component/claimPreviewTile/index.js
+++ b/ui/component/claimPreviewTile/index.js
@@ -6,14 +6,12 @@ import {
makeSelectTitleForUri,
makeSelectChannelForClaimUri,
makeSelectClaimIsNsfw,
- makeSelectClaimIsStreamPlaceholder,
makeSelectDateForUri,
} from 'redux/selectors/claims';
import { doFileGet } from 'redux/actions/file';
import { doResolveUri } from 'redux/actions/claims';
import { selectMutedChannels } from 'redux/selectors/blocked';
import { makeSelectViewCountForUri, selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc';
-import { makeSelectIsActiveLivestream } from 'redux/selectors/livestream';
import { selectShowMatureContent } from 'redux/selectors/settings';
import ClaimPreviewTile from './view';
import formatMediaDuration from 'util/formatMediaDuration';
@@ -36,8 +34,6 @@ const select = (state, props) => {
blockedChannelUris: selectMutedChannels(state),
showMature: selectShowMatureContent(state),
isMature: makeSelectClaimIsNsfw(props.uri)(state),
- isLivestream: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
- isLivestreamActive: makeSelectIsActiveLivestream(props.uri)(state),
viewCount: makeSelectViewCountForUri(props.uri)(state),
};
};
diff --git a/ui/component/claimPreviewTile/view.jsx b/ui/component/claimPreviewTile/view.jsx
index 8c562b269..1c921f64e 100644
--- a/ui/component/claimPreviewTile/view.jsx
+++ b/ui/component/claimPreviewTile/view.jsx
@@ -49,10 +49,7 @@ type Props = {
showHiddenByUser?: boolean,
properties?: (Claim) => void,
collectionId?: string,
- showNoSourceClaims?: boolean,
- isLivestream: boolean,
viewCount: string,
- isLivestreamActive: boolean,
};
// preview image cards used in related video functionality, channel overview page and homepage
@@ -76,9 +73,6 @@ function ClaimPreviewTile(props: Props) {
showMature,
showHiddenByUser,
properties,
- showNoSourceClaims,
- isLivestream,
- isLivestreamActive,
collectionId,
mediaDuration,
viewCount,
@@ -175,13 +169,13 @@ function ClaimPreviewTile(props: Props) {
shouldHide = blockedChannelUris.some((blockedUri) => isURIEqual(blockedUri, signingChannel.permanent_url));
}
- if (shouldHide || (isLivestream && !showNoSourceClaims)) {
+ if (shouldHide) {
return null;
}
const isChannelPage = window.location.pathname.startsWith('/@');
- const shouldShowViewCount = !(!viewCount || (claim && claim.repost_url) || isLivestream || !isChannelPage);
+ const shouldShowViewCount = !(!viewCount || (claim && claim.repost_url) || !isChannelPage);
if (placeholder || (!claim && isResolvingUri)) {
return (
@@ -202,16 +196,12 @@ function ClaimPreviewTile(props: Props) {
}
let liveProperty = null;
- if (isLivestreamActive === true) {
- liveProperty = (claim) => <>LIVE>;
- }
return (
@@ -273,7 +263,7 @@ function ClaimPreviewTile(props: Props) {
diff --git a/ui/component/claimType/index.js b/ui/component/claimType/index.js
index 98034acda..64ef15cb6 100644
--- a/ui/component/claimType/index.js
+++ b/ui/component/claimType/index.js
@@ -1,10 +1,9 @@
import { connect } from 'react-redux';
-import { makeSelectClaimForUri, makeSelectClaimIsStreamPlaceholder } from 'redux/selectors/claims';
+import { makeSelectClaimForUri } from 'redux/selectors/claims';
import FileType from './view';
const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state),
- isLivestream: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
});
export default connect(select)(FileType);
diff --git a/ui/component/commentCreate/index.js b/ui/component/commentCreate/index.js
index baa416468..61d209e5d 100644
--- a/ui/component/commentCreate/index.js
+++ b/ui/component/commentCreate/index.js
@@ -26,18 +26,7 @@ const select = (state, props) => ({
const perform = (dispatch, ownProps) => ({
createComment: (comment, claimId, parentId, txid, payment_intent_id, environment) =>
- dispatch(
- doCommentCreate(
- comment,
- claimId,
- parentId,
- ownProps.uri,
- ownProps.livestream,
- txid,
- payment_intent_id,
- environment
- )
- ),
+ dispatch(doCommentCreate(comment, claimId, parentId, ownProps.uri, txid, payment_intent_id, environment)),
sendTip: (params, callback, errorCallback) => dispatch(doSendTip(params, false, callback, errorCallback, false)),
doToast: (options) => dispatch(doToast(options)),
doFetchCreatorSettings: (channelClaimId) => dispatch(doFetchCreatorSettings(channelClaimId)),
diff --git a/ui/component/commentCreate/view.jsx b/ui/component/commentCreate/view.jsx
index eedeb5c2c..f0635650d 100644
--- a/ui/component/commentCreate/view.jsx
+++ b/ui/component/commentCreate/view.jsx
@@ -1,5 +1,5 @@
// @flow
-import { FF_MAX_CHARS_IN_COMMENT, FF_MAX_CHARS_IN_LIVESTREAM_COMMENT } from 'constants/form-field';
+import { FF_MAX_CHARS_IN_COMMENT } from 'constants/form-field';
import { FormField, Form } from 'component/common/form';
import { getChannelIdFromClaim } from 'util/claim';
import { Lbryio } from 'lbryinc';
@@ -40,7 +40,6 @@ type Props = {
activeChannel: string,
activeChannelClaim: ?ChannelClaim,
bottom: boolean,
- livestream?: boolean,
embed?: boolean,
claimIsMine: boolean,
supportDisabled: boolean,
@@ -68,8 +67,6 @@ export function CommentCreate(props: Props) {
parentId,
activeChannelClaim,
bottom,
- livestream,
- embed,
claimIsMine,
settingsByChannelId,
supportDisabled,
@@ -179,7 +176,6 @@ export function CommentCreate(props: Props) {
let newMentionValue = mentionValue.replace('lbry://', '');
if (newMentionValue.includes('#')) newMentionValue = newMentionValue.replace('#', ':');
- if (livestream && key !== KEYCODES.TAB) setPauseQuickSend(true);
setCommentValue(
commentValue.substring(0, selectedMentionIndex) +
`${newMentionValue}` +
@@ -190,7 +186,7 @@ export function CommentCreate(props: Props) {
}
function altEnterListener(e: SyntheticKeyboardEvent<*>) {
- if ((livestream || e.ctrlKey || e.metaKey) && e.keyCode === KEYCODES.ENTER) {
+ if ((e.ctrlKey || e.metaKey) && e.keyCode === KEYCODES.ENTER) {
e.preventDefault();
buttonRef.current.click();
}
@@ -442,17 +438,8 @@ export function CommentCreate(props: Props) {
{
- if (embed) {
- window.open(`https://odysee.com/$/${PAGES.AUTH}?redirect=/$/${PAGES.LIVESTREAM}`);
- return;
- }
-
const pathPlusRedirect = `/$/${PAGES.CHANNEL_NEW}?redirect=${pathname}`;
- if (livestream) {
- window.open(pathPlusRedirect);
- } else {
- push(pathPlusRedirect);
- }
+ push(pathPlusRedirect);
}}
>
@@ -518,7 +505,6 @@ export function CommentCreate(props: Props) {
{!advancedEditor && (
- {!livestream && (
- {isReply ? __('Replying as') + ' ' : __('Comment as') + ' '}
- )}
+ {isReply ? __('Replying as') + ' ' : __('Comment as') + ' '}
}
@@ -548,7 +532,7 @@ export function CommentCreate(props: Props) {
charCount={charCount}
onChange={handleCommentChange}
autoFocus={isReply}
- textAreaMaxLength={livestream ? FF_MAX_CHARS_IN_LIVESTREAM_COMMENT : FF_MAX_CHARS_IN_COMMENT}
+ textAreaMaxLength={FF_MAX_CHARS_IN_COMMENT}
/>
{isSupportComment && (
),
- [ICONS.LIVESTREAM]: (props: CustomProps) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {/* }//fill="#FFFFFF" */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ),
- [ICONS.LIVESTREAM_SOLID]: (props: CustomProps) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ),
- [ICONS.LIVESTREAM_MONOCHROME]: (props: CustomProps) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ),
-
- [ICONS.LIVESTREAM]: (props: CustomProps) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {/* }//fill="#FFFFFF" */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ),
- [ICONS.LIVESTREAM_SOLID]: (props: CustomProps) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ),
- [ICONS.LIVESTREAM_MONOCHROME]: (props: CustomProps) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ),
[ICONS.STACK]: (props: CustomProps) => (
({
renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
costInfo: makeSelectCostInfoForUri(props.uri)(state),
myChannels: selectMyChannelClaims(state),
- isLivestreamClaim: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
reactionsDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state),
streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state),
});
diff --git a/ui/component/fileActions/view.jsx b/ui/component/fileActions/view.jsx
index c7656316b..303737bfa 100644
--- a/ui/component/fileActions/view.jsx
+++ b/ui/component/fileActions/view.jsx
@@ -30,7 +30,6 @@ type Props = {
doToast: ({ message: string }) => void,
clearPlayingUri: () => void,
hideRepost?: boolean,
- isLivestreamClaim: boolean,
reactionsDisabled: boolean,
download: (string) => void,
streamingUrl: ?string,
@@ -50,7 +49,6 @@ function FileActions(props: Props) {
clearPlayingUri,
doToast,
hideRepost,
- isLivestreamClaim,
reactionsDisabled,
} = props;
const {
@@ -96,7 +94,7 @@ function FileActions(props: Props) {
const lhsSection = (
<>
- {ENABLE_FILE_REACTIONS && !reactionsDisabled && }
+ {ENABLE_FILE_REACTIONS && !reactionsDisabled && }
{!hideRepost && (
@@ -124,14 +122,12 @@ function FileActions(props: Props) {
const rhsSection = (
<>
- {/* @if TARGET='app' */}
- {/* @endif */}
{claimIsMine && (
{
prepareEdit(claim, editUri, fileInfo);
@@ -147,7 +143,7 @@ function FileActions(props: Props) {
onClick={() => openModal(MODALS.CONFIRM_FILE_REMOVE, { uri })}
/>
)}
- {(!isLivestreamClaim || !claimIsMine) && (
+ {!claimIsMine && (
- {!claimIsMine && (
- push(`/$/${PAGES.REPORT_CONTENT}?claimId=${claimId}`)}
- >
-
-
- {__('Report content')}
-
-
- )}
+ push(`/$/${PAGES.REPORT_CONTENT}?claimId=${claimId}`)}
+ >
+
+
+ {__('Report content')}
+
+
)}
diff --git a/ui/component/fileReactions/view.jsx b/ui/component/fileReactions/view.jsx
index 048c3daba..a07534bfd 100644
--- a/ui/component/fileReactions/view.jsx
+++ b/ui/component/fileReactions/view.jsx
@@ -16,7 +16,6 @@ type Props = {
likeCount: number,
dislikeCount: number,
myReaction: ?string,
- livestream?: boolean,
};
function FileReactions(props: Props) {
@@ -29,7 +28,6 @@ function FileReactions(props: Props) {
myReaction,
likeCount,
dislikeCount,
- livestream,
} = props;
const claimId = claim && claim.claim_id;
@@ -42,21 +40,10 @@ function FileReactions(props: Props) {
doFetchReactions(claimId);
}
- let fetchInterval;
if (claimId) {
fetchReactions();
-
- if (livestream) {
- fetchInterval = setInterval(fetchReactions, 45000);
- }
}
-
- return () => {
- if (fetchInterval) {
- clearInterval(fetchInterval);
- }
- };
- }, [claimId, doFetchReactions, livestream]);
+ }, [claimId, doFetchReactions]);
return (
<>
@@ -98,7 +85,9 @@ function FileReactions(props: Props) {
requiresAuth={IS_WEB}
authSrc={'filereaction_dislike'}
title={__('I dislike this')}
- className={classnames('button--file-action', { 'button--file-action-active': myReaction === REACTION_TYPES.DISLIKE })}
+ className={classnames('button--file-action', {
+ 'button--file-action-active': myReaction === REACTION_TYPES.DISLIKE,
+ })}
label={<>{formatNumberWithCommas(dislikeCount, 0)}>}
iconSize={18}
icon={dislikeIcon}
diff --git a/ui/component/fileSubtitle/view.jsx b/ui/component/fileSubtitle/view.jsx
index 60f9c489c..781cdfe46 100644
--- a/ui/component/fileSubtitle/view.jsx
+++ b/ui/component/fileSubtitle/view.jsx
@@ -1,28 +1,22 @@
// @flow
import React from 'react';
-import DateTime from 'component/dateTime';
import FileViewCount from 'component/fileViewCount';
import FileActions from 'component/fileActions';
type Props = {
uri: string,
- livestream?: boolean,
- activeViewers?: number,
- isLive?: boolean,
};
function FileSubtitle(props: Props) {
- const { uri, livestream = false, activeViewers, isLive = false } = props;
+ const { uri } = props;
return (
- {livestream ? {__('Right now')} : }
-
-
+
-
+
);
}
diff --git a/ui/component/fileTitleSection/index.js b/ui/component/fileTitleSection/index.js
index fa5be5a0a..0e9f3a4f9 100644
--- a/ui/component/fileTitleSection/index.js
+++ b/ui/component/fileTitleSection/index.js
@@ -2,18 +2,15 @@ import { connect } from 'react-redux';
import { doFetchSubCount, makeSelectSubCountForUri } from 'lbryinc';
import { makeSelectTitleForUri, makeSelectClaimForUri } from 'redux/selectors/claims';
import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content';
-import { makeSelectViewersForId } from 'redux/selectors/livestream';
import FileTitleSection from './view';
const select = (state, props) => {
const claim = makeSelectClaimForUri(props.uri)(state);
- const viewers = claim && makeSelectViewersForId(claim.claim_id)(state);
const channelClaimId = claim && claim.signing_channel ? claim.signing_channel.claim_id : undefined;
const channelUri = claim && claim.signing_channel ? claim.signing_channel.canonical_url : undefined;
const subCount = channelUri && makeSelectSubCountForUri(channelUri)(state);
return {
- viewers,
isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state),
title: makeSelectTitleForUri(props.uri)(state),
channelClaimId,
diff --git a/ui/component/fileTitleSection/view.jsx b/ui/component/fileTitleSection/view.jsx
index a6db551ee..45665434c 100644
--- a/ui/component/fileTitleSection/view.jsx
+++ b/ui/component/fileTitleSection/view.jsx
@@ -20,27 +20,13 @@ type Props = {
title: string,
nsfw: boolean,
isNsfwBlocked: boolean,
- livestream?: boolean,
- isLive?: boolean,
- viewers?: number,
subCount: number,
channelClaimId?: string,
fetchSubCount: (string) => void,
};
function FileTitleSection(props: Props) {
- const {
- title,
- uri,
- nsfw,
- isNsfwBlocked,
- livestream = false,
- isLive = false,
- viewers,
- subCount,
- channelClaimId,
- fetchSubCount,
- } = props;
+ const { title, uri, nsfw, isNsfwBlocked, subCount, channelClaimId, fetchSubCount } = props;
const [hasAcknowledgedSec, setHasAcknowledgedSec] = usePersistedState('sec-nag', false);
React.useEffect(() => {
@@ -78,7 +64,7 @@ function FileTitleSection(props: Props) {
body={
-
+
}
actions={
diff --git a/ui/component/fileType/index.js b/ui/component/fileType/index.js
index 67e40411b..7baca94ea 100644
--- a/ui/component/fileType/index.js
+++ b/ui/component/fileType/index.js
@@ -1,11 +1,9 @@
import { connect } from 'react-redux';
import { makeSelectMediaTypeForUri } from 'redux/selectors/file_info';
-import { makeSelectClaimIsStreamPlaceholder } from 'redux/selectors/claims';
import FileType from './view';
const select = (state, props) => ({
mediaType: makeSelectMediaTypeForUri(props.uri)(state),
- isLivestream: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
});
export default connect(select)(FileType);
diff --git a/ui/component/fileType/view.jsx b/ui/component/fileType/view.jsx
index 9f15484ec..f99edb6bc 100644
--- a/ui/component/fileType/view.jsx
+++ b/ui/component/fileType/view.jsx
@@ -7,19 +7,18 @@ import * as COL from 'constants/collections';
type Props = {
uri: string,
mediaType: string,
- isLivestream: boolean,
small: boolean,
};
function FileType(props: Props) {
- const { mediaType, isLivestream, small } = props;
+ const { mediaType, small } = props;
const size = small ? COL.ICON_SIZE : undefined;
if (mediaType === 'image') {
return ;
} else if (mediaType === 'audio') {
return ;
- } else if (mediaType === 'video' || isLivestream) {
+ } else if (mediaType === 'video') {
return ;
} else if (mediaType === 'text') {
return ;
diff --git a/ui/component/fileViewCount/view.jsx b/ui/component/fileViewCount/view.jsx
index cdfbafe33..9feeaba05 100644
--- a/ui/component/fileViewCount/view.jsx
+++ b/ui/component/fileViewCount/view.jsx
@@ -8,24 +8,12 @@ type Props = {
fetchingViewCount: boolean,
uri: string,
viewCount: string,
- livestream?: boolean,
- activeViewers?: number,
- isLive?: boolean,
- doAnalyticsView: (string) => void,
};
function FileViewCount(props: Props) {
- const { claim, uri, fetchViewCount, viewCount, livestream, activeViewers, doAnalyticsView } = props;
+ const { claim, uri, fetchViewCount, viewCount } = props;
const claimId = claim && claim.claim_id;
- React.useEffect(() => {
- if (livestream) {
- // Regular claims will call the file/view event when a user actually watches the claim
- // This can be removed when we get rid of the livestream iframe
- doAnalyticsView(uri);
- }
- }, [livestream, doAnalyticsView, uri]);
-
React.useEffect(() => {
if (claimId) {
fetchViewCount(claimId);
@@ -36,9 +24,7 @@ function FileViewCount(props: Props) {
return (
- {!livestream &&
- activeViewers === undefined &&
- (viewCount !== 1 ? __('%view_count% views', { view_count: formattedViewCount }) : __('1 view'))}
+ {viewCount !== 1 ? __('%view_count% views', { view_count: formattedViewCount }) : __('1 view')}
{ }
);
diff --git a/ui/component/fileViewCountInline/view.jsx b/ui/component/fileViewCountInline/view.jsx
index 640cababf..fd1f366cb 100644
--- a/ui/component/fileViewCountInline/view.jsx
+++ b/ui/component/fileViewCountInline/view.jsx
@@ -4,7 +4,6 @@ import 'scss/component/_view_count.scss';
type Props = {
uri: string,
- isLivestream?: boolean,
// --- select ---
claim: ?StreamClaim,
viewCount: string,
@@ -12,7 +11,7 @@ type Props = {
};
export default function FileViewCountInline(props: Props) {
- const { isLivestream, claim, viewCount, lang } = props;
+ const { claim, viewCount, lang } = props;
let formattedViewCount;
try {
@@ -30,8 +29,8 @@ export default function FileViewCountInline(props: Props) {
// clean up (only one place edit/remove).
const isChannelPage = window.location.pathname.startsWith('/@');
- // dont show if no view count, if it's a repost, a livestream or isn't a channel page
- if (!viewCount || (claim && claim.repost_url) || isLivestream || !isChannelPage) {
+ // dont show if no view count, if it's a repost or isn't a channel page
+ if (!viewCount || (claim && claim.repost_url) || !isChannelPage) {
// (1) Currently, makeSelectViewCountForUri doesn't differentiate between
// un-fetched view-count vs zero view-count. But since it's probably not
// ideal to highlight that a view has 0 count, let's just not show anything.
diff --git a/ui/component/header/index.js b/ui/component/header/index.js
index a7c7bf21e..1584630d3 100644
--- a/ui/component/header/index.js
+++ b/ui/component/header/index.js
@@ -9,7 +9,7 @@ import { doClearEmailEntry, doClearPasswordEntry } from 'redux/actions/user';
import { doSetClientSetting } from 'redux/actions/settings';
import { doSignOut, doOpenModal } from 'redux/actions/app';
import { makeSelectClientSetting, selectLanguage } from 'redux/selectors/settings';
-import { selectHasNavigated, selectActiveChannelClaim, selectActiveChannelStakedLevel } from 'redux/selectors/app';
+import { selectHasNavigated, selectActiveChannelClaim } from 'redux/selectors/app';
import Header from './view';
const select = (state) => ({
@@ -27,7 +27,6 @@ const select = (state) => ({
hasNavigated: selectHasNavigated(state),
user: selectUser(state),
activeChannelClaim: selectActiveChannelClaim(state),
- activeChannelStakedLevel: selectActiveChannelStakedLevel(state),
});
const perform = (dispatch) => ({
diff --git a/ui/component/header/view.jsx b/ui/component/header/view.jsx
index a94703bba..cfedb816a 100644
--- a/ui/component/header/view.jsx
+++ b/ui/component/header/view.jsx
@@ -1,5 +1,5 @@
// @flow
-import { ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM, ENABLE_UI_NOTIFICATIONS } from 'config';
+import { ENABLE_UI_NOTIFICATIONS } from 'config';
import * as ICONS from 'constants/icons';
import * as SETTINGS from 'constants/settings';
import * as PAGES from 'constants/pages';
@@ -63,7 +63,6 @@ type Props = {
isAbsoluteSideNavHidden: boolean,
hideCancel: boolean,
activeChannelClaim: ?ChannelClaim,
- activeChannelStakedLevel: number,
};
const Header = (props: Props) => {
@@ -92,7 +91,6 @@ const Header = (props: Props) => {
hideCancel,
user,
activeChannelClaim,
- activeChannelStakedLevel,
} = props;
const isMobile = useIsMobile();
// on the verify page don't let anyone escape other than by closing the tab to keep session data consistent
@@ -103,12 +101,6 @@ const Header = (props: Props) => {
const hasBackout = Boolean(backout);
const { backLabel, backNavDefault, title: backTitle, simpleTitle: simpleBackTitle } = backout || {};
const notificationsEnabled = ENABLE_UI_NOTIFICATIONS || (user && user.experimental_ui);
- const livestreamEnabled = Boolean(
- ENABLE_NO_SOURCE_CLAIMS &&
- user &&
- !user.odysee_live_disabled &&
- (activeChannelStakedLevel >= CHANNEL_STAKED_LEVEL_LIVESTREAM || user.odysee_live_enabled)
- );
const activeChannelUrl = activeChannelClaim && activeChannelClaim.permanent_url;
// Sign out if they click the "x" when they are on the password prompt
@@ -288,7 +280,6 @@ const Header = (props: Props) => {
history={history}
handleThemeToggle={handleThemeToggle}
currentTheme={currentTheme}
- livestreamEnabled={livestreamEnabled}
/>
)}
@@ -405,11 +396,10 @@ type HeaderMenuButtonProps = {
history: { push: (string) => void },
handleThemeToggle: (string) => void,
currentTheme: string,
- livestreamEnabled: boolean,
};
function HeaderMenuButtons(props: HeaderMenuButtonProps) {
- const { authenticated, notificationsEnabled, history, handleThemeToggle, currentTheme, livestreamEnabled } = props;
+ const { authenticated, notificationsEnabled, history, handleThemeToggle, currentTheme } = props;
return (
@@ -437,18 +427,6 @@ function HeaderMenuButtons(props: HeaderMenuButtonProps) {
{__('New Channel')}
- {/* @if TARGET='web' */}
-
history.push(`/$/${PAGES.YOUTUBE_SYNC}`)}>
-
- {__('Sync YouTube Channel')}
-
- {/* @endif */}
- {livestreamEnabled && (
-
history.push(`/$/${PAGES.LIVESTREAM}`)}>
-
- {__('Go Live')}
-
- )}
)}
diff --git a/ui/component/livestreamComment/index.js b/ui/component/livestreamComment/index.js
deleted file mode 100644
index 8c6a97de5..000000000
--- a/ui/component/livestreamComment/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import { connect } from 'react-redux';
-import { makeSelectStakedLevelForChannelUri, makeSelectClaimForUri } from 'redux/selectors/claims';
-import LivestreamComment from './view';
-
-const select = (state, props) => ({
- claim: makeSelectClaimForUri(props.uri)(state),
- stakedLevel: makeSelectStakedLevelForChannelUri(props.authorUri)(state),
-});
-
-export default connect(select)(LivestreamComment);
diff --git a/ui/component/livestreamComment/view.jsx b/ui/component/livestreamComment/view.jsx
deleted file mode 100644
index 49dd26f95..000000000
--- a/ui/component/livestreamComment/view.jsx
+++ /dev/null
@@ -1,133 +0,0 @@
-// @flow
-import * as ICONS from 'constants/icons';
-import React from 'react';
-import { parseURI } from 'util/lbryURI';
-import MarkdownPreview from 'component/common/markdown-preview';
-import Tooltip from 'component/common/tooltip';
-import ChannelThumbnail from 'component/channelThumbnail';
-import { Menu, MenuButton } from '@reach/menu-button';
-import Icon from 'component/common/icon';
-import classnames from 'classnames';
-import CommentMenuList from 'component/commentMenuList';
-import Button from 'component/button';
-import CreditAmount from 'component/common/credit-amount';
-
-type Props = {
- uri: string,
- claim: StreamClaim,
- authorUri: string,
- commentId: string,
- message: string,
- commentIsMine: boolean,
- stakedLevel: number,
- supportAmount: number,
- isModerator: boolean,
- isGlobalMod: boolean,
- isFiat: boolean,
- isPinned: boolean,
-};
-
-function LivestreamComment(props: Props) {
- const {
- claim,
- uri,
- authorUri,
- message,
- commentIsMine,
- commentId,
- stakedLevel,
- supportAmount,
- isModerator,
- isGlobalMod,
- isFiat,
- isPinned,
- } = props;
-
- const commentByOwnerOfContent = claim && claim.signing_channel && claim.signing_channel.permanent_url === authorUri;
- const { claimName } = parseURI(authorUri);
-
- return (
-
0,
- })}
- >
- {supportAmount > 0 && (
-
- )}
-
-
- {supportAmount > 0 &&
}
-
- {isGlobalMod && (
-
-
-
-
-
- )}
-
- {isModerator && (
-
-
-
-
-
- )}
-
- {commentByOwnerOfContent && (
-
-
-
-
-
- )}
-
-
- {claimName}
-
-
- {isPinned && (
-
-
- {__('Pinned')}
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
- 0}
- />
-
-
-
- );
-}
-
-export default LivestreamComment;
diff --git a/ui/component/livestreamComments/index.js b/ui/component/livestreamComments/index.js
deleted file mode 100644
index f68fc3372..000000000
--- a/ui/component/livestreamComments/index.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import { connect } from 'react-redux';
-import { makeSelectClaimForUri, selectMyChannelClaims } from 'redux/selectors/claims';
-import { doCommentSocketConnect, doCommentSocketDisconnect } from 'redux/actions/websocket';
-import { doCommentList, doSuperChatList } from 'redux/actions/comments';
-import {
- makeSelectTopLevelCommentsForUri,
- selectIsFetchingComments,
- makeSelectSuperChatsForUri,
- makeSelectSuperChatTotalAmountForUri,
- makeSelectPinnedCommentsForUri,
-} from 'redux/selectors/comments';
-import LivestreamComments from './view';
-
-const select = (state, props) => ({
- claim: makeSelectClaimForUri(props.uri)(state),
- comments: makeSelectTopLevelCommentsForUri(props.uri)(state).slice(0, 75),
- pinnedComments: makeSelectPinnedCommentsForUri(props.uri)(state),
- fetchingComments: selectIsFetchingComments(state),
- superChats: makeSelectSuperChatsForUri(props.uri)(state),
- superChatsTotalAmount: makeSelectSuperChatTotalAmountForUri(props.uri)(state),
- myChannels: selectMyChannelClaims(state),
-});
-
-export default connect(select, {
- doCommentSocketConnect,
- doCommentSocketDisconnect,
- doCommentList,
- doSuperChatList,
-})(LivestreamComments);
diff --git a/ui/component/livestreamComments/view.jsx b/ui/component/livestreamComments/view.jsx
deleted file mode 100644
index a9db254de..000000000
--- a/ui/component/livestreamComments/view.jsx
+++ /dev/null
@@ -1,319 +0,0 @@
-// @flow
-import React from 'react';
-import classnames from 'classnames';
-import Spinner from 'component/spinner';
-import CommentCreate from 'component/commentCreate';
-import LivestreamComment from 'component/livestreamComment';
-import Button from 'component/button';
-import UriIndicator from 'component/uriIndicator';
-import CreditAmount from 'component/common/credit-amount';
-import ChannelThumbnail from 'component/channelThumbnail';
-import Tooltip from 'component/common/tooltip';
-import * as ICONS from 'constants/icons';
-
-type Props = {
- uri: string,
- claim: ?StreamClaim,
- activeViewers: number,
- embed?: boolean,
- doCommentSocketConnect: (string, string) => void,
- doCommentSocketDisconnect: (string) => void,
- doCommentList: (string, string, number, number) => void,
- comments: Array
,
- pinnedComments: Array,
- fetchingComments: boolean,
- doSuperChatList: (string) => void,
- superChats: Array,
- myChannels: ?Array,
-};
-
-const VIEW_MODE_CHAT = 'view_chat';
-const VIEW_MODE_SUPER_CHAT = 'view_superchat';
-const COMMENT_SCROLL_TIMEOUT = 25;
-
-export default function LivestreamComments(props: Props) {
- const {
- claim,
- uri,
- embed,
- doCommentSocketConnect,
- doCommentSocketDisconnect,
- comments: commentsByChronologicalOrder,
- pinnedComments,
- doCommentList,
- fetchingComments,
- doSuperChatList,
- myChannels,
- superChats: superChatsByTipAmount,
- } = props;
-
- let superChatsFiatAmount, superChatsTotalAmount;
-
- const commentsRef = React.createRef();
- const [viewMode, setViewMode] = React.useState(VIEW_MODE_CHAT);
- const [scrollPos, setScrollPos] = React.useState(0);
- const [showPinned, setShowPinned] = React.useState(true);
- const claimId = claim && claim.claim_id;
- const commentsLength = commentsByChronologicalOrder && commentsByChronologicalOrder.length;
-
- // which kind of superchat to display, either
- const commentsToDisplay = viewMode === VIEW_MODE_CHAT ? commentsByChronologicalOrder : superChatsByTipAmount;
-
- const discussionElement = document.querySelector('.livestream__comments');
-
- const pinnedComment = pinnedComments.length > 0 ? pinnedComments[0] : null;
-
- function restoreScrollPos() {
- if (discussionElement) {
- discussionElement.scrollTop = 0;
- }
- }
-
- React.useEffect(() => {
- if (claimId) {
- doCommentList(uri, '', 1, 75);
- doSuperChatList(uri);
- doCommentSocketConnect(uri, claimId);
- }
-
- return () => {
- if (claimId) {
- doCommentSocketDisconnect(claimId);
- }
- };
- }, [claimId, uri, doCommentList, doSuperChatList, doCommentSocketConnect, doCommentSocketDisconnect]);
-
- // Register scroll handler (TODO: Should throttle/debounce)
- React.useEffect(() => {
- function handleScroll() {
- if (discussionElement) {
- const scrollTop = discussionElement.scrollTop;
- if (scrollTop !== scrollPos) {
- setScrollPos(scrollTop);
- }
- }
- }
-
- if (discussionElement) {
- discussionElement.addEventListener('scroll', handleScroll);
- return () => discussionElement.removeEventListener('scroll', handleScroll);
- }
- }, [discussionElement, scrollPos]);
-
- // Retain scrollPos=0 when receiving new messages.
- React.useEffect(() => {
- if (discussionElement && commentsLength > 0) {
- // Only update comment scroll if the user hasn't scrolled up to view old comments
- if (scrollPos >= 0) {
- // +ve scrollPos: not scrolled (Usually, there'll be a few pixels beyond 0).
- // -ve scrollPos: user scrolled.
- const timer = setTimeout(() => {
- // Use a timer here to ensure we reset after the new comment has been rendered.
- discussionElement.scrollTop = 0;
- }, COMMENT_SCROLL_TIMEOUT);
- return () => clearTimeout(timer);
- }
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [commentsLength]); // (Just respond to 'commentsLength' updates and nothing else)
-
- // sum total amounts for fiat tips and lbc tips
- if (superChatsByTipAmount) {
- let fiatAmount = 0;
- let LBCAmount = 0;
- for (const superChat of superChatsByTipAmount) {
- if (superChat.is_fiat) {
- fiatAmount = fiatAmount + superChat.support_amount;
- } else {
- LBCAmount = LBCAmount + superChat.support_amount;
- }
- }
-
- superChatsFiatAmount = fiatAmount;
- superChatsTotalAmount = LBCAmount;
- }
-
- let superChatsReversed;
- // array of superchats organized by fiat or not first, then support amount
- if (superChatsByTipAmount) {
- const clonedSuperchats = JSON.parse(JSON.stringify(superChatsByTipAmount));
-
- // for top to bottom display, oldest superchat on top most recent on bottom
- superChatsReversed = clonedSuperchats
- .sort((a, b) => {
- return b.timestamp - a.timestamp;
- }); }
-
- // todo: implement comment_list --mine in SDK so redux can grab with selectCommentIsMine
- function isMyComment(channelId: string) {
- if (myChannels != null && channelId != null) {
- for (let i = 0; i < myChannels.length; i++) {
- if (myChannels[i].claim_id === channelId) {
- return true;
- }
- }
- }
- return false;
- }
-
- if (!claim) {
- return null;
- }
-
- return (
-
-
-
{__('Live discussion')}
- {(superChatsTotalAmount || 0) > 0 && (
-
- {/* the superchats in chronological order button */}
- {
- setViewMode(VIEW_MODE_CHAT);
- const livestreamCommentsDiv = document.getElementsByClassName('livestream__comments')[0];
- livestreamCommentsDiv.scrollTop = livestreamCommentsDiv.scrollHeight;
- }}
- />
-
- {/* the button to show superchats listed by most to least support amount */}
-
- /
- {__('Tipped')}
- >
- }
- onClick={() => {
- setViewMode(VIEW_MODE_SUPER_CHAT);
- const livestreamCommentsDiv = document.getElementsByClassName('livestream__comments')[0];
- const divHeight = livestreamCommentsDiv.scrollHeight;
- livestreamCommentsDiv.scrollTop = divHeight * -1;
- }}
- />
-
- )}
-
- <>
- {fetchingComments && !commentsByChronologicalOrder && (
-
-
-
- )}
-
- {viewMode === VIEW_MODE_CHAT && superChatsByTipAmount && (superChatsTotalAmount || 0) > 0 && (
-
-
- {superChatsByTipAmount.map((superChat: Comment) => (
-
-
-
- ))}
-
-
- )}
-
- {pinnedComment && showPinned && viewMode === VIEW_MODE_CHAT && (
-
-
- setShowPinned(false)}
- icon={ICONS.REMOVE}
- />
-
- )}
-
- {/* top to bottom comment display */}
- {!fetchingComments && commentsByChronologicalOrder.length > 0 ? (
-
- {viewMode === VIEW_MODE_CHAT &&
- commentsToDisplay.map((comment) => (
-
- ))}
-
- {/* listing comments on top of eachother */}
- {viewMode === VIEW_MODE_SUPER_CHAT &&
- superChatsReversed &&
- superChatsReversed.map((comment) => (
-
- ))}
-
- ) : (
-
- )}
-
- {scrollPos < 0 && viewMode === VIEW_MODE_CHAT && (
-
- )}
-
-
-
-
-
- >
-
- );
-}
diff --git a/ui/component/livestreamLayout/index.js b/ui/component/livestreamLayout/index.js
deleted file mode 100644
index 03547a34d..000000000
--- a/ui/component/livestreamLayout/index.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { connect } from 'react-redux';
-import {
- makeSelectClaimForUri,
- makeSelectTagInClaimOrChannelForUri,
- makeSelectThumbnailForUri,
-} from 'redux/selectors/claims';
-import LivestreamLayout from './view';
-import { DISABLE_COMMENTS_TAG } from 'constants/tags';
-
-const select = (state, props) => ({
- claim: makeSelectClaimForUri(props.uri)(state),
- thumbnail: makeSelectThumbnailForUri(props.uri)(state),
- chatDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state),
-});
-
-export default connect(select)(LivestreamLayout);
diff --git a/ui/component/livestreamLayout/view.jsx b/ui/component/livestreamLayout/view.jsx
deleted file mode 100644
index 2a1c5e9ca..000000000
--- a/ui/component/livestreamLayout/view.jsx
+++ /dev/null
@@ -1,63 +0,0 @@
-// @flow
-import { LIVESTREAM_EMBED_URL } from 'constants/livestream';
-import React from 'react';
-import FileTitleSection from 'component/fileTitleSection';
-import LivestreamComments from 'component/livestreamComments';
-import { useIsMobile } from 'effects/use-screensize';
-
-type Props = {
- uri: string,
- claim: ?StreamClaim,
- isLive: boolean,
- chatDisabled: boolean,
-};
-
-export default function LivestreamLayout(props: Props) {
- const { claim, uri, isLive, chatDisabled } = props;
- const isMobile = useIsMobile();
-
- if (!claim || !claim.signing_channel) {
- return null;
- }
-
- const channelName = claim.signing_channel.name;
- const channelClaimId = claim.signing_channel.claim_id;
-
- return (
- <>
-
-
-
- {Boolean(chatDisabled) && (
-
- {channelName
- ? __('%channel% has disabled chat for this stream. Enjoy the stream!', { channel: channelName })
- : __('This channel has disabled chat for this stream. Enjoy the stream!')}
-
- )}
-
- {!isLive && (
-
- {channelName
- ? __("%channelName% isn't live right now, but the chat is! Check back later to watch the stream.", {
- channelName,
- })
- : __("This channel isn't live right now, but the chat is! Check back later to watch the stream.")}
-
- )}
-
- {isMobile &&
}
-
-
-
- >
- );
-}
diff --git a/ui/component/livestreamLink/index.js b/ui/component/livestreamLink/index.js
deleted file mode 100644
index efc44ccaa..000000000
--- a/ui/component/livestreamLink/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import { connect } from 'react-redux';
-import { makeSelectClaimForUri } from 'redux/selectors/claims';
-import LivestreamLink from './view';
-
-const select = (state, props) => ({
- channelClaim: makeSelectClaimForUri(props.uri)(state),
-});
-
-export default connect(select)(LivestreamLink);
diff --git a/ui/component/livestreamLink/view.jsx b/ui/component/livestreamLink/view.jsx
deleted file mode 100644
index 23243cb5a..000000000
--- a/ui/component/livestreamLink/view.jsx
+++ /dev/null
@@ -1,101 +0,0 @@
-// @flow
-import { LIVESTREAM_LIVE_API } from 'constants/livestream';
-import * as CS from 'constants/claim_search';
-import React from 'react';
-import Card from 'component/common/card';
-import ClaimPreview from 'component/claimPreview';
-import Lbry from 'lbry';
-import { useHistory } from 'react-router';
-import { formatLbryUrlForWeb } from 'util/url';
-
-type Props = {
- channelClaim: ChannelClaim,
-};
-
-export default function LivestreamLink(props: Props) {
- const { channelClaim } = props;
- const { push } = useHistory();
- 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
- // TODO: pput this back when hubs claims_in_channel are fixed
- const isChannelEmpty = !channelClaim || !channelClaim.meta;
- // ||
- // !channelClaim.meta.claims_in_channel;
-
- React.useEffect(() => {
- // 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,
- })
- .then((res) => {
- if (res && res.items && res.items.length > 0) {
- const claim = res.items[0];
- // $FlowFixMe Too many Claim GenericClaim etc types.
- setLivestreamClaim(claim);
- }
- })
- .catch(() => {});
- }
- }, [livestreamChannelId, isChannelEmpty]);
-
- React.useEffect(() => {
- function fetchIsStreaming() {
- // $FlowFixMe livestream API can handle garbage
- fetch(`${LIVESTREAM_LIVE_API}/${livestreamChannelId}`)
- .then((res) => res.json())
- .then((res) => {
- if (res && res.success && res.data && res.data.live) {
- setIsLivestreaming(true);
- } else {
- setIsLivestreaming(false);
- }
- })
- .catch((e) => {});
- }
-
- let interval;
- // 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, livestreamClaim]);
-
- if (!livestreamClaim || !isLivestreaming) {
- return null;
- }
-
- // gonna pass the wrapper in so I don't have to rewrite the dmca/blocking logic in claimPreview.
- const element = (props: { children: any }) => (
- {
- push(formatLbryUrlForWeb(livestreamClaim.canonical_url));
- }}
- >
- {props.children}
-
- );
-
- return ;
-}
diff --git a/ui/component/livestreamList/index.js b/ui/component/livestreamList/index.js
deleted file mode 100644
index 3dffaca29..000000000
--- a/ui/component/livestreamList/index.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import { connect } from 'react-redux';
-import LivestreamList from './view';
-
-const select = (state) => ({});
-
-export default connect(select)(LivestreamList);
diff --git a/ui/component/livestreamList/view.jsx b/ui/component/livestreamList/view.jsx
deleted file mode 100644
index 332a9e654..000000000
--- a/ui/component/livestreamList/view.jsx
+++ /dev/null
@@ -1,78 +0,0 @@
-// @flow
-import * as ICONS from 'constants/icons';
-import { LIVESTREAM_LIVE_API } from 'constants/livestream';
-import React from 'react';
-import Icon from 'component/common/icon';
-import Spinner from 'component/spinner';
-import ClaimTilesDiscover from 'component/claimTilesDiscover';
-
-const LIVESTREAM_POLL_IN_MS = 10 * 1000;
-
-export default function LivestreamList() {
- const [loading, setLoading] = React.useState(true);
- const [livestreamMap, setLivestreamMap] = React.useState();
-
- React.useEffect(() => {
- function checkCurrentLivestreams() {
- fetch(LIVESTREAM_LIVE_API)
- .then((res) => res.json())
- .then((res) => {
- setLoading(false);
- if (!res.data) {
- setLivestreamMap({});
- return;
- }
-
- const livestreamMap = res.data.reduce((acc, curr) => {
- return {
- ...acc,
- [curr.claimId]: curr,
- };
- }, {});
-
- setLivestreamMap(livestreamMap);
- })
- .catch((err) => {
- setLoading(false);
- });
- }
-
- checkCurrentLivestreams();
- let fetchInterval = setInterval(checkCurrentLivestreams, LIVESTREAM_POLL_IN_MS);
- return () => {
- if (fetchInterval) {
- clearInterval(fetchInterval);
- }
- };
- }, []);
-
- return (
- <>
- {loading && (
-
-
-
- )}
-
- {livestreamMap && Object.keys(livestreamMap).length > 0 && (
- {
- const livestream = livestreamMap[claim.signing_channel.claim_id];
-
- return (
-
- {livestream.viewCount}
-
- );
- }}
- />
- )}
- >
- );
-}
diff --git a/ui/component/notification/view.jsx b/ui/component/notification/view.jsx
index b0f4b8587..a97bee087 100644
--- a/ui/component/notification/view.jsx
+++ b/ui/component/notification/view.jsx
@@ -37,6 +37,10 @@ export default function Notification(props: Props) {
const [isReplying, setReplying] = React.useState(false);
const [quickReply, setQuickReply] = React.useState();
+ const isIgnoredNotification = notification_rule === RULE.NEW_LIVESTREAM;
+ if (isIgnoredNotification) {
+ return null;
+ }
const isCommentNotification =
notification_rule === RULE.COMMENT ||
notification_rule === RULE.COMMENT_REPLY ||
@@ -83,10 +87,6 @@ export default function Notification(props: Props) {
channelUrl = notification_parameters.dynamic.channel_url;
icon = creatorIcon(channelUrl);
break;
- case RULE.NEW_LIVESTREAM:
- channelUrl = notification_parameters.dynamic.channel_url;
- icon = creatorIcon(channelUrl);
- break;
case RULE.DAILY_WATCH_AVAILABLE:
case RULE.DAILY_WATCH_REMIND:
case RULE.MISSED_OUT:
diff --git a/ui/component/page/view.jsx b/ui/component/page/view.jsx
index a9cfb5efa..1cb21c7ae 100644
--- a/ui/component/page/view.jsx
+++ b/ui/component/page/view.jsx
@@ -28,7 +28,6 @@ type Props = {
fullWidthPage: boolean,
videoTheaterMode: boolean,
isMarkdown?: boolean,
- livestream?: boolean,
chatDisabled: boolean,
rightSide?: Node,
backout: {
@@ -52,9 +51,7 @@ function Page(props: Props) {
backout,
videoTheaterMode,
isMarkdown = false,
- livestream,
rightSide,
- chatDisabled,
} = props;
const {
@@ -127,8 +124,7 @@ function Page(props: Props) {
'main--file-page': filePage,
'main--settings-page': settingsPage,
'main--markdown': isMarkdown,
- 'main--theater-mode': isOnFilePage && videoTheaterMode && !livestream,
- 'main--livestream': livestream && !chatDisabled,
+ 'main--theater-mode': isOnFilePage && videoTheaterMode,
})}
>
{children}
diff --git a/ui/component/publishFile/index.js b/ui/component/publishFile/index.js
index 6d2089a4f..fa595baee 100644
--- a/ui/component/publishFile/index.js
+++ b/ui/component/publishFile/index.js
@@ -2,12 +2,11 @@ import { connect } from 'react-redux';
import { selectBalance } from 'redux/selectors/wallet';
import { selectIsStillEditing, makeSelectPublishFormValue } from 'redux/selectors/publish';
import { doUpdatePublishForm, doClearPublish } from 'redux/actions/publish';
-import { makeSelectClaimIsStreamPlaceholder } from 'redux/selectors/claims';
import { doToast } from 'redux/actions/notifications';
import { selectFfmpegStatus } from 'redux/selectors/settings';
import PublishPage from './view';
-const select = (state, props) => ({
+const select = (state) => ({
name: makeSelectPublishFormValue('name')(state),
title: makeSelectPublishFormValue('title')(state),
filePath: makeSelectPublishFormValue('filePath')(state),
@@ -20,7 +19,6 @@ const select = (state, props) => ({
size: makeSelectPublishFormValue('fileSize')(state),
duration: makeSelectPublishFormValue('fileDur')(state),
isVid: makeSelectPublishFormValue('fileVid')(state),
- isLivestreamClaim: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
});
const perform = (dispatch) => ({
diff --git a/ui/component/publishFile/view.jsx b/ui/component/publishFile/view.jsx
index 1deaac089..38f082632 100644
--- a/ui/component/publishFile/view.jsx
+++ b/ui/component/publishFile/view.jsx
@@ -1,5 +1,4 @@
// @flow
-import { SITE_NAME, WEB_PUBLISH_SIZE_LIMIT_GB } from 'config';
import type { Node } from 'react';
import * as ICONS from 'constants/icons';
import React, { useState, useEffect } from 'react';
@@ -14,11 +13,6 @@ import I18nMessage from 'component/i18nMessage';
import usePersistedState from 'effects/use-persisted-state';
import * as PUBLISH_MODES from 'constants/publish_types';
import PublishName from 'component/publishName';
-import CopyableText from 'component/copyableText';
-import Empty from 'component/common/empty';
-import moment from 'moment';
-import classnames from 'classnames';
-import ReactPaginate from 'react-paginate';
type Props = {
uri: ?string,
@@ -44,12 +38,7 @@ type Props = {
setPublishMode: (string) => void,
setPrevFileText: (string) => void,
header: Node,
- livestreamData: LivestreamReplayData,
- isLivestreamClaim: boolean,
- checkLivestreams: (string, ?string, ?string) => void,
channelId: string,
- channelSignature: { signature?: string, signing_ts?: string },
- isCheckingLivestreams: boolean,
setWaitForFile: (boolean) => void,
};
@@ -76,23 +65,10 @@ function PublishFile(props: Props) {
setPublishMode,
setPrevFileText,
header,
- livestreamData,
- isLivestreamClaim,
subtitle,
- checkLivestreams,
- channelId,
- channelSignature,
- isCheckingLivestreams,
- setWaitForFile,
} = props;
- const SOURCE_NONE = 'none';
- const SOURCE_SELECT = 'select';
- const SOURCE_UPLOAD = 'upload';
-
const RECOMMENDED_BITRATE = 6000000;
- const TV_PUBLISH_SIZE_LIMIT_BYTES = WEB_PUBLISH_SIZE_LIMIT_GB * 1073741824;
- const TV_PUBLISH_SIZE_LIMIT_GB_STR = String(WEB_PUBLISH_SIZE_LIMIT_GB);
const PROCESSING_MB_PER_SECOND = 0.5;
const MINUTES_THRESHOLD = 30;
@@ -101,35 +77,10 @@ function PublishFile(props: Props) {
const sizeInMB = Number(size) / 1000000;
const secondsToProcess = sizeInMB / PROCESSING_MB_PER_SECOND;
const ffmpegAvail = ffmpegStatus.available;
- const [oversized, setOversized] = useState(false);
const [currentFile, setCurrentFile] = useState(null);
const [currentFileType, setCurrentFileType] = useState(null);
const [optimizeAvail, setOptimizeAvail] = useState(false);
const [userOptimize, setUserOptimize] = usePersistedState('publish-file-user-optimize', false);
- const UPLOAD_SIZE_MESSAGE = __(
- '%SITE_NAME% uploads are limited to %limit% GB. Download the app for unrestricted publishing.',
- { SITE_NAME, limit: TV_PUBLISH_SIZE_LIMIT_GB_STR }
- );
-
- const fileSelectorModes = [
- { label: __('Upload'), actionName: SOURCE_UPLOAD, icon: ICONS.PUBLISH },
- { label: __('Choose Replay'), actionName: SOURCE_SELECT, icon: ICONS.MENU },
- { label: __('None'), actionName: SOURCE_NONE },
- ];
-
- const livestreamDataStr = JSON.stringify(livestreamData);
- const hasLivestreamData = livestreamData && Boolean(livestreamData.length);
- const showSourceSelector = isLivestreamClaim || (hasLivestreamData && mode === PUBLISH_MODES.FILE);
-
- const [fileSelectSource, setFileSelectSource] = useState(
- IS_WEB && showSourceSelector && name ? SOURCE_SELECT : SOURCE_UPLOAD
- );
- // const [showFileUpdate, setShowFileUpdate] = useState(false);
- const [selectedFileIndex, setSelectedFileIndex] = useState(null);
- const PAGE_SIZE = 4;
- const [currentPage, setCurrentPage] = useState(1);
- const totalPages =
- hasLivestreamData && livestreamData.length > PAGE_SIZE ? Math.ceil(livestreamData.length / PAGE_SIZE) : 1;
// Reset filePath if publish mode changed
useEffect(() => {
@@ -137,46 +88,12 @@ function PublishFile(props: Props) {
if (currentFileType !== 'text/markdown' && !isStillEditing) {
updatePublishForm({ filePath: '' });
}
- } else if (mode === PUBLISH_MODES.LIVESTREAM) {
- updatePublishForm({ filePath: '' });
}
}, [currentFileType, mode, isStillEditing, updatePublishForm]);
- // set default file source to select if necessary
- useEffect(() => {
- if (hasLivestreamData && isLivestreamClaim) {
- setWaitForFile(true);
- setFileSelectSource(SOURCE_SELECT);
- } else if (isLivestreamClaim) {
- setFileSelectSource(SOURCE_NONE);
- }
- }, [hasLivestreamData, isLivestreamClaim, setFileSelectSource]);
-
- const normalizeUrlForProtocol = (url) => {
- if (url.startsWith('https://')) {
- return url;
- } else {
- if (url.startsWith('http://')) {
- return url;
- } else {
- return `https://${url}`;
- }
- }
- };
- // update remoteUrl when replay selected
- useEffect(() => {
- const livestreamData = JSON.parse(livestreamDataStr);
- if (selectedFileIndex !== null && livestreamData && livestreamData.length) {
- updatePublishForm({
- remoteFileUrl: normalizeUrlForProtocol(livestreamData[selectedFileIndex].data.fileLocation),
- });
- }
- }, [selectedFileIndex, updatePublishForm, livestreamDataStr]);
-
useEffect(() => {
if (!filePath || filePath === '') {
setCurrentFile('');
- setOversized(false);
updateFileInfo(0, 0, false);
} else if (typeof filePath !== 'string') {
// Update currentFile file
@@ -198,10 +115,6 @@ function PublishFile(props: Props) {
updatePublishForm({ fileDur: duration, fileSize: size, fileVid: isvid });
}
- function handlePaginateReplays(page) {
- setCurrentPage(page);
- }
-
function getBitrate(size, duration) {
const s = Number(size);
const d = Number(duration);
@@ -236,16 +149,6 @@ function PublishFile(props: Props) {
}
function getUploadMessage() {
- // @if TARGET='web'
- if (oversized) {
- return (
-
- {UPLOAD_SIZE_MESSAGE}{' '}
-
-
- );
- }
- // @endif
if (isVid && duration && getBitrate(size, duration) > RECOMMENDED_BITRATE) {
return (
@@ -267,32 +170,13 @@ function PublishFile(props: Props) {
}
if (!!isStillEditing && name) {
- if (isLivestreamClaim) {
- return (
-
{__('You can upload your own recording or select a replay when your stream is over')}
- );
- }
return (
{__("If you don't choose a file, the file from your existing claim %name% will be used", { name: name })}
);
}
- // @if TARGET='web'
- if (!isStillEditing) {
- return (
-
- {__(
- 'For video content, use MP4s in H264/AAC format and a friendly bitrate (under 5 Mbps) and resolution (720p) for more reliable streaming. %SITE_NAME% uploads are restricted to %limit% GB.',
- { SITE_NAME, limit: TV_PUBLISH_SIZE_LIMIT_GB_STR }
- )}{' '}
-
-
- );
- }
- // @endif
- // @if TARGET='app'
if (!isStillEditing) {
return (
@@ -303,7 +187,6 @@ function PublishFile(props: Props) {
);
}
- // @endif
}
function parseName(newName) {
@@ -311,27 +194,6 @@ function PublishFile(props: Props) {
return newName.replace(INVALID_URI_CHARS, '-');
}
- function handleFileSource(source) {
- if (source === SOURCE_NONE) {
- // clear files and remotes...
- // https://github.com/lbryio/lbry-desktop/issues/5855
- // publish is trying to use one field to share html file blob and string and such
- // $FlowFixMe
- handleFileChange(false, false);
- updatePublishForm({ remoteFileUrl: undefined });
- } else if (source === SOURCE_UPLOAD) {
- updatePublishForm({ remoteFileUrl: undefined });
- } else if (source === SOURCE_SELECT) {
- // $FlowFixMe
- handleFileChange(false, false);
- if (selectedFileIndex !== null) {
- updatePublishForm({ remoteFileUrl: livestreamData[selectedFileIndex].data.fileLocation });
- }
- }
- setFileSelectSource(source);
- setWaitForFile(source !== SOURCE_NONE);
- }
-
function handleTitleChange(event) {
const title = event.target.value;
// Update title
@@ -348,9 +210,7 @@ function PublishFile(props: Props) {
}
function handleFileChange(file: WebFile, clearName = true) {
- const { showToast } = props;
window.URL = window.URL || window.webkitURL;
- setOversized(false);
// select file, start to select a new one, then cancel
if (!file) {
@@ -410,16 +270,6 @@ function PublishFile(props: Props) {
setPublishMode(PUBLISH_MODES.FILE);
}
- // @if TARGET='web'
- // we only need to enforce file sizes on 'web'
- if (file.size && Number(file.size) > TV_PUBLISH_SIZE_LIMIT_BYTES) {
- setOversized(true);
- showToast(__(UPLOAD_SIZE_MESSAGE));
- updatePublishForm({ filePath: '', name: '' });
- return;
- }
- // @endif
-
const publishFormParams: { filePath: string | WebFile, name?: string, optimize?: boolean } = {
// if electron, we'll set filePath to the path string because SDK is handling publishing.
// File.path will be undefined from web due to browser security, so it will default to the File Object.
@@ -472,157 +322,18 @@ function PublishFile(props: Props) {
value={title}
onChange={handleTitleChange}
/>
- {/* Decide whether to show file upload or replay selector */}
- {/* @if TARGET='web' */}
- <>
- {showSourceSelector && (
-
-
-
-
{__('Replay video available')}
-
- {fileSelectorModes.map((fmode) => (
- {
- // $FlowFixMe
- handleFileSource(fmode.actionName);
- }}
- className={classnames('button-toggle', {
- 'button-toggle--active': fileSelectSource === fmode.actionName,
- })}
- />
- ))}
-
-
- {fileSelectSource === SOURCE_SELECT && (
-
- checkLivestreams(channelId, channelSignature.signature, channelSignature.signing_ts)
- }
- />
- )}
-
-
- )}
-
- {fileSelectSource === SOURCE_UPLOAD && showFileUpload && (
- <>
-
- {getUploadMessage()}
- >
- )}
- {fileSelectSource === SOURCE_SELECT && showFileUpload && hasLivestreamData && !isCheckingLivestreams && (
- <>
-
- {__('Select Replay')}
-
-
-
- {livestreamData.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE).map((item, i) => (
- setSelectedFileIndex((currentPage - 1) * PAGE_SIZE + i)}
- key={item.id}
- className={classnames('livestream__data-row', {
- 'livestream__data-row--selected': selectedFileIndex === (currentPage - 1) * PAGE_SIZE + i,
- })}
- >
-
- setSelectedFileIndex((currentPage - 1) * PAGE_SIZE + i)}
- className="livestream__data-row-radio"
- />
-
-
-
- {item.data.thumbnails.slice(0, 3).map((thumb) => (
-
- ))}
-
-
-
- {`${Math.floor(item.data.fileDuration / 60)} ${
- Math.floor(item.data.fileDuration / 60) > 1 ? __('minutes') : __('minute')
- }`}
-
- {`${moment(item.data.uploadedAt).from(moment())}`}
-
-
-
-
-
-
- ))}
-
-
-
-
-
-
- handlePaginateReplays(e.selected + 1)}
- forcePage={currentPage - 1}
- initialPage={currentPage - 1}
- containerClassName="pagination"
- />
-
-
- >
- )}
- {fileSelectSource === SOURCE_SELECT && showFileUpload && !hasLivestreamData && !isCheckingLivestreams && (
-
-
-
- )}
- {fileSelectSource === SOURCE_SELECT && showFileUpload && isCheckingLivestreams && (
-
-
-
- )}
- >
- {/* @endif */}
- {/* @if TARGET='app' */}
{showFileUpload && (
-
+ <>
+
+ {getUploadMessage()}
+ >
)}
{showFileUpload && (
)}
- {/* @endif */}
{isPublishPost && (
{
user: selectUser(state),
// The winning claim for a short lbry uri
amountNeededForTakeover: selectTakeOverAmount(state),
- isLivestreamClaim: makeSelectClaimIsStreamPlaceholder(permanentUrl)(state),
isPostClaim,
permanentUrl,
// My previously published claims under this short lbry uri
diff --git a/ui/component/publishForm/view.jsx b/ui/component/publishForm/view.jsx
index 1a1389857..68750c8b1 100644
--- a/ui/component/publishForm/view.jsx
+++ b/ui/component/publishForm/view.jsx
@@ -8,9 +8,8 @@
File upload is carried out in the background by that function.
*/
-import { SITE_NAME, ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM } from 'config';
+import { SITE_NAME } from 'config';
import React, { useEffect, useState } from 'react';
-import Lbry from 'lbry';
import { buildURI, isURIValid, isNameValid } from 'util/lbryURI';
import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses';
import Button from 'component/button';
@@ -29,13 +28,9 @@ import I18nMessage from 'component/i18nMessage';
import * as PUBLISH_MODES from 'constants/publish_types';
import { useHistory } from 'react-router';
import Spinner from 'component/spinner';
-import { toHex } from 'util/hex';
-import { LIVESTREAM_REPLAY_API } from 'constants/livestream';
-// @if TARGET='app'
import fs from 'fs';
import tempy from 'tempy';
-// @endif
type Props = {
disabled: boolean,
@@ -88,7 +83,6 @@ type Props = {
incognito: boolean,
user: ?User,
activeChannelStakedLevel: number,
- isLivestreamClaim: boolean,
isPostClaim: boolean,
permanentUrl: ?string,
remoteUrl: ?string,
@@ -127,9 +121,6 @@ function PublishForm(props: Props) {
enablePublishPreview,
activeChannelClaim,
incognito,
- user,
- activeChannelStakedLevel,
- isLivestreamClaim,
isPostClaim,
permanentUrl,
remoteUrl,
@@ -143,46 +134,31 @@ function PublishForm(props: Props) {
const TYPE_PARAM = 'type';
const uploadType = urlParams.get(TYPE_PARAM);
const _uploadType = uploadType && uploadType.toLowerCase();
- const enableLivestream =
- ENABLE_NO_SOURCE_CLAIMS &&
- user &&
- !user.odysee_live_disabled &&
- (activeChannelStakedLevel >= CHANNEL_STAKED_LEVEL_LIVESTREAM || user.odysee_live_enabled);
// $FlowFixMe
const AVAILABLE_MODES = Object.values(PUBLISH_MODES).filter((mode) => {
// $FlowFixMe
if (editingURI) {
if (isPostClaim) {
return mode === PUBLISH_MODES.POST;
- } else if (isLivestreamClaim) {
- return mode === PUBLISH_MODES.LIVESTREAM && enableLivestream;
} else {
return mode === PUBLISH_MODES.FILE;
}
} else if (_uploadType) {
- return mode === _uploadType && (mode !== PUBLISH_MODES.LIVESTREAM || enableLivestream);
+ return mode === _uploadType;
} else {
- return mode !== PUBLISH_MODES.LIVESTREAM || enableLivestream;
+ return false;
}
});
const MODE_TO_I18N_STR = {
[PUBLISH_MODES.FILE]: 'File',
[PUBLISH_MODES.POST]: 'Post --[noun, markdown post tab button]--',
- [PUBLISH_MODES.LIVESTREAM]: 'Livestream --[noun, livestream tab button]--',
};
const [mode, setMode] = React.useState(_uploadType || PUBLISH_MODES.FILE);
- const [isCheckingLivestreams, setCheckingLivestreams] = React.useState(false);
let customSubtitle;
- if (mode === PUBLISH_MODES.LIVESTREAM || isLivestreamClaim) {
- if (isLivestreamClaim) {
- customSubtitle = __('Update your livestream');
- } else {
- customSubtitle = __('Prepare an upcoming livestream');
- }
- } else if (mode === PUBLISH_MODES.POST || isPostClaim) {
+ if (mode === PUBLISH_MODES.POST || isPostClaim) {
if (isPostClaim) {
customSubtitle = __('Edit your post');
} else {
@@ -206,16 +182,12 @@ function PublishForm(props: Props) {
const [prevFileText, setPrevFileText] = React.useState('');
const [waitForFile, setWaitForFile] = useState(false);
- const [livestreamData, setLivestreamData] = React.useState([]);
- const [signedMessage, setSignedMessage] = React.useState({ signature: undefined, signing_ts: undefined });
- const signedMessageStr = JSON.stringify(signedMessage);
const TAGS_LIMIT = 5;
const fileFormDisabled = mode === PUBLISH_MODES.FILE && !filePath && !remoteUrl;
const emptyPostError = mode === PUBLISH_MODES.POST && (!fileText || fileText.trim() === '');
const formDisabled = (fileFormDisabled && !editingURI) || emptyPostError || publishing;
const isInProgress = filePath || editingURI || name || title;
const activeChannelName = activeChannelClaim && activeChannelClaim.name;
- const activeChannelClaimStr = JSON.stringify(activeChannelClaim);
// Editing content info
const fileMimeType =
myClaimForUri && myClaimForUri.value && myClaimForUri.value.source
@@ -251,27 +223,6 @@ function PublishForm(props: Props) {
const [previewing, setPreviewing] = React.useState(false);
- React.useEffect(() => {
- if (activeChannelClaimStr) {
- const channelClaim = JSON.parse(activeChannelClaimStr);
- const message = 'get-claim-id-replays';
- setSignedMessage({ signature: null, signing_ts: null });
- // ensure we have a channel
- if (channelClaim.claim_id) {
- Lbry.channel_sign({
- channel_id: channelClaim.claim_id,
- hexdata: toHex(message),
- })
- .then((data) => {
- setSignedMessage(data);
- })
- .catch((error) => {
- setSignedMessage({ signature: null, signing_ts: null });
- });
- }
- }
- }, [activeChannelClaimStr, setSignedMessage]);
-
useEffect(() => {
if (!hasClaimedInitialRewards) {
claimInitialRewards();
@@ -286,32 +237,6 @@ function PublishForm(props: Props) {
}
}, [modal]);
- // move this to lbryinc OR to a file under ui, and/or provide a standardized livestreaming config.
- function fetchLivestreams(channelId, signature, timestamp) {
- setCheckingLivestreams(true);
- fetch(`${LIVESTREAM_REPLAY_API}/${channelId}?signature=${signature || ''}&signing_ts=${timestamp || ''}`) // claimChannelId
- .then((res) => res.json())
- .then((res) => {
- if (!res || !res.data) {
- setLivestreamData([]);
- }
- setLivestreamData(res.data);
- setCheckingLivestreams(false);
- })
- .catch((e) => {
- setLivestreamData([]);
- setCheckingLivestreams(false);
- });
- }
-
- useEffect(() => {
- const signedMessage = JSON.parse(signedMessageStr);
- if (claimChannelId && signedMessage.signature) {
- fetchLivestreams(claimChannelId, signedMessage.signature, signedMessage.signing_ts);
- }
- }, [claimChannelId, signedMessageStr]);
-
- const isLivestreamMode = mode === PUBLISH_MODES.LIVESTREAM;
let submitLabel;
if (isClaimingInitialRewards) {
@@ -319,8 +244,6 @@ function PublishForm(props: Props) {
} else if (publishing) {
if (isStillEditing) {
submitLabel = __('Saving...');
- } else if (isLivestreamMode) {
- submitLabel = __('Creating...');
} else {
submitLabel = __('Uploading...');
}
@@ -329,8 +252,6 @@ function PublishForm(props: Props) {
} else {
if (isStillEditing) {
submitLabel = __('Save');
- } else if (isLivestreamMode) {
- submitLabel = __('Create');
} else {
submitLabel = __('Upload');
}
@@ -398,26 +319,20 @@ function PublishForm(props: Props) {
}
}, [editingURI, resolveUri]);
- // set isMarkdownPost in publish form if so, also update isLivestreamPublish
+ // set isMarkdownPost in publish form if so
useEffect(() => {
updatePublishForm({
isMarkdownPost: mode === PUBLISH_MODES.POST,
- isLivestreamPublish: mode === PUBLISH_MODES.LIVESTREAM,
});
}, [mode, updatePublishForm]);
useEffect(() => {
if (incognito) {
updatePublishForm({ channel: undefined });
-
- // Anonymous livestreams aren't supported
- if (isLivestreamMode) {
- setMode(PUBLISH_MODES.FILE);
- }
} else if (activeChannelName) {
updatePublishForm({ channel: activeChannelName });
}
- }, [activeChannelName, incognito, updatePublishForm, isLivestreamMode]);
+ }, [activeChannelName, incognito, updatePublishForm]);
// set mode based on urlParams 'type'
useEffect(() => {
@@ -437,19 +352,10 @@ function PublishForm(props: Props) {
setMode(PUBLISH_MODES.POST);
return;
}
- // LiveStream publish
- if (_uploadType === PUBLISH_MODES.LIVESTREAM.toLowerCase()) {
- if (enableLivestream) {
- setMode(PUBLISH_MODES.LIVESTREAM);
- } else {
- setMode(PUBLISH_MODES.FILE);
- }
- return;
- }
// Default to standard file publish
setMode(PUBLISH_MODES.FILE);
- }, [_uploadType, enableLivestream]);
+ }, [_uploadType]);
// if we have a type urlparam, update it? necessary?
useEffect(() => {
@@ -509,7 +415,7 @@ function PublishForm(props: Props) {
}
}
// Publish file
- if (mode === PUBLISH_MODES.FILE || isLivestreamMode) {
+ if (mode === PUBLISH_MODES.FILE) {
runPublish = true;
}
@@ -555,7 +461,7 @@ function PublishForm(props: Props) {
// Editing claim uri
return (
-
+
{AVAILABLE_MODES.map((modeName) => (
@@ -595,7 +497,7 @@ function PublishForm(props: Props) {
{!publishing && (
{mode !== PUBLISH_MODES.POST &&
}
-
} />
+
} />
- {!isLivestreamMode &&
}
+
)}
diff --git a/ui/component/router/view.jsx b/ui/component/router/view.jsx
index a9a0b6609..6d42cb2a3 100644
--- a/ui/component/router/view.jsx
+++ b/ui/component/router/view.jsx
@@ -46,8 +46,6 @@ import InvitedPage from 'page/invited';
import LibraryPage from 'page/library';
import ListBlockedPage from 'page/listBlocked';
import ListsPage from 'page/lists';
-import LiveStreamSetupPage from 'page/livestreamSetup';
-import LivestreamCurrentPage from 'page/livestreamCurrent';
import OwnComments from 'page/ownComments';
import PasswordResetPage from 'page/passwordReset';
import PasswordSetPage from 'page/passwordSet';
@@ -306,8 +304,6 @@ function AppRouter(props: Props) {
-
-
diff --git a/ui/constants/action_types.js b/ui/constants/action_types.js
index 9fbeeecd1..4a1d2e46d 100644
--- a/ui/constants/action_types.js
+++ b/ui/constants/action_types.js
@@ -463,16 +463,6 @@ export const REPORT_CONTENT_STARTED = 'REPORT_CONTENT_STARTED';
export const REPORT_CONTENT_COMPLETED = 'REPORT_CONTENT_COMPLETED';
export const REPORT_CONTENT_FAILED = 'REPORT_CONTENT_FAILED';
-// Livestream
-export const FETCH_NO_SOURCE_CLAIMS_STARTED = 'FETCH_NO_SOURCE_CLAIMS_STARTED';
-export const FETCH_NO_SOURCE_CLAIMS_COMPLETED = 'FETCH_NO_SOURCE_CLAIMS_COMPLETED';
-export const FETCH_NO_SOURCE_CLAIMS_FAILED = 'FETCH_NO_SOURCE_CLAIMS_FAILED';
-export const VIEWERS_RECEIVED = 'VIEWERS_RECEIVED';
-export const FETCH_ACTIVE_LIVESTREAMS_STARTED = 'FETCH_ACTIVE_LIVESTREAMS_STARTED';
-export const FETCH_ACTIVE_LIVESTREAMS_FAILED = 'FETCH_ACTIVE_LIVESTREAMS_FAILED';
-export const FETCH_ACTIVE_LIVESTREAMS_SKIPPED = 'FETCH_ACTIVE_LIVESTREAMS_SKIPPED';
-export const FETCH_ACTIVE_LIVESTREAMS_COMPLETED = 'FETCH_ACTIVE_LIVESTREAMS_COMPLETED';
-
// Blacklist
export const FETCH_BLACK_LISTED_CONTENT_STARTED = 'FETCH_BLACK_LISTED_CONTENT_STARTED';
export const FETCH_BLACK_LISTED_CONTENT_COMPLETED = 'FETCH_BLACK_LISTED_CONTENT_COMPLETED';
diff --git a/ui/constants/form-field.js b/ui/constants/form-field.js
index 7c011626e..7ca0ece5d 100644
--- a/ui/constants/form-field.js
+++ b/ui/constants/form-field.js
@@ -1,6 +1,5 @@
export const FF_MAX_CHARS_DEFAULT = 2000;
export const FF_MAX_CHARS_IN_COMMENT = 2000;
-export const FF_MAX_CHARS_IN_LIVESTREAM_COMMENT = 300;
export const FF_MAX_CHARS_IN_DESCRIPTION = 5000;
export const FF_MAX_CHARS_REPORT_CONTENT_DETAILS = 500;
export const FF_MAX_CHARS_REPORT_CONTENT_ADDRESS = 255;
diff --git a/ui/constants/icons.js b/ui/constants/icons.js
index c66264ffd..e707d3adb 100644
--- a/ui/constants/icons.js
+++ b/ui/constants/icons.js
@@ -158,9 +158,6 @@ export const CHEESE = 'Cheese';
export const PEACE = 'Peace';
export const PORK_BUN = 'PorkBun';
export const MIND_BLOWN = 'MindBlown';
-export const LIVESTREAM = 'Livestream';
-export const LIVESTREAM_SOLID = 'LivestreamSolid';
-export const LIVESTREAM_MONOCHROME = 'LivestreamMono';
export const STACK = 'stack';
export const TIME = 'time';
export const GLOBE = 'globe';
diff --git a/ui/constants/livestream.js b/ui/constants/livestream.js
deleted file mode 100644
index dced95c79..000000000
--- a/ui/constants/livestream.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export const LIVESTREAM_EMBED_URL = 'https://player.live.odysee.com/odysee';
-export const LIVESTREAM_LIVE_API = 'https://api.live.odysee.com/v1/odysee/live';
-export const LIVESTREAM_REPLAY_API = 'https://api.live.odysee.com/v1/replays/odysee';
-export const LIVESTREAM_RTMP_URL = 'rtmp://stream.odysee.com/live';
diff --git a/ui/constants/pageTitles.js b/ui/constants/pageTitles.js
index fd330974b..17c5c3920 100644
--- a/ui/constants/pageTitles.js
+++ b/ui/constants/pageTitles.js
@@ -34,8 +34,6 @@ export const PAGE_TITLE = {
[PAGES.HELP]: 'Help',
[PAGES.INVITE]: 'Invite',
[PAGES.LISTS]: 'Lists',
- [PAGES.LIVESTREAM]: 'Go Live on Odysee',
- [PAGES.LIVESTREAM_CURRENT]: 'Live (Experimental)',
[PAGES.NOTIFICATIONS]: 'Notifications',
[PAGES.RECEIVE]: 'Your address',
[PAGES.REPORT]: 'Report an issue or request a feature',
diff --git a/ui/constants/pages.js b/ui/constants/pages.js
index 495c1bf93..770514ac7 100644
--- a/ui/constants/pages.js
+++ b/ui/constants/pages.js
@@ -73,7 +73,5 @@ exports.SWAP = 'swap';
exports.CHANNEL_NEW = 'channel/new';
exports.NOTIFICATIONS = 'notifications';
exports.YOUTUBE_SYNC = 'youtube';
-exports.LIVESTREAM = 'livestream';
-exports.LIVESTREAM_CURRENT = 'live';
exports.GENERAL = 'general';
exports.LIST = 'list';
diff --git a/ui/constants/publish_types.js b/ui/constants/publish_types.js
index e07befd3b..c6436ab94 100644
--- a/ui/constants/publish_types.js
+++ b/ui/constants/publish_types.js
@@ -1,3 +1,2 @@
export const FILE = 'file';
export const POST = 'post';
-export const LIVESTREAM = 'livestream';
diff --git a/ui/modal/modalPublish/index.js b/ui/modal/modalPublish/index.js
index 910d9b782..d42adb08d 100644
--- a/ui/modal/modalPublish/index.js
+++ b/ui/modal/modalPublish/index.js
@@ -1,18 +1,13 @@
import { connect } from 'react-redux';
import { doHideModal } from 'redux/actions/app';
import ModalPublishSuccess from './view';
-import { makeSelectClaimForUri } from 'redux/selectors/claims';
import { doClearPublish } from 'redux/actions/publish';
import { push } from 'connected-react-router';
-const select = (state, props) => ({
- claim: makeSelectClaimForUri(props.uri)(state),
-});
-
const perform = (dispatch) => ({
closeModal: () => dispatch(doHideModal()),
clearPublish: () => dispatch(doClearPublish()),
navigate: (path) => dispatch(push(path)),
});
-export default connect(select, perform)(ModalPublishSuccess);
+export default connect(null, perform)(ModalPublishSuccess);
diff --git a/ui/modal/modalPublish/view.jsx b/ui/modal/modalPublish/view.jsx
index 34075e3c3..ad7588011 100644
--- a/ui/modal/modalPublish/view.jsx
+++ b/ui/modal/modalPublish/view.jsx
@@ -15,7 +15,6 @@ type Props = {
isEdit: boolean,
filePath: ?string,
lbryFirstError: ?string,
- claim: Claim,
};
class ModalPublishSuccess extends React.PureComponent {
@@ -24,13 +23,10 @@ class ModalPublishSuccess extends React.PureComponent {
clearPublish();
}
render() {
- const { closeModal, clearPublish, navigate, uri, isEdit, filePath, lbryFirstError, claim } = this.props;
+ const { closeModal, clearPublish, navigate, uri, isEdit, filePath, lbryFirstError } = this.props;
// $FlowFixMe
- const livestream = claim && claim.value && claim.value_type === 'stream' && !claim.value.source;
let contentLabel;
- if (livestream) {
- contentLabel = __('Livestream Created');
- } else if (isEdit) {
+ if (isEdit) {
contentLabel = __('Update published');
} else {
contentLabel = __('File published');
@@ -39,10 +35,6 @@ class ModalPublishSuccess extends React.PureComponent {
let publishMessage;
if (isEdit) {
publishMessage = __('Your update is now pending. It will take a few minutes to appear for other users.');
- } else if (livestream) {
- publishMessage = __(
- 'Your livestream is now pending. You will be able to start shortly at the streaming dashboard.'
- );
} else {
publishMessage = __('Your content will be live shortly.');
}
@@ -54,7 +46,7 @@ class ModalPublishSuccess extends React.PureComponent {
return (
@@ -75,28 +67,15 @@ class ModalPublishSuccess extends React.PureComponent {
}
actions={
- {!livestream && (
- {
- clearPublish();
- navigate(`/$/${PAGES.UPLOADS}`);
- closeModal();
- }}
- />
- )}
- {livestream && (
- {
- clearPublish();
- navigate(`/$/${PAGES.LIVESTREAM}`);
- closeModal();
- }}
- />
- )}
+ {
+ clearPublish();
+ navigate(`/$/${PAGES.UPLOADS}`);
+ closeModal();
+ }}
+ />
}
diff --git a/ui/modal/modalPublishPreview/index.js b/ui/modal/modalPublishPreview/index.js
index 8a3056169..74e834969 100644
--- a/ui/modal/modalPublishPreview/index.js
+++ b/ui/modal/modalPublishPreview/index.js
@@ -2,26 +2,21 @@ import { connect } from 'react-redux';
import { doHideModal } from 'redux/actions/app';
import ModalPublishPreview from './view';
import { makeSelectPublishFormValue, selectPublishFormValues, selectIsStillEditing } from 'redux/selectors/publish';
-import { selectMyChannelClaims, makeSelectClaimIsStreamPlaceholder } from 'redux/selectors/claims';
+import { selectMyChannelClaims } from 'redux/selectors/claims';
import * as SETTINGS from 'constants/settings';
import { selectFfmpegStatus, makeSelectClientSetting } from 'redux/selectors/settings';
import { doPublishDesktop } from 'redux/actions/publish';
import { doSetClientSetting } from 'redux/actions/settings';
-const select = (state, props) => {
- const editingUri = makeSelectPublishFormValue('editingURI')(state);
-
+const select = (state) => {
return {
...selectPublishFormValues(state),
myChannels: selectMyChannelClaims(state),
isVid: makeSelectPublishFormValue('fileVid')(state),
- publishSuccess: makeSelectPublishFormValue('publishSuccess')(state),
publishing: makeSelectPublishFormValue('publishing')(state),
- remoteFile: makeSelectPublishFormValue('remoteFileUrl')(state),
isStillEditing: selectIsStillEditing(state),
ffmpegStatus: selectFfmpegStatus(state),
enablePublishPreview: makeSelectClientSetting(SETTINGS.ENABLE_PUBLISH_PREVIEW)(state),
- isLivestreamClaim: makeSelectClaimIsStreamPlaceholder(editingUri)(state),
};
};
diff --git a/ui/modal/modalPublishPreview/view.jsx b/ui/modal/modalPublishPreview/view.jsx
index 194e538b1..e95adddc1 100644
--- a/ui/modal/modalPublishPreview/view.jsx
+++ b/ui/modal/modalPublishPreview/view.jsx
@@ -45,7 +45,6 @@ type Props = {
myChannels: ?Array,
publishSuccess: boolean,
publishing: boolean,
- isLivestreamClaim: boolean,
remoteFile: string,
};
@@ -75,12 +74,9 @@ const ModalPublishPreview = (props: Props) => {
setEnablePublishPreview,
isStillEditing,
myChannels,
- publishSuccess,
publishing,
publish,
closeModal,
- isLivestreamClaim,
- remoteFile,
} = props;
const maxCharsBeforeOverflow = 128;
@@ -99,20 +95,7 @@ const ModalPublishPreview = (props: Props) => {
return uri;
}, [uri]);
- const livestream =
- (uri && isLivestreamClaim) ||
- // $FlowFixMe
- (previewResponse.outputs[0] && previewResponse.outputs[0].value && !previewResponse.outputs[0].value.source);
// leave the confirm modal up if we're not going straight to upload/reflecting
- // @if TARGET='web'
- React.useEffect(() => {
- if (publishing && !livestream) {
- closeModal();
- } else if (publishSuccess) {
- closeModal();
- }
- }, [publishSuccess, publishing, livestream]);
- // @endif
function onConfirmed() {
// Publish for real:
publish(getFilePathName(filePath), false);
@@ -147,13 +130,7 @@ const ModalPublishPreview = (props: Props) => {
const isOptimizeAvail = filePath && filePath !== '' && isVid && ffmpegStatus.available;
let modalTitle;
if (isStillEditing) {
- if (livestream) {
- modalTitle = __('Confirm Update');
- } else {
- modalTitle = __('Confirm Edit');
- }
- } else if (livestream) {
- modalTitle = __('Create Livestream');
+ modalTitle = __('Confirm Edit');
} else {
modalTitle = __('Confirm Upload');
}
@@ -162,16 +139,12 @@ const ModalPublishPreview = (props: Props) => {
if (!publishing) {
if (isStillEditing) {
confirmBtnText = __('Save');
- } else if (livestream) {
- confirmBtnText = __('Create');
} else {
confirmBtnText = __('Upload');
}
} else {
if (isStillEditing) {
confirmBtnText = __('Saving');
- } else if (livestream) {
- confirmBtnText = __('Creating');
} else {
confirmBtnText = __('Uploading');
}
@@ -240,8 +213,7 @@ const ModalPublishPreview = (props: Props) => {
- {!livestream && !isMarkdownPost && createRow(__('File'), getFilePathName(filePath))}
- {livestream && remoteFile && createRow(__('Replay'), __('Remote File Selected'))}
+ {!isMarkdownPost && createRow(__('File'), getFilePathName(filePath))}
{isOptimizeAvail && createRow(__('Transcode'), optimize ? __('Yes') : __('No'))}
{createRow(__('Title'), formattedTitle)}
{createRow(__('Description'), descriptionValue)}
diff --git a/ui/page/discover/index.js b/ui/page/discover/index.js
index 9ff45a9f0..0d0823b74 100644
--- a/ui/page/discover/index.js
+++ b/ui/page/discover/index.js
@@ -3,8 +3,6 @@ import { connect } from 'react-redux';
import { doResolveUri } from 'redux/actions/claims';
import { makeSelectClaimForUri } from 'redux/selectors/claims';
import * as SETTINGS from 'constants/settings';
-import { doFetchActiveLivestreams } from 'redux/actions/livestream';
-import { selectActiveLivestreams } from 'redux/selectors/livestream';
import { selectUserVerifiedEmail } from 'redux/selectors/user';
import { selectFollowedTags } from 'redux/selectors/tags';
import { doToggleTagFollowDesktop } from 'redux/actions/tags';
@@ -22,12 +20,10 @@ const select = (state, props) => {
repostedClaim: repostedUri ? makeSelectClaimForUri(repostedUri)(state) : null,
isAuthenticated: selectUserVerifiedEmail(state),
tileLayout: makeSelectClientSetting(SETTINGS.TILE_LAYOUT)(state),
- activeLivestreams: selectActiveLivestreams(state),
};
};
export default connect(select, {
doToggleTagFollowDesktop,
doResolveUri,
- doFetchActiveLivestreams,
})(Tags);
diff --git a/ui/page/file/index.js b/ui/page/file/index.js
index 794c0ce78..0395c634f 100644
--- a/ui/page/file/index.js
+++ b/ui/page/file/index.js
@@ -5,7 +5,6 @@ import {
makeSelectMetadataForUri,
makeSelectClaimIsNsfw,
makeSelectTagInClaimOrChannelForUri,
- makeSelectClaimIsStreamPlaceholder,
} from 'redux/selectors/claims';
import { makeSelectFileInfoForUri } from 'redux/selectors/file_info';
import { doFetchFileInfo } from 'redux/actions/file_info';
@@ -34,7 +33,6 @@ const select = (state, props) => {
renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
videoTheaterMode: makeSelectClientSetting(SETTINGS.VIDEO_THEATER_MODE)(state),
commentsDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state),
- isLivestream: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
collection: makeSelectCollectionForId(collectionId)(state),
collectionId,
position: makeSelectContentPositionForUri(props.uri)(state),
diff --git a/ui/page/file/view.jsx b/ui/page/file/view.jsx
index 3ea978c0e..10df5fce0 100644
--- a/ui/page/file/view.jsx
+++ b/ui/page/file/view.jsx
@@ -1,5 +1,4 @@
// @flow
-import * as PAGES from 'constants/pages';
import * as React from 'react';
import classnames from 'classnames';
import Page from 'component/page';
@@ -11,8 +10,6 @@ import FileRenderDownload from 'component/fileRenderDownload';
import RecommendedContent from 'component/recommendedContent';
import CollectionContent from 'component/collectionContentSidebar';
import CommentsList from 'component/commentsList';
-import Button from 'component/button';
-import I18nMessage from 'component/i18nMessage';
import Empty from 'component/common/empty';
import PostViewer from 'component/postViewer';
@@ -36,7 +33,6 @@ type Props = {
videoTheaterMode: boolean,
claimIsMine: boolean,
commentsDisabled: boolean,
- isLivestream: boolean,
clearPosition: (string) => void,
position: number,
};
@@ -55,12 +51,9 @@ function FilePage(props: Props) {
linkedCommentId,
setPrimaryUri,
videoTheaterMode,
-
- claimIsMine,
commentsDisabled,
collection,
collectionId,
- isLivestream,
clearPosition,
position,
} = props;
@@ -190,18 +183,6 @@ 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 &&
}
diff --git a/ui/page/livestream/index.js b/ui/page/livestream/index.js
deleted file mode 100644
index a4ab99d66..000000000
--- a/ui/page/livestream/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import { connect } from 'react-redux';
-import { makeSelectTagInClaimOrChannelForUri, makeSelectClaimForUri } from 'redux/selectors/claims';
-import { doResolveUri } from 'redux/actions/claims';
-import { doSetPlayingUri } from 'redux/actions/content';
-import { doUserSetReferrer } from 'redux/actions/user';
-import { selectUserVerifiedEmail } from 'redux/selectors/user';
-import { selectHasUnclaimedRefereeReward } from 'redux/selectors/rewards';
-import { DISABLE_COMMENTS_TAG } from 'constants/tags';
-import LivestreamPage from './view';
-
-const select = (state, props) => ({
- hasUnclaimedRefereeReward: selectHasUnclaimedRefereeReward(state),
- isAuthenticated: selectUserVerifiedEmail(state),
- channelClaim: makeSelectClaimForUri(props.uri)(state),
- chatDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state),
-});
-
-export default connect(select, {
- doSetPlayingUri,
- doResolveUri,
- doUserSetReferrer,
-})(LivestreamPage);
diff --git a/ui/page/livestream/view.jsx b/ui/page/livestream/view.jsx
deleted file mode 100644
index 727c66fb0..000000000
--- a/ui/page/livestream/view.jsx
+++ /dev/null
@@ -1,124 +0,0 @@
-// @flow
-import { LIVESTREAM_LIVE_API } from 'constants/livestream';
-import React from 'react';
-import Page from 'component/page';
-import LivestreamLayout from 'component/livestreamLayout';
-import LivestreamComments from 'component/livestreamComments';
-import analytics from 'analytics';
-import Lbry from 'lbry';
-
-type Props = {
- uri: string,
- claim: StreamClaim,
- doSetPlayingUri: ({ uri: ?string }) => void,
- isAuthenticated: boolean,
- doUserSetReferrer: (string) => void,
- channelClaim: ChannelClaim,
- chatDisabled: boolean,
-};
-
-export default function LivestreamPage(props: Props) {
- const { uri, claim, doSetPlayingUri, isAuthenticated, doUserSetReferrer, channelClaim, chatDisabled } = props;
- const [isLive, setIsLive] = React.useState(false);
- const livestreamChannelId = channelClaim && channelClaim.signing_channel && channelClaim.signing_channel.claim_id;
- const [hasLivestreamClaim, setHasLivestreamClaim] = React.useState(false);
-
- const STREAMING_POLL_INTERVAL_IN_MS = 10000;
- const LIVESTREAM_CLAIM_POLL_IN_MS = 60000;
-
- React.useEffect(() => {
- let checkClaimsInterval;
- function checkHasLivestreamClaim() {
- Lbry.claim_search({
- channel_ids: [livestreamChannelId],
- has_no_source: true,
- claim_type: ['stream'],
- })
- .then((res) => {
- if (res && res.items && res.items.length > 0) {
- setHasLivestreamClaim(true);
- }
- })
- .catch(() => {});
- }
- if (livestreamChannelId && !isLive) {
- if (!checkClaimsInterval) checkHasLivestreamClaim();
- checkClaimsInterval = setInterval(checkHasLivestreamClaim, LIVESTREAM_CLAIM_POLL_IN_MS);
-
- return () => {
- if (checkClaimsInterval) {
- clearInterval(checkClaimsInterval);
- }
- };
- }
- }, [livestreamChannelId, isLive]);
-
- React.useEffect(() => {
- let interval;
- function checkIsLive() {
- // TODO: duplicate code below
- // $FlowFixMe livestream API can handle garbage
- fetch(`${LIVESTREAM_LIVE_API}/${livestreamChannelId}`)
- .then((res) => res.json())
- .then((res) => {
- if (!res || !res.data) {
- setIsLive(false);
- return;
- }
-
- if (res.data.hasOwnProperty('live')) {
- setIsLive(res.data.live);
- }
- });
- }
- if (livestreamChannelId && hasLivestreamClaim) {
- if (!interval) checkIsLive();
- interval = setInterval(checkIsLive, STREAMING_POLL_INTERVAL_IN_MS);
-
- return () => {
- if (interval) {
- clearInterval(interval);
- }
- };
- }
- }, [livestreamChannelId, hasLivestreamClaim]);
-
- const stringifiedClaim = JSON.stringify(claim);
- React.useEffect(() => {
- if (uri && stringifiedClaim) {
- const jsonClaim = JSON.parse(stringifiedClaim);
-
- if (jsonClaim) {
- const { txid, nout, claim_id: claimId } = jsonClaim;
- const outpoint = `${txid}:${nout}`;
-
- analytics.apiLogView(uri, outpoint, claimId);
- }
-
- if (!isAuthenticated) {
- const uri = jsonClaim.signing_channel && jsonClaim.signing_channel.permanent_url;
- if (uri) {
- doUserSetReferrer(uri.replace('lbry://', ''));
- }
- }
- }
- }, [uri, stringifiedClaim, isAuthenticated]);
-
- React.useEffect(() => {
- // Set playing uri to null so the popout player doesnt start playing the dummy claim if a user navigates back
- // This can be removed when we start using the app video player, not a LIVESTREAM iframe
- doSetPlayingUri({ uri: null });
- }, [doSetPlayingUri]);
-
- return (
-
}
- >
-
-
- );
-}
diff --git a/ui/page/livestreamCurrent/index.js b/ui/page/livestreamCurrent/index.js
deleted file mode 100644
index 972e69dee..000000000
--- a/ui/page/livestreamCurrent/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import { connect } from 'react-redux';
-import { selectUser } from 'redux/selectors/user';
-import LivestreamCurrent from './view';
-
-const select = (state) => ({
- user: selectUser(state),
-});
-
-export default connect(select)(LivestreamCurrent);
diff --git a/ui/page/livestreamCurrent/view.jsx b/ui/page/livestreamCurrent/view.jsx
deleted file mode 100644
index 8296fb4e7..000000000
--- a/ui/page/livestreamCurrent/view.jsx
+++ /dev/null
@@ -1,34 +0,0 @@
-// @flow
-import React from 'react';
-import LivestreamList from 'component/livestreamList';
-import Button from 'component/button';
-import Page from 'component/page';
-import Yrbl from 'component/yrbl';
-
-type Props = {
- user: ?User,
-};
-
-export default function LivestreamCurrentPage(props: Props) {
- const { user } = props;
- const canView = process.env.ENABLE_WIP_FEATURES || (user && user.global_mod);
-
- return (
-
- {canView ? (
-
- ) : (
-
-
-
- }
- />
- )}
-
- );
-}
diff --git a/ui/page/livestreamSetup/index.js b/ui/page/livestreamSetup/index.js
deleted file mode 100644
index c00883391..000000000
--- a/ui/page/livestreamSetup/index.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import { connect } from 'react-redux';
-import { selectMyChannelClaims, selectFetchingMyChannels } from 'redux/selectors/claims';
-import { doClearPublish } from 'redux/actions/publish';
-import { selectActiveChannelClaim } from 'redux/selectors/app';
-import { doFetchNoSourceClaims } from 'redux/actions/livestream';
-import {
- makeSelectPendingLivestreamsForChannelId,
- makeSelectLivestreamsForChannelId,
- makeSelectIsFetchingLivestreams,
-} from 'redux/selectors/livestream';
-import LivestreamSetupPage from './view';
-import { push } from 'connected-react-router';
-
-const select = (state) => {
- const activeChannelClaim = selectActiveChannelClaim(state);
- const { claim_id: channelId, name: channelName } = activeChannelClaim || {};
- return {
- channelName,
- channelId,
- channels: selectMyChannelClaims(state),
- fetchingChannels: selectFetchingMyChannels(state),
- activeChannelClaim,
- myLivestreamClaims: makeSelectLivestreamsForChannelId(channelId)(state),
- pendingClaims: makeSelectPendingLivestreamsForChannelId(channelId)(state),
- fetchingLivestreams: makeSelectIsFetchingLivestreams(channelId)(state),
- };
-};
-const perform = (dispatch) => ({
- doNewLivestream: (path) => {
- dispatch(doClearPublish());
- dispatch(push(path));
- },
- fetchNoSourceClaims: (id) => dispatch(doFetchNoSourceClaims(id)),
-});
-export default connect(select, perform)(LivestreamSetupPage);
diff --git a/ui/page/livestreamSetup/view.jsx b/ui/page/livestreamSetup/view.jsx
deleted file mode 100644
index 301dc5368..000000000
--- a/ui/page/livestreamSetup/view.jsx
+++ /dev/null
@@ -1,324 +0,0 @@
-// @flow
-import * as PAGES from 'constants/pages';
-import * as ICONS from 'constants/icons';
-import * as PUBLISH_MODES from 'constants/publish_types';
-import I18nMessage from 'component/i18nMessage';
-import React from 'react';
-import Page from 'component/page';
-import Spinner from 'component/spinner';
-import Button from 'component/button';
-import ChannelSelector from 'component/channelSelector';
-import Yrbl from 'component/yrbl';
-import Lbry from 'lbry';
-import { toHex } from 'util/hex';
-import { FormField } from 'component/common/form';
-import CopyableText from 'component/copyableText';
-import Card from 'component/common/card';
-import ClaimList from 'component/claimList';
-import usePersistedState from 'effects/use-persisted-state';
-import { LIVESTREAM_RTMP_URL } from 'constants/livestream';
-
-type Props = {
- channels: Array
,
- fetchingChannels: boolean,
- activeChannelClaim: ?ChannelClaim,
- pendingClaims: Array,
- doNewLivestream: (string) => void,
- fetchNoSourceClaims: (string) => void,
- myLivestreamClaims: Array,
- fetchingLivestreams: boolean,
- channelId: ?string,
- channelName: ?string,
-};
-
-export default function LivestreamSetupPage(props: Props) {
- const LIVESTREAM_CLAIM_POLL_IN_MS = 60000;
- const {
- channels,
- fetchingChannels,
- activeChannelClaim,
- pendingClaims,
- doNewLivestream,
- fetchNoSourceClaims,
- myLivestreamClaims,
- fetchingLivestreams,
- channelId,
- channelName,
- } = props;
-
- const [sigData, setSigData] = React.useState({ signature: undefined, signing_ts: undefined });
- const [showHelp, setShowHelp] = usePersistedState('livestream-help-seen', true);
-
- const hasChannels = channels && channels.length > 0;
- const hasLivestreamClaims = Boolean(myLivestreamClaims.length || pendingClaims.length);
-
- function createStreamKey() {
- if (!channelId || !channelName || !sigData.signature || !sigData.signing_ts) return null;
- return `${channelId}?d=${toHex(channelName)}&s=${sigData.signature}&t=${sigData.signing_ts}`;
- }
-
- const streamKey = createStreamKey();
-
- const pendingLength = pendingClaims.length;
- const totalLivestreamClaims = pendingClaims.concat(myLivestreamClaims);
- const helpText = (
-
-
- {__(
- `Create a Livestream by first submitting your livestream details and waiting for approval confirmation. This can be done well in advance and will take a few minutes.`
- )}{' '}
- {__(
- `The livestream will not be visible on your channel page until you are live, but you can share the URL in advance.`
- )}{' '}
- {__(
- `Once the your livestream is confirmed, configure your streaming software (OBS, Restream, etc) and input the server URL along with the stream key in it.`
- )}
-
-
{__(`To ensure the best streaming experience with OBS, open settings -> output`)}
-
{__(`Select advanced mode from the dropdown at the top.`)}
-
{__(`Ensure the following settings are selected under the streaming tab:`)}
-
- {__(`Bitrate: 1000 to 2500 kbps`)}
- {__(`Keyframes: 1`)}
- {__(`Profile: High`)}
- {__(`Tune: Zerolatency`)}
-
-
- {__(`If using other streaming software, make sure the bitrate is below 4500 kbps or the stream will not work.`)}
-
-
- {__(
- `After your stream:\nClick the Update button on the content page. This will allow you to select a replay or upload your own edited MP4. Replays are limited to 4 hours and may take a few minutes to show (use the Check For Replays button).`
- )}
-
-
{__(`Click Save, then confirm, and you are done!`)}
-
- {__(
- `Note: If you don't plan on publishing your replay, you'll want to delete your livestream and then start with a fresh one next time.`
- )}
-
-
- );
-
- React.useEffect(() => {
- // ensure we have a channel
- if (channelId && channelName) {
- Lbry.channel_sign({
- channel_id: channelId,
- hexdata: toHex(channelName),
- })
- .then((data) => {
- setSigData(data);
- })
- .catch((error) => {
- setSigData({ signature: null, signing_ts: null });
- });
- }
- }, [channelName, channelId, setSigData]);
-
- React.useEffect(() => {
- let checkClaimsInterval;
- if (!channelId) return;
-
- if (!checkClaimsInterval) {
- fetchNoSourceClaims(channelId);
- checkClaimsInterval = setInterval(() => fetchNoSourceClaims(channelId), LIVESTREAM_CLAIM_POLL_IN_MS);
- }
- return () => {
- if (checkClaimsInterval) {
- clearInterval(checkClaimsInterval);
- }
- };
- }, [channelId, pendingLength, fetchNoSourceClaims]);
-
- return (
-
- {fetchingChannels && (
-
-
-
- )}
-
- {!fetchingChannels && !hasChannels && (
-
-
-
- }
- />
- )}
- {!fetchingChannels && (
-
-
- setShowHelp(!showHelp)} label={__('How does this work?')} />
-
- )}
-
- {fetchingLivestreams && !fetchingChannels && !hasLivestreamClaims && (
-
-
-
- )}
-
- {!fetchingChannels && channelId && (
- <>
- {showHelp && (
-
setShowHelp(false)} />}
- title={__('Go Live on Odysee')}
- subtitle={__(`You're invited to try out our new livestreaming service while in beta!`)}
- actions={helpText}
- />
- )}
- {streamKey && totalLivestreamClaims.length > 0 && (
-
-
-
- >
- }
- />
- )}
-
- {totalLivestreamClaims.length > 0 ? (
- <>
- {Boolean(pendingClaims.length) && (
-
- claim.permanent_url)}
- />
-
- )}
- {Boolean(myLivestreamClaims.length) && (
-
- fetchNoSourceClaims(channelId)}
- label={__('Check again')}
- />
- ),
- }}
- >
- Nothing here yet. %check_again%
-
- }
- uris={myLivestreamClaims
- .filter(
- (claim) => !pendingClaims.some((pending) => pending.permanent_url === claim.permanent_url)
- )
- .map((claim) => claim.permanent_url)}
- />
-
- )}
- >
- ) : (
-
-
- doNewLivestream(`/$/${PAGES.UPLOAD}?type=${PUBLISH_MODES.LIVESTREAM.toLowerCase()}`)
- }
- label={__('Create A Livestream')}
- />
- {
- fetchNoSourceClaims(channelId);
- }}
- label={__('Check again...')}
- />
-
- }
- />
- )}
-
- {/* Debug Stuff */}
- {streamKey && false && activeChannelClaim && (
-
-
Debug Info
-
- {/* Channel ID */}
-
-
- {/* Signature */}
-
-
- {/* Signature TS */}
-
-
- {/* Hex Data */}
-
-
- {/* Channel Public Key */}
-
-
- )}
- >
- )}
-
-
- );
-}
diff --git a/ui/page/ownComments/view.jsx b/ui/page/ownComments/view.jsx
index 63661cf32..504b098f6 100644
--- a/ui/page/ownComments/view.jsx
+++ b/ui/page/ownComments/view.jsx
@@ -57,7 +57,6 @@ export default function OwnComments(props: Props) {
return comments.map((comment) => {
const contentClaim = claimsById[comment.claim_id];
const isChannel = contentClaim && contentClaim.value_type === 'channel';
- const isLivestream = Boolean(contentClaim && contentClaim.value_type === 'stream' && !contentClaim.value.source);
return (
@@ -68,7 +67,6 @@ export default function OwnComments(props: Props) {
uri={contentClaim.canonical_url}
searchParams={{
...(isChannel ? { view: 'discussion' } : {}),
- ...(isLivestream ? {} : { lc: comment.comment_id }),
}}
hideActions
hideMenu
diff --git a/ui/page/settingsCreator/view.jsx b/ui/page/settingsCreator/view.jsx
index b32da3d52..bf8e0c4a2 100644
--- a/ui/page/settingsCreator/view.jsx
+++ b/ui/page/settingsCreator/view.jsx
@@ -385,11 +385,11 @@ export default function SettingsCreatorPage(props: Props) {
// prettier-ignore
const HELP = {
- SLOW_MODE: 'Minimum time gap in seconds between comments (affects livestream chat as well).',
- MIN_TIP: 'Enabling a minimum amount to comment will force all comments, including livestreams, to have tips associated with them. This can help prevent spam.',
+ SLOW_MODE: 'Minimum time gap in seconds between comments.',
+ MIN_TIP: 'Enabling a minimum amount to comment will force all comments to have tips associated with them. This can help prevent spam.',
MIN_SUPER: 'Enabling a minimum amount to hyperchat will force all TIPPED comments to have this value in order to be shown. This still allows regular comments to be posted.',
MIN_SUPER_OFF: '(This settings is not applicable if all comments require a tip.)',
- BLOCKED_WORDS: 'Comments and livestream chat containing these words will be blocked.',
+ BLOCKED_WORDS: 'Comments containing these words will be blocked.',
MODERATORS: 'Moderators can block channels on your behalf. Blocked channels will appear in your "Blocked and Muted" list.',
MODERATOR_SEARCH: 'Enter a channel name or URL to add as a moderator.\nExamples:\n - @channel\n - @channel#3\n - https://odysee.com/@Odysee:8\n - lbry://@Odysee#8',
};
diff --git a/ui/page/show/index.js b/ui/page/show/index.js
index 27e36d716..5f1ca151d 100644
--- a/ui/page/show/index.js
+++ b/ui/page/show/index.js
@@ -10,7 +10,6 @@ import {
makeSelectTitleForUri,
makeSelectClaimIsMine,
makeSelectClaimIsPending,
- makeSelectClaimIsStreamPlaceholder,
} from 'redux/selectors/claims';
import {
makeSelectCollectionForId,
@@ -79,7 +78,6 @@ const select = (state, props) => {
title: makeSelectTitleForUri(uri)(state),
claimIsMine: makeSelectClaimIsMine(uri)(state),
claimIsPending: makeSelectClaimIsPending(uri)(state),
- isLivestream: makeSelectClaimIsStreamPlaceholder(uri)(state),
collection: makeSelectCollectionForId(collectionId)(state),
collectionId: collectionId,
collectionUrls: makeSelectUrlsForCollectionId(collectionId)(state),
diff --git a/ui/page/show/view.jsx b/ui/page/show/view.jsx
index 70182adec..08342a665 100644
--- a/ui/page/show/view.jsx
+++ b/ui/page/show/view.jsx
@@ -1,5 +1,4 @@
// @flow
-import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
import * as PAGES from 'constants/pages';
import React, { useEffect } from 'react';
import { Redirect, useHistory } from 'react-router-dom';
@@ -14,7 +13,6 @@ import * as COLLECTIONS_CONSTS from 'constants/collections';
import AbandonedChannelPreview from 'component/abandonedChannelPreview';
import FilePage from 'page/file';
-import LivestreamPage from 'page/livestream';
import Yrbl from 'component/yrbl';
type Props = {
@@ -31,7 +29,6 @@ type Props = {
title: string,
claimIsMine: boolean,
claimIsPending: boolean,
- isLivestream: boolean,
beginPublish: (?string) => void,
collectionId: string,
collection: Collection,
@@ -51,7 +48,6 @@ function ShowPage(props: Props) {
claimIsMine,
isSubscribed,
claimIsPending,
- isLivestream,
beginPublish,
fetchCollectionItems,
collectionId,
@@ -175,8 +171,6 @@ function ShowPage(props: Props) {
/>
);
- } else if (isLivestream && ENABLE_NO_SOURCE_CLAIMS) {
- innerContent = ;
} else {
innerContent = ;
}
diff --git a/ui/reducers.js b/ui/reducers.js
index 2728436b5..93a6441dd 100644
--- a/ui/reducers.js
+++ b/ui/reducers.js
@@ -17,7 +17,6 @@ import userReducer from 'redux/reducers/user';
import commentsReducer from 'redux/reducers/comments';
import blockedReducer from 'redux/reducers/blocked';
import coinSwapReducer from 'redux/reducers/coinSwap';
-import livestreamReducer from 'redux/reducers/livestream';
import searchReducer from 'redux/reducers/search';
import reactionsReducer from 'redux/reducers/reactions';
import syncReducer from 'redux/reducers/sync';
@@ -34,7 +33,6 @@ export default (history) =>
content: contentReducer,
costInfo: costInfoReducer,
fileInfo: fileInfoReducer,
- livestream: livestreamReducer,
notifications: notificationsReducer,
publish: publishReducer,
reactions: reactionsReducer,
diff --git a/ui/redux/actions/comments.js b/ui/redux/actions/comments.js
index 38ed48494..d93cb6b52 100644
--- a/ui/redux/actions/comments.js
+++ b/ui/redux/actions/comments.js
@@ -552,7 +552,6 @@ export function doCommentReact(commentId: string, type: string) {
* @param claim_id - File claim id
* @param parent_id - What is this?
* @param uri
- * @param livestream
* @param {string} [txid] Optional transaction id
* @param {string} [payment_intent_id] Optional transaction id
* @param {string} [environment] Optional environment for Stripe (test|live)
@@ -563,7 +562,6 @@ export function doCommentCreate(
claim_id: string = '',
parent_id?: string,
uri: string,
- livestream?: boolean = false,
txid?: string,
payment_intent_id?: string,
environment?: string
@@ -624,7 +622,6 @@ export function doCommentCreate(
type: ACTIONS.COMMENT_CREATE_COMPLETED,
data: {
uri,
- livestream,
comment: result,
claimId: claim_id,
},
diff --git a/ui/redux/actions/livestream.js b/ui/redux/actions/livestream.js
deleted file mode 100644
index 4ff513c08..000000000
--- a/ui/redux/actions/livestream.js
+++ /dev/null
@@ -1,122 +0,0 @@
-// @flow
-import * as ACTIONS from 'constants/action_types';
-import { doClaimSearch } from 'redux/actions/claims';
-import { LIVESTREAM_LIVE_API } from 'constants/livestream';
-
-export const doFetchNoSourceClaims = (channelId: string) => async (dispatch: Dispatch, getState: GetState) => {
- dispatch({
- type: ACTIONS.FETCH_NO_SOURCE_CLAIMS_STARTED,
- data: channelId,
- });
- try {
- await dispatch(
- doClaimSearch({
- channel_ids: [channelId],
- has_no_source: true,
- claim_type: ['stream'],
- no_totals: true,
- page_size: 20,
- page: 1,
- include_is_my_output: true,
- })
- );
-
- dispatch({
- type: ACTIONS.FETCH_NO_SOURCE_CLAIMS_COMPLETED,
- data: channelId,
- });
- } catch (error) {
- dispatch({
- type: ACTIONS.FETCH_NO_SOURCE_CLAIMS_FAILED,
- data: channelId,
- });
- }
-};
-
-const FETCH_ACTIVE_LIVESTREAMS_MIN_INTERVAL_MS = 5 * 60 * 1000;
-
-export const doFetchActiveLivestreams = (
- orderBy: Array = ['release_time'],
- pageSize: number = 50,
- forceFetch: boolean = false
-) => {
- return async (dispatch: Dispatch, getState: GetState) => {
- const state = getState();
- const now = Date.now();
- const timeDelta = now - state.livestream.activeLivestreamsLastFetchedDate;
-
- const prevOptions = state.livestream.activeLivestreamsLastFetchedOptions;
- const nextOptions = { page_size: pageSize, order_by: orderBy };
- const sameOptions = JSON.stringify(prevOptions) === JSON.stringify(nextOptions);
-
- if (!forceFetch && sameOptions && timeDelta < FETCH_ACTIVE_LIVESTREAMS_MIN_INTERVAL_MS) {
- dispatch({ type: ACTIONS.FETCH_ACTIVE_LIVESTREAMS_SKIPPED });
- return;
- }
-
- dispatch({ type: ACTIONS.FETCH_ACTIVE_LIVESTREAMS_STARTED });
-
- fetch(LIVESTREAM_LIVE_API)
- .then((res) => res.json())
- .then((res) => {
- if (!res.data) {
- dispatch({ type: ACTIONS.FETCH_ACTIVE_LIVESTREAMS_FAILED });
- return;
- }
-
- const activeLivestreams: LivestreamInfo = res.data.reduce((acc, curr) => {
- acc[curr.claimId] = {
- live: curr.live,
- viewCount: curr.viewCount,
- creatorId: curr.claimId,
- };
- return acc;
- }, {});
-
- dispatch(
- // ** Creators can have multiple livestream claims (each with unique
- // chat), and all of them will play the same stream when creator goes
- // live. The UI usually just wants to report the latest claim, so we
- // query that store it in `latestClaimUri`.
- doClaimSearch({
- page: 1,
- page_size: nextOptions.page_size,
- has_no_source: true,
- channel_ids: Object.keys(activeLivestreams),
- claim_type: ['stream'],
- order_by: nextOptions.order_by, // **
- limit_claims_per_channel: 1, // **
- no_totals: true,
- })
- )
- .then((resolveInfo) => {
- Object.values(resolveInfo).forEach((x) => {
- // $FlowFixMe
- const channelId = x.stream.signing_channel.claim_id;
- activeLivestreams[channelId] = {
- ...activeLivestreams[channelId],
- // $FlowFixMe
- latestClaimId: x.stream.claim_id,
- // $FlowFixMe
- latestClaimUri: x.stream.canonical_url,
- };
- });
-
- dispatch({
- type: ACTIONS.FETCH_ACTIVE_LIVESTREAMS_COMPLETED,
- data: {
- activeLivestreams,
- activeLivestreamsLastFetchedDate: now,
- activeLivestreamsLastFetchedOptions: nextOptions,
- },
- });
- })
- .catch(() => {
- dispatch({ type: ACTIONS.FETCH_ACTIVE_LIVESTREAMS_FAILED });
- });
- })
- .catch((err) => {
- dispatch({ type: ACTIONS.FETCH_ACTIVE_LIVESTREAMS_FAILED });
- });
- };
-};
diff --git a/ui/redux/actions/publish.js b/ui/redux/actions/publish.js
index 9078421b0..d4721eaa3 100644
--- a/ui/redux/actions/publish.js
+++ b/ui/redux/actions/publish.js
@@ -4,14 +4,8 @@ import * as ACTIONS from 'constants/action_types';
import * as PAGES from 'constants/pages';
import { batchActions } from 'util/batch-actions';
import { doCheckPendingClaims } from 'redux/actions/claims';
-import {
- makeSelectClaimForUri,
- selectMyClaims,
- selectMyChannelClaims,
- // selectMyClaimsWithoutChannels,
- selectReflectingById,
-} from 'redux/selectors/claims';
-import { makeSelectPublishFormValue, selectPublishFormValues, selectMyClaimForUri } from 'redux/selectors/publish';
+import { selectMyClaims, selectMyChannelClaims, selectReflectingById } from 'redux/selectors/claims';
+import { selectPublishFormValues, selectMyClaimForUri } from 'redux/selectors/publish';
import { doError } from 'redux/actions/notifications';
import { push } from 'connected-react-router';
import analytics from 'analytics';
@@ -21,7 +15,6 @@ import { SPEECH_STATUS, SPEECH_PUBLISH } from 'constants/speech_urls';
import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses';
import { creditsToString } from 'util/format-credits';
import Lbry from 'lbry';
-// import LbryFirst from 'extras/lbry-first/lbry-first';
import { isClaimNsfw } from 'util/claim';
export const NO_FILE = '---';
@@ -34,14 +27,6 @@ export const doPublishDesktop = (filePath: string, preview?: boolean) => (dispat
);
};
- const noFileParam = !filePath || filePath === NO_FILE;
- const state = getState();
- const editingUri = makeSelectPublishFormValue('editingURI')(state) || '';
- const remoteUrl = makeSelectPublishFormValue('remoteFileUrl')(state);
- const claim = makeSelectClaimForUri(editingUri)(state) || {};
- const hasSourceFile = claim.value && claim.value.source;
- const redirectToLivestream = noFileParam && !hasSourceFile && !remoteUrl;
-
const publishSuccess = (successResponse, lbryFirstError) => {
const state = getState();
const myClaims = selectMyClaims(state);
@@ -87,14 +72,7 @@ export const doPublishDesktop = (filePath: string, preview?: boolean) => (dispat
})
);
dispatch(doCheckPendingClaims());
- // @if TARGET='app'
dispatch(doCheckReflectingFiles());
- // @endif
- // @if TARGET='web'
- if (redirectToLivestream) {
- dispatch(push(`/$/${PAGES.LIVESTREAM}`));
- }
- // @endif
};
const publishFail = (error) => {
@@ -111,15 +89,6 @@ export const doPublishDesktop = (filePath: string, preview?: boolean) => (dispat
return;
}
- // Redirect on web immediately because we have a file upload progress componenet
- // on the publishes page. This doesn't exist on desktop so wait until we get a response
- // from the SDK
- // @if TARGET='web'
- if (!redirectToLivestream) {
- dispatch(push(`/$/${PAGES.UPLOADS}`));
- }
- // @endif
-
dispatch(doPublish(publishSuccess, publishFail));
};
@@ -381,12 +350,9 @@ export const doPublish = (success: Function, fail: Function, preview: Function)
title,
contentIsFree,
fee,
- // uri,
tags,
// locations,
optimize,
- isLivestreamPublish,
- remoteFileUrl,
} = publishData;
// Handle scenario where we have a claim that has the same name as a channel we are publishing with.
@@ -439,10 +405,6 @@ export const doPublish = (success: Function, fail: Function, preview: Function)
};
// Temporary solution to keep the same publish flow with the new tags api
// Eventually we will allow users to enter their own tags on publish
- // `nsfw` will probably be removed
- if (remoteFileUrl) {
- publishPayload.remote_url = remoteFileUrl;
- }
if (publishingLicense) {
publishPayload.license = publishingLicense;
@@ -490,7 +452,7 @@ export const doPublish = (success: Function, fail: Function, preview: Function)
// Only pass file on new uploads, not metadata only edits.
// The sdk will figure it out
- if (filePath && !isLivestreamPublish) publishPayload.file_path = filePath;
+ if (filePath) publishPayload.file_path = filePath;
if (preview) {
publishPayload.preview = true;
@@ -502,22 +464,7 @@ export const doPublish = (success: Function, fail: Function, preview: Function)
}
return Lbry.publish(publishPayload).then((response: PublishResponse) => {
- // TODO: Restore LbryFirst
- // if (!useLBRYUploader) {
return success(response);
- // }
-
- // $FlowFixMe
- // publishPayload.permanent_url = response.outputs[0].permanent_url;
- //
- // return LbryFirst.upload(publishPayload)
- // .then(() => {
- // // Return original publish response so app treats it like a normal publish
- // return success(response);
- // })
- // .catch((error) => {
- // return success(response, error);
- // });
}, fail);
};
diff --git a/ui/redux/actions/websocket.js b/ui/redux/actions/websocket.js
index 78552ab18..ab0ca0e4a 100644
--- a/ui/redux/actions/websocket.js
+++ b/ui/redux/actions/websocket.js
@@ -103,13 +103,6 @@ export const doCommentSocketConnect = (uri, claimId) => (dispatch) => {
data: { comment: newComment, claimId, uri },
});
}
- if (response.type === 'viewers') {
- const connected = response.data.connected;
- dispatch({
- type: ACTIONS.VIEWERS_RECEIVED,
- data: { connected, claimId },
- });
- }
if (response.type === 'pinned') {
const pinnedComment = response.data.comment;
dispatch({
diff --git a/ui/redux/reducers/comments.js b/ui/redux/reducers/comments.js
index ca3869f08..1a8733c8d 100644
--- a/ui/redux/reducers/comments.js
+++ b/ui/redux/reducers/comments.js
@@ -71,12 +71,7 @@ export default handleActions(
}),
[ACTIONS.COMMENT_CREATE_COMPLETED]: (state: CommentsState, action: any): CommentsState => {
- const {
- comment,
- claimId,
- uri,
- livestream,
- }: { comment: Comment, claimId: string, uri: string, livestream: boolean } = action.data;
+ const { comment, claimId, uri }: { comment: Comment, claimId: string, uri: string } = action.data;
const commentById = Object.assign({}, state.commentById);
const byId = Object.assign({}, state.byId);
@@ -87,37 +82,34 @@ export default handleActions(
const comments = byId[claimId] || [];
const newCommentIds = comments.slice();
- // If it was created during a livestream, let the websocket handler perform the state update
- if (!livestream) {
- // add the comment by its ID
- commentById[comment.comment_id] = comment;
+ // add the comment by its ID
+ commentById[comment.comment_id] = comment;
- // push the comment_id to the top of ID list
- newCommentIds.unshift(comment.comment_id);
- byId[claimId] = newCommentIds;
+ // push the comment_id to the top of ID list
+ newCommentIds.unshift(comment.comment_id);
+ byId[claimId] = newCommentIds;
- if (totalCommentsById[claimId]) {
- totalCommentsById[claimId] += 1;
+ if (totalCommentsById[claimId]) {
+ totalCommentsById[claimId] += 1;
+ }
+
+ if (comment['parent_id']) {
+ if (!repliesByParentId[comment.parent_id]) {
+ repliesByParentId[comment.parent_id] = [comment.comment_id];
+ } else {
+ repliesByParentId[comment.parent_id].unshift(comment.comment_id);
}
- if (comment['parent_id']) {
- if (!repliesByParentId[comment.parent_id]) {
- repliesByParentId[comment.parent_id] = [comment.comment_id];
- } else {
- repliesByParentId[comment.parent_id].unshift(comment.comment_id);
- }
-
- // Update the parent's "replies" value
- if (commentById[comment.parent_id]) {
- commentById[comment.parent_id].replies = (commentById[comment.parent_id].replies || 0) + 1;
- }
+ // Update the parent's "replies" value
+ if (commentById[comment.parent_id]) {
+ commentById[comment.parent_id].replies = (commentById[comment.parent_id].replies || 0) + 1;
+ }
+ } else {
+ if (!topLevelCommentsById[claimId]) {
+ commentsByUri[uri] = claimId;
+ topLevelCommentsById[claimId] = [comment.comment_id];
} else {
- if (!topLevelCommentsById[claimId]) {
- commentsByUri[uri] = claimId;
- topLevelCommentsById[claimId] = [comment.comment_id];
- } else {
- topLevelCommentsById[claimId].unshift(comment.comment_id);
- }
+ topLevelCommentsById[claimId].unshift(comment.comment_id);
}
}
diff --git a/ui/redux/reducers/livestream.js b/ui/redux/reducers/livestream.js
deleted file mode 100644
index 7a5d8af84..000000000
--- a/ui/redux/reducers/livestream.js
+++ /dev/null
@@ -1,61 +0,0 @@
-// @flow
-import * as ACTIONS from 'constants/action_types';
-import { handleActions } from 'util/redux-utils';
-
-const defaultState: LivestreamState = {
- fetchingById: {},
- viewersById: {},
- fetchingActiveLivestreams: false,
- activeLivestreams: null,
- activeLivestreamsLastFetchedDate: 0,
- activeLivestreamsLastFetchedOptions: {},
-};
-
-export default handleActions(
- {
- [ACTIONS.FETCH_NO_SOURCE_CLAIMS_STARTED]: (state: LivestreamState, action: any): LivestreamState => {
- const claimId = action.data;
- const newIdsFetching = Object.assign({}, state.fetchingById);
- newIdsFetching[claimId] = true;
-
- return { ...state, fetchingById: newIdsFetching };
- },
- [ACTIONS.FETCH_NO_SOURCE_CLAIMS_COMPLETED]: (state: LivestreamState, action: any): LivestreamState => {
- const claimId = action.data;
- const newIdsFetching = Object.assign({}, state.fetchingById);
- newIdsFetching[claimId] = false;
-
- return { ...state, fetchingById: newIdsFetching };
- },
- [ACTIONS.FETCH_NO_SOURCE_CLAIMS_FAILED]: (state: LivestreamState, action: any) => {
- const claimId = action.data;
- const newIdsFetching = Object.assign({}, state.fetchingById);
- newIdsFetching[claimId] = false;
-
- return { ...state, fetchingById: newIdsFetching };
- },
- [ACTIONS.VIEWERS_RECEIVED]: (state: LivestreamState, action: any) => {
- const { connected, claimId } = action.data;
- const newViewersById = Object.assign({}, state.viewersById);
- newViewersById[claimId] = connected;
- return { ...state, viewersById: newViewersById };
- },
- [ACTIONS.FETCH_ACTIVE_LIVESTREAMS_STARTED]: (state: LivestreamState) => {
- return { ...state, fetchingActiveLivestreams: true };
- },
- [ACTIONS.FETCH_ACTIVE_LIVESTREAMS_FAILED]: (state: LivestreamState) => {
- return { ...state, fetchingActiveLivestreams: false };
- },
- [ACTIONS.FETCH_ACTIVE_LIVESTREAMS_COMPLETED]: (state: LivestreamState, action: any) => {
- const { activeLivestreams, activeLivestreamsLastFetchedDate, activeLivestreamsLastFetchedOptions } = action.data;
- return {
- ...state,
- fetchingActiveLivestreams: false,
- activeLivestreams,
- activeLivestreamsLastFetchedDate,
- activeLivestreamsLastFetchedOptions,
- };
- },
- },
- defaultState
-);
diff --git a/ui/redux/selectors/livestream.js b/ui/redux/selectors/livestream.js
deleted file mode 100644
index 2ad1c0e6e..000000000
--- a/ui/redux/selectors/livestream.js
+++ /dev/null
@@ -1,62 +0,0 @@
-// @flow
-import { createSelector } from 'reselect';
-import { selectMyClaims, selectPendingClaims } from 'redux/selectors/claims';
-
-const selectState = (state) => state.livestream || {};
-
-// select non-pending claims without sources for given channel
-export const makeSelectLivestreamsForChannelId = (channelId: string) =>
- createSelector(selectState, selectMyClaims, (livestreamState, myClaims = []) => {
- return myClaims
- .filter(
- (claim) =>
- claim.value_type === 'stream' &&
- claim.value &&
- !claim.value.source &&
- claim.confirmations > 0 &&
- claim.signing_channel &&
- claim.signing_channel.claim_id === channelId
- )
- .sort((a, b) => b.timestamp - a.timestamp); // newest first
- });
-
-export const selectFetchingLivestreams = createSelector(selectState, (state) => state.fetchingById);
-export const selectViewersById = createSelector(selectState, (state) => state.viewersById);
-
-export const makeSelectIsFetchingLivestreams = (channelId: string) =>
- createSelector(selectFetchingLivestreams, (fetchingLivestreams) => Boolean(fetchingLivestreams[channelId]));
-
-export const makeSelectViewersForId = (channelId: string) =>
- createSelector(selectViewersById, (viewers) => viewers[channelId]);
-
-export const makeSelectPendingLivestreamsForChannelId = (channelId: string) =>
- createSelector(selectPendingClaims, (pendingClaims) => {
- return pendingClaims.filter(
- (claim) =>
- claim.value_type === 'stream' &&
- claim.value &&
- !claim.value.source &&
- claim.signing_channel &&
- claim.signing_channel.claim_id === channelId
- );
- });
-
-export const selectActiveLivestreams = createSelector(selectState, (state) => state.activeLivestreams);
-
-export const makeSelectIsActiveLivestream = (uri: string) =>
- createSelector(selectState, (state) => {
- const activeLivestreamValues = (state.activeLivestreams && Object.values(state.activeLivestreams)) || [];
- // $FlowFixMe
- return Boolean(activeLivestreamValues.find((v) => v.latestClaimUri === uri));
- });
-
-export const makeSelectActiveLivestreamUris = (uri: string) =>
- createSelector(selectState, (state) => {
- const activeLivestreamValues = (state.activeLivestreams && Object.values(state.activeLivestreams)) || [];
- const uris = [];
- activeLivestreamValues.forEach((v) => {
- // $FlowFixMe
- if (v.latestClaimUri) uris.push(v.latestClaimUri);
- });
- return uris;
- });
diff --git a/ui/scss/all.scss b/ui/scss/all.scss
index 7767f9e79..c654e7b0d 100644
--- a/ui/scss/all.scss
+++ b/ui/scss/all.scss
@@ -57,7 +57,6 @@
@import 'component/superchat';
@import 'component/syntax-highlighter';
@import 'component/table';
-@import 'component/livestream';
@import 'component/tabs';
@import 'component/tooltip';
@import 'component/txo-list';
diff --git a/ui/scss/component/_livestream.scss b/ui/scss/component/_livestream.scss
deleted file mode 100644
index a2373f683..000000000
--- a/ui/scss/component/_livestream.scss
+++ /dev/null
@@ -1,469 +0,0 @@
-$discussion-header__height: 3rem;
-$recent-msg-button__height: 2rem;
-
-.livestream {
- flex: 1;
- width: 100%;
- padding-top: var(--aspect-ratio-standard);
- position: relative;
- border-radius: var(--border-radius);
-
- .media__thumb,
- iframe {
- overflow: hidden;
- border-radius: var(--border-radius);
- height: 100%;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- }
-
- ~ .notice-message {
- margin-top: var(--spacing-m);
- }
-}
-
-.livestream__discussion {
- width: 100%;
-
- @media (min-width: $breakpoint-medium) {
- margin: 0;
- width: var(--livestream-comments-width);
- height: calc(100vh - var(--header-height));
- position: fixed;
- right: 0;
- top: var(--header-height);
- bottom: 0;
- border-radius: 0;
- border-top: none;
- border-bottom: none;
- border-right: none;
-
- .card__main-actions {
- padding: 0;
- }
- }
-}
-
-.livestream-discussion__header {
- border-bottom: 1px solid var(--color-border);
- padding-bottom: var(--spacing-s);
- margin-bottom: 0;
- align-items: center;
-
- @media (min-width: $breakpoint-small) {
- height: $discussion-header__height;
- padding: 0 var(--spacing-s);
- padding-right: 0;
- }
-}
-
-.livestream-discussion__title {
- @extend .card__title-section;
- @extend .card__title-section--small;
- padding: 0;
-}
-
-.livestream__comments-wrapper {
- display: flex;
- flex-direction: column;
- height: calc(100vh - var(--header-height) - #{$discussion-header__height});
-}
-
-.livestream__comments {
- display: flex;
- flex-direction: column-reverse;
- font-size: var(--font-small);
- overflow-y: scroll;
- overflow-x: visible;
- padding-top: var(--spacing-s);
- width: 100%;
-}
-
-.livestream-comment {
- list-style-type: none;
- position: relative;
-
- .channel-name {
- font-size: var(--font-xsmall);
- }
-}
-
-.livestream-comment--superchat {
- + .livestream-comment--superchat {
- margin-bottom: var(--spacing-xxs);
- }
-
- .livestream-comment__info {
- margin-top: calc(var(--spacing-xxs) / 2);
- }
-
- &::before {
- position: absolute;
- left: 0;
- height: 100%;
- max-height: 4rem;
- border-top-right-radius: 2px;
- border-bottom-right-radius: 2px;
- width: 5px;
- background-color: var(--color-superchat);
- content: '';
- }
-}
-
-.livestream-comment__body {
- display: flex;
- align-items: flex-start;
-}
-
-.livestream-comment__body {
- display: flex;
- align-items: flex-start;
- margin-left: var(--spacing-s);
-
- .channel-thumbnail {
- @include handleChannelGif(2rem);
- margin-top: var(--spacing-xxs);
- flex-shrink: 0;
- }
-}
-
-.livestream-comment__menu {
- position: absolute;
- right: var(--spacing-xs);
- top: var(--spacing-xs);
-}
-
-.livestream__comments__scroll-to-recent {
- margin-top: -$recent-msg-button__height;
- align-self: center;
- margin-bottom: var(--spacing-xs);
- font-size: var(--font-xsmall);
- padding: var(--spacing-xxs) var(--spacing-s);
- opacity: 0.9;
-
- &:hover {
- opacity: 1;
- }
-}
-
-.livestream__comment-create {
- padding: var(--spacing-s);
- border-top: 1px solid var(--color-border);
- margin-top: auto;
-}
-
-.livestream__channel-link {
- margin-bottom: var(--spacing-xl);
- box-shadow: 0 0 0 rgba(246, 72, 83, 0.4);
- animation: livePulse 2s infinite;
-
- &:hover {
- cursor: pointer;
- }
-}
-
-@keyframes livePulse {
- 0% {
- box-shadow: 0 0 0 0 rgba(246, 72, 83, 0.4);
- }
- 70% {
- box-shadow: 0 0 0 10px rgba(246, 72, 83, 0);
- }
- 100% {
- box-shadow: 0 0 0 0 rgba(246, 72, 83, 0);
- }
-}
-
-.livestream__publish-checkbox {
- margin: var(--spacing-l) 0;
-
- .checkbox,
- .radio {
- margin-top: var(--spacing-m);
-
- label {
- color: #444;
- }
- }
-}
-
-.livestream__creator-message {
- background-color: #fde68a;
- padding: var(--spacing-m);
- color: black;
- border-radius: var(--border-radius);
-
- h4 {
- font-weight: bold;
- font-size: var(--font-small);
- margin-bottom: var(--spacing-s);
- }
-}
-
-.livestream__publish-intro {
- margin-top: var(--spacing-l);
-}
-
-.livestream__viewer-count {
- display: flex;
- align-items: center;
-
- .icon {
- margin-left: var(--spacing-xs);
- }
-}
-
-.livestream-superchats__wrapper {
- flex-shrink: 0;
- position: relative;
- overflow-x: scroll;
- padding: var(--spacing-s) var(--spacing-xs);
- border-bottom: 1px solid var(--color-border);
- font-size: var(--font-small);
- background-color: var(--color-card-background);
-
- @media (min-width: $breakpoint-small) {
- padding: var(--spacing-xs);
- width: var(--livestream-comments-width);
- }
-}
-
-.livestream-pinned__wrapper {
- display: flex;
- flex-shrink: 0;
- position: relative;
- padding: var(--spacing-s) var(--spacing-xs);
- border-bottom: 1px solid var(--color-border);
- font-size: var(--font-small);
- background-color: var(--color-card-background-highlighted);
- width: 100%;
-
- .livestream-comment {
- width: 100%;
- padding-top: var(--spacing-xs);
- max-height: 6rem;
- overflow-y: scroll;
- }
-
- .close-button {
- border-left: 1px solid var(--color-border);
- padding: 0 calc(var(--spacing-m) - var(--spacing-xs)) 0 var(--spacing-m);
- color: var(--color-text-subtitle);
- }
-
- @media (min-width: $breakpoint-small) {
- padding: var(--spacing-xs);
- width: var(--livestream-comments-width);
- }
-}
-
-.livestream-superchat__amount-large {
- .credit-amount {
- display: flex;
- align-items: center;
- flex-wrap: nowrap;
- }
-}
-
-.livestream-superchats__inner {
- display: flex;
-}
-
-.livestream-superchat {
- display: flex;
- margin-right: var(--spacing-xs);
- padding: var(--spacing-xxs);
- border-radius: var(--border-radius);
-
- .channel-thumbnail {
- margin-right: var(--spacing-xs);
- @include handleChannelGif(2rem);
- }
-
- &:first-of-type {
- background-color: var(--color-superchat);
-
- .channel-name {
- max-width: 8rem;
- }
- }
-
- &:nth-of-type(2) {
- background-color: var(--color-superchat-2);
- }
- &:nth-of-type(3) {
- background-color: var(--color-superchat-3);
- }
-
- &:nth-of-type(-n + 3) {
- .channel-name,
- .credit-amount {
- color: var(--color-black);
- }
- }
-
- .channel-name {
- max-width: 5rem;
- }
-}
-
-.livestream-superchat__info {
- display: flex;
- flex-direction: column;
- justify-content: center;
- font-size: var(--font-xsmall);
-}
-
-.livestream-superchat__banner {
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
- padding: 0.25rem var(--spacing-s);
- display: inline-block;
- position: relative;
-}
-
-// This is just a two small circles that overlap to make it look like
-// the banner and the left border are connected
-.livestream-superchat__banner-corner {
- height: calc(var(--border-radius) * 2);
- width: calc(var(--border-radius) * 2);
- border-radius: 50%;
- position: absolute;
- background-color: var(--color-superchat);
- bottom: 0;
- left: 0;
- transform: translateX(0) translateY(50%);
-
- &::after {
- content: '';
- height: calc(var(--border-radius) * 2);
- width: calc(var(--border-radius) * 2);
- border-top-left-radius: var(--border-radius);
- background-color: var(--color-card-background);
- position: absolute;
- bottom: 0;
- left: 0;
- transform: translateX(25%) translateY(50%);
- }
-}
-
-.livestream-comment__text {
- padding-right: var(--spacing-xl);
- padding-bottom: var(--spacing-xxs);
- .markdown-preview {
- p {
- word-break: break-word;
- }
-
- .channel-name {
- font-size: var(--font-small);
- }
- }
-}
-
-.livestream-superchat__tooltip-amount {
- margin-top: var(--spacing-xs);
- margin-left: 0;
- background-color: transparent;
- padding: 0;
-}
-
-.livestream__superchat-comment {
- margin-top: var(--spacing-s);
- max-width: 5rem;
- overflow-wrap: break-word;
-}
-
-.livestream-superchat__amount-large {
- min-width: 2.5rem;
-}
-
-.table--livestream-data {
- td:nth-of-type(1) {
- max-width: 4rem;
- }
- td:nth-of-type(2) {
- min-width: 8.5rem;
- }
- td:nth-of-type(3) {
- width: 4rem;
- min-width: 9rem;
- }
- td:nth-of-type(4) {
- display: none;
- }
- @media (min-width: $breakpoint-small) {
- td:nth-of-type(1) {
- max-width: 4rem;
- }
- td:nth-of-type(2) {
- width: 40%;
- }
- td:nth-of-type(3) {
- width: 5rem;
- }
- td:nth-of-type(4) {
- width: 100%;
- display: table-cell;
- }
- }
-}
-
-.livestream_thumb_container {
- height: 4rem;
- width: 100%;
- display: flex;
- flex-direction: row;
- overflow: hidden;
-}
-
-.livestream___thumb {
- padding: 0 var(--spacing-xxs);
- object-fit: cover;
-}
-
-.livestream__data-row {
- cursor: pointer;
- .radio {
- cursor: pointer;
- }
- &:nth-child(n) {
- &.livestream__data-row--selected {
- background-color: var(--color-button-toggle-bg);
- }
- }
- td {
- padding-right: var(--spacing-m);
-
- @media (max-width: $breakpoint-small) {
- padding: var(--spacing-xs);
- }
- }
- &:hover {
- td {
- .radio {
- label::before {
- cursor: pointer;
- background-color: var(--color-input-toggle-bg-hover);
- }
- }
- label {
- cursor: pointer;
- }
- }
-
- input {
- cursor: pointer;
- background-color: var(--color-input-bg-selected);
- }
- }
-}
-
-.livestream-list--view-more {
- display: flex;
- align-items: flex-end;
- margin-bottom: var(--spacing-m);
-}
diff --git a/ui/scss/component/_main.scss b/ui/scss/component/_main.scss
index 266d66428..4d1836ecd 100644
--- a/ui/scss/component/_main.scss
+++ b/ui/scss/component/_main.scss
@@ -206,47 +206,6 @@
}
}
-.main--livestream {
- @extend .main--file-page;
- margin: 0;
- padding: 0;
- max-width: none;
-
- .card-stack {
- margin-top: var(--spacing-m);
- margin-bottom: var(--spacing-m);
-
- @media (min-width: $breakpoint-large + 300px) {
- max-width: calc(var(--page-max-width--filepage) / 1.25);
- margin-left: auto;
- margin-right: auto;
- }
-
- @media (min-width: $breakpoint-medium) and (max-width: $breakpoint-large + 300px) {
- max-width: calc(100vw - var(--livestream-comments-width) - var(--spacing-m) * 3);
- margin-left: var(--spacing-m);
- margin-right: var(--spacing-m);
- }
-
- @media (max-width: $breakpoint-medium) {
- max-width: none;
- }
- }
-
- .main__right-side {
- width: var(--livestream-comments-width);
-
- @media (max-width: $breakpoint-medium) {
- width: 100%;
- margin-bottom: var(--spacing-m);
- }
- }
-
- @media (max-width: $breakpoint-medium) {
- padding: 0 var(--spacing-m);
- }
-}
-
.main--full-width {
@extend .main;
diff --git a/ui/scss/init/_vars.scss b/ui/scss/init/_vars.scss
index 7775a9abc..67a98edaa 100644
--- a/ui/scss/init/_vars.scss
+++ b/ui/scss/init/_vars.scss
@@ -97,8 +97,6 @@ $breakpoint-large: 1600px;
--file-list-thumbnail-width: 10rem;
--tag-height: 1.5rem;
-
- --livestream-comments-width: 30rem;
}
@media (max-width: $breakpoint-small) {
diff --git a/ui/util/livestream.js b/ui/util/livestream.js
deleted file mode 100644
index 2cf026194..000000000
--- a/ui/util/livestream.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// @flow
-
-/**
- * Helper to extract livestream claim uris from the output of
- * `selectActiveLivestreams`.
- *
- * @param activeLivestreams Object obtained from `selectActiveLivestreams`.
- * @param channelIds List of channel IDs to filter the results with.
- * @returns {[]|Array<*>}
- */
-export function getLivestreamUris(activeLivestreams: ?LivestreamInfo, channelIds: ?Array) {
- let values = (activeLivestreams && Object.values(activeLivestreams)) || [];
-
- if (channelIds && channelIds.length > 0) {
- // $FlowFixMe
- values = values.filter((v) => channelIds.includes(v.creatorId) && Boolean(v.latestClaimUri));
- } else {
- // $FlowFixMe
- values = values.filter((v) => Boolean(v.latestClaimUri));
- }
-
- // $FlowFixMe
- return values.map((v) => v.latestClaimUri);
-}