Add an ALT button to images

This commit is contained in:
Nick Colley 2023-03-12 15:36:35 +00:00
parent a7eaec3391
commit fefce1e255
10 changed files with 115 additions and 7 deletions

View File

@ -262,6 +262,8 @@ export default {
unmute: 'Stummschaltung aufheben', unmute: 'Stummschaltung aufheben',
zoomOut: 'Herauszoomen', zoomOut: 'Herauszoomen',
zoomIn: 'Hineinzoomen', zoomIn: 'Hineinzoomen',
imageDescription: 'Image description',
altMediaAriaLabel: 'alternative description (ALT) for media {number}',
// Reporting // Reporting
reportingLabel: 'Du machst eine Meldung von {account} an die Moderatoren von {instance}.', reportingLabel: 'Du machst eine Meldung von {account} an die Moderatoren von {instance}.',
additionalComments: 'Zusätzliche Kommentare', additionalComments: 'Zusätzliche Kommentare',

View File

@ -270,6 +270,8 @@ export default {
unmute: 'Unmute', unmute: 'Unmute',
zoomOut: 'Zoom out', zoomOut: 'Zoom out',
zoomIn: 'Zoom in', zoomIn: 'Zoom in',
imageDescription: 'Image description',
altMediaAriaLabel: 'alternative description (ALT) for media {number}',
// Reporting // Reporting
reportingLabel: 'You are reporting {account} to the moderators of {instance}.', reportingLabel: 'You are reporting {account} to the moderators of {instance}.',
additionalComments: 'Additional comments', additionalComments: 'Additional comments',

View File

@ -271,6 +271,8 @@ export default {
unmute: 'Dejar de silenciar', unmute: 'Dejar de silenciar',
zoomOut: 'Alejar', zoomOut: 'Alejar',
zoomIn: 'Acercar', zoomIn: 'Acercar',
imageDescription: 'Image description',
altMediaAriaLabel: 'alternative description (ALT) for media {number}',
// Reporting // Reporting
reportingLabel: 'Estás denunciando a {account} a los moderadores de {instance}.', reportingLabel: 'Estás denunciando a {account} a los moderadores de {instance}.',
additionalComments: 'Comentarios adicionales', additionalComments: 'Comentarios adicionales',

View File

@ -264,6 +264,8 @@ export default {
unmute: 'Ne plus mettre en sourdine', unmute: 'Ne plus mettre en sourdine',
zoomOut: 'Dé-zoomer', zoomOut: 'Dé-zoomer',
zoomIn: 'Zoomer', zoomIn: 'Zoomer',
imageDescription: 'Image description',
altMediaAriaLabel: 'alternative description (ALT) for media {number}',
// Reporting // Reporting
reportingLabel: 'Vous signalez {account} aux modérateurs/modératrices de {instance}.', reportingLabel: 'Vous signalez {account} aux modérateurs/modératrices de {instance}.',
additionalComments: 'Commentaires additionels', additionalComments: 'Commentaires additionels',

View File

@ -270,6 +270,8 @@ export default {
unmute: 'Не игнорировать', unmute: 'Не игнорировать',
zoomOut: 'Уменьшить', zoomOut: 'Уменьшить',
zoomIn: 'Увеличить', zoomIn: 'Увеличить',
imageDescription: 'Image description',
altMediaAriaLabel: 'alternative description (ALT) for media {number}',
// Reporting // Reporting
reportingLabel: 'Вы отправляете жалобу на {account} модератору {instance}.', reportingLabel: 'Вы отправляете жалобу на {account} модератору {instance}.',
additionalComments: 'Дополнительные комментарии', additionalComments: 'Дополнительные комментарии',

View File

@ -0,0 +1,4 @@
export const importShowMediaAltDialog = () => import(
'../creators/showMediaAltDialog.js'
).then(mod => mod.default)

View File

@ -0,0 +1,34 @@
<ModalDialog
{id}
{label}
title="{intl.imageDescription}"
background="var(--main-bg)">
<div class="content">
{#if description}{description}{/if}
</div>
</ModalDialog>
<style>
.content {
box-sizing: border-box;
padding: 13px 11px 15px;
font-size: 1.2em;
width: 100%;
}
</style>
<script>
import ModalDialog from './ModalDialog.html'
import { show } from '../helpers/showDialog.js'
import { close } from '../helpers/closeDialog.js'
import { oncreate } from '../helpers/onCreateDialog.js'
export default {
oncreate,
components: {
ModalDialog
},
methods: {
show,
close
}
}
</script>

View File

@ -0,0 +1,9 @@
import MediaAltDialog from '../components/MediaAltDialog.html'
import { showDialog } from './showDialog.js'
export default function showMediaAltDialog (description) {
return showDialog(MediaAltDialog, {
label: 'ASKASKLAALAAABEL',
description
})
}

View File

@ -1,3 +1,4 @@
<div class="media">
{#if !blurhash && (type === 'video' || type === 'audio')} {#if !blurhash && (type === 'video' || type === 'audio')}
<button id={elementId} <button id={elementId}
type="button" type="button"
@ -70,8 +71,19 @@
{/if} {/if}
</button> </button>
{/if} {/if}
{#if !blurhash && type === 'image' && description}
<button
on:click='handleAltClick(event)'
class="alt-button"
aria-label={altLabel}
>ALT</button>
{/if}
</div>
<style> <style>
.media {
position: relative;
width: 100%;
}
:global(.status-media video, .status-media img) { :global(.status-media video, .status-media img) {
object-fit: cover; object-fit: cover;
} }
@ -92,6 +104,31 @@
.inline-media { .inline-media {
position: relative; position: relative;
display: block;
}
.alt-button {
--alt-button-margin: 10px;
z-index: 1;
position: absolute;
bottom: var(--alt-button-margin);
left: var(--alt-button-margin);
padding: 6px 8px;
font-size: 1em;
line-height: 1;
border: none;
border-radius: 2px;
background: var(--mask-opaque-bg);
}
/* Increase touch area to make it easy not to miss the button */
.alt-button::before {
content: '';
position: absolute;
top: calc(-1 * var(--alt-button-margin) - 1px);
right: calc(-1 * var(--alt-button-margin) - 1px);
bottom: calc(-1 * var(--alt-button-margin) - 1px);
left: calc(-1 * var(--alt-button-margin) - 1px);
} }
@media (max-width: 240px) { @media (max-width: 240px) {
@ -103,6 +140,7 @@
<script> <script>
import { DEFAULT_MEDIA_WIDTH, DEFAULT_MEDIA_HEIGHT, ONE_TRANSPARENT_PIXEL } from '../../_static/media.js' import { DEFAULT_MEDIA_WIDTH, DEFAULT_MEDIA_HEIGHT, ONE_TRANSPARENT_PIXEL } from '../../_static/media.js'
import { importShowMediaDialog } from '../dialog/asyncDialogs/importShowMediaDialog.js' import { importShowMediaDialog } from '../dialog/asyncDialogs/importShowMediaDialog.js'
import { importShowMediaAltDialog } from '../dialog/asyncDialogs/importShowMediaAltDialog.js'
import { mouseover } from '../../_utils/events.js' import { mouseover } from '../../_utils/events.js'
import NonAutoplayGifv from '../NonAutoplayGifv.html' import NonAutoplayGifv from '../NonAutoplayGifv.html'
import PlayVideoIcon from '../PlayVideoIcon.html' import PlayVideoIcon from '../PlayVideoIcon.html'
@ -116,7 +154,7 @@
export default { export default {
async oncreate () { async oncreate () {
const { elementId } = this.get() const { elementId } = this.get()
registerClickDelegate(this, elementId, () => this.onClick()) registerClickDelegate(this, elementId, () => this.handleImageClick())
}, },
computed: { computed: {
focus: ({ meta }) => meta && meta.focus, focus: ({ meta }) => meta && meta.focus,
@ -176,16 +214,29 @@ export default {
), ),
animatedLabel: ({ description }) => ( animatedLabel: ({ description }) => (
formatIntl('intl.animatedImage', { description }) formatIntl('intl.animatedImage', { description })
),
altLabel: ({ index }) => (
formatIntl('intl.altMediaAriaLabel', { number : index + 1 })
) )
}, },
methods: { methods: {
onClick () { handleImageClick () {
(async () => { (async () => {
const { mediaAttachments, index } = this.get() const { mediaAttachments, index } = this.get()
const showMediaDialog = await importShowMediaDialog() const showMediaDialog = await importShowMediaDialog()
showMediaDialog(mediaAttachments, index) showMediaDialog(mediaAttachments, index)
})() })()
return true return true
},
handleAltClick (event) {
(async () => {
const { mediaAttachments, index } = this.get()
const media = mediaAttachments[index];
const { description } = media;
const showMediaAltDialog = await importShowMediaAltDialog()
showMediaAltDialog(description)
})()
return true
} }
}, },
data: () => ({ data: () => ({

View File

@ -23,22 +23,22 @@
border-radius: 6px; border-radius: 6px;
} }
.status-media.grouped-images > :global(.inline-media) { .status-media.grouped-images :global(.inline-media) {
padding-bottom: 56.25%; padding-bottom: 56.25%;
width: 100%; width: 100%;
} }
.status-media.grouped-images.two-cols > :global(.inline-media) { .status-media.grouped-images.two-cols :global(.inline-media) {
padding-bottom: calc(112.5% + 5px); padding-bottom: calc(112.5% + 5px);
} }
.status-media.grouped-images.odd-cols > :global(.inline-media:first-child) { .status-media.grouped-images.odd-cols :global(.inline-media:first-child) {
grid-row-end: span 2; grid-row-end: span 2;
padding-bottom: calc(112.5% + 5px); padding-bottom: calc(112.5% + 5px);
background-color: blue; background-color: blue;
} }
.status-media.not-grouped-images > :global(.inline-media) { .status-media.not-grouped-images :global(.inline-media) {
width: 100%; width: 100%;
min-height: 250px; min-height: 250px;
} }