Option to change commments-server (desktop)

## Issue
> 5459 Add setting for changing your comment server. Visible on desktop (and possibly defaulting to Odysee URL), hidden on odysee.

## Comments
Not sure how this would actually work properly without the user recompiling the app to handle server differences. For example, even when we use our own server but switch between v1 and v2, some code changes are need to handle the differences. At that point, it seems easier for the user to just change the .env file? Anyway...

## Changes
- Added Desktop-only options to define custom server. [Settings > Advanced Settings > "Comment server" section].
This commit is contained in:
infinite-persistence 2021-07-25 20:52:45 +08:00
parent 4731786a3f
commit ff9ca662f2
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
9 changed files with 149 additions and 17 deletions

View file

@ -12,6 +12,7 @@ LBRY_WEB_API=https://api.na-backend.odysee.com
LBRY_WEB_STREAMING_API=https://cdn.lbryplayer.xyz LBRY_WEB_STREAMING_API=https://cdn.lbryplayer.xyz
LBRY_WEB_BUFFER_API=https://collector-service.api.lbry.tv/api/v1/events/video LBRY_WEB_BUFFER_API=https://collector-service.api.lbry.tv/api/v1/events/video
COMMENT_SERVER_API=https://comments.odysee.com/api/v2 COMMENT_SERVER_API=https://comments.odysee.com/api/v2
COMMENT_SERVER_NAME=Odysee
SEARCH_SERVER_API=https://lighthouse.odysee.com/search SEARCH_SERVER_API=https://lighthouse.odysee.com/search
SOCKETY_SERVER_API=wss://sockety.odysee.com/ws SOCKETY_SERVER_API=wss://sockety.odysee.com/ws
THUMBNAIL_CDN_URL=https://image-processor.vanwanet.com/optimize/ THUMBNAIL_CDN_URL=https://image-processor.vanwanet.com/optimize/

View file

@ -15,6 +15,7 @@ const config = {
LBRY_WEB_BUFFER_API: process.env.LBRY_WEB_BUFFER_API, LBRY_WEB_BUFFER_API: process.env.LBRY_WEB_BUFFER_API,
SEARCH_SERVER_API: process.env.SEARCH_SERVER_API, SEARCH_SERVER_API: process.env.SEARCH_SERVER_API,
COMMENT_SERVER_API: process.env.COMMENT_SERVER_API, COMMENT_SERVER_API: process.env.COMMENT_SERVER_API,
COMMENT_SERVER_NAME: process.env.COMMENT_SERVER_NAME,
SOCKETY_SERVER_API: process.env.SOCKETY_SERVER_API, SOCKETY_SERVER_API: process.env.SOCKETY_SERVER_API,
WELCOME_VERSION: process.env.WELCOME_VERSION, WELCOME_VERSION: process.env.WELCOME_VERSION,
DOMAIN: process.env.DOMAIN, DOMAIN: process.env.DOMAIN,

View file

@ -2038,6 +2038,13 @@
"Your publish is being confirmed and will be live soon": "Your publish is being confirmed and will be live soon", "Your publish is being confirmed and will be live soon": "Your publish is being confirmed and will be live soon",
"Clear Edits": "Clear Edits", "Clear Edits": "Clear Edits",
"Something not quite right..": "Something not quite right..", "Something not quite right..": "Something not quite right..",
"Comments server": "Comments server",
"Default comments server (%name%)": "Default comments server (%name%)",
"Custom comments server": "Custom comments server",
"Failed to fetch comments.": "Failed to fetch comments.",
"Failed to fetch comments. Verify custom server settings.": "Failed to fetch comments. Verify custom server settings.",
"Commenting server is not set.": "Commenting server is not set.",
"Comments are not currently enabled.": "Comments are not currently enabled.",
"See All": "See All", "See All": "See All",
"Supporting content requires %lbc%": "Supporting content requires %lbc%", "Supporting content requires %lbc%": "Supporting content requires %lbc%",
"With %lbc%, you can send tips to your favorite creators, or help boost their content for more people to see.": "With %lbc%, you can send tips to your favorite creators, or help boost their content for more people to see.", "With %lbc%, you can send tips to your favorite creators, or help boost their content for more people to see.": "With %lbc%, you can send tips to your favorite creators, or help boost their content for more people to see.",

View file

@ -4,6 +4,13 @@ import { COMMENT_SERVER_API } from 'config';
const Comments = { const Comments = {
url: COMMENT_SERVER_API, url: COMMENT_SERVER_API,
enabled: Boolean(COMMENT_SERVER_API), enabled: Boolean(COMMENT_SERVER_API),
isCustomServer: false,
setServerUrl: (customUrl: ?string) => {
Comments.url = customUrl === undefined ? COMMENT_SERVER_API : customUrl;
Comments.enabled = Boolean(Comments.url);
Comments.isCustomServer = Comments.url !== COMMENT_SERVER_API;
},
moderation_block: (params: ModerationBlockParams) => fetchCommentsApi('moderation.Block', params), moderation_block: (params: ModerationBlockParams) => fetchCommentsApi('moderation.Block', params),
moderation_unblock: (params: ModerationBlockParams) => fetchCommentsApi('moderation.UnBlock', params), moderation_unblock: (params: ModerationBlockParams) => fetchCommentsApi('moderation.UnBlock', params),
@ -31,8 +38,10 @@ const Comments = {
}; };
function fetchCommentsApi(method: string, params: {}) { function fetchCommentsApi(method: string, params: {}) {
if (!Comments.enabled) { if (!Comments.url) {
return Promise.reject('Comments are not currently enabled'); // eslint-disable-line return Promise.reject(new Error('Commenting server is not set.'));
} else if (!Comments.enabled) {
return Promise.reject('Comments are not currently enabled.'); // eslint-disable-line
} }
const url = `${Comments.url}?m=${method}`; const url = `${Comments.url}?m=${method}`;

View file

@ -0,0 +1,17 @@
import { connect } from 'react-redux';
import { SETTINGS } from 'lbry-redux';
import { doSetClientSetting } from 'redux/actions/settings';
import { makeSelectClientSetting } from 'redux/selectors/settings';
import SettingCommentsServer from './view';
const select = (state) => ({
customServerEnabled: makeSelectClientSetting(SETTINGS.CUSTOM_COMMENTS_SERVER_ENABLED)(state),
customServerUrl: makeSelectClientSetting(SETTINGS.CUSTOM_COMMENTS_SERVER_URL)(state),
});
const perform = (dispatch) => ({
setCustomServerEnabled: (val) => dispatch(doSetClientSetting(SETTINGS.CUSTOM_COMMENTS_SERVER_ENABLED, val, true)),
setCustomServerUrl: (url) => dispatch(doSetClientSetting(SETTINGS.CUSTOM_COMMENTS_SERVER_URL, url, true)),
});
export default connect(select, perform)(SettingCommentsServer);

View file

@ -0,0 +1,70 @@
// @flow
import { COMMENT_SERVER_NAME } from 'config';
import React from 'react';
import Comments from 'comments';
import { FormField } from 'component/common/form';
const DEBOUNCE_TEXT_INPUT_MS = 500;
type Props = {
customServerEnabled: boolean,
customServerUrl: string,
setCustomServerEnabled: (boolean) => void,
setCustomServerUrl: (string) => void,
};
function SettingCommentsServer(props: Props) {
const { customServerEnabled, customServerUrl, setCustomServerEnabled, setCustomServerUrl } = props;
const [customUrl, setCustomUrl] = React.useState(customServerUrl);
React.useEffect(() => {
const timer = setTimeout(() => {
setCustomServerUrl(customUrl);
Comments.url = customUrl;
}, DEBOUNCE_TEXT_INPUT_MS);
return () => clearTimeout(timer);
}, [customUrl, setCustomServerUrl]);
return (
<React.Fragment>
<fieldset-section>
<FormField
type="radio"
name="use_default_comments_server"
label={__('Default comments server (%name%)', { name: COMMENT_SERVER_NAME })}
checked={!customServerEnabled}
onChange={(e) => {
if (e.target.checked) {
setCustomServerEnabled(false);
}
}}
/>
<FormField
type="radio"
name="use_custom_comments_server"
label={__('Custom comments server')}
checked={customServerEnabled}
onChange={(e) => {
if (e.target.checked) {
setCustomServerEnabled(true);
}
}}
/>
{customServerEnabled && (
<div className="section__body">
<FormField
type="text"
placeholder="https://comment.mysite.com"
value={customUrl}
onChange={(e) => setCustomUrl(e.target.value)}
/>
</div>
)}
</fieldset-section>
</React.Fragment>
);
}
export default SettingCommentsServer;

View file

@ -5,6 +5,7 @@ import { FormField, FormFieldPrice } from 'component/common/form';
import Button from 'component/button'; import Button from 'component/button';
import I18nMessage from 'component/i18nMessage'; import I18nMessage from 'component/i18nMessage';
import Page from 'component/page'; import Page from 'component/page';
import SettingCommentsServer from 'component/settingCommentsServer';
import SettingWalletServer from 'component/settingWalletServer'; import SettingWalletServer from 'component/settingWalletServer';
import SettingAutoLaunch from 'component/settingAutoLaunch'; import SettingAutoLaunch from 'component/settingAutoLaunch';
import SettingClosingBehavior from 'component/settingClosingBehavior'; import SettingClosingBehavior from 'component/settingClosingBehavior';
@ -507,6 +508,10 @@ class SettingsAdvancedPage extends React.PureComponent<Props, State> {
/> />
)} )}
{/* @if TARGET='app' */}
<Card title={__('Comments server')} actions={<SettingCommentsServer />} />
{/* @endif */}
<Card title={__('Upload settings')} actions={<PublishSettings />} /> <Card title={__('Upload settings')} actions={<PublishSettings />} />
{/* @if TARGET='app' */} {/* @if TARGET='app' */}

View file

@ -28,6 +28,7 @@ import { selectPrefsReady } from 'redux/selectors/sync';
import { doAlertWaitingForSync } from 'redux/actions/app'; import { doAlertWaitingForSync } from 'redux/actions/app';
const isDev = process.env.NODE_ENV !== 'production'; const isDev = process.env.NODE_ENV !== 'production';
const FETCH_API_FAILED_TO_FETCH = 'Failed to fetch';
const COMMENTRON_MSG_REMAP = { const COMMENTRON_MSG_REMAP = {
// <-- Commentron msg --> : <-- App msg --> // <-- Commentron msg --> : <-- App msg -->
@ -111,7 +112,8 @@ export function doCommentList(
return result; return result;
}) })
.catch((error) => { .catch((error) => {
if (error.message === 'comments are disabled by the creator') { switch (error.message) {
case 'comments are disabled by the creator':
dispatch({ dispatch({
type: ACTIONS.COMMENT_LIST_COMPLETED, type: ACTIONS.COMMENT_LIST_COMPLETED,
data: { data: {
@ -119,12 +121,23 @@ export function doCommentList(
disabled: true, disabled: true,
}, },
}); });
} else { break;
devToast(dispatch, `doCommentList: ${error.message}`);
dispatch({ case FETCH_API_FAILED_TO_FETCH:
type: ACTIONS.COMMENT_LIST_FAILED, dispatch(
data: error, doToast({
}); isError: true,
message: Comments.isCustomServer
? __('Failed to fetch comments. Verify custom server settings.')
: __('Failed to fetch comments.'),
})
);
dispatch({ type: ACTIONS.COMMENT_LIST_FAILED, data: error });
break;
default:
dispatch(doToast({ isError: true, message: `${error.message}` }));
dispatch({ type: ACTIONS.COMMENT_LIST_FAILED, data: error });
} }
}); });
}; };
@ -261,7 +274,6 @@ export function doCommentReactList(commentIds: Array<string>) {
}); });
}) })
.catch((error) => { .catch((error) => {
devToast(dispatch, `doCommentReactList: ${error.message}`);
dispatch({ dispatch({
type: ACTIONS.COMMENT_REACTION_LIST_FAILED, type: ACTIONS.COMMENT_REACTION_LIST_FAILED,
data: error, data: error,

View file

@ -4,6 +4,7 @@ import { ACTIONS as LBRY_REDUX_ACTIONS, SETTINGS, SHARED_PREFERENCES } from 'lbr
import { getSubsetFromKeysArray } from 'util/sync-settings'; import { getSubsetFromKeysArray } from 'util/sync-settings';
import { getDefaultLanguage } from 'util/default-languages'; import { getDefaultLanguage } from 'util/default-languages';
import { UNSYNCED_SETTINGS, SIMPLE_SITE } from 'config'; import { UNSYNCED_SETTINGS, SIMPLE_SITE } from 'config';
import Comments from 'comments';
const { CLIENT_SYNC_KEYS } = SHARED_PREFERENCES; const { CLIENT_SYNC_KEYS } = SHARED_PREFERENCES;
const settingsToIgnore = (UNSYNCED_SETTINGS && UNSYNCED_SETTINGS.trim().split(' ')) || []; const settingsToIgnore = (UNSYNCED_SETTINGS && UNSYNCED_SETTINGS.trim().split(' ')) || [];
@ -51,6 +52,8 @@ const defaultState = {
[SETTINGS.VIDEO_THEATER_MODE]: false, [SETTINGS.VIDEO_THEATER_MODE]: false,
[SETTINGS.VIDEO_PLAYBACK_RATE]: 1, [SETTINGS.VIDEO_PLAYBACK_RATE]: 1,
[SETTINGS.DESKTOP_WINDOW_ZOOM]: 1, [SETTINGS.DESKTOP_WINDOW_ZOOM]: 1,
[SETTINGS.CUSTOM_COMMENTS_SERVER_ENABLED]: false,
[SETTINGS.CUSTOM_COMMENTS_SERVER_URL]: '',
[SETTINGS.DARK_MODE_TIMES]: { [SETTINGS.DARK_MODE_TIMES]: {
from: { hour: '21', min: '00', formattedTime: '21:00' }, from: { hour: '21', min: '00', formattedTime: '21:00' },
@ -169,6 +172,13 @@ reducers[LBRY_REDUX_ACTIONS.USER_STATE_POPULATE] = (state, action) => {
const selectedSettings = sharedPreferences ? getSubsetFromKeysArray(sharedPreferences, clientSyncKeys) : {}; const selectedSettings = sharedPreferences ? getSubsetFromKeysArray(sharedPreferences, clientSyncKeys) : {};
const mergedClientSettings = { ...currentClientSettings, ...selectedSettings }; const mergedClientSettings = { ...currentClientSettings, ...selectedSettings };
const newSharedPreferences = sharedPreferences || {}; const newSharedPreferences = sharedPreferences || {};
Comments.setServerUrl(
mergedClientSettings[SETTINGS.CUSTOM_COMMENTS_SERVER_ENABLED]
? mergedClientSettings[SETTINGS.CUSTOM_COMMENTS_SERVER_URL]
: undefined
);
return Object.assign({}, state, { return Object.assign({}, state, {
sharedPreferences: newSharedPreferences, sharedPreferences: newSharedPreferences,
clientSettings: mergedClientSettings, clientSettings: mergedClientSettings,