Add custom offline message+api. Part of #1901
This commit is contained in:
parent
2c1624127a
commit
681067ab93
@ -141,6 +141,25 @@ func SetServerSummary(w http.ResponseWriter, r *http.Request) {
|
|||||||
controllers.WriteSimpleResponse(w, true, "changed")
|
controllers.WriteSimpleResponse(w, true, "changed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetCustomOfflineMessage will set a message to display when the server is offline.
|
||||||
|
func SetCustomOfflineMessage(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !requirePOST(w, r) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
configValue, success := getValueFromRequest(w, r)
|
||||||
|
if !success {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := data.SetCustomOfflineMessage(strings.TrimSpace(configValue.Value.(string))); err != nil {
|
||||||
|
controllers.WriteSimpleResponse(w, false, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controllers.WriteSimpleResponse(w, true, "changed")
|
||||||
|
}
|
||||||
|
|
||||||
// SetServerWelcomeMessage will handle the web config request to set the welcome message text.
|
// SetServerWelcomeMessage will handle the web config request to set the welcome message text.
|
||||||
func SetServerWelcomeMessage(w http.ResponseWriter, r *http.Request) {
|
func SetServerWelcomeMessage(w http.ResponseWriter, r *http.Request) {
|
||||||
if !requirePOST(w, r) {
|
if !requirePOST(w, r) {
|
||||||
|
@ -41,6 +41,7 @@ func GetServerConfig(w http.ResponseWriter, r *http.Request) {
|
|||||||
ExtraPageContent: data.GetExtraPageBodyContent(),
|
ExtraPageContent: data.GetExtraPageBodyContent(),
|
||||||
StreamTitle: data.GetStreamTitle(),
|
StreamTitle: data.GetStreamTitle(),
|
||||||
WelcomeMessage: data.GetServerWelcomeMessage(),
|
WelcomeMessage: data.GetServerWelcomeMessage(),
|
||||||
|
OfflineMessage: data.GetCustomOfflineMessage(),
|
||||||
Logo: data.GetLogoPath(),
|
Logo: data.GetLogoPath(),
|
||||||
SocialHandles: data.GetSocialHandles(),
|
SocialHandles: data.GetSocialHandles(),
|
||||||
NSFW: data.GetNSFW(),
|
NSFW: data.GetNSFW(),
|
||||||
@ -126,6 +127,7 @@ type webConfigResponse struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Summary string `json:"summary"`
|
Summary string `json:"summary"`
|
||||||
WelcomeMessage string `json:"welcomeMessage"`
|
WelcomeMessage string `json:"welcomeMessage"`
|
||||||
|
OfflineMessage string `json:"offlineMessage"`
|
||||||
Logo string `json:"logo"`
|
Logo string `json:"logo"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
type webConfigResponse struct {
|
type webConfigResponse struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Summary string `json:"summary"`
|
Summary string `json:"summary"`
|
||||||
|
OfflineMessage string `json:"offlineMessage"`
|
||||||
Logo string `json:"logo"`
|
Logo string `json:"logo"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
@ -108,6 +109,7 @@ func GetWebConfig(w http.ResponseWriter, r *http.Request) {
|
|||||||
configuration := webConfigResponse{
|
configuration := webConfigResponse{
|
||||||
Name: data.GetServerName(),
|
Name: data.GetServerName(),
|
||||||
Summary: serverSummary,
|
Summary: serverSummary,
|
||||||
|
OfflineMessage: data.GetCustomOfflineMessage(),
|
||||||
Logo: "/logo",
|
Logo: "/logo",
|
||||||
Tags: data.GetServerMetadataTags(),
|
Tags: data.GetServerMetadataTags(),
|
||||||
Version: config.GetReleaseString(),
|
Version: config.GetReleaseString(),
|
||||||
|
@ -66,6 +66,7 @@ const (
|
|||||||
twitterConfigurationKey = "twitter_configuration"
|
twitterConfigurationKey = "twitter_configuration"
|
||||||
hasConfiguredInitialNotificationsKey = "has_configured_initial_notifications"
|
hasConfiguredInitialNotificationsKey = "has_configured_initial_notifications"
|
||||||
hideViewerCountKey = "hide_viewer_count"
|
hideViewerCountKey = "hide_viewer_count"
|
||||||
|
customOfflineMessageKey = "custom_offline_message"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetExtraPageBodyContent will return the user-supplied body content.
|
// GetExtraPageBodyContent will return the user-supplied body content.
|
||||||
@ -920,3 +921,14 @@ func GetHideViewerCount() bool {
|
|||||||
func SetHideViewerCount(hide bool) error {
|
func SetHideViewerCount(hide bool) error {
|
||||||
return _datastore.SetBool(hideViewerCountKey, hide)
|
return _datastore.SetBool(hideViewerCountKey, hide)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCustomOfflineMessage will return the custom offline message.
|
||||||
|
func GetCustomOfflineMessage() string {
|
||||||
|
message, _ := _datastore.GetString(customOfflineMessageKey)
|
||||||
|
return message
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCustomOfflineMessage will set the custom offline message.
|
||||||
|
func SetCustomOfflineMessage(message string) error {
|
||||||
|
return _datastore.SetString(customOfflineMessageKey, message)
|
||||||
|
}
|
||||||
|
@ -185,6 +185,9 @@ func Start() error {
|
|||||||
// Server summary
|
// Server summary
|
||||||
http.HandleFunc("/api/admin/config/serversummary", middleware.RequireAdminAuth(admin.SetServerSummary))
|
http.HandleFunc("/api/admin/config/serversummary", middleware.RequireAdminAuth(admin.SetServerSummary))
|
||||||
|
|
||||||
|
// Offline message
|
||||||
|
http.HandleFunc("/api/admin/config/offlinemessage", middleware.RequireAdminAuth(admin.SetCustomOfflineMessage))
|
||||||
|
|
||||||
// Server welcome message
|
// Server welcome message
|
||||||
http.HandleFunc("/api/admin/config/welcomemessage", middleware.RequireAdminAuth(admin.SetServerWelcomeMessage))
|
http.HandleFunc("/api/admin/config/welcomemessage", middleware.RequireAdminAuth(admin.SetServerWelcomeMessage))
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ request = request('http://127.0.0.1:8080');
|
|||||||
const serverName = randomString();
|
const serverName = randomString();
|
||||||
const streamTitle = randomString();
|
const streamTitle = randomString();
|
||||||
const serverSummary = randomString();
|
const serverSummary = randomString();
|
||||||
|
const offlineMessage = randomString();
|
||||||
const pageContent = `<p>${randomString()}</p>`;
|
const pageContent = `<p>${randomString()}</p>`;
|
||||||
const tags = [randomString(), randomString(), randomString()];
|
const tags = [randomString(), randomString(), randomString()];
|
||||||
const latencyLevel = Math.floor(Math.random() * 4);
|
const latencyLevel = Math.floor(Math.random() * 4);
|
||||||
@ -97,12 +98,18 @@ test('set hide viewer count', async (done) => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('set offline message', async (done) => {
|
||||||
|
const res = await sendConfigChangeRequest('offlinemessage', offlineMessage);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
test('verify updated config values', async (done) => {
|
test('verify updated config values', async (done) => {
|
||||||
const res = await request.get('/api/config');
|
const res = await request.get('/api/config');
|
||||||
expect(res.body.name).toBe(serverName);
|
expect(res.body.name).toBe(serverName);
|
||||||
expect(res.body.streamTitle).toBe(streamTitle);
|
expect(res.body.streamTitle).toBe(streamTitle);
|
||||||
expect(res.body.summary).toBe(`${serverSummary}`);
|
expect(res.body.summary).toBe(`${serverSummary}`);
|
||||||
expect(res.body.extraPageContent).toBe(pageContent);
|
expect(res.body.extraPageContent).toBe(pageContent);
|
||||||
|
expect(res.body.offlineMessage).toBe(offlineMessage);
|
||||||
expect(res.body.logo).toBe('/logo');
|
expect(res.body.logo).toBe('/logo');
|
||||||
expect(res.body.socialHandles).toStrictEqual(socialHandles);
|
expect(res.body.socialHandles).toStrictEqual(socialHandles);
|
||||||
done();
|
done();
|
||||||
@ -134,6 +141,7 @@ test('admin configuration is correct', (done) => {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
expect(res.body.instanceDetails.name).toBe(serverName);
|
expect(res.body.instanceDetails.name).toBe(serverName);
|
||||||
expect(res.body.instanceDetails.summary).toBe(serverSummary);
|
expect(res.body.instanceDetails.summary).toBe(serverSummary);
|
||||||
|
expect(res.body.instanceDetails.offlineMessage).toBe(offlineMessage);
|
||||||
expect(res.body.instanceDetails.tags).toStrictEqual(tags);
|
expect(res.body.instanceDetails.tags).toStrictEqual(tags);
|
||||||
expect(res.body.instanceDetails.socialHandles).toStrictEqual(
|
expect(res.body.instanceDetails.socialHandles).toStrictEqual(
|
||||||
socialHandles
|
socialHandles
|
||||||
|
@ -124,3 +124,23 @@ curl 'http://localhost:8080/api/admin/config/externalactions' \
|
|||||||
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36' \
|
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36' \
|
||||||
--data-raw '{"value":[{"url":"https://owncast.online/docs","title":"Documentation","description":"","icon":"","color":"","openExternally":false},{"url":"https://media1.giphy.com/media/Ju7l5y9osyymQ/giphy.gif?cid=ecf05e47otegqpl9mqfz880pi861dnjm5loy6kyrquy9lku0&rid=giphy.gif&ct=g","title":"Important","description":"","icon":"https://findicons.com/files/icons/1184/quickpix_2008/128/rick_roll_d.png","color":"#c87fd7","openExternally":false},{"url":"https://randommer.io/random-images","title":"New Tab","description":"","icon":"","color":"","openExternally":true}]}' \
|
--data-raw '{"value":[{"url":"https://owncast.online/docs","title":"Documentation","description":"","icon":"","color":"","openExternally":false},{"url":"https://media1.giphy.com/media/Ju7l5y9osyymQ/giphy.gif?cid=ecf05e47otegqpl9mqfz880pi861dnjm5loy6kyrquy9lku0&rid=giphy.gif&ct=g","title":"Important","description":"","icon":"https://findicons.com/files/icons/1184/quickpix_2008/128/rick_roll_d.png","color":"#c87fd7","openExternally":false},{"url":"https://randommer.io/random-images","title":"New Tab","description":"","icon":"","color":"","openExternally":true}]}' \
|
||||||
--compressed
|
--compressed
|
||||||
|
|
||||||
|
# Offline message
|
||||||
|
|
||||||
|
curl 'http://localhost:8080/api/admin/config/offlinemessage' \
|
||||||
|
-H 'Accept: */*' \
|
||||||
|
-H 'Accept-Language: en-US,en;q=0.9' \
|
||||||
|
-H 'Authorization: Basic YWRtaW46YWJjMTIz' \
|
||||||
|
-H 'Cache-Control: no-cache' \
|
||||||
|
-H 'Connection: keep-alive' \
|
||||||
|
-H 'Content-Type: text/plain;charset=UTF-8' \
|
||||||
|
-H 'Origin: http://localhost:8080' \
|
||||||
|
-H 'Pragma: no-cache' \
|
||||||
|
-H 'Referer: http://localhost:8080/admin/config-public-details/' \
|
||||||
|
-H 'Sec-Fetch-Dest: empty' \
|
||||||
|
-H 'Sec-Fetch-Mode: cors' \
|
||||||
|
-H 'Sec-Fetch-Site: same-origin' \
|
||||||
|
-H 'Sec-GPC: 1' \
|
||||||
|
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36' \
|
||||||
|
--data-raw '{"value":"Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. I am offline. This is my message."}' \
|
||||||
|
--compressed
|
||||||
|
@ -53,7 +53,7 @@ export default function ContentComponent() {
|
|||||||
const chatUserId = useRecoilValue<string>(chatUserIdAtom);
|
const chatUserId = useRecoilValue<string>(chatUserIdAtom);
|
||||||
const { viewerCount, lastConnectTime, lastDisconnectTime } =
|
const { viewerCount, lastConnectTime, lastDisconnectTime } =
|
||||||
useRecoilValue<ServerStatus>(serverStatusState);
|
useRecoilValue<ServerStatus>(serverStatusState);
|
||||||
const { extraPageContent, version, name, externalActions } = clientConfig;
|
const { extraPageContent, version, name, externalActions, offlineMessage } = clientConfig;
|
||||||
const [showNotifyReminder, setShowNotifyReminder] = useState(false);
|
const [showNotifyReminder, setShowNotifyReminder] = useState(false);
|
||||||
const [showNotifyPopup, setShowNotifyPopup] = useState(false);
|
const [showNotifyPopup, setShowNotifyPopup] = useState(false);
|
||||||
|
|
||||||
@ -109,7 +109,10 @@ export default function ContentComponent() {
|
|||||||
{!online && (
|
{!online && (
|
||||||
<OfflineBanner
|
<OfflineBanner
|
||||||
name={name}
|
name={name}
|
||||||
text="Stream is offline text goes here. Will create a new form to set it in the Admin."
|
text={
|
||||||
|
offlineMessage ||
|
||||||
|
'Stream is offline text goes here. Will create a new form to set it in the Admin.'
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<StatusBar
|
<StatusBar
|
||||||
|
@ -2,6 +2,7 @@ export interface ClientConfig {
|
|||||||
name: string;
|
name: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
summary: string;
|
summary: string;
|
||||||
|
offlineMessage?: string;
|
||||||
logo: string;
|
logo: string;
|
||||||
tags: string[];
|
tags: string[];
|
||||||
version: string;
|
version: string;
|
||||||
@ -46,6 +47,7 @@ export function makeEmptyClientConfig(): ClientConfig {
|
|||||||
return {
|
return {
|
||||||
name: '',
|
name: '',
|
||||||
summary: '',
|
summary: '',
|
||||||
|
offlineMessage: '',
|
||||||
logo: '',
|
logo: '',
|
||||||
tags: [],
|
tags: [],
|
||||||
version: '',
|
version: '',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user