From 030b936f054431846f0ffa35ae37657b063f116a Mon Sep 17 00:00:00 2001 From: Jannik Date: Wed, 12 Jan 2022 19:17:14 +0100 Subject: [PATCH] feat: add option to save custom username suggestions (#415) * :lipstick: add option to save custom username suggestions that shall be used instead of the docker style usernames. * :children_crossing: add minimum of 10 usernames / update wording * Prettified Code! * :children_crossing: add message for the default name generator / indicate that no further action is required Co-authored-by: jeyemwey --- web/components/config/edit-string-array.tsx | 10 ++- web/pages/config-chat.tsx | 95 ++++++++++++++++++--- web/styles/config-edit-string-tags.scss | 4 + web/types/config-section.ts | 1 + web/utils/config-constants.tsx | 10 +++ web/utils/server-status-context.tsx | 1 + 6 files changed, 106 insertions(+), 15 deletions(-) diff --git a/web/components/config/edit-string-array.tsx b/web/components/config/edit-string-array.tsx index 873ad59bf..c155b08b4 100644 --- a/web/components/config/edit-string-array.tsx +++ b/web/components/config/edit-string-array.tsx @@ -5,6 +5,7 @@ import { Typography, Tag } from 'antd'; import TextField from './form-textfield'; import { UpdateArgs } from '../../types/config-section'; import { StatusState } from '../../utils/input-statuses'; +import FormStatusIndicator from './form-status-indicator'; const { Title } = Typography; @@ -17,6 +18,7 @@ interface EditStringArrayProps { maxLength?: number; values: string[]; submitStatus?: StatusState; + continuousStatusMessage?: StatusState; handleDeleteIndex: (index: number) => void; handleCreateString: (arg: string) => void; } @@ -32,6 +34,7 @@ export default function EditValueArray(props: EditStringArrayProps) { handleDeleteIndex, handleCreateString, submitStatus, + continuousStatusMessage, } = props; const handleInputChange = ({ value }: UpdateArgs) => { @@ -63,7 +66,11 @@ export default function EditValueArray(props: EditStringArrayProps) { ); })} - + {continuousStatusMessage && ( +
+ +
+ )}
{ @@ -40,7 +47,7 @@ export default function ConfigChat() { } function resetForbiddenUsernameState() { - setForbidenUsernameSaveState(null); + setForbiddenUsernameSaveState(null); } function saveForbiddenUsernames() { @@ -52,22 +59,22 @@ export default function ConfigChat() { fieldName: 'forbiddenUsernames', value: formDataValues.forbiddenUsernames, }); - setForbidenUsernameSaveState(STATUS_SUCCESS); + setForbiddenUsernameSaveState(STATUS_SUCCESS); setTimeout(resetForbiddenUsernameState, RESET_TIMEOUT); }, onError: (message: string) => { - setForbidenUsernameSaveState(createInputStatus(STATUS_ERROR, message)); + setForbiddenUsernameSaveState(createInputStatus(STATUS_ERROR, message)); setTimeout(resetForbiddenUsernameState, RESET_TIMEOUT); }, }); } - function handleDeleteUsername(index: number) { + function handleDeleteForbiddenUsernameIndex(index: number) { formDataValues.forbiddenUsernames.splice(index, 1); saveForbiddenUsernames(); } - function handleCreateUsername(tag: string) { + function handleCreateForbiddenUsername(tag: string) { formDataValues.forbiddenUsernames.push(tag); handleFieldChange({ fieldName: 'forbiddenUsernames', @@ -76,10 +83,56 @@ export default function ConfigChat() { saveForbiddenUsernames(); } + function resetSuggestedUsernameState() { + setSuggestedUsernameSaveState(null); + } + + function saveSuggestedUsernames() { + postConfigUpdateToAPI({ + apiPath: API_CHAT_SUGGESTED_USERNAMES, + data: { value: formDataValues.suggestedUsernames }, + onSuccess: () => { + setFieldInConfigState({ + fieldName: 'suggestedUsernames', + value: formDataValues.suggestedUsernames, + }); + setSuggestedUsernameSaveState(STATUS_SUCCESS); + setTimeout(resetSuggestedUsernameState, RESET_TIMEOUT); + }, + onError: (message: string) => { + setForbiddenUsernameSaveState(createInputStatus(STATUS_ERROR, message)); + setTimeout(resetSuggestedUsernameState, RESET_TIMEOUT); + }, + }); + } + + function handleDeleteSuggestedUsernameIndex(index: number) { + formDataValues.suggestedUsernames.splice(index, 1); + saveSuggestedUsernames(); + } + + function handleCreateSuggestedUsername(tag: string) { + formDataValues.suggestedUsernames.push(tag); + handleFieldChange({ + fieldName: 'suggestedUsernames', + value: formDataValues.suggestedUsernames, + }); + saveSuggestedUsernames(); + } + + function getSuggestedUsernamesLimitWarning(length: number): StatusState | null { + if (length === 0) + return createInputStatus('success', TEXTFIELD_PROPS_CHAT_SUGGESTED_USERNAMES.no_entries); + if (length > 0 && length < 10) + return createInputStatus('warning', TEXTFIELD_PROPS_CHAT_SUGGESTED_USERNAMES.min_not_reached); + return null; + } + useEffect(() => { setFormDataValues({ chatDisabled, forbiddenUsernames, + suggestedUsernames, welcomeMessage, }); }, [serverConfig]); @@ -114,10 +167,24 @@ export default function ConfigChat() { placeholder={TEXTFIELD_PROPS_CHAT_FORBIDDEN_USERNAMES.placeholder} description={TEXTFIELD_PROPS_CHAT_FORBIDDEN_USERNAMES.tip} values={formDataValues.forbiddenUsernames} - handleDeleteIndex={handleDeleteUsername} - handleCreateString={handleCreateUsername} + handleDeleteIndex={handleDeleteForbiddenUsernameIndex} + handleCreateString={handleCreateForbiddenUsername} submitStatus={createInputStatus(forbiddenUsernameSaveState)} /> +
+
+
); diff --git a/web/styles/config-edit-string-tags.scss b/web/styles/config-edit-string-tags.scss index 2a8f96724..0a7a04e7a 100644 --- a/web/styles/config-edit-string-tags.scss +++ b/web/styles/config-edit-string-tags.scss @@ -37,3 +37,7 @@ align-items: center; margin-top: 2em; } + +.continuous-status-section { + margin-top: 1em; +} diff --git a/web/types/config-section.ts b/web/types/config-section.ts index 6d3d16e2a..59bc0f4cd 100644 --- a/web/types/config-section.ts +++ b/web/types/config-section.ts @@ -102,5 +102,6 @@ export interface ConfigDetails { supportedCodecs: string[]; videoCodec: string; forbiddenUsernames: string[]; + suggestedUsernames: string[]; chatDisabled: boolean; } diff --git a/web/utils/config-constants.tsx b/web/utils/config-constants.tsx index f97a93985..06dca26a5 100644 --- a/web/utils/config-constants.tsx +++ b/web/utils/config-constants.tsx @@ -31,6 +31,7 @@ export const API_WEB_PORT = '/webserverport'; export const API_YP_SWITCH = '/directoryenabled'; export const API_CHAT_DISABLE = '/chat/disable'; export const API_CHAT_FORBIDDEN_USERNAMES = '/chat/forbiddenusernames'; +export const API_CHAT_SUGGESTED_USERNAMES = '/chat/suggestedusernames'; export const API_EXTERNAL_ACTIONS = '/externalactions'; export const API_VIDEO_CODEC = '/video/codec'; @@ -190,6 +191,15 @@ export const TEXTFIELD_PROPS_CHAT_FORBIDDEN_USERNAMES = { tip: 'A list of words in chat usernames you disallow.', }; +export const TEXTFIELD_PROPS_CHAT_SUGGESTED_USERNAMES = { + apiPath: API_CHAT_SUGGESTED_USERNAMES, + placeholder: 'username', + label: 'Default usernames', + tip: 'An optional list of chat usernames that new users get assigned. If the list holds less then 10 items, random names will be generated. Users can change their usernames afterwards and the same username may be given out multple times.', + min_not_reached: 'At least 10 items are required for this feature.', + no_entries: 'The default name generator is used.', +}; + export const VIDEO_VARIANT_SETTING_DEFAULTS = { // this one is currently unused audioBitrate: { diff --git a/web/utils/server-status-context.tsx b/web/utils/server-status-context.tsx index ee8dd84e3..827fd2f05 100644 --- a/web/utils/server-status-context.tsx +++ b/web/utils/server-status-context.tsx @@ -49,6 +49,7 @@ export const initialServerConfigState: ConfigDetails = { supportedCodecs: [], videoCodec: '', forbiddenUsernames: [], + suggestedUsernames: [], chatDisabled: false, };