This commit is contained in:
parent
295e7768a0
commit
7aca27cb08
@ -72,6 +72,7 @@ func GetWebConfig(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func getConfigResponse() webConfigResponse {
|
||||
pageContent := utils.RenderPageContentMarkdown(data.GetExtraPageBodyContent())
|
||||
offlineMessage := utils.RenderSimpleMarkdown(data.GetCustomOfflineMessage())
|
||||
socialHandles := data.GetSocialHandles()
|
||||
for i, handle := range socialHandles {
|
||||
platform := models.GetSocialHandle(handle.Platform)
|
||||
@ -119,7 +120,7 @@ func getConfigResponse() webConfigResponse {
|
||||
return webConfigResponse{
|
||||
Name: data.GetServerName(),
|
||||
Summary: serverSummary,
|
||||
OfflineMessage: data.GetCustomOfflineMessage(),
|
||||
OfflineMessage: offlineMessage,
|
||||
Logo: "/logo",
|
||||
Tags: data.GetServerMetadataTags(),
|
||||
Version: config.GetReleaseString(),
|
||||
|
@ -371,11 +371,12 @@ test('set override websocket host', async (done) => {
|
||||
|
||||
test('verify updated config values', async (done) => {
|
||||
const res = await request.get('/api/config');
|
||||
|
||||
expect(res.body.name).toBe(newServerName);
|
||||
expect(res.body.streamTitle).toBe(newStreamTitle);
|
||||
expect(res.body.summary).toBe(`${newServerSummary}`);
|
||||
expect(res.body.extraPageContent).toBe(newPageContent);
|
||||
expect(res.body.offlineMessage).toBe(newOfflineMessage);
|
||||
expect(res.body.offlineMessage).toBe(`<p>${newOfflineMessage}</p>`);
|
||||
expect(res.body.logo).toBe('/logo');
|
||||
expect(res.body.socialHandles).toStrictEqual(newSocialHandles);
|
||||
expect(res.body.socketHostOverride).toBe(overriddenWebsocketHost);
|
||||
|
@ -145,7 +145,7 @@ func RenderSimpleMarkdown(raw string) string {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
return strings.TrimSpace(buf.String())
|
||||
}
|
||||
|
||||
// RenderPageContentMarkdown will return HTML specifically handled for the user-specified page content.
|
||||
|
@ -1,5 +1,9 @@
|
||||
import React, { useState, useContext, useEffect } from 'react';
|
||||
import { Typography } from 'antd';
|
||||
import { Button, Typography } from 'antd';
|
||||
import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
|
||||
import CodeMirror from '@uiw/react-codemirror';
|
||||
import { bbedit } from '@uiw/codemirror-theme-bbedit';
|
||||
import { languages } from '@codemirror/language-data';
|
||||
import {
|
||||
TextFieldWithSubmit,
|
||||
TEXTFIELD_TYPE_TEXTAREA,
|
||||
@ -16,10 +20,13 @@ import {
|
||||
FIELD_PROPS_YP,
|
||||
FIELD_PROPS_NSFW,
|
||||
FIELD_PROPS_HIDE_VIEWER_COUNT,
|
||||
API_SERVER_OFFLINE_MESSAGE,
|
||||
} from '../../../../utils/config-constants';
|
||||
import { UpdateArgs } from '../../../../types/config-section';
|
||||
import { ToggleSwitch } from '../../ToggleSwitch';
|
||||
import { EditLogo } from '../../EditLogo';
|
||||
import FormStatusIndicator from '../../FormStatusIndicator';
|
||||
import { createInputStatus, STATUS_SUCCESS } from '../../../../utils/input-statuses';
|
||||
|
||||
const { Title } = Typography;
|
||||
|
||||
@ -32,6 +39,8 @@ export default function EditInstanceDetails() {
|
||||
const { instanceDetails, yp, hideViewerCount } = serverConfig;
|
||||
const { instanceUrl } = yp;
|
||||
|
||||
const [offlineMessageSaveStatus, setOfflineMessageSaveStatus] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
setFormDataValues({
|
||||
...instanceDetails,
|
||||
@ -56,6 +65,17 @@ export default function EditInstanceDetails() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleSaveOfflineMessage = () => {
|
||||
postConfigUpdateToAPI({
|
||||
apiPath: API_SERVER_OFFLINE_MESSAGE,
|
||||
data: { value: formDataValues.offlineMessage },
|
||||
});
|
||||
setOfflineMessageSaveStatus(createInputStatus(STATUS_SUCCESS));
|
||||
setTimeout(() => {
|
||||
setOfflineMessageSaveStatus(null);
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
const handleFieldChange = ({ fieldName, value }: UpdateArgs) => {
|
||||
setFormDataValues({
|
||||
...formDataValues,
|
||||
@ -103,14 +123,42 @@ export default function EditInstanceDetails() {
|
||||
onChange={handleFieldChange}
|
||||
/>
|
||||
|
||||
<TextFieldWithSubmit
|
||||
fieldName="offlineMessage"
|
||||
{...TEXTFIELD_PROPS_SERVER_OFFLINE_MESSAGE}
|
||||
type={TEXTFIELD_TYPE_TEXTAREA}
|
||||
value={formDataValues.offlineMessage}
|
||||
initialValue={instanceDetails.offlineMessage}
|
||||
onChange={handleFieldChange}
|
||||
/>
|
||||
<div style={{ marginBottom: '50px', marginRight: '150px' }}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
width: '80vh',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'end',
|
||||
}}
|
||||
>
|
||||
<p style={{ margin: '20px', marginRight: '10px', fontWeight: '400' }}>Offline Message:</p>
|
||||
<CodeMirror
|
||||
value={formDataValues.offlineMessage}
|
||||
{...TEXTFIELD_PROPS_SERVER_OFFLINE_MESSAGE}
|
||||
theme={bbedit}
|
||||
height="150px"
|
||||
width="450px"
|
||||
onChange={value => {
|
||||
handleFieldChange({ fieldName: 'offlineMessage', value });
|
||||
}}
|
||||
extensions={[markdown({ base: markdownLanguage, codeLanguages: languages })]}
|
||||
/>
|
||||
</div>
|
||||
<div className="field-tip">
|
||||
The offline message is displayed to your page visitors when you're not streaming.
|
||||
Markdown is supported.
|
||||
</div>
|
||||
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={handleSaveOfflineMessage}
|
||||
style={{ margin: '10px', float: 'right' }}
|
||||
>
|
||||
Save Message
|
||||
</Button>
|
||||
<FormStatusIndicator status={offlineMessageSaveStatus} />
|
||||
</div>
|
||||
|
||||
{/* Logo section */}
|
||||
<EditLogo />
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable react/no-danger */
|
||||
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
||||
import { Divider } from 'antd';
|
||||
import { FC } from 'react';
|
||||
@ -85,7 +86,12 @@ export const OfflineBanner: FC<OfflineBannerProps> = ({
|
||||
<Divider className={styles.separator} />
|
||||
</>
|
||||
)}
|
||||
<div className={styles.bodyText}>{text}</div>
|
||||
{customText ? (
|
||||
<div className={styles.bodyText} dangerouslySetInnerHTML={{ __html: text }} />
|
||||
) : (
|
||||
<div className={styles.bodyText}>{text}</div>
|
||||
)}
|
||||
|
||||
{lastLive && (
|
||||
<div className={styles.lastLiveDate}>
|
||||
<ClockCircleOutlined className={styles.clockIcon} />
|
||||
|
Loading…
Reference in New Issue
Block a user