Keyboard handlers and aria labels added

This commit is contained in:
banaanihillo 2024-05-05 12:20:13 +03:00
parent 36ca23cc82
commit 7bf4852303
7 changed files with 95 additions and 27 deletions

View file

@ -1,12 +1,17 @@
<script setup> <script setup>
defineProps(['ico']); defineProps(['ico']);
defineEmits(['click']); defineEmits(['click']);
import { useI18n } from '@/stores/misc.js';
const {t} = useI18n()
</script> </script>
<template> <template>
<button <button
:class="'bi clickable bi-' + (ico ? ico : 'play')" :class="'bi clickable bi-' + (ico ?? 'play')"
@click="$emit('click')"> @click="$emit('click')"
:aria-label="ico ? t(`action.${ico}`) : 'play'"
:title="ico ? t(`action.${ico}`) : 'play'">
<slot name="menu"></slot> <slot name="menu"></slot>
</button> </button>
</template> </template>

View file

@ -28,7 +28,12 @@ function set(page) {
<template> <template>
<nav> <nav>
<h1 class="bi" @click="home"> <h1
class="bi"
@click="home"
@keydown.enter="home"
tabindex="0"
aria-label="Home">
<IcoHyp /> <IcoHyp />
</h1> </h1>

View file

@ -44,6 +44,7 @@ onMounted(() => {
<button <button
class="bi bi-shuffle pl-btn" class="bi bi-shuffle pl-btn"
title="shuffle queue" title="shuffle queue"
:aria-label="t('playlist.shuffle_queue')"
@click=" @click="
() => { () => {
data.state.urls = useShuffle(data.state.urls); data.state.urls = useShuffle(data.state.urls);
@ -53,6 +54,7 @@ onMounted(() => {
<button <button
class="bi bi-bookmark-plus pl-btn" class="bi bi-bookmark-plus pl-btn"
title="save queue" title="save queue"
:aria-label="t('playlist.save_queue')"
@click=" @click="
() => { () => {
let urls = data.state.urls.map(i => ({ let urls = data.state.urls.map(i => ({
@ -67,13 +69,17 @@ onMounted(() => {
<button <button
class="bi bi-dash-lg pl-btn" class="bi bi-dash-lg pl-btn"
title="clear queue" title="clear queue"
:aria-label="t('playlist.clear_queue')"
@click="data.state.urls = []"></button> @click="data.state.urls = []"></button>
</div> </div>
<div <div
v-for="plurl in data.state.urls" v-for="plurl in data.state.urls"
class="pl-item" class="pl-item"
:key="plurl.url" :key="plurl.url"
@click="handleClick(plurl, $event)"> @click="handleClick(plurl, $event)"
tabindex="0"
@keydown.enter="handleClick(plurl, $event)"
:aria-label="`Play track: ${plurl.title}`">
<span <span
v-if="data.state.url == plurl.url" v-if="data.state.url == plurl.url"
class="bars-wrap" class="bars-wrap"

View file

@ -274,9 +274,13 @@ onDeactivated(() => {
<div v-if="albumMenu" class="alb popup"> <div v-if="albumMenu" class="alb popup">
<button <button
class="bi bi-bookmark-plus clickable" class="bi bi-bookmark-plus clickable"
@click="saveAlbum"></button> @click="saveAlbum"
:aria-label="t('action.save_album')"></button>
<button class="bi bi-share clickable" @click="shareAlbum"></button> <button
class="bi bi-share clickable"
@click="shareAlbum"
:aria-label="t('action.share')"></button>
<button <button
class="bi bi-plus-lg clickable" class="bi bi-plus-lg clickable"
@ -288,16 +292,19 @@ onDeactivated(() => {
thumbnails: [{ url: i.thumbnail }], thumbnails: [{ url: i.thumbnail }],
})), })),
) )
"></button> "
:aria-label="t('playlist.add_album_to_playlist')"></button>
<button <button
class="bi bi-shuffle clickable" class="bi bi-shuffle clickable"
@click="shuffleAdd"></button> @click="shuffleAdd"
:aria-label="t('action.shuffle')"></button>
<button <button
v-if="plId" v-if="plId"
class="bi bi-trash3 clickable" class="bi bi-trash3 clickable"
@click="removePlaylist"></button> @click="removePlaylist"
:aria-label="t('action.remove_playlist')"></button>
</div> </div>
</Transition> </Transition>
</template> </template>

View file

@ -129,7 +129,7 @@ const openSong = el => {
<i class="ign">{{ author ? author.replaceAll(' - Topic', '') : '' }}</i> <i class="ign">{{ author ? author.replaceAll(' - Topic', '') : '' }}</i>
</a> </a>
<span v-if="play === data.state?.url"> <span v-if="play === data.state?.url">
<span class="bi-play"></span> <span class="bi-play" aria-hidden="true"></span>
<span>{{ t('title.now_playing') }}</span> <span>{{ t('title.now_playing') }}</span>
</span> </span>
</span> </span>
@ -138,24 +138,35 @@ const openSong = el => {
class="bi bi-three-dots-vertical popup-wrap ign" class="bi bi-three-dots-vertical popup-wrap ign"
@mouseenter="show = true" @mouseenter="show = true"
@mouseleave="show = false" @mouseleave="show = false"
@keyup.enter="show = !show"> @keyup.enter="show = !show"
:aria-label="t('action.more_controls')">
<Transition name="fade"> <Transition name="fade">
<div v-if="show" class="popup ign"> <div v-if="show" class="popup ign">
<button <button
v-if="playlistId || offlineUri" v-if="playlistId || offlineUri"
class="bi bi-dash-lg clickable ign" class="bi bi-dash-lg clickable ign"
:aria-label="t('action.remove_from_playlist')"
@click="Remove"></button> @click="Remove"></button>
<button <button
class="bi bi-chevron-bar-right clickable ign" class="bi bi-chevron-bar-right clickable ign"
:aria-label="t('action.play_next')"
@click="appendSong"></button> @click="appendSong"></button>
<button <button
class="bi bi-collection clickable ign" class="bi bi-collection clickable ign"
:aria-label="t('action.add_current_to_playlist')"
@click="showPl = true"></button> @click="showPl = true"></button>
<button <button
class="bi bi-broadcast clickable ign" class="bi bi-broadcast clickable ign"
:aria-label="t('action.play_now')"
@click="$emit('nxt-song')"></button> @click="$emit('nxt-song')"></button>
<button class="bi bi-plus-lg clickable ign" @click="addSong"></button> <button
<button class="bi bi-share clickable ign" @click="Share"></button> class="bi bi-plus-lg clickable ign"
:aria-label="t('action.add_to_playlist')"
@click="addSong"></button>
<button
class="bi bi-share clickable ign"
:aria-label="t('action.share')"
@click="Share"></button>
</div> </div>
</Transition> </Transition>
</button> </button>

View file

@ -77,10 +77,16 @@ async function Like() {
<template> <template>
<div id="statusbar" class="flex"> <div id="statusbar" class="flex">
<div class="flex statusbar-progress-container"> <div class="flex statusbar-progress-container">
<span>{{ getFormattedTime(player.state.realTime) }}</span> <span
<div id="statusbar-progress" class="range-wrap"> :aria-label="t('info.time_elapsed')">
{{ getFormattedTime(player.state.realTime) }}
</span>
<div
id="statusbar-progress"
class="range-wrap"
:aria-label="t('action.change_time')">
<input <input
aria-label="Change Time" :aria-label="t('action.change_time')"
:value="player.state.time" :value="player.state.time"
type="range" type="range"
name="statusbar-progress" name="statusbar-progress"
@ -90,7 +96,10 @@ async function Like() {
($event.target.value / 100) * player.state.duration ($event.target.value / 100) * player.state.duration
" /> " />
</div> </div>
<span>{{ getFormattedTime(player.state.duration) }}</span> <span
:aria-label="t('info.track_duration')">
{{ getFormattedTime(player.state.duration) }}
</span>
</div> </div>
<div class="flex statusbar-controls-container"> <div class="flex statusbar-controls-container">
@ -150,7 +159,7 @@ async function Like() {
: 'hidden', : 'hidden',
}" }"
id="btn-nexttrack" id="btn-nexttrack"
aria-label="Play next track" :aria-label="t('action.play_next_track')"
class="bi bi-chevron-bar-right clickable" class="bi bi-chevron-bar-right clickable"
@click="data.nextTrack"></button> @click="data.nextTrack"></button>
</div> </div>
@ -179,7 +188,7 @@ async function Like() {
<button <button
class="bi bi-three-dots clickable" class="bi bi-three-dots clickable"
aria-label="More Controls" :aria-label="t('action.more_controls')"
@click=" @click="
showme.menu = !showme.menu; showme.menu = !showme.menu;
showme.vol = false; showme.vol = false;
@ -189,14 +198,16 @@ async function Like() {
<button <button
id="info-btn" id="info-btn"
class="bi bi-info-circle clickable" class="bi bi-info-circle clickable"
aria-label="Show Information About Song" :title="t('action.show_information_about_track')"
:aria-label="t('action.show_information_about_track')"
:data-active="player.state.info" :data-active="player.state.info"
@click="player.toggle('info')"></button> @click="player.toggle('info')"></button>
<button <button
v-if="store.auth" v-if="store.auth"
id="like-btn" id="like-btn"
title="Add song to favorites" :title="t('action.add_track_to_favorites')"
:aria-label="t('action.add_track_to_favorites')"
class="bi blink clickable" class="bi blink clickable"
:class="data.state.url == liked ? 'bi-heart-fill' : 'bi-heart'" :class="data.state.url == liked ? 'bi-heart-fill' : 'bi-heart'"
:data-active="data.state.url == liked" :data-active="data.state.url == liked"
@ -205,14 +216,15 @@ async function Like() {
<button <button
id="dl-btn" id="dl-btn"
title="Save for Offline Playback" :title="t('action.save_for_offline_playback')"
:aria-label="t('action.save_for_offline_playback')"
class="bi bi-download clickable" class="bi bi-download clickable"
@click="Offline"></button> @click="Offline"></button>
<button <button
id="addToPlaylist" id="addToPlaylist"
:title="t('statusBar.add_current_to_playlist')" :title="t('action.add_current_to_playlist')"
:aria-label="t('statusBar.add_current_to_playlist')" :aria-label="t('action.add_current_to_playlist')"
class="bi bi-collection clickable" class="bi bi-collection clickable"
@click=" @click="
player.toggle('add'); player.toggle('add');

View file

@ -30,16 +30,36 @@
"receive": "Receive", "receive": "Receive",
"import": "Import", "import": "Import",
"export": "Export", "export": "Export",
"register_on": "Don't have an account? Register on" "register_on": "Don't have an account? Register on",
"remove_from_playlist": "Remove from playlist",
"play_next": "Play next",
"add_current_to_playlist": "Add current track to a playlist",
"play_now": "Play now",
"add_to_playlist": "Add to playlist",
"share": "Share",
"play_next_track": "Play next track",
"change_time": "Change time",
"add_track_to_favorites": "Add track to favorites",
"save_for_offline_playback": "Save for offline playback",
"show_information_about_track": "Show information about track",
"more_controls": "More controls",
"three-dots": "More controls",
"remove_playlist": "Remove playlist",
"shuffle": "Shuffle",
"save_album": "Save album"
}, },
"playlist": { "playlist": {
"local": "Local Playlists", "local": "Local Playlists",
"remote": "Remote Playlists", "remote": "Remote Playlists",
"name": "Playlist name", "name": "Playlist name",
"add": "Add Songs to Playlist", "add": "Add Songs to Playlist",
"add_album_to_playlist": "Add album to playlist",
"create": "Create a new Playlist", "create": "Create a new Playlist",
"sync": "Sync playlists", "sync": "Sync playlists",
"select": "Select Playlist to Add" "select": "Select Playlist to Add",
"clear_queue": "Clear queue",
"save_queue": "Save queue",
"shuffle_queue": "Shuffle queue"
}, },
"artist": { "artist": {
"subscribers": "Subscribers", "subscribers": "Subscribers",
@ -80,7 +100,9 @@
"search": "Start Searching", "search": "Start Searching",
"no_info": "No Information Available", "no_info": "No Information Available",
"saved": "Saved!", "saved": "Saved!",
"copied_to_clipboard": "Copied to Clipboard" "copied_to_clipboard": "Copied to Clipboard",
"time_elapsed": "Time elapsed",
"track_duration": "Track duration"
}, },
"instances": { "instances": {
"hyp": "Hyperpipe Instance", "hyp": "Hyperpipe Instance",