Add option to hide viewer count. Closes #1939
This commit is contained in:
parent
97db93e0d7
commit
b08393295f
@ -711,6 +711,26 @@ func SetChatJoinMessagesEnabled(w http.ResponseWriter, r *http.Request) {
|
|||||||
controllers.WriteSimpleResponse(w, true, "chat join message status updated")
|
controllers.WriteSimpleResponse(w, true, "chat join message status updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetHideViewerCount will enable or disable hiding the viewer count.
|
||||||
|
func SetHideViewerCount(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !requirePOST(w, r) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
configValue, success := getValueFromRequest(w, r)
|
||||||
|
if !success {
|
||||||
|
controllers.WriteSimpleResponse(w, false, "unable to update hiding viewer count")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := data.SetHideViewerCount(configValue.Value.(bool)); err != nil {
|
||||||
|
controllers.WriteSimpleResponse(w, false, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controllers.WriteSimpleResponse(w, true, "hide viewer count setting updated")
|
||||||
|
}
|
||||||
|
|
||||||
func requirePOST(w http.ResponseWriter, r *http.Request) bool {
|
func requirePOST(w http.ResponseWriter, r *http.Request) bool {
|
||||||
if r.Method != controllers.POST {
|
if r.Method != controllers.POST {
|
||||||
controllers.WriteSimpleResponse(w, false, r.Method+" not supported")
|
controllers.WriteSimpleResponse(w, false, r.Method+" not supported")
|
||||||
|
@ -55,6 +55,7 @@ func GetServerConfig(w http.ResponseWriter, r *http.Request) {
|
|||||||
ChatJoinMessagesEnabled: data.GetChatJoinMessagesEnabled(),
|
ChatJoinMessagesEnabled: data.GetChatJoinMessagesEnabled(),
|
||||||
SocketHostOverride: data.GetWebsocketOverrideHost(),
|
SocketHostOverride: data.GetWebsocketOverrideHost(),
|
||||||
ChatEstablishedUserMode: data.GetChatEstbalishedUsersOnlyMode(),
|
ChatEstablishedUserMode: data.GetChatEstbalishedUsersOnlyMode(),
|
||||||
|
HideViewerCount: data.GetHideViewerCount(),
|
||||||
VideoSettings: videoSettings{
|
VideoSettings: videoSettings{
|
||||||
VideoQualityVariants: videoQualityVariants,
|
VideoQualityVariants: videoQualityVariants,
|
||||||
LatencyLevel: data.GetStreamLatencyLevel().Level,
|
LatencyLevel: data.GetStreamLatencyLevel().Level,
|
||||||
@ -113,6 +114,7 @@ type serverConfigAdminResponse struct {
|
|||||||
SuggestedUsernames []string `json:"suggestedUsernames"`
|
SuggestedUsernames []string `json:"suggestedUsernames"`
|
||||||
SocketHostOverride string `json:"socketHostOverride,omitempty"`
|
SocketHostOverride string `json:"socketHostOverride,omitempty"`
|
||||||
Notifications notificationsConfigResponse `json:"notifications"`
|
Notifications notificationsConfigResponse `json:"notifications"`
|
||||||
|
HideViewerCount bool `json:"hideViewerCount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type videoSettings struct {
|
type videoSettings struct {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/owncast/owncast/core"
|
"github.com/owncast/owncast/core"
|
||||||
|
"github.com/owncast/owncast/core/data"
|
||||||
"github.com/owncast/owncast/router/middleware"
|
"github.com/owncast/owncast/router/middleware"
|
||||||
"github.com/owncast/owncast/utils"
|
"github.com/owncast/owncast/utils"
|
||||||
)
|
)
|
||||||
@ -15,7 +16,6 @@ func GetStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
status := core.GetStatus()
|
status := core.GetStatus()
|
||||||
response := webStatusResponse{
|
response := webStatusResponse{
|
||||||
Online: status.Online,
|
Online: status.Online,
|
||||||
ViewerCount: status.ViewerCount,
|
|
||||||
ServerTime: time.Now(),
|
ServerTime: time.Now(),
|
||||||
LastConnectTime: status.LastConnectTime,
|
LastConnectTime: status.LastConnectTime,
|
||||||
LastDisconnectTime: status.LastDisconnectTime,
|
LastDisconnectTime: status.LastDisconnectTime,
|
||||||
@ -23,6 +23,10 @@ func GetStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
StreamTitle: status.StreamTitle,
|
StreamTitle: status.StreamTitle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !data.GetHideViewerCount() {
|
||||||
|
response.ViewerCount = status.ViewerCount
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
middleware.DisableCache(w)
|
middleware.DisableCache(w)
|
||||||
|
|
||||||
@ -33,7 +37,7 @@ func GetStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
type webStatusResponse struct {
|
type webStatusResponse struct {
|
||||||
Online bool `json:"online"`
|
Online bool `json:"online"`
|
||||||
ViewerCount int `json:"viewerCount"`
|
ViewerCount int `json:"viewerCount,omitempty"`
|
||||||
ServerTime time.Time `json:"serverTime"`
|
ServerTime time.Time `json:"serverTime"`
|
||||||
LastConnectTime *utils.NullTime `json:"lastConnectTime"`
|
LastConnectTime *utils.NullTime `json:"lastConnectTime"`
|
||||||
LastDisconnectTime *utils.NullTime `json:"lastDisconnectTime"`
|
LastDisconnectTime *utils.NullTime `json:"lastDisconnectTime"`
|
||||||
|
@ -65,6 +65,7 @@ const (
|
|||||||
browserPushPrivateKeyKey = "browser_push_private_key"
|
browserPushPrivateKeyKey = "browser_push_private_key"
|
||||||
twitterConfigurationKey = "twitter_configuration"
|
twitterConfigurationKey = "twitter_configuration"
|
||||||
hasConfiguredInitialNotificationsKey = "has_configured_initial_notifications"
|
hasConfiguredInitialNotificationsKey = "has_configured_initial_notifications"
|
||||||
|
hideViewerCountKey = "hide_viewer_count"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetExtraPageBodyContent will return the user-supplied body content.
|
// GetExtraPageBodyContent will return the user-supplied body content.
|
||||||
@ -908,3 +909,14 @@ func GetHasPerformedInitialNotificationsConfig() bool {
|
|||||||
configured, _ := _datastore.GetBool(hasConfiguredInitialNotificationsKey)
|
configured, _ := _datastore.GetBool(hasConfiguredInitialNotificationsKey)
|
||||||
return configured
|
return configured
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetHideViewerCount will return if the viewer count shold be hidden.
|
||||||
|
func GetHideViewerCount() bool {
|
||||||
|
hide, _ := _datastore.GetBool(hideViewerCountKey)
|
||||||
|
return hide
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetHideViewerCount will set if the viewer count should be hidden.
|
||||||
|
func SetHideViewerCount(hide bool) error {
|
||||||
|
return _datastore.SetBool(hideViewerCountKey, hide)
|
||||||
|
}
|
||||||
|
@ -312,6 +312,9 @@ func Start() error {
|
|||||||
// Video playback metrics
|
// Video playback metrics
|
||||||
http.HandleFunc("/api/admin/metrics/video", middleware.RequireAdminAuth(admin.GetVideoPlaybackMetrics))
|
http.HandleFunc("/api/admin/metrics/video", middleware.RequireAdminAuth(admin.GetVideoPlaybackMetrics))
|
||||||
|
|
||||||
|
// Is the viewer count hidden from viewers
|
||||||
|
http.HandleFunc("/api/admin/config/hideviewercount", middleware.RequireAdminAuth(admin.SetHideViewerCount))
|
||||||
|
|
||||||
// Inline chat moderation actions
|
// Inline chat moderation actions
|
||||||
|
|
||||||
// Update chat message visibility
|
// Update chat message visibility
|
||||||
|
@ -9,192 +9,211 @@ const tags = [randomString(), randomString(), randomString()];
|
|||||||
const latencyLevel = Math.floor(Math.random() * 4);
|
const latencyLevel = Math.floor(Math.random() * 4);
|
||||||
|
|
||||||
const streamOutputVariants = {
|
const streamOutputVariants = {
|
||||||
videoBitrate: randomNumber() * 100,
|
videoBitrate: randomNumber() * 100,
|
||||||
framerate: 42,
|
framerate: 42,
|
||||||
cpuUsageLevel: 2,
|
cpuUsageLevel: 2,
|
||||||
scaledHeight: randomNumber() * 100,
|
scaledHeight: randomNumber() * 100,
|
||||||
scaledWidth: randomNumber() * 100,
|
scaledWidth: randomNumber() * 100,
|
||||||
};
|
};
|
||||||
const socialHandles = [
|
const socialHandles = [
|
||||||
{
|
{
|
||||||
url: 'http://facebook.org/' + randomString(),
|
url: 'http://facebook.org/' + randomString(),
|
||||||
platform: randomString(),
|
platform: randomString(),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const s3Config = {
|
const s3Config = {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
endpoint: 'http://' + randomString(),
|
endpoint: 'http://' + randomString(),
|
||||||
accessKey: randomString(),
|
accessKey: randomString(),
|
||||||
secret: randomString(),
|
secret: randomString(),
|
||||||
bucket: randomString(),
|
bucket: randomString(),
|
||||||
region: randomString(),
|
region: randomString(),
|
||||||
forcePathStyle: true,
|
forcePathStyle: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const forbiddenUsernames = [randomString(), randomString(), randomString()];
|
const forbiddenUsernames = [randomString(), randomString(), randomString()];
|
||||||
|
|
||||||
test('set server name', async (done) => {
|
test('set server name', async (done) => {
|
||||||
const res = await sendConfigChangeRequest('name', serverName);
|
const res = await sendConfigChangeRequest('name', serverName);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set stream title', async (done) => {
|
test('set stream title', async (done) => {
|
||||||
const res = await sendConfigChangeRequest('streamtitle', streamTitle);
|
const res = await sendConfigChangeRequest('streamtitle', streamTitle);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set server summary', async (done) => {
|
test('set server summary', async (done) => {
|
||||||
const res = await sendConfigChangeRequest('serversummary', serverSummary);
|
const res = await sendConfigChangeRequest('serversummary', serverSummary);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set extra page content', async (done) => {
|
test('set extra page content', async (done) => {
|
||||||
const res = await sendConfigChangeRequest('pagecontent', pageContent);
|
const res = await sendConfigChangeRequest('pagecontent', pageContent);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set tags', async (done) => {
|
test('set tags', async (done) => {
|
||||||
const res = await sendConfigChangeRequest('tags', tags);
|
const res = await sendConfigChangeRequest('tags', tags);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set latency level', async (done) => {
|
test('set latency level', async (done) => {
|
||||||
const res = await sendConfigChangeRequest(
|
const res = await sendConfigChangeRequest(
|
||||||
'video/streamlatencylevel',
|
'video/streamlatencylevel',
|
||||||
latencyLevel
|
latencyLevel
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set video stream output variants', async (done) => {
|
test('set video stream output variants', async (done) => {
|
||||||
const res = await sendConfigChangeRequest('video/streamoutputvariants', [
|
const res = await sendConfigChangeRequest('video/streamoutputvariants', [
|
||||||
streamOutputVariants,
|
streamOutputVariants,
|
||||||
]);
|
]);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set social handles', async (done) => {
|
test('set social handles', async (done) => {
|
||||||
const res = await sendConfigChangeRequest('socialhandles', socialHandles);
|
const res = await sendConfigChangeRequest('socialhandles', socialHandles);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set s3 configuration', async (done) => {
|
test('set s3 configuration', async (done) => {
|
||||||
const res = await sendConfigChangeRequest('s3', s3Config);
|
const res = await sendConfigChangeRequest('s3', s3Config);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set forbidden usernames', async (done) => {
|
test('set forbidden usernames', async (done) => {
|
||||||
const res = await sendConfigChangeRequest('chat/forbiddenusernames', forbiddenUsernames);
|
const res = await sendConfigChangeRequest(
|
||||||
done();
|
'chat/forbiddenusernames',
|
||||||
|
forbiddenUsernames
|
||||||
|
);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('set hide viewer count', async (done) => {
|
||||||
|
const res = await sendConfigChangeRequest('hideviewercount', true);
|
||||||
|
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(`<p>${serverSummary}</p>`);
|
expect(res.body.summary).toBe(`<p>${serverSummary}</p>`);
|
||||||
expect(res.body.extraPageContent).toBe(pageContent);
|
expect(res.body.extraPageContent).toBe(pageContent);
|
||||||
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();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test that the raw video details being broadcasted are coming through
|
// Test that the raw video details being broadcasted are coming through
|
||||||
test('stream details are correct', (done) => {
|
test('admin stream details are correct', (done) => {
|
||||||
request
|
request
|
||||||
.get('/api/admin/status')
|
.get('/api/admin/status')
|
||||||
.auth('admin', 'abc123')
|
.auth('admin', 'abc123')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
expect(res.body.broadcaster.streamDetails.width).toBe(320);
|
expect(res.body.broadcaster.streamDetails.width).toBe(320);
|
||||||
expect(res.body.broadcaster.streamDetails.height).toBe(180);
|
expect(res.body.broadcaster.streamDetails.height).toBe(180);
|
||||||
expect(res.body.broadcaster.streamDetails.framerate).toBe(24);
|
expect(res.body.broadcaster.streamDetails.framerate).toBe(24);
|
||||||
expect(res.body.broadcaster.streamDetails.videoBitrate).toBe(1269);
|
expect(res.body.broadcaster.streamDetails.videoBitrate).toBe(1269);
|
||||||
expect(res.body.broadcaster.streamDetails.videoCodec).toBe('H.264');
|
expect(res.body.broadcaster.streamDetails.videoCodec).toBe('H.264');
|
||||||
expect(res.body.broadcaster.streamDetails.audioCodec).toBe('AAC');
|
expect(res.body.broadcaster.streamDetails.audioCodec).toBe('AAC');
|
||||||
expect(res.body.online).toBe(true);
|
expect(res.body.online).toBe(true);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('admin configuration is correct', (done) => {
|
test('admin configuration is correct', (done) => {
|
||||||
request
|
request
|
||||||
.get('/api/admin/serverconfig')
|
.get('/api/admin/serverconfig')
|
||||||
.auth('admin', 'abc123')
|
.auth('admin', 'abc123')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.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.tags).toStrictEqual(tags);
|
expect(res.body.instanceDetails.tags).toStrictEqual(tags);
|
||||||
expect(res.body.instanceDetails.socialHandles).toStrictEqual(
|
expect(res.body.instanceDetails.socialHandles).toStrictEqual(
|
||||||
socialHandles
|
socialHandles
|
||||||
);
|
);
|
||||||
expect(res.body.forbiddenUsernames).toStrictEqual(forbiddenUsernames);
|
expect(res.body.forbiddenUsernames).toStrictEqual(forbiddenUsernames);
|
||||||
|
|
||||||
expect(res.body.videoSettings.latencyLevel).toBe(latencyLevel);
|
expect(res.body.videoSettings.latencyLevel).toBe(latencyLevel);
|
||||||
expect(res.body.videoSettings.videoQualityVariants[0].framerate).toBe(
|
expect(res.body.videoSettings.videoQualityVariants[0].framerate).toBe(
|
||||||
streamOutputVariants.framerate
|
streamOutputVariants.framerate
|
||||||
);
|
);
|
||||||
expect(res.body.videoSettings.videoQualityVariants[0].cpuUsageLevel).toBe(
|
expect(res.body.videoSettings.videoQualityVariants[0].cpuUsageLevel).toBe(
|
||||||
streamOutputVariants.cpuUsageLevel
|
streamOutputVariants.cpuUsageLevel
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(res.body.yp.enabled).toBe(false);
|
expect(res.body.yp.enabled).toBe(false);
|
||||||
expect(res.body.streamKey).toBe('abc123');
|
expect(res.body.streamKey).toBe('abc123');
|
||||||
|
|
||||||
expect(res.body.s3.enabled).toBe(s3Config.enabled);
|
expect(res.body.s3.enabled).toBe(s3Config.enabled);
|
||||||
expect(res.body.s3.endpoint).toBe(s3Config.endpoint);
|
expect(res.body.s3.endpoint).toBe(s3Config.endpoint);
|
||||||
expect(res.body.s3.accessKey).toBe(s3Config.accessKey);
|
expect(res.body.s3.accessKey).toBe(s3Config.accessKey);
|
||||||
expect(res.body.s3.secret).toBe(s3Config.secret);
|
expect(res.body.s3.secret).toBe(s3Config.secret);
|
||||||
expect(res.body.s3.bucket).toBe(s3Config.bucket);
|
expect(res.body.s3.bucket).toBe(s3Config.bucket);
|
||||||
expect(res.body.s3.region).toBe(s3Config.region);
|
expect(res.body.s3.region).toBe(s3Config.region);
|
||||||
expect(res.body.s3.forcePathStyle).toBeTruthy();
|
expect(res.body.s3.forcePathStyle).toBe(true);
|
||||||
done();
|
expect(res.body.hideViewerCount).toBe(true);
|
||||||
});
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('frontend configuration is correct', (done) => {
|
test('frontend configuration is correct', (done) => {
|
||||||
request
|
request
|
||||||
.get('/api/config')
|
.get('/api/config')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
expect(res.body.name).toBe(serverName);
|
expect(res.body.name).toBe(serverName);
|
||||||
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();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('frontend status is correct', (done) => {
|
||||||
|
request
|
||||||
|
.get('/api/status')
|
||||||
|
.expect(200)
|
||||||
|
.then((res) => {
|
||||||
|
expect(res.body.viewerCount).toBe(undefined);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
async function sendConfigChangeRequest(endpoint, value) {
|
async function sendConfigChangeRequest(endpoint, value) {
|
||||||
const url = '/api/admin/config/' + endpoint;
|
const url = '/api/admin/config/' + endpoint;
|
||||||
const res = await request
|
const res = await request
|
||||||
.post(url)
|
.post(url)
|
||||||
.auth('admin', 'abc123')
|
.auth('admin', 'abc123')
|
||||||
.send({ value: value })
|
.send({ value: value })
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
expect(res.body.success).toBe(true);
|
expect(res.body.success).toBe(true);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendConfigChangePayload(endpoint, payload) {
|
async function sendConfigChangePayload(endpoint, payload) {
|
||||||
const url = '/api/admin/config/' + endpoint;
|
const url = '/api/admin/config/' + endpoint;
|
||||||
const res = await request
|
const res = await request
|
||||||
.post(url)
|
.post(url)
|
||||||
.auth('admin', 'abc123')
|
.auth('admin', 'abc123')
|
||||||
.send(payload)
|
.send(payload)
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
expect(res.body.success).toBe(true);
|
expect(res.body.success).toBe(true);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function randomString(length = 20) {
|
function randomString(length = 20) {
|
||||||
return Math.random().toString(16).substr(2, length);
|
return Math.random().toString(16).substr(2, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
function randomNumber() {
|
function randomNumber() {
|
||||||
return Math.floor(Math.random() * 5);
|
return Math.floor(Math.random() * 5);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
API_YP_SWITCH,
|
API_YP_SWITCH,
|
||||||
FIELD_PROPS_YP,
|
FIELD_PROPS_YP,
|
||||||
FIELD_PROPS_NSFW,
|
FIELD_PROPS_NSFW,
|
||||||
|
FIELD_PROPS_HIDE_VIEWER_COUNT,
|
||||||
} from '../../utils/config-constants';
|
} from '../../utils/config-constants';
|
||||||
|
|
||||||
import { UpdateArgs } from '../../types/config-section';
|
import { UpdateArgs } from '../../types/config-section';
|
||||||
@ -61,6 +62,10 @@ export default function EditInstanceDetails() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function handleHideViewerCountChange(enabled: boolean) {
|
||||||
|
handleFieldChange({ fieldName: 'hideViewerCount', value: enabled });
|
||||||
|
}
|
||||||
|
|
||||||
const hasInstanceUrl = instanceUrl !== '';
|
const hasInstanceUrl = instanceUrl !== '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -100,6 +105,14 @@ export default function EditInstanceDetails() {
|
|||||||
{/* Logo section */}
|
{/* Logo section */}
|
||||||
<EditLogo />
|
<EditLogo />
|
||||||
|
|
||||||
|
<ToggleSwitch
|
||||||
|
fieldName="hideViewerCount"
|
||||||
|
useSubmit
|
||||||
|
{...FIELD_PROPS_HIDE_VIEWER_COUNT}
|
||||||
|
checked={formDataValues.hideViewerCount}
|
||||||
|
onChange={handleHideViewerCountChange}
|
||||||
|
/>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<p className="description">
|
<p className="description">
|
||||||
Increase your audience by appearing in the{' '}
|
Increase your audience by appearing in the{' '}
|
||||||
|
@ -40,12 +40,12 @@ export default function Statusbar(props: Props) {
|
|||||||
if (online && lastConnectTime) {
|
if (online && lastConnectTime) {
|
||||||
const duration = makeDurationString(new Date(lastConnectTime));
|
const duration = makeDurationString(new Date(lastConnectTime));
|
||||||
onlineMessage = online ? `Live for ${duration}` : 'Offline';
|
onlineMessage = online ? `Live for ${duration}` : 'Offline';
|
||||||
rightSideMessage = (
|
rightSideMessage = viewerCount > 0 && (
|
||||||
<span>
|
<span>
|
||||||
<EyeOutlined /> {viewerCount}
|
<EyeOutlined /> {viewerCount}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
} else {
|
} else if (!online) {
|
||||||
onlineMessage = 'Offline';
|
onlineMessage = 'Offline';
|
||||||
if (lastDisconnectTime) {
|
if (lastDisconnectTime) {
|
||||||
rightSideMessage = `Last live ${formatDistanceToNow(new Date(lastDisconnectTime))} ago.`;
|
rightSideMessage = `Last live ${formatDistanceToNow(new Date(lastDisconnectTime))} ago.`;
|
||||||
|
@ -152,4 +152,5 @@ export interface ConfigDetails {
|
|||||||
notifications: NotificationsConfig;
|
notifications: NotificationsConfig;
|
||||||
chatJoinMessagesEnabled: boolean;
|
chatJoinMessagesEnabled: boolean;
|
||||||
chatEstablishedUserMode: boolean;
|
chatEstablishedUserMode: boolean;
|
||||||
|
hideViewerCount: boolean;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ export const API_VIDEO_SEGMENTS = '/video/streamlatencylevel';
|
|||||||
export const API_VIDEO_VARIANTS = '/video/streamoutputvariants';
|
export const API_VIDEO_VARIANTS = '/video/streamoutputvariants';
|
||||||
export const API_WEB_PORT = '/webserverport';
|
export const API_WEB_PORT = '/webserverport';
|
||||||
export const API_YP_SWITCH = '/directoryenabled';
|
export const API_YP_SWITCH = '/directoryenabled';
|
||||||
|
export const API_HIDE_VIEWER_COUNT = '/hideviewercount';
|
||||||
export const API_CHAT_DISABLE = '/chat/disable';
|
export const API_CHAT_DISABLE = '/chat/disable';
|
||||||
export const API_CHAT_JOIN_MESSAGES_ENABLED = '/chat/joinmessagesenabled';
|
export const API_CHAT_JOIN_MESSAGES_ENABLED = '/chat/joinmessagesenabled';
|
||||||
export const API_CHAT_ESTABLISHED_MODE = '/chat/establishedusermode';
|
export const API_CHAT_ESTABLISHED_MODE = '/chat/establishedusermode';
|
||||||
@ -188,6 +189,13 @@ export const FIELD_PROPS_YP = {
|
|||||||
tip: 'Turn this ON to request to show up in the directory.',
|
tip: 'Turn this ON to request to show up in the directory.',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const FIELD_PROPS_HIDE_VIEWER_COUNT = {
|
||||||
|
apiPath: API_HIDE_VIEWER_COUNT,
|
||||||
|
configPath: '',
|
||||||
|
label: 'Hide viewer count',
|
||||||
|
tip: 'Turn this ON to hide the viewer count the web page.',
|
||||||
|
};
|
||||||
|
|
||||||
export const DEFAULT_VARIANT_STATE: VideoVariant = {
|
export const DEFAULT_VARIANT_STATE: VideoVariant = {
|
||||||
framerate: 24,
|
framerate: 24,
|
||||||
videoPassthrough: false,
|
videoPassthrough: false,
|
||||||
|
@ -75,6 +75,7 @@ export const initialServerConfigState: ConfigDetails = {
|
|||||||
chatDisabled: false,
|
chatDisabled: false,
|
||||||
chatJoinMessagesEnabled: true,
|
chatJoinMessagesEnabled: true,
|
||||||
chatEstablishedUserMode: false,
|
chatEstablishedUserMode: false,
|
||||||
|
hideViewerCount: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialServerStatusState = {
|
const initialServerStatusState = {
|
||||||
@ -156,6 +157,7 @@ const ServerStatusProvider = ({ children }) => {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/jsx-no-constructed-context-values
|
||||||
const providerValue = {
|
const providerValue = {
|
||||||
...status,
|
...status,
|
||||||
serverConfig: config,
|
serverConfig: config,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user