mirror of
https://github.com/LBRYFoundation/lbry-desktop.git
synced 2025-08-31 09:21:27 +00:00
use comment component for livestream comments
This commit is contained in:
parent
d8a5ca082b
commit
64e8c8e095
7 changed files with 100 additions and 76 deletions
|
@ -50,6 +50,7 @@ type Props = {
|
||||||
activeChannelClaim: ?ChannelClaim,
|
activeChannelClaim: ?ChannelClaim,
|
||||||
playingUri: ?PlayingUri,
|
playingUri: ?PlayingUri,
|
||||||
stakedLevel: number,
|
stakedLevel: number,
|
||||||
|
livestream?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
const LENGTH_TO_COLLAPSE = 300;
|
const LENGTH_TO_COLLAPSE = 300;
|
||||||
|
@ -77,6 +78,7 @@ function Comment(props: Props) {
|
||||||
othersReacts,
|
othersReacts,
|
||||||
playingUri,
|
playingUri,
|
||||||
stakedLevel,
|
stakedLevel,
|
||||||
|
livestream,
|
||||||
} = props;
|
} = props;
|
||||||
const {
|
const {
|
||||||
push,
|
push,
|
||||||
|
@ -162,6 +164,7 @@ function Comment(props: Props) {
|
||||||
className={classnames('comment', {
|
className={classnames('comment', {
|
||||||
'comment--top-level': isTopLevel,
|
'comment--top-level': isTopLevel,
|
||||||
'comment--reply': !isTopLevel,
|
'comment--reply': !isTopLevel,
|
||||||
|
'comment--livestream': livestream,
|
||||||
})}
|
})}
|
||||||
id={commentId}
|
id={commentId}
|
||||||
onMouseOver={() => setMouseHover(true)}
|
onMouseOver={() => setMouseHover(true)}
|
||||||
|
@ -173,13 +176,20 @@ function Comment(props: Props) {
|
||||||
'comment--slimed': slimedToDeath && !displayDeadComment,
|
'comment--slimed': slimedToDeath && !displayDeadComment,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div className="comment__thumbnail-wrapper">
|
{!livestream && (
|
||||||
{authorUri ? (
|
<div className="comment__thumbnail-wrapper">
|
||||||
<ChannelThumbnail uri={authorUri} obscure={channelIsBlocked} small className="comment__author-thumbnail" />
|
{authorUri ? (
|
||||||
) : (
|
<ChannelThumbnail
|
||||||
<ChannelThumbnail small className="comment__author-thumbnail" />
|
uri={authorUri}
|
||||||
)}
|
obscure={channelIsBlocked}
|
||||||
</div>
|
small
|
||||||
|
className="comment__author-thumbnail"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<ChannelThumbnail small className="comment__author-thumbnail" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="comment__body_container">
|
<div className="comment__body_container">
|
||||||
<div className="comment__meta">
|
<div className="comment__meta">
|
||||||
|
@ -187,13 +197,15 @@ function Comment(props: Props) {
|
||||||
{!author ? (
|
{!author ? (
|
||||||
<span className="comment__author">{__('Anonymous')}</span>
|
<span className="comment__author">{__('Anonymous')}</span>
|
||||||
) : (
|
) : (
|
||||||
<UriIndicator link uri={authorUri} />
|
<UriIndicator link external={livestream} uri={authorUri} />
|
||||||
|
)}
|
||||||
|
{!livestream && (
|
||||||
|
<Button
|
||||||
|
className="comment__time"
|
||||||
|
onClick={handleTimeClick}
|
||||||
|
label={<DateTime date={timePosted} timeAgo />}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
<Button
|
|
||||||
className="comment__time"
|
|
||||||
onClick={handleTimeClick}
|
|
||||||
label={<DateTime date={timePosted} timeAgo />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{isPinned && (
|
{isPinned && (
|
||||||
<span className="comment__pin">
|
<span className="comment__pin">
|
||||||
|
@ -273,18 +285,20 @@ function Comment(props: Props) {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="comment__actions">
|
{!livestream && (
|
||||||
{threadDepth !== 0 && (
|
<div className="comment__actions">
|
||||||
<Button
|
{threadDepth !== 0 && (
|
||||||
requiresAuth={IS_WEB}
|
<Button
|
||||||
label={commentingEnabled ? __('Reply') : __('Log in to reply')}
|
requiresAuth={IS_WEB}
|
||||||
className="comment__action"
|
label={commentingEnabled ? __('Reply') : __('Log in to reply')}
|
||||||
onClick={handleCommentReply}
|
className="comment__action"
|
||||||
icon={ICONS.REPLY}
|
onClick={handleCommentReply}
|
||||||
/>
|
icon={ICONS.REPLY}
|
||||||
)}
|
/>
|
||||||
{ENABLE_COMMENT_REACTIONS && <CommentReactions uri={uri} commentId={commentId} />}
|
)}
|
||||||
</div>
|
{ENABLE_COMMENT_REACTIONS && <CommentReactions uri={uri} commentId={commentId} />}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{isReplying && (
|
{isReplying && (
|
||||||
<CommentCreate
|
<CommentCreate
|
||||||
|
|
|
@ -4,8 +4,7 @@ import classnames from 'classnames';
|
||||||
import Card from 'component/common/card';
|
import Card from 'component/common/card';
|
||||||
import Spinner from 'component/spinner';
|
import Spinner from 'component/spinner';
|
||||||
import CommentCreate from 'component/commentCreate';
|
import CommentCreate from 'component/commentCreate';
|
||||||
import Button from 'component/button';
|
import CommentView from 'component/comment';
|
||||||
import MarkdownPreview from 'component/common/markdown-preview';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
@ -114,20 +113,17 @@ export default function LivestreamFeed(props: Props) {
|
||||||
<div className="livestream__comments">
|
<div className="livestream__comments">
|
||||||
{comments.map((comment) => (
|
{comments.map((comment) => (
|
||||||
<div key={comment.comment_id} className={classnames('livestream__comment')}>
|
<div key={comment.comment_id} className={classnames('livestream__comment')}>
|
||||||
{comment.channel_url ? (
|
<CommentView
|
||||||
<Button
|
livestream
|
||||||
target="_blank"
|
isTopLevel
|
||||||
className={classnames('livestream__comment-author', {
|
uri={uri}
|
||||||
'livestream__comment-author--streamer':
|
authorUri={comment.channel_url}
|
||||||
claim.signing_channel && claim.signing_channel.claim_id === comment.channel_id,
|
author={comment.channel_name}
|
||||||
})}
|
claimId={comment.claim_id}
|
||||||
navigate={comment.channel_url}
|
commentId={comment.comment_id}
|
||||||
label={comment.channel_name}
|
message={comment.comment}
|
||||||
/>
|
timePosted={comment.timestamp * 1000}
|
||||||
) : (
|
/>
|
||||||
<div className="livestream__comment-author">{comment.channel_name}</div>
|
|
||||||
)}
|
|
||||||
<MarkdownPreview content={comment.comment} simpleLinks />
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,6 +17,7 @@ type Props = {
|
||||||
// to allow for other elements to be nested within the UriIndicator
|
// to allow for other elements to be nested within the UriIndicator
|
||||||
children: ?Node,
|
children: ?Node,
|
||||||
inline: boolean,
|
inline: boolean,
|
||||||
|
external?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
class UriIndicator extends React.PureComponent<Props> {
|
class UriIndicator extends React.PureComponent<Props> {
|
||||||
|
@ -37,7 +38,7 @@ class UriIndicator extends React.PureComponent<Props> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { link, isResolvingUri, claim, children, inline, hideAnonymous = false } = this.props;
|
const { link, isResolvingUri, claim, children, inline, hideAnonymous = false, external = false } = this.props;
|
||||||
|
|
||||||
if (!claim) {
|
if (!claim) {
|
||||||
return <span className="empty">{isResolvingUri ? 'Validating...' : 'Unused'}</span>;
|
return <span className="empty">{isResolvingUri ? 'Validating...' : 'Unused'}</span>;
|
||||||
|
@ -74,10 +75,14 @@ class UriIndicator extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (children) {
|
if (children) {
|
||||||
return <Button navigate={channelLink}>{children}</Button>;
|
return (
|
||||||
|
<Button target={external ? '_blank' : undefined} navigate={channelLink}>
|
||||||
|
{children}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Button className="button--uri-indicator" navigate={channelLink}>
|
<Button className="button--uri-indicator" navigate={channelLink} target={external ? '_blank' : undefined}>
|
||||||
{inner}
|
{inner}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,13 +13,13 @@ const NO_WALLET_ERROR = 'no wallet found for this user';
|
||||||
const BAD_PASSWORD_ERROR_NAME = 'InvalidPasswordError';
|
const BAD_PASSWORD_ERROR_NAME = 'InvalidPasswordError';
|
||||||
|
|
||||||
export function doSetDefaultAccount(success, failure) {
|
export function doSetDefaultAccount(success, failure) {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.SET_DEFAULT_ACCOUNT,
|
type: ACTIONS.SET_DEFAULT_ACCOUNT,
|
||||||
});
|
});
|
||||||
|
|
||||||
Lbry.account_list()
|
Lbry.account_list()
|
||||||
.then(accountList => {
|
.then((accountList) => {
|
||||||
const { lbc_mainnet: accounts } = accountList;
|
const { lbc_mainnet: accounts } = accountList;
|
||||||
let defaultId;
|
let defaultId;
|
||||||
for (let i = 0; i < accounts.length; ++i) {
|
for (let i = 0; i < accounts.length; ++i) {
|
||||||
|
@ -43,7 +43,7 @@ export function doSetDefaultAccount(success, failure) {
|
||||||
success();
|
success();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch((err) => {
|
||||||
if (failure) {
|
if (failure) {
|
||||||
failure(err);
|
failure(err);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ export function doSetDefaultAccount(success, failure) {
|
||||||
failure('Could not set a default account'); // fail
|
failure('Could not set a default account'); // fail
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch((err) => {
|
||||||
if (failure) {
|
if (failure) {
|
||||||
failure(err);
|
failure(err);
|
||||||
}
|
}
|
||||||
|
@ -62,13 +62,13 @@ export function doSetDefaultAccount(success, failure) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doSetSync(oldHash, newHash, data) {
|
export function doSetSync(oldHash, newHash, data) {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.SET_SYNC_STARTED,
|
type: ACTIONS.SET_SYNC_STARTED,
|
||||||
});
|
});
|
||||||
|
|
||||||
return Lbryio.call('sync', 'set', { old_hash: oldHash, new_hash: newHash, data }, 'post')
|
return Lbryio.call('sync', 'set', { old_hash: oldHash, new_hash: newHash, data }, 'post')
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
if (!response.hash) {
|
if (!response.hash) {
|
||||||
throw Error('No hash returned for sync/set.');
|
throw Error('No hash returned for sync/set.');
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ export function doSetSync(oldHash, newHash, data) {
|
||||||
data: { syncHash: response.hash },
|
data: { syncHash: response.hash },
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.SET_SYNC_FAILED,
|
type: ACTIONS.SET_SYNC_FAILED,
|
||||||
data: { error },
|
data: { error },
|
||||||
|
@ -94,7 +94,7 @@ export const doGetSyncDesktop = (cb?, password) => (dispatch, getState) => {
|
||||||
const setSyncPending = selectSetSyncIsPending(state);
|
const setSyncPending = selectSetSyncIsPending(state);
|
||||||
const syncLocked = selectSyncIsLocked(state);
|
const syncLocked = selectSyncIsLocked(state);
|
||||||
|
|
||||||
return getSavedPassword().then(savedPassword => {
|
return getSavedPassword().then((savedPassword) => {
|
||||||
const passwordArgument = password || password === '' ? password : savedPassword === null ? '' : savedPassword;
|
const passwordArgument = password || password === '' ? password : savedPassword === null ? '' : savedPassword;
|
||||||
|
|
||||||
if (syncEnabled && !getSyncPending && !setSyncPending && !syncLocked) {
|
if (syncEnabled && !getSyncPending && !setSyncPending && !syncLocked) {
|
||||||
|
@ -128,7 +128,7 @@ export function doSyncLoop(noInterval) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doSyncUnsubscribe() {
|
export function doSyncUnsubscribe() {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
if (syncTimer) {
|
if (syncTimer) {
|
||||||
clearInterval(syncTimer);
|
clearInterval(syncTimer);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ export function doGetSync(passedPassword, callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.GET_SYNC_STARTED,
|
type: ACTIONS.GET_SYNC_STARTED,
|
||||||
});
|
});
|
||||||
|
@ -156,7 +156,7 @@ export function doGetSync(passedPassword, callback) {
|
||||||
const data = {};
|
const data = {};
|
||||||
|
|
||||||
Lbry.wallet_status()
|
Lbry.wallet_status()
|
||||||
.then(status => {
|
.then((status) => {
|
||||||
if (status.is_locked) {
|
if (status.is_locked) {
|
||||||
return Lbry.wallet_unlock({ password });
|
return Lbry.wallet_unlock({ password });
|
||||||
}
|
}
|
||||||
|
@ -164,15 +164,15 @@ export function doGetSync(passedPassword, callback) {
|
||||||
// Wallet is already unlocked
|
// Wallet is already unlocked
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.then(isUnlocked => {
|
.then((isUnlocked) => {
|
||||||
if (isUnlocked) {
|
if (isUnlocked) {
|
||||||
return Lbry.sync_hash();
|
return Lbry.sync_hash();
|
||||||
}
|
}
|
||||||
data.unlockFailed = true;
|
data.unlockFailed = true;
|
||||||
throw new Error();
|
throw new Error();
|
||||||
})
|
})
|
||||||
.then(hash => Lbryio.call('sync', 'get', { hash }, 'post'))
|
.then((hash) => Lbryio.call('sync', 'get', { hash }, 'post'))
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
const syncHash = response.hash;
|
const syncHash = response.hash;
|
||||||
data.syncHash = syncHash;
|
data.syncHash = syncHash;
|
||||||
data.syncData = response.data;
|
data.syncData = response.data;
|
||||||
|
@ -183,7 +183,7 @@ export function doGetSync(passedPassword, callback) {
|
||||||
return Lbry.sync_apply({ password, data: response.data, blocking: true });
|
return Lbry.sync_apply({ password, data: response.data, blocking: true });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
if (!response) {
|
if (!response) {
|
||||||
dispatch({ type: ACTIONS.GET_SYNC_COMPLETED, data });
|
dispatch({ type: ACTIONS.GET_SYNC_COMPLETED, data });
|
||||||
handleCallback(null, data.changed);
|
handleCallback(null, data.changed);
|
||||||
|
@ -200,7 +200,7 @@ export function doGetSync(passedPassword, callback) {
|
||||||
dispatch({ type: ACTIONS.GET_SYNC_COMPLETED, data });
|
dispatch({ type: ACTIONS.GET_SYNC_COMPLETED, data });
|
||||||
handleCallback(null, data.changed);
|
handleCallback(null, data.changed);
|
||||||
})
|
})
|
||||||
.catch(syncAttemptError => {
|
.catch((syncAttemptError) => {
|
||||||
const badPasswordError =
|
const badPasswordError =
|
||||||
syncAttemptError && syncAttemptError.data && syncAttemptError.data.name === BAD_PASSWORD_ERROR_NAME;
|
syncAttemptError && syncAttemptError.data && syncAttemptError.data.name === BAD_PASSWORD_ERROR_NAME;
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ export function doGetSync(passedPassword, callback) {
|
||||||
dispatch(doSetSync('', walletHash, syncApplyData, password));
|
dispatch(doSetSync('', walletHash, syncApplyData, password));
|
||||||
handleCallback();
|
handleCallback();
|
||||||
})
|
})
|
||||||
.catch(syncApplyError => {
|
.catch((syncApplyError) => {
|
||||||
handleCallback(syncApplyError);
|
handleCallback(syncApplyError);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,7 @@ export function doGetSync(passedPassword, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doSyncApply(syncHash, syncData, password) {
|
export function doSyncApply(syncHash, syncData, password) {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.SYNC_APPLY_STARTED,
|
type: ACTIONS.SYNC_APPLY_STARTED,
|
||||||
});
|
});
|
||||||
|
@ -286,14 +286,14 @@ export function doSyncApply(syncHash, syncData, password) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doCheckSync() {
|
export function doCheckSync() {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.GET_SYNC_STARTED,
|
type: ACTIONS.GET_SYNC_STARTED,
|
||||||
});
|
});
|
||||||
|
|
||||||
Lbry.sync_hash().then(hash => {
|
Lbry.sync_hash().then((hash) => {
|
||||||
Lbryio.call('sync', 'get', { hash }, 'post')
|
Lbryio.call('sync', 'get', { hash }, 'post')
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
const data = {
|
const data = {
|
||||||
hasSyncedWallet: true,
|
hasSyncedWallet: true,
|
||||||
syncHash: response.hash,
|
syncHash: response.hash,
|
||||||
|
@ -314,19 +314,19 @@ export function doCheckSync() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doResetSync() {
|
export function doResetSync() {
|
||||||
return dispatch =>
|
return (dispatch) =>
|
||||||
new Promise(resolve => {
|
new Promise((resolve) => {
|
||||||
dispatch({ type: ACTIONS.SYNC_RESET });
|
dispatch({ type: ACTIONS.SYNC_RESET });
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doSyncEncryptAndDecrypt(oldPassword, newPassword, encrypt) {
|
export function doSyncEncryptAndDecrypt(oldPassword, newPassword, encrypt) {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
const data = {};
|
const data = {};
|
||||||
return Lbry.sync_hash()
|
return Lbry.sync_hash()
|
||||||
.then(hash => Lbryio.call('sync', 'get', { hash }, 'post'))
|
.then((hash) => Lbryio.call('sync', 'get', { hash }, 'post'))
|
||||||
.then(syncGetResponse => {
|
.then((syncGetResponse) => {
|
||||||
data.oldHash = syncGetResponse.hash;
|
data.oldHash = syncGetResponse.hash;
|
||||||
|
|
||||||
return Lbry.sync_apply({ password: oldPassword, data: syncGetResponse.data });
|
return Lbry.sync_apply({ password: oldPassword, data: syncGetResponse.data });
|
||||||
|
@ -339,7 +339,7 @@ export function doSyncEncryptAndDecrypt(oldPassword, newPassword, encrypt) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(() => Lbry.sync_apply({ password: newPassword }))
|
.then(() => Lbry.sync_apply({ password: newPassword }))
|
||||||
.then(syncApplyResponse => {
|
.then((syncApplyResponse) => {
|
||||||
if (syncApplyResponse.hash !== data.oldHash) {
|
if (syncApplyResponse.hash !== data.oldHash) {
|
||||||
return dispatch(doSetSync(data.oldHash, syncApplyResponse.hash, syncApplyResponse.data));
|
return dispatch(doSetSync(data.oldHash, syncApplyResponse.hash, syncApplyResponse.data));
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,12 +105,20 @@ export const makeSelectCommentIdsForUri = (uri: string) =>
|
||||||
|
|
||||||
export const makeSelectMyReactionsForComment = (commentId: string) =>
|
export const makeSelectMyReactionsForComment = (commentId: string) =>
|
||||||
createSelector(selectState, (state) => {
|
createSelector(selectState, (state) => {
|
||||||
|
if (!state.myReactsByCommentId) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
return state.myReactsByCommentId[commentId] || [];
|
return state.myReactsByCommentId[commentId] || [];
|
||||||
});
|
});
|
||||||
|
|
||||||
export const makeSelectOthersReactionsForComment = (commentId: string) =>
|
export const makeSelectOthersReactionsForComment = (commentId: string) =>
|
||||||
createSelector(selectState, (state) => {
|
createSelector(selectState, (state) => {
|
||||||
return state.othersReactsByCommentId[commentId];
|
if (!state.othersReactsByCommentId) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.othersReactsByCommentId[commentId] || {};
|
||||||
});
|
});
|
||||||
|
|
||||||
export const selectPendingCommentReacts = createSelector(selectState, (state) => state.pendingCommentReactions);
|
export const selectPendingCommentReacts = createSelector(selectState, (state) => state.pendingCommentReactions);
|
||||||
|
|
|
@ -34,6 +34,7 @@ $thumbnailWidthSmall: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment {
|
.comment {
|
||||||
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
font-size: var(--font-small);
|
font-size: var(--font-small);
|
||||||
|
@ -101,6 +102,10 @@ $thumbnailWidthSmall: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.comment--livestream {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.comment--slimed {
|
.comment--slimed {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,10 +48,6 @@
|
||||||
margin-top: var(--spacing-s);
|
margin-top: var(--spacing-s);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
> :first-child {
|
|
||||||
margin-right: var(--spacing-s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.livestream__comment-author {
|
.livestream__comment-author {
|
||||||
|
|
Loading…
Add table
Reference in a new issue