131 lines
3.1 KiB
Vue
131 lines
3.1 KiB
Vue
<script setup lang="ts">
|
|
import { computed, ref, watch } from 'vue'
|
|
import { LogIn, LogOut, Radio } from 'lucide-vue-next'
|
|
import { api } from '@/api/client'
|
|
import { useToasts } from '@/composables/useToasts'
|
|
import type { BotStatus } from '@/types/status'
|
|
|
|
const props = defineProps<{ status: BotStatus | null }>()
|
|
|
|
const { notify, run } = useToasts()
|
|
const selected = ref('')
|
|
const defaultPlays = ref(5)
|
|
|
|
const channels = computed(() => props.status?.voice_channels ?? [])
|
|
const active = computed(() => props.status?.active_voice_channel ?? null)
|
|
|
|
// Wybór podąża za realnym połączeniem, a bez niego domyślnie wskazuje pierwszy kanał.
|
|
watch(
|
|
[active, channels],
|
|
([activeChannel, available]) => {
|
|
if (activeChannel) {
|
|
selected.value = activeChannel.channel_id
|
|
} else if (!available.some((channel) => channel.channel_id === selected.value)) {
|
|
selected.value = available[0]?.channel_id ?? ''
|
|
}
|
|
},
|
|
{ immediate: true },
|
|
)
|
|
|
|
watch(
|
|
() => props.status?.default_plays,
|
|
(value) => {
|
|
if (value !== undefined) defaultPlays.value = value
|
|
},
|
|
{ immediate: true },
|
|
)
|
|
|
|
async function toggle() {
|
|
if (active.value) {
|
|
await run(() => api.disconnect(), '', 'Błąd rozłączania')
|
|
return
|
|
}
|
|
if (!selected.value) {
|
|
notify('Wybierz kanał głosowy z listy!', 'error')
|
|
return
|
|
}
|
|
await run(() => api.connect(selected.value), '', 'Nie udało się połączyć')
|
|
}
|
|
|
|
async function saveDefaultPlays() {
|
|
await run(
|
|
() => api.setDefaultPlays(defaultPlays.value),
|
|
'Zapisano domyślną liczbę odtworzeń',
|
|
'Nie udało się zapisać domyślnej liczby odtworzeń',
|
|
)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="glass-card connection-panel">
|
|
<h2 class="card-title">
|
|
<Radio /> Kanał Głosowy
|
|
</h2>
|
|
<div class="control-row">
|
|
<select
|
|
v-model="selected"
|
|
class="premium-select"
|
|
:disabled="!channels.length"
|
|
>
|
|
<option
|
|
v-if="!channels.length"
|
|
value=""
|
|
>
|
|
Brak dostępnych kanałów
|
|
</option>
|
|
<option
|
|
v-for="channel in channels"
|
|
:key="channel.channel_id"
|
|
:value="channel.channel_id"
|
|
>
|
|
{{ channel.channel_name }}
|
|
</option>
|
|
</select>
|
|
<button
|
|
class="btn"
|
|
:class="active ? 'btn-danger' : 'btn-primary btn-glow'"
|
|
@click="toggle"
|
|
>
|
|
<component :is="active ? LogOut : LogIn" />
|
|
{{ active ? 'Odłącz' : 'Połącz' }}
|
|
</button>
|
|
</div>
|
|
<div class="default-plays-row">
|
|
<label for="default-plays">Domyślny licznik</label>
|
|
<input
|
|
id="default-plays"
|
|
v-model.number="defaultPlays"
|
|
class="premium-input"
|
|
type="number"
|
|
min="1"
|
|
max="999"
|
|
>
|
|
<button
|
|
class="btn btn-secondary"
|
|
type="button"
|
|
@click="saveDefaultPlays"
|
|
>
|
|
Zapisz
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.default-plays-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
margin-top: 14px;
|
|
}
|
|
|
|
.default-plays-row label {
|
|
min-width: 130px;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.default-plays-row .premium-input {
|
|
width: 90px;
|
|
}
|
|
</style>
|