Comment server swap #7706
6 changed files with 111 additions and 18 deletions
|
@ -28,7 +28,6 @@ import type { ElementRef } from 'react';
|
||||||
import UriIndicator from 'component/uriIndicator';
|
import UriIndicator from 'component/uriIndicator';
|
||||||
import usePersistedState from 'effects/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
import WalletTipAmountSelector from 'component/walletTipAmountSelector';
|
import WalletTipAmountSelector from 'component/walletTipAmountSelector';
|
||||||
|
|
||||||
import { getStripeEnvironment } from 'util/stripe';
|
import { getStripeEnvironment } from 'util/stripe';
|
||||||
const stripeEnvironment = getStripeEnvironment();
|
const stripeEnvironment = getStripeEnvironment();
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,9 @@ import { doCommentReset, doCommentList, doCommentById, doCommentReactList } from
|
||||||
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
||||||
import { getChannelIdFromClaim } from 'util/claim';
|
import { getChannelIdFromClaim } from 'util/claim';
|
||||||
import CommentsList from './view';
|
import CommentsList from './view';
|
||||||
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
|
import * as SETTINGS from 'constants/settings';
|
||||||
|
import { doSetClientSetting } from 'redux/actions/settings';
|
||||||
|
|
||||||
const select = (state, props) => {
|
const select = (state, props) => {
|
||||||
const { uri } = props;
|
const { uri } = props;
|
||||||
|
@ -56,15 +59,19 @@ const select = (state, props) => {
|
||||||
myReactsByCommentId: selectMyReacts(state),
|
myReactsByCommentId: selectMyReacts(state),
|
||||||
othersReactsById: selectOthersReacts(state),
|
othersReactsById: selectOthersReacts(state),
|
||||||
activeChannelId: activeChannelClaim && activeChannelClaim.claim_id,
|
activeChannelId: activeChannelClaim && activeChannelClaim.claim_id,
|
||||||
|
customCommentServers: makeSelectClientSetting(SETTINGS.CUSTOM_COMMENTS_SERVERS)(state),
|
||||||
|
commentServer: makeSelectClientSetting(SETTINGS.CUSTOM_COMMENTS_SERVER_URL)(state),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const perform = {
|
const perform = (dispatch, ownProps) => ({
|
||||||
fetchTopLevelComments: doCommentList,
|
fetchTopLevelComments: (uri, parentId, page, pageSize, sortBy) =>
|
||||||
fetchComment: doCommentById,
|
dispatch(doCommentList(uri, parentId, page, pageSize, sortBy)),
|
||||||
fetchReacts: doCommentReactList,
|
fetchComment: (commentId) => dispatch(doCommentById(commentId)),
|
||||||
resetComments: doCommentReset,
|
fetchReacts: (commentIds) => dispatch(doCommentReactList(commentIds)),
|
||||||
doResolveUris,
|
resetComments: (claimId) => dispatch(doCommentReset(claimId)),
|
||||||
};
|
doResolveUris: (uris, returnCachedClaims) => dispatch(doResolveUris(uris, returnCachedClaims)),
|
||||||
|
setCommentServer: (url) => dispatch(doSetClientSetting(SETTINGS.CUSTOM_COMMENTS_SERVER_URL, url, true)),
|
||||||
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(CommentsList);
|
export default connect(select, perform)(CommentsList);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { COMMENT_PAGE_SIZE_TOP_LEVEL, SORT_BY } from 'constants/comment';
|
import { COMMENT_PAGE_SIZE_TOP_LEVEL, SORT_BY } from 'constants/comment';
|
||||||
import { ENABLE_COMMENT_REACTIONS } from 'config';
|
import { ENABLE_COMMENT_REACTIONS, COMMENT_SERVER_API, COMMENT_SERVER_NAME } from 'config';
|
||||||
import { useIsMobile, useIsMediumScreen } from 'effects/use-screensize';
|
import { useIsMobile, useIsMediumScreen } from 'effects/use-screensize';
|
||||||
import { getCommentsListTitle } from 'util/comments';
|
import { getCommentsListTitle } from 'util/comments';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
|
@ -15,6 +15,8 @@ import Empty from 'component/common/empty';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import Spinner from 'component/spinner';
|
import Spinner from 'component/spinner';
|
||||||
import usePersistedState from 'effects/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
|
import { FormField } from 'component/common/form';
|
||||||
|
import Comments from 'comments';
|
||||||
|
|
||||||
const DEBOUNCE_SCROLL_HANDLER_MS = 200;
|
const DEBOUNCE_SCROLL_HANDLER_MS = 200;
|
||||||
|
|
||||||
|
@ -52,6 +54,9 @@ type Props = {
|
||||||
fetchReacts: (commentIds: Array<string>) => Promise<any>,
|
fetchReacts: (commentIds: Array<string>) => Promise<any>,
|
||||||
resetComments: (claimId: string) => void,
|
resetComments: (claimId: string) => void,
|
||||||
doResolveUris: (uris: Array<string>, returnCachedClaims: boolean) => void,
|
doResolveUris: (uris: Array<string>, returnCachedClaims: boolean) => void,
|
||||||
|
customCommentServers: Array<CommentServerDetails>,
|
||||||
|
setCommentServer: (string) => void,
|
||||||
|
commentServer: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function CommentList(props: Props) {
|
export default function CommentList(props: Props) {
|
||||||
|
@ -80,11 +85,17 @@ export default function CommentList(props: Props) {
|
||||||
fetchReacts,
|
fetchReacts,
|
||||||
resetComments,
|
resetComments,
|
||||||
doResolveUris,
|
doResolveUris,
|
||||||
|
customCommentServers,
|
||||||
|
setCommentServer,
|
||||||
|
commentServer,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const isMediumScreen = useIsMediumScreen();
|
const isMediumScreen = useIsMediumScreen();
|
||||||
|
|
||||||
|
const defaultServer = { name: COMMENT_SERVER_NAME, url: COMMENT_SERVER_API };
|
||||||
|
const allServers = [defaultServer, ...(customCommentServers || [])];
|
||||||
|
|
||||||
const spinnerRef = React.useRef();
|
const spinnerRef = React.useRef();
|
||||||
const DEFAULT_SORT = ENABLE_COMMENT_REACTIONS ? SORT_BY.POPULARITY : SORT_BY.NEWEST;
|
const DEFAULT_SORT = ENABLE_COMMENT_REACTIONS ? SORT_BY.POPULARITY : SORT_BY.NEWEST;
|
||||||
const [sort, setSort] = usePersistedState('comment-sort-by', DEFAULT_SORT);
|
const [sort, setSort] = usePersistedState('comment-sort-by', DEFAULT_SORT);
|
||||||
|
@ -255,7 +266,16 @@ export default function CommentList(props: Props) {
|
||||||
}, [alreadyResolved, doResolveUris, topLevelComments]);
|
}, [alreadyResolved, doResolveUris, topLevelComments]);
|
||||||
|
|
||||||
const commentProps = { isTopLevel: true, threadDepth: 3, uri, claimIsMine, linkedCommentId };
|
const commentProps = { isTopLevel: true, threadDepth: 3, uri, claimIsMine, linkedCommentId };
|
||||||
const actionButtonsProps = { totalComments, sort, changeSort, setPage };
|
const actionButtonsProps = {
|
||||||
|
totalComments,
|
||||||
|
sort,
|
||||||
|
changeSort,
|
||||||
|
setPage,
|
||||||
|
allServers,
|
||||||
|
commentServer,
|
||||||
|
defaultServer,
|
||||||
|
setCommentServer,
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
|
@ -334,11 +354,15 @@ type ActionButtonsProps = {
|
||||||
sort: string,
|
sort: string,
|
||||||
changeSort: (string) => void,
|
changeSort: (string) => void,
|
||||||
setPage: (number) => void,
|
setPage: (number) => void,
|
||||||
|
allServers: Array<CommentServerDetails>,
|
||||||
|
commentServer: string,
|
||||||
|
setCommentServer: (string) => void,
|
||||||
|
defaultServer: CommentServerDetails,
|
||||||
};
|
};
|
||||||
|
|
||||||
const CommentActionButtons = (actionButtonsProps: ActionButtonsProps) => {
|
const CommentActionButtons = (actionButtonsProps: ActionButtonsProps) => {
|
||||||
const { totalComments, sort, changeSort, setPage } = actionButtonsProps;
|
const { totalComments, sort, changeSort, setPage, allServers, commentServer, setCommentServer, defaultServer } =
|
||||||
|
actionButtonsProps;
|
||||||
const sortButtonProps = { activeSort: sort, changeSort };
|
const sortButtonProps = { activeSort: sort, changeSort };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -355,8 +379,34 @@ const CommentActionButtons = (actionButtonsProps: ActionButtonsProps) => {
|
||||||
<SortButton {...sortButtonProps} label={__('New')} icon={ICONS.NEW} sortOption={SORT_BY.NEWEST} />
|
<SortButton {...sortButtonProps} label={__('New')} icon={ICONS.NEW} sortOption={SORT_BY.NEWEST} />
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
<div className="button_refresh">
|
||||||
<Button button="alt" icon={ICONS.REFRESH} title={__('Refresh')} onClick={() => setPage(0)} />
|
<Button button="alt" icon={ICONS.REFRESH} title={__('Refresh')} onClick={() => setPage(0)} />
|
||||||
|
</div>
|
||||||
|
{allServers.length >= 2 && (
|
||||||
|
<div className="button_selectedServer">
|
||||||
|
<FormField
|
||||||
|
type="select-tiny"
|
||||||
|
onChange={function (x) {
|
||||||
|
const selectedServer = x.target.value;
|
||||||
|
setCommentServer(selectedServer);
|
||||||
|
if (selectedServer === defaultServer.url) {
|
||||||
|
Comments.setServerUrl(undefined);
|
||||||
|
} else {
|
||||||
|
Comments.setServerUrl(selectedServer);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
value={commentServer}
|
||||||
|
>
|
||||||
|
{allServers.map(function (server) {
|
||||||
|
return (
|
||||||
|
<option key={server.url} value={server.url}>
|
||||||
|
{server.name}
|
||||||
|
</option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</FormField>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -274,6 +274,21 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
.select--slim {
|
||||||
|
display: flex;
|
||||||
|
margin-left: var(--spacing-s);
|
||||||
|
margin-bottom: var(--spacing-s);
|
||||||
|
|
||||||
|
@media (min-width: $breakpoint-small) {
|
||||||
|
max-width: none;
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 0 var(--spacing-xs);
|
||||||
|
padding-right: var(--spacing-l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card--enable-overflow {
|
.card--enable-overflow {
|
||||||
|
@ -318,6 +333,7 @@
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
.button--alt {
|
.button--alt {
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
|
padding: 0 var(--spacing-s);
|
||||||
}
|
}
|
||||||
.comment__sort {
|
.comment__sort {
|
||||||
.button--alt {
|
.button--alt {
|
||||||
|
@ -642,3 +658,25 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button_selectedServer {
|
||||||
|
display: inline;
|
||||||
|
float: right;
|
||||||
|
select {
|
||||||
|
width: 12rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
@media (max-width: $breakpoint-small) {
|
||||||
|
select {
|
||||||
|
width: 8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_refresh {
|
||||||
|
display: inline;
|
||||||
|
float: right;
|
||||||
|
margin-left: var(--spacing-s);
|
||||||
|
}
|
||||||
|
|
|
@ -37,16 +37,12 @@ $thumbnailWidthSmall: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment__sort {
|
.comment__sort {
|
||||||
margin-right: var(--spacing-s);
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
@media (min-width: $breakpoint-small) {
|
@media (min-width: $breakpoint-small) {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
@media (max-width: $breakpoint-small) {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment {
|
.comment {
|
||||||
|
|
|
@ -62,6 +62,9 @@ $spacing-width: 36px;
|
||||||
--floating-viewer-container-height: calc(var(--floating-viewer-height) + var(--floating-viewer-info-height));
|
--floating-viewer-container-height: calc(var(--floating-viewer-height) + var(--floating-viewer-info-height));
|
||||||
--option-select-width: 8rem;
|
--option-select-width: 8rem;
|
||||||
|
|
||||||
|
--input-select-server-min-width: 100px;
|
||||||
|
--input-select-server-max-width: 250px;
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
--text-max-width: 660px;
|
--text-max-width: 660px;
|
||||||
--text-link-padding: 4px;
|
--text-link-padding: 4px;
|
||||||
|
|
Loading…
Reference in a new issue