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.
This commit is contained in:
infinite-persistence 2022-03-24 14:25:08 +08:00
parent a96db41782
commit f53680ea63
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
2 changed files with 42 additions and 53 deletions

View file

@ -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);
});
};

View file

@ -25,86 +25,75 @@ export function devToast(dispatch: Dispatch, msg: string) {
// Error mapping
// ****************************************************************************
declare type CommentronErrorMap = {
[string]: {
commentron: string | RegExp,
type ApiMsgConfig = {
originalMsg: string | RegExp,
replacement: string,
linkText?: string,
linkTarget?: 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<ApiMsgConfig> = 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);
}