mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Fixes for screen readers on podcast page and episodes table
This commit is contained in:
		
							parent
							
								
									31be775c32
								
							
						
					
					
						commit
						d3fd19da65
					
				@ -11,7 +11,7 @@
 | 
				
			|||||||
        </template>
 | 
					        </template>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div v-if="publishedYear" class="flex py-0.5">
 | 
					    <div v-if="publishedYear" role="paragraph" class="flex py-0.5">
 | 
				
			||||||
      <div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
 | 
					      <div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
 | 
				
			||||||
        <span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelPublishYear }}</span>
 | 
					        <span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelPublishYear }}</span>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
@ -19,7 +19,7 @@
 | 
				
			|||||||
        {{ publishedYear }}
 | 
					        {{ publishedYear }}
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div v-if="publisher" class="flex py-0.5">
 | 
					    <div v-if="publisher" role="paragraph" class="flex py-0.5">
 | 
				
			||||||
      <div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
 | 
					      <div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
 | 
				
			||||||
        <span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelPublisher }}</span>
 | 
					        <span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelPublisher }}</span>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
@ -27,7 +27,7 @@
 | 
				
			|||||||
        <nuxt-link :to="`/library/${libraryId}/bookshelf?filter=publishers.${$encode(publisher)}`" class="hover:underline">{{ publisher }}</nuxt-link>
 | 
					        <nuxt-link :to="`/library/${libraryId}/bookshelf?filter=publishers.${$encode(publisher)}`" class="hover:underline">{{ publisher }}</nuxt-link>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div v-if="podcastType" class="flex py-0.5">
 | 
					    <div v-if="podcastType" role="paragraph" class="flex py-0.5">
 | 
				
			||||||
      <div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
 | 
					      <div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
 | 
				
			||||||
        <span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelPodcastType }}</span>
 | 
					        <span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelPodcastType }}</span>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
@ -65,7 +65,7 @@
 | 
				
			|||||||
        <nuxt-link :to="`/library/${libraryId}/bookshelf?filter=languages.${$encode(language)}`" class="hover:underline">{{ language }}</nuxt-link>
 | 
					        <nuxt-link :to="`/library/${libraryId}/bookshelf?filter=languages.${$encode(language)}`" class="hover:underline">{{ language }}</nuxt-link>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div v-if="tracks.length || (isPodcast && totalPodcastDuration)" class="flex py-0.5">
 | 
					    <div v-if="tracks.length || (isPodcast && totalPodcastDuration)" role="paragraph" class="flex py-0.5">
 | 
				
			||||||
      <div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
 | 
					      <div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
 | 
				
			||||||
        <span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelDuration }}</span>
 | 
					        <span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelDuration }}</span>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
@ -73,7 +73,7 @@
 | 
				
			|||||||
        {{ durationPretty }}
 | 
					        {{ durationPretty }}
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="flex py-0.5">
 | 
					    <div role="paragraph" class="flex py-0.5">
 | 
				
			||||||
      <div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
 | 
					      <div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
 | 
				
			||||||
        <span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelSize }}</span>
 | 
					        <span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelSize }}</span>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,23 +1,25 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div ref="wrapper" class="relative" v-click-outside="clickOutside">
 | 
					  <div ref="wrapper" class="relative" v-click-outside="clickOutside">
 | 
				
			||||||
    <button type="button" class="relative w-full h-full border border-gray-500 hover:border-gray-400 rounded shadow-sm pl-3 pr-3 py-0 text-left focus:outline-none cursor-pointer" aria-haspopup="listbox" aria-expanded="true" aria-labelledby="listbox-label" @click.prevent="showMenu = !showMenu">
 | 
					    <div class="relative h-9">
 | 
				
			||||||
 | 
					      <button type="button" class="relative w-full h-full border border-gray-500 hover:border-gray-400 rounded shadow-sm pl-3 pr-3 py-0 text-left focus:outline-none cursor-pointer" aria-haspopup="menu" :aria-expanded="showMenu" @click.prevent="showMenu = !showMenu">
 | 
				
			||||||
        <span class="flex items-center justify-between">
 | 
					        <span class="flex items-center justify-between">
 | 
				
			||||||
          <span class="block truncate text-xs">{{ selectedText }}</span>
 | 
					          <span class="block truncate text-xs">{{ selectedText }}</span>
 | 
				
			||||||
        </span>
 | 
					        </span>
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
      <span v-if="selected === 'all'" class="ml-3 absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
 | 
					      <span v-if="selected === 'all'" class="ml-3 absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
 | 
				
			||||||
        <svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
 | 
					        <svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
 | 
				
			||||||
          <path fill-rule="evenodd" d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" />
 | 
					          <path fill-rule="evenodd" d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" />
 | 
				
			||||||
        </svg>
 | 
					        </svg>
 | 
				
			||||||
      </span>
 | 
					      </span>
 | 
				
			||||||
      <div v-else class="ml-3 absolute inset-y-0 right-0 flex items-center pr-2 cursor-pointer text-gray-400 hover:text-gray-300" @mousedown.stop @mouseup.stop @click.stop.prevent="clearSelected">
 | 
					      <button v-else type="button" :aria-label="$strings.ButtonClearFilter" class="ml-3 absolute inset-y-0 right-0 flex items-center pr-2 cursor-pointer text-gray-400 hover:text-gray-300" @mousedown.stop @mouseup.stop @click.stop.prevent="clearSelected">
 | 
				
			||||||
        <span class="material-symbols" style="font-size: 1.1rem">close</span>
 | 
					        <span class="material-symbols" style="font-size: 1.1rem">close</span>
 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      </button>
 | 
					      </button>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div v-show="showMenu" class="absolute z-10 mt-1 w-full bg-bg border border-black-200 shadow-lg max-h-96 rounded-md py-1 text-sm ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none">
 | 
					    <div v-show="showMenu" class="absolute z-10 mt-1 w-full bg-bg border border-black-200 shadow-lg max-h-96 rounded-md py-1 text-sm ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none">
 | 
				
			||||||
      <ul class="h-full w-full" role="listbox" aria-labelledby="listbox-label">
 | 
					      <ul class="h-full w-full" role="menu">
 | 
				
			||||||
        <template v-for="item in items">
 | 
					        <template v-for="item in items">
 | 
				
			||||||
          <li :key="item.value" class="select-none relative py-2 pr-9 cursor-pointer hover:bg-white/5" :class="item.value === selected ? 'bg-white/5 text-yellow-400' : 'text-gray-200 hover:text-white'" role="option" @click="clickedOption(item)">
 | 
					          <li :key="item.value" class="select-none relative py-2 pr-9 cursor-pointer hover:bg-white/5" :class="item.value === selected ? 'bg-white/5 text-yellow-400' : 'text-gray-200 hover:text-white'" role="menuitem" @click="clickedOption(item)">
 | 
				
			||||||
            <div class="flex items-center justify-between">
 | 
					            <div class="flex items-center justify-between">
 | 
				
			||||||
              <span class="font-normal ml-3 block truncate">{{ item.text }}</span>
 | 
					              <span class="font-normal ml-3 block truncate">{{ item.text }}</span>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -26,12 +26,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        <div class="flex items-center pt-2">
 | 
					        <div class="flex items-center pt-2">
 | 
				
			||||||
          <button class="h-8 px-4 border border-white border-opacity-20 hover:bg-white hover:bg-opacity-10 rounded-full flex items-center justify-center cursor-pointer focus:outline-none" :class="userIsFinished ? 'text-white text-opacity-40' : ''" @click.stop="playClick">
 | 
					          <button class="h-8 px-4 border border-white border-opacity-20 hover:bg-white hover:bg-opacity-10 rounded-full flex items-center justify-center cursor-pointer focus:outline-none" :class="userIsFinished ? 'text-white text-opacity-40' : ''" @click.stop="playClick">
 | 
				
			||||||
            <span class="material-symbols fill text-2xl" :class="streamIsPlaying ? '' : 'text-success'">{{ streamIsPlaying ? 'pause' : 'play_arrow' }}</span>
 | 
					            <span class="material-symbols fill text-2xl" aria-hidden="true" :class="streamIsPlaying ? '' : 'text-success'">{{ streamIsPlaying ? 'pause' : 'play_arrow' }}</span>
 | 
				
			||||||
            <p class="pl-2 pr-1 text-sm font-semibold">{{ timeRemaining }}</p>
 | 
					            <span class="sr-only">{{ streamIsPlaying ? $strings.ButtonPause : $strings.ButtonPlay }}</span>
 | 
				
			||||||
 | 
					            <p class="pl-2 pr-1 text-sm font-semibold" aria-hidden="true">{{ timeRemaining }}</p>
 | 
				
			||||||
          </button>
 | 
					          </button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <ui-tooltip v-if="libraryItemIdStreaming && !isStreamingFromDifferentLibrary" :text="isQueued ? $strings.MessageRemoveFromPlayerQueue : $strings.MessageAddToPlayerQueue" :class="isQueued ? 'text-success' : ''" direction="top">
 | 
					          <ui-tooltip v-if="libraryItemIdStreaming && !isStreamingFromDifferentLibrary" :text="isQueued ? $strings.MessageRemoveFromPlayerQueue : $strings.MessageAddToPlayerQueue" :class="isQueued ? 'text-success' : ''" direction="top">
 | 
				
			||||||
            <ui-icon-btn :icon="isQueued ? 'playlist_add_check' : 'playlist_play'" borderless @click="queueBtnClick" />
 | 
					            <ui-icon-btn :icon="isQueued ? 'playlist_add_check' : 'playlist_play'" :aria-label="isQueued ? $strings.LabelRemoveFromPlayerQueue : $strings.LabelAddToPlayerQueue" borderless @click="queueBtnClick" />
 | 
				
			||||||
          </ui-tooltip>
 | 
					          </ui-tooltip>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <ui-tooltip :text="userIsFinished ? $strings.MessageMarkAsNotFinished : $strings.MessageMarkAsFinished" direction="top">
 | 
					          <ui-tooltip :text="userIsFinished ? $strings.MessageMarkAsNotFinished : $strings.MessageMarkAsFinished" direction="top">
 | 
				
			||||||
@ -39,11 +40,11 @@
 | 
				
			|||||||
          </ui-tooltip>
 | 
					          </ui-tooltip>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <ui-tooltip :text="$strings.LabelYourPlaylists" direction="top">
 | 
					          <ui-tooltip :text="$strings.LabelYourPlaylists" direction="top">
 | 
				
			||||||
            <ui-icon-btn icon="playlist_add" borderless @click="clickAddToPlaylist" />
 | 
					            <ui-icon-btn icon="playlist_add" :aria-label="$strings.LabelYourPlaylists" borderless @click="clickAddToPlaylist" />
 | 
				
			||||||
          </ui-tooltip>
 | 
					          </ui-tooltip>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <ui-icon-btn v-if="userCanUpdate" icon="edit" borderless @click="clickEdit" />
 | 
					          <ui-icon-btn v-if="userCanUpdate" icon="edit" borderless @click="clickEdit" />
 | 
				
			||||||
          <ui-icon-btn v-if="userCanDelete" icon="close" borderless @click="removeClick" />
 | 
					          <ui-icon-btn v-if="userCanDelete" icon="close" :aria-label="$strings.HeaderRemoveEpisode" borderless @click="removeClick" />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div v-if="isHovering || isSelected || isSelectionMode" class="hidden md:block w-12 min-w-12" />
 | 
					      <div v-if="isHovering || isSelected || isSelectionMode" class="hidden md:block w-12 min-w-12" />
 | 
				
			||||||
@ -53,7 +54,7 @@
 | 
				
			|||||||
    <div class="hidden md:block md:w-12 md:min-w-12 md:-right-0 md:absolute md:top-0 h-full transform transition-transform z-20" :class="!isHovering && !isSelected && !isSelectionMode ? 'translate-x-24' : 'translate-x-0'">
 | 
					    <div class="hidden md:block md:w-12 md:min-w-12 md:-right-0 md:absolute md:top-0 h-full transform transition-transform z-20" :class="!isHovering && !isSelected && !isSelectionMode ? 'translate-x-24' : 'translate-x-0'">
 | 
				
			||||||
      <div class="flex h-full items-center">
 | 
					      <div class="flex h-full items-center">
 | 
				
			||||||
        <div class="mx-1">
 | 
					        <div class="mx-1">
 | 
				
			||||||
          <ui-checkbox v-model="isSelected" @input="selectedUpdated" checkbox-bg="bg" />
 | 
					          <ui-checkbox v-model="isSelected" @input="selectedUpdated" checkbox-bg="bg" aria-label="Select episode" />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <label class="flex justify-start items-center" :class="!disabled ? 'cursor-pointer' : ''">
 | 
					  <label class="flex justify-start items-center" :class="!disabled ? 'cursor-pointer' : ''">
 | 
				
			||||||
    <div class="border-2 rounded flex flex-shrink-0 justify-center items-center" :class="wrapperClass">
 | 
					    <div class="border-2 rounded flex flex-shrink-0 justify-center items-center" :class="wrapperClass">
 | 
				
			||||||
      <input v-model="selected" :disabled="disabled" type="checkbox" class="opacity-0 absolute" :class="!disabled ? 'cursor-pointer' : ''" />
 | 
					      <input v-model="selected" :disabled="disabled" type="checkbox" :aria-label="ariaLabel" class="opacity-0 absolute" :class="!disabled ? 'cursor-pointer' : ''" />
 | 
				
			||||||
      <span v-if="partial" class="material-symbols text-base leading-none text-gray-400">remove</span>
 | 
					      <span v-if="partial" class="material-symbols text-base leading-none text-gray-400">remove</span>
 | 
				
			||||||
      <svg v-else-if="selected" class="fill-current pointer-events-none" :class="svgClass" viewBox="0 0 20 20"><path d="M0 11l2-2 5 5L18 3l2 2L7 18z" /></svg>
 | 
					      <svg v-else-if="selected" class="fill-current pointer-events-none" :class="svgClass" viewBox="0 0 20 20"><path d="M0 11l2-2 5 5L18 3l2 2L7 18z" /></svg>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@ -33,7 +33,11 @@ export default {
 | 
				
			|||||||
      default: ''
 | 
					      default: ''
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    disabled: Boolean,
 | 
					    disabled: Boolean,
 | 
				
			||||||
    partial: Boolean
 | 
					    partial: Boolean,
 | 
				
			||||||
 | 
					    ariaLabel: {
 | 
				
			||||||
 | 
					      type: String,
 | 
				
			||||||
 | 
					      default: ''
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {}
 | 
					    return {}
 | 
				
			||||||
 | 
				
			|||||||
@ -123,7 +123,7 @@
 | 
				
			|||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <div class="my-4 w-full">
 | 
					          <div class="my-4 w-full">
 | 
				
			||||||
            <div ref="description" id="item-description" dir="auto" class="default-style less-spacing text-base text-gray-100 whitespace-pre-line mb-1" :class="{ 'show-full': showFullDescription }" v-html="description" />
 | 
					            <div ref="description" id="item-description" dir="auto" role="paragraph" class="default-style less-spacing text-base text-gray-100 whitespace-pre-line mb-1" :class="{ 'show-full': showFullDescription }" v-html="description" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <button v-if="isDescriptionClamped" class="py-0.5 flex items-center text-slate-300 hover:text-white" @click="showFullDescription = !showFullDescription">{{ showFullDescription ? $strings.ButtonReadLess : $strings.ButtonReadMore }} <span class="material-symbols text-xl pl-1" v-html="showFullDescription ? 'expand_less' : ''" /></button>
 | 
					            <button v-if="isDescriptionClamped" class="py-0.5 flex items-center text-slate-300 hover:text-white" @click="showFullDescription = !showFullDescription">{{ showFullDescription ? $strings.ButtonReadLess : $strings.ButtonReadMore }} <span class="material-symbols text-xl pl-1" v-html="showFullDescription ? 'expand_less' : ''" /></button>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user