mirror of
https://github.com/owncast/owncast.git
synced 2024-11-25 06:12:23 +03:00
feat: add option to save custom username suggestions (#415)
* 💄 add option to save custom username suggestions that shall be used instead of the docker style usernames. * 🚸 add minimum of 10 usernames / update wording * Prettified Code! * 🚸 add message for the default name generator / indicate that no further action is required Co-authored-by: jeyemwey <jeyemwey@users.noreply.github.com>
This commit is contained in:
parent
0f3051960f
commit
030b936f05
6 changed files with 106 additions and 15 deletions
|
@ -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) {
|
|||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{continuousStatusMessage && (
|
||||
<div className="continuous-status-section">
|
||||
<FormStatusIndicator status={continuousStatusMessage} />
|
||||
</div>
|
||||
)}
|
||||
<div className="add-new-string-section">
|
||||
<TextField
|
||||
fieldName="string-input"
|
||||
|
@ -83,4 +90,5 @@ EditValueArray.defaultProps = {
|
|||
maxLength: 50,
|
||||
description: null,
|
||||
submitStatus: null,
|
||||
continuousStatusMessage: null,
|
||||
};
|
||||
|
|
|
@ -4,28 +4,35 @@ import { TEXTFIELD_TYPE_TEXTAREA } from '../components/config/form-textfield';
|
|||
import TextFieldWithSubmit from '../components/config/form-textfield-with-submit';
|
||||
import ToggleSwitch from '../components/config/form-toggleswitch';
|
||||
import EditValueArray from '../components/config/edit-string-array';
|
||||
import { createInputStatus, STATUS_ERROR, STATUS_SUCCESS } from '../utils/input-statuses';
|
||||
import {
|
||||
createInputStatus,
|
||||
StatusState,
|
||||
STATUS_ERROR,
|
||||
STATUS_SUCCESS,
|
||||
} from '../utils/input-statuses';
|
||||
|
||||
import { UpdateArgs } from '../types/config-section';
|
||||
import {
|
||||
FIELD_PROPS_DISABLE_CHAT,
|
||||
TEXTFIELD_PROPS_CHAT_FORBIDDEN_USERNAMES,
|
||||
TEXTFIELD_PROPS_SERVER_WELCOME_MESSAGE,
|
||||
API_CHAT_FORBIDDEN_USERNAMES,
|
||||
API_CHAT_SUGGESTED_USERNAMES,
|
||||
FIELD_PROPS_DISABLE_CHAT,
|
||||
postConfigUpdateToAPI,
|
||||
RESET_TIMEOUT,
|
||||
TEXTFIELD_PROPS_CHAT_FORBIDDEN_USERNAMES,
|
||||
TEXTFIELD_PROPS_CHAT_SUGGESTED_USERNAMES,
|
||||
TEXTFIELD_PROPS_SERVER_WELCOME_MESSAGE,
|
||||
} from '../utils/config-constants';
|
||||
import { ServerStatusContext } from '../utils/server-status-context';
|
||||
|
||||
export default function ConfigChat() {
|
||||
const { Title } = Typography;
|
||||
const [formDataValues, setFormDataValues] = useState(null);
|
||||
const [forbiddenUsernameSaveState, setForbidenUsernameSaveState] = useState(null);
|
||||
const [forbiddenUsernameSaveState, setForbiddenUsernameSaveState] = useState(null);
|
||||
const [suggestedUsernameSaveState, setSuggestedUsernameSaveState] = useState(null);
|
||||
const serverStatusData = useContext(ServerStatusContext);
|
||||
const { serverConfig, setFieldInConfigState } = serverStatusData || {};
|
||||
|
||||
const { chatDisabled, forbiddenUsernames } = serverConfig;
|
||||
const { instanceDetails } = serverConfig;
|
||||
const { chatDisabled, forbiddenUsernames, instanceDetails, suggestedUsernames } = serverConfig;
|
||||
const { welcomeMessage } = instanceDetails;
|
||||
|
||||
const handleFieldChange = ({ fieldName, value }: UpdateArgs) => {
|
||||
|
@ -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)}
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
<EditValueArray
|
||||
title={TEXTFIELD_PROPS_CHAT_SUGGESTED_USERNAMES.label}
|
||||
placeholder={TEXTFIELD_PROPS_CHAT_SUGGESTED_USERNAMES.placeholder}
|
||||
description={TEXTFIELD_PROPS_CHAT_SUGGESTED_USERNAMES.tip}
|
||||
values={formDataValues.suggestedUsernames}
|
||||
handleDeleteIndex={handleDeleteSuggestedUsernameIndex}
|
||||
handleCreateString={handleCreateSuggestedUsername}
|
||||
submitStatus={createInputStatus(suggestedUsernameSaveState)}
|
||||
continuousStatusMessage={getSuggestedUsernamesLimitWarning(
|
||||
formDataValues.suggestedUsernames.length,
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -37,3 +37,7 @@
|
|||
align-items: center;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.continuous-status-section {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
|
|
@ -102,5 +102,6 @@ export interface ConfigDetails {
|
|||
supportedCodecs: string[];
|
||||
videoCodec: string;
|
||||
forbiddenUsernames: string[];
|
||||
suggestedUsernames: string[];
|
||||
chatDisabled: boolean;
|
||||
}
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -49,6 +49,7 @@ export const initialServerConfigState: ConfigDetails = {
|
|||
supportedCodecs: [],
|
||||
videoCodec: '',
|
||||
forbiddenUsernames: [],
|
||||
suggestedUsernames: [],
|
||||
chatDisabled: false,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue