diff --git a/client/src/components/settings.vue b/client/src/components/settings.vue
index b5ae941d..612ee183 100644
--- a/client/src/components/settings.vue
+++ b/client/src/components/settings.vue
@@ -48,6 +48,19 @@
+
+
+ {{ $t('setting.broadcast_is_active') }}
+
+
+
+ {{ $t('setting.broadcast_url') }}
+
+
+
@@ -220,6 +233,30 @@
}
}
}
+
+ .input {
+ display: block;
+ height: 30px;
+ text-align: right;
+ padding: 0 10px;
+ margin-left: 10px;
+ line-height: 30px;
+ text-overflow: ellipsis;
+ border: 1px solid transparent;
+ border-radius: 5px;
+ color: white;
+ background-color: $background-tertiary;
+ font-weight: lighter;
+ user-select: auto;
+
+ &::selection {
+ background: $text-normal;
+ }
+
+ &[disabled] {
+ background: none;
+ }
+ }
}
}
}
@@ -230,6 +267,12 @@
@Component({ name: 'neko-settings' })
export default class extends Vue {
+ private broadcast_url: string = '';
+
+ get admin() {
+ return this.$accessor.user.admin
+ }
+
get connected() {
return this.$accessor.connected
}
@@ -282,6 +325,27 @@
return this.$accessor.settings.keyboard_layout
}
+ get broadcast_is_active() {
+ return this.$accessor.settings.broadcast_is_active
+ }
+
+ set broadcast_is_active(value: boolean) {
+ if (value) {
+ this.$accessor.settings.broadcastCreate(this.broadcast_url)
+ } else {
+ this.$accessor.settings.broadcastDestroy()
+ }
+ }
+
+ get broadcast_url_remote() {
+ return this.$accessor.settings.broadcast_url
+ }
+
+ @Watch('broadcast_url_remote', { immediate: true })
+ onBroadcastUrlChange() {
+ this.broadcast_url = this.broadcast_url_remote
+ }
+
set keyboard_layout(value: string) {
this.$accessor.settings.setKeyboardLayout(value)
this.$accessor.remote.changeKeyboard()
diff --git a/client/src/locale/en-us.ts b/client/src/locale/en-us.ts
index 2cb49328..2f910381 100644
--- a/client/src/locale/en-us.ts
+++ b/client/src/locale/en-us.ts
@@ -61,6 +61,8 @@ export const setting = {
ignore_emotes: 'Ignore Emotes',
chat_sound: 'Play Chat Sound',
keyboard_layout: 'Change Keyboard Layout',
+ broadcast_is_active: 'Broadcast Enabled',
+ broadcast_url: 'RTMP url',
}
export const connection = {
diff --git a/client/src/neko/events.ts b/client/src/neko/events.ts
index 92987513..b2bb0435 100644
--- a/client/src/neko/events.ts
+++ b/client/src/neko/events.ts
@@ -38,6 +38,11 @@ export const EVENT = {
RESOLUTION: 'screen/resolution',
SET: 'screen/set',
},
+ BROADCAST: {
+ STATUS: "broadcast/status",
+ CREATE: "broadcast/create",
+ DESTROY: "broadcast/destroy",
+ },
ADMIN: {
BAN: 'admin/ban',
KICK: 'admin/kick',
@@ -60,6 +65,7 @@ export type WebSocketEvents =
| SignalEvents
| ChatEvents
| ScreenEvents
+ | BroadcastEvents
| AdminEvents
export type ControlEvents =
@@ -76,6 +82,11 @@ export type SignalEvents = typeof EVENT.SIGNAL.ANSWER | typeof EVENT.SIGNAL.PROV
export type ChatEvents = typeof EVENT.CHAT.MESSAGE | typeof EVENT.CHAT.EMOTE
export type ScreenEvents = typeof EVENT.SCREEN.CONFIGURATIONS | typeof EVENT.SCREEN.RESOLUTION | typeof EVENT.SCREEN.SET
+export type BroadcastEvents =
+ | typeof EVENT.BROADCAST.STATUS
+ | typeof EVENT.BROADCAST.CREATE
+ | typeof EVENT.BROADCAST.DESTROY
+
export type AdminEvents =
| typeof EVENT.ADMIN.BAN
| typeof EVENT.ADMIN.KICK
diff --git a/client/src/neko/index.ts b/client/src/neko/index.ts
index e1f5b832..67698274 100644
--- a/client/src/neko/index.ts
+++ b/client/src/neko/index.ts
@@ -326,6 +326,13 @@ export class NekoClient extends BaseClient implements EventEmitter {
})
}
+ /////////////////////////////
+ // Broadcast Events
+ /////////////////////////////
+ protected [EVENT.BROADCAST.STATUS](payload: BroadcastStatusPayload) {
+ this.$accessor.settings.broadcastStatus(payload)
+ }
+
/////////////////////////////
// Admin Events
/////////////////////////////
diff --git a/client/src/neko/messages.ts b/client/src/neko/messages.ts
index 27c737bd..cc4ced52 100644
--- a/client/src/neko/messages.ts
+++ b/client/src/neko/messages.ts
@@ -22,6 +22,7 @@ export type WebSocketMessages =
| ScreenResolutionMessage
| ScreenConfigurationsMessage
| ChatMessage
+ | BroadcastCreateMessage
export type WebSocketPayloads =
| SignalProvidePayload
@@ -37,6 +38,7 @@ export type WebSocketPayloads =
| ScreenResolutionPayload
| ScreenConfigurationsPayload
| AdminPayload
+ | BroadcastStatusPayload
export interface WebSocketMessage {
event: WebSocketEvents | string
@@ -177,6 +179,19 @@ export interface ScreenConfigurationsPayload {
configurations: ScreenConfigurations
}
+/*
+ BROADCAST PAYLOADS
+*/
+export interface BroadcastCreateMessage extends WebSocketMessage {
+ event: typeof EVENT.BROADCAST.CREATE
+ url: string
+}
+
+export interface BroadcastStatusPayload extends WebSocketMessage {
+ url: string
+ isActive: boolean
+}
+
/*
ADMIN PAYLOADS
*/
diff --git a/client/src/store/settings.ts b/client/src/store/settings.ts
index eb1295db..96c0c56e 100644
--- a/client/src/store/settings.ts
+++ b/client/src/store/settings.ts
@@ -1,5 +1,6 @@
import { getterTree, mutationTree, actionTree } from 'typed-vuex'
import { get, set } from '~/utils/localstorage'
+import { EVENT } from '~/neko/events'
import { accessor } from '~/store'
export const namespaced = true
@@ -18,6 +19,9 @@ export const state = () => {
keyboard_layout: get('keyboard_layout', 'us'),
keyboard_layouts_list: {} as KeyboardLayouts,
+
+ broadcast_is_active: false,
+ broadcast_url: "",
}
}
@@ -57,6 +61,10 @@ export const mutations = mutationTree(state, {
setKeyboardLayoutsList(state, value: KeyboardLayouts) {
state.keyboard_layouts_list = value
},
+ setBroadcastStatus(state, { url, isActive }) {
+ state.broadcast_url = url,
+ state.broadcast_is_active = isActive
+ },
})
export const actions = actionTree(
@@ -71,5 +79,15 @@ export const actions = actionTree(
})
.catch(console.error)
},
+
+ broadcastStatus({ getters }, { url, isActive }) {
+ accessor.settings.setBroadcastStatus({ url, isActive })
+ },
+ broadcastCreate({ getters }, url: string) {
+ $client.sendMessage(EVENT.BROADCAST.CREATE, { url })
+ },
+ broadcastDestroy({ getters }) {
+ $client.sendMessage(EVENT.BROADCAST.DESTROY)
+ },
},
)