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 @@ +
  • @@ -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) + }, }, )