From f53680ea63c3f0bd479898b857fcb45b1063ff1c Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Thu, 24 Mar 2022 14:25:08 +0800 Subject: [PATCH 1/3] Refactor ERR_MAP to be general purpose - Remove the need for an object key. Just use an array. It gets hard to maintain as more messages come in, and so far there is no need to access the configs directly. - Just focus on handling the message and not creating a toast object. Leave the latter to the client. --- ui/redux/actions/comments.js | 4 +- ui/util/commentron-error.js | 91 ++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 53 deletions(-) diff --git a/ui/redux/actions/comments.js b/ui/redux/actions/comments.js index db5f77ed8..9247ba8e7 100644 --- a/ui/redux/actions/comments.js +++ b/ui/redux/actions/comments.js @@ -5,7 +5,7 @@ import * as PAGES from 'constants/pages'; import { SORT_BY, BLOCK_LEVEL } from 'constants/comment'; import Lbry from 'lbry'; import { parseURI, buildURI, isURIEqual } from 'util/lbryURI'; -import { devToast, doFailedSignatureToast, resolveCommentronError } from 'util/commentron-error'; +import { devToast, doFailedSignatureToast, resolveApiMessage } from 'util/commentron-error'; import { selectClaimForUri, selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims'; import { doResolveUris, doClaimSearch } from 'redux/actions/claims'; import { doToast, doSeeNotifications } from 'redux/actions/notifications'; @@ -558,7 +558,7 @@ export function doCommentCreate(uri: string, livestream: boolean, params: Commen }) .catch((error) => { dispatch({ type: ACTIONS.COMMENT_CREATE_FAILED, data: error }); - dispatch(doToast(resolveCommentronError(error.message))); + dispatch(doToast({ message: resolveApiMessage(error.message), isError: true })); return Promise.reject(error); }); }; diff --git a/ui/util/commentron-error.js b/ui/util/commentron-error.js index 0bc492694..9b6ad9544 100644 --- a/ui/util/commentron-error.js +++ b/ui/util/commentron-error.js @@ -25,86 +25,75 @@ export function devToast(dispatch: Dispatch, msg: string) { // Error mapping // **************************************************************************** -declare type CommentronErrorMap = { - [string]: { - commentron: string | RegExp, - replacement: string, - linkText?: string, - linkTarget?: string, - }, +type ApiMsgConfig = { + originalMsg: string | RegExp, + replacement: string, }; // prettier-ignore -const ERR_MAP: CommentronErrorMap = { - SIMILAR_NAME: { - commentron: /^your user name (.*) is too close to the creator's user name (.*) and may cause confusion. Please use another identity.$/, +const MESSAGE_MAP: Array = Object.freeze([ + { + originalMsg: /^your user name (.*) is too close to the creator's user name (.*) and may cause confusion. Please use another identity.$/, replacement: 'Your user name "%1%" is too close to the creator\'s user name "%2%" and may cause confusion. Please use another identity.', }, - SLOW_MODE_IS_ON: { - commentron: /^Slow mode is on. Please wait at most (.*) seconds before commenting again.$/, + { + originalMsg: /^Slow mode is on. Please wait at most (.*) seconds before commenting again.$/, replacement: 'Slow mode is on. Please wait up to %1% seconds before commenting again.', }, - HAS_MUTED_WORDS: { - commentron: /^the comment contents are blocked by (.*)$/, + { + originalMsg: /^the comment contents are blocked by (.*)$/, replacement: 'The comment contains contents that are blocked by %1%.', }, - BLOCKED_BY_CREATOR: { - commentron: 'channel is blocked by publisher', + { + originalMsg: 'channel is blocked by publisher', replacement: 'Unable to comment. This channel has blocked you.', }, - BLOCKED_BY_ADMIN: { - commentron: 'channel is not allowed to post comments', + { + originalMsg: 'channel is not allowed to post comments', replacement: 'Unable to comment. Your channel has been blocked by an admin.', }, - CREATOR_DISABLED: { - commentron: 'comments are disabled by the creator', + { + originalMsg: 'comments are disabled by the creator', replacement: 'Unable to comment. The content owner has disabled comments.', }, - STOP_SPAMMING: { - commentron: 'duplicate comment!', + { + originalMsg: 'duplicate comment!', replacement: 'Please do not spam.', }, - CHANNEL_AGE: { - commentron: 'this creator has set minimum account age requirements that are not currently met', + { + originalMsg: 'this creator has set minimum account age requirements that are not currently met', replacement: "Your channel does not meet the creator's minimum channel-age limit.", }, -}; +]); -export function resolveCommentronError(commentronMsg: string) { - for (const key in ERR_MAP) { - // noinspection JSUnfilteredForInLoop - const data = ERR_MAP[key]; - if (typeof data.commentron === 'string') { - if (data.commentron === commentronMsg) { - return { - message: __(data.replacement), - linkText: data.linkText ? __(data.linkText) : undefined, - linkTarget: data.linkTarget, - isError: true, - }; +/** + * Returns a re-mapped and localized version of the given API string. + * + * Ideally, the API should be returning a code and variable values, but + * that won't be happening anytime soon (or ever), so this is the alternative. + * + * @param message + * @returns {string} + */ +export function resolveApiMessage(message: string) { + for (let n = 0; n < MESSAGE_MAP.length; ++n) { + const config: ApiMsgConfig = MESSAGE_MAP[n]; + + if (typeof config.originalMsg === 'string') { + if (config.originalMsg === message) { + return __(config.replacement); } } else { - const match = commentronMsg.match(data.commentron); + const match = message.match(config.originalMsg); if (match) { const subs = {}; for (let i = 1; i < match.length; ++i) { subs[`${i}`] = match[i]; } - - return { - message: __(data.replacement, subs), - linkText: data.linkText ? __(data.linkText) : undefined, - linkTarget: data.linkTarget, - isError: true, - }; + return __(config.replacement, subs); } } } - return { - // Fallback to commentron original message. It will be in English - // only and most likely not capitalized correctly. - message: commentronMsg, - isError: true, - }; + return __(message); } From e0ddd94c01478bccd1d8ba2bc0c27baf8de3605b Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Thu, 24 Mar 2022 15:18:13 +0800 Subject: [PATCH 2/3] Rename: [commentron-error.js] -> [api-message.js] --- ui/redux/actions/comments.js | 2 +- ui/util/{commentron-error.js => api-message.js} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename ui/util/{commentron-error.js => api-message.js} (100%) diff --git a/ui/redux/actions/comments.js b/ui/redux/actions/comments.js index 9247ba8e7..17e6f1ad8 100644 --- a/ui/redux/actions/comments.js +++ b/ui/redux/actions/comments.js @@ -5,7 +5,7 @@ import * as PAGES from 'constants/pages'; import { SORT_BY, BLOCK_LEVEL } from 'constants/comment'; import Lbry from 'lbry'; import { parseURI, buildURI, isURIEqual } from 'util/lbryURI'; -import { devToast, doFailedSignatureToast, resolveApiMessage } from 'util/commentron-error'; +import { devToast, doFailedSignatureToast, resolveApiMessage } from 'util/api-message'; import { selectClaimForUri, selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims'; import { doResolveUris, doClaimSearch } from 'redux/actions/claims'; import { doToast, doSeeNotifications } from 'redux/actions/notifications'; diff --git a/ui/util/commentron-error.js b/ui/util/api-message.js similarity index 100% rename from ui/util/commentron-error.js rename to ui/util/api-message.js From 42451e14a86f69d809e8fb75ee9097e3dc2b8ab7 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Thu, 24 Mar 2022 14:33:20 +0800 Subject: [PATCH 3/3] Split toast wrappers into separate file --- ui/redux/actions/comments.js | 3 ++- ui/util/api-message.js | 25 ------------------------- ui/util/toast-wrappers.js | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 26 deletions(-) create mode 100644 ui/util/toast-wrappers.js diff --git a/ui/redux/actions/comments.js b/ui/redux/actions/comments.js index 17e6f1ad8..164041d6d 100644 --- a/ui/redux/actions/comments.js +++ b/ui/redux/actions/comments.js @@ -4,8 +4,9 @@ import * as REACTION_TYPES from 'constants/reactions'; import * as PAGES from 'constants/pages'; import { SORT_BY, BLOCK_LEVEL } from 'constants/comment'; import Lbry from 'lbry'; +import { resolveApiMessage } from 'util/api-message'; import { parseURI, buildURI, isURIEqual } from 'util/lbryURI'; -import { devToast, doFailedSignatureToast, resolveApiMessage } from 'util/api-message'; +import { devToast, doFailedSignatureToast } from 'util/toast-wrappers'; import { selectClaimForUri, selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims'; import { doResolveUris, doClaimSearch } from 'redux/actions/claims'; import { doToast, doSeeNotifications } from 'redux/actions/notifications'; diff --git a/ui/util/api-message.js b/ui/util/api-message.js index 9b6ad9544..e2fae3fdb 100644 --- a/ui/util/api-message.js +++ b/ui/util/api-message.js @@ -1,29 +1,4 @@ // @flow -import { doToast } from 'redux/actions/notifications'; - -// **************************************************************************** -// Helpers -// **************************************************************************** - -export function doFailedSignatureToast(dispatch: Dispatch, channelName: string) { - dispatch( - doToast({ - message: __('Unable to verify signature for %channel%.', { channel: channelName }), - isError: true, - }) - ); -} - -export function devToast(dispatch: Dispatch, msg: string) { - // @if process.env.NODE_ENV!='production' - console.error(msg); // eslint-disable-line - dispatch(doToast({ isError: true, message: `DEV: ${msg}` })); - // @endif -} - -// **************************************************************************** -// Error mapping -// **************************************************************************** type ApiMsgConfig = { originalMsg: string | RegExp, diff --git a/ui/util/toast-wrappers.js b/ui/util/toast-wrappers.js new file mode 100644 index 000000000..c258eb066 --- /dev/null +++ b/ui/util/toast-wrappers.js @@ -0,0 +1,18 @@ +// @flow +import { doToast } from 'redux/actions/notifications'; + +export function doFailedSignatureToast(dispatch: Dispatch, channelName: string) { + dispatch( + doToast({ + message: __('Unable to verify signature for %channel%.', { channel: channelName }), + isError: true, + }) + ); +} + +export function devToast(dispatch: Dispatch, msg: string) { + // @if process.env.NODE_ENV!='production' + console.error(msg); // eslint-disable-line + dispatch(doToast({ isError: true, message: `DEV: ${msg}` })); + // @endif +}