API message localization map
This commit is contained in:
commit
c958cb4a40
4 changed files with 95 additions and 112 deletions
|
@ -4,8 +4,9 @@ import * as REACTION_TYPES from 'constants/reactions';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
import { SORT_BY, BLOCK_LEVEL } from 'constants/comment';
|
import { SORT_BY, BLOCK_LEVEL } from 'constants/comment';
|
||||||
import Lbry from 'lbry';
|
import Lbry from 'lbry';
|
||||||
|
import { resolveApiMessage } from 'util/api-message';
|
||||||
import { parseURI, buildURI, isURIEqual } from 'util/lbryURI';
|
import { parseURI, buildURI, isURIEqual } from 'util/lbryURI';
|
||||||
import { devToast, doFailedSignatureToast, resolveCommentronError } from 'util/commentron-error';
|
import { devToast, doFailedSignatureToast } from 'util/toast-wrappers';
|
||||||
import { selectClaimForUri, selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims';
|
import { selectClaimForUri, selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims';
|
||||||
import { doResolveUris, doClaimSearch } from 'redux/actions/claims';
|
import { doResolveUris, doClaimSearch } from 'redux/actions/claims';
|
||||||
import { doToast, doSeeNotifications } from 'redux/actions/notifications';
|
import { doToast, doSeeNotifications } from 'redux/actions/notifications';
|
||||||
|
@ -558,7 +559,7 @@ export function doCommentCreate(uri: string, livestream: boolean, params: Commen
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
dispatch({ type: ACTIONS.COMMENT_CREATE_FAILED, data: 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);
|
return Promise.reject(error);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
74
ui/util/api-message.js
Normal file
74
ui/util/api-message.js
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
type ApiMsgConfig = {
|
||||||
|
originalMsg: string | RegExp,
|
||||||
|
replacement: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
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.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalMsg: /^the comment contents are blocked by (.*)$/,
|
||||||
|
replacement: 'The comment contains contents that are blocked by %1%.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalMsg: 'channel is blocked by publisher',
|
||||||
|
replacement: 'Unable to comment. This channel has blocked you.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalMsg: 'channel is not allowed to post comments',
|
||||||
|
replacement: 'Unable to comment. Your channel has been blocked by an admin.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalMsg: 'comments are disabled by the creator',
|
||||||
|
replacement: 'Unable to comment. The content owner has disabled comments.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalMsg: 'duplicate comment!',
|
||||||
|
replacement: 'Please do not spam.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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.",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 = message.match(config.originalMsg);
|
||||||
|
if (match) {
|
||||||
|
const subs = {};
|
||||||
|
for (let i = 1; i < match.length; ++i) {
|
||||||
|
subs[`${i}`] = match[i];
|
||||||
|
}
|
||||||
|
return __(config.replacement, subs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return __(message);
|
||||||
|
}
|
|
@ -1,110 +0,0 @@
|
||||||
// @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
|
|
||||||
// ****************************************************************************
|
|
||||||
|
|
||||||
declare type CommentronErrorMap = {
|
|
||||||
[string]: {
|
|
||||||
commentron: 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.$/,
|
|
||||||
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.$/,
|
|
||||||
replacement: 'Slow mode is on. Please wait up to %1% seconds before commenting again.',
|
|
||||||
},
|
|
||||||
HAS_MUTED_WORDS: {
|
|
||||||
commentron: /^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',
|
|
||||||
replacement: 'Unable to comment. This channel has blocked you.',
|
|
||||||
},
|
|
||||||
BLOCKED_BY_ADMIN: {
|
|
||||||
commentron: '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',
|
|
||||||
replacement: 'Unable to comment. The content owner has disabled comments.',
|
|
||||||
},
|
|
||||||
STOP_SPAMMING: {
|
|
||||||
commentron: 'duplicate comment!',
|
|
||||||
replacement: 'Please do not spam.',
|
|
||||||
},
|
|
||||||
CHANNEL_AGE: {
|
|
||||||
commentron: '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,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const match = commentronMsg.match(data.commentron);
|
|
||||||
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 {
|
|
||||||
// Fallback to commentron original message. It will be in English
|
|
||||||
// only and most likely not capitalized correctly.
|
|
||||||
message: commentronMsg,
|
|
||||||
isError: true,
|
|
||||||
};
|
|
||||||
}
|
|
18
ui/util/toast-wrappers.js
Normal file
18
ui/util/toast-wrappers.js
Normal file
|
@ -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
|
||||||
|
}
|
Loading…
Reference in a new issue