feat: add support for audio attachments (#1293)

This is a new thing in Mastodon v2.9. I kept the "camera" icon because I like it better than the paperclip, and I think it covers the 99% use case.
This commit is contained in:
Nolan Lawson 2019-06-23 09:41:31 -07:00 committed by GitHub
parent ea220c32d3
commit d31f2ce010
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 21 deletions

View File

@ -1,5 +1,9 @@
<li class="compose-media compose-media-realm-{realm}">
<img src={mediaItem.data.preview_url} {alt} />
<img
class="{type === 'audio' ? 'audio-preview' : ''}"
src={previewSrc}
{alt}
/>
<div class="compose-media-delete">
<button class="compose-media-delete-button"
aria-label="Delete {shortName}"
@ -10,13 +14,11 @@
<div class="compose-media-alt">
<textarea id="compose-media-input-{uuid}"
class="compose-media-alt-input"
placeholder="Describe for the visually impaired"
placeholder="Description"
ref:textarea
bind:value=rawText
></textarea>
<label for="compose-media-input-{uuid}" class="sr-only">
Describe {shortName} for the visually impaired
</label>
<label for="compose-media-input-{uuid}" class="sr-only">{label}</label>
</div>
</li>
<style>
@ -85,6 +87,10 @@
height: 18px;
}
.audio-preview {
background: var(--audio-bg);
}
.compose-media-realm-dialog {
max-height: 20vh;
}
@ -106,6 +112,7 @@
import { observe } from 'svelte-extras'
import SvgIcon from '../SvgIcon.html'
import { autosize } from '../../_thirdparty/autosize/autosize'
import { ONE_TRANSPARENT_PIXEL } from '../../_static/media'
export default {
oncreate () {
@ -126,7 +133,14 @@
// so fall back to the description if it was provided
filename || mediaItem.description || ''
),
type: ({ mediaItem }) => mediaItem.data.type,
shortName: ({ filename }) => filename || 'media',
previewSrc: ({ mediaItem, type }) => (
type === 'audio' ? ONE_TRANSPARENT_PIXEL : mediaItem.data.preview_url
),
label: ({ shortName }) => (
`Describe ${shortName} for the visually impaired (image, video) or auditorily impaired (audio, video)`
),
uuid: ({ realm, mediaItem }) => `${realm}-${mediaItem.data.id}`
},
store: () => store,

View File

@ -217,7 +217,7 @@
computed: {
length: ({ mediaItems }) => mediaItems.length,
dots: ({ length }) => times(length, i => ({ i })),
canPinchZoom: ({ mediaItems }) => !mediaItems.some(media => media.type === 'video')
canPinchZoom: ({ mediaItems }) => !mediaItems.some(media => ['video', 'audio'].includes(media.type))
},
components: {
ModalDialog,

View File

@ -6,8 +6,18 @@
{poster}
controls
{intrinsicsize}
ref:video
ref:player
/>
{:elseif type === 'audio'}
<div class="audio-player-container">
<audio
class="audio-player"
aria-label={description}
src={url}
controls
ref:player
/>
</div>
{:elseif type === 'gifv'}
<video
class="media-fit"
@ -36,6 +46,27 @@
width: 100%;
height: 100%;
}
.audio-player-container {
min-height: 400px;
min-width: 400px;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: flex-end;
background: var(--audio-bg);
}
.audio-player {
padding: 30px 10px;
margin: 10px;
}
@media (max-width: 767px) {
.audio-player-container {
min-height: 200px;
min-width: calc(100vw - 40px);
align-items: center;
}
}
</style>
<script>
export default {
@ -54,8 +85,9 @@
}
},
ondestroy () {
if (this.refs.video && !this.refs.video.paused) {
this.refs.video.pause()
let player = this.refs.player
if (player && !player.paused) {
player.pause()
}
}
}

View File

@ -1,20 +1,22 @@
{#if type === 'video'}
{#if type === 'video' || type === 'audio'}
<button id={elementId}
type="button"
class="play-video-button {$largeInlineMedia ? '' : 'fixed-size'}"
class="play-video-button {$largeInlineMedia ? '' : 'fixed-size'} {type === 'audio' ? 'play-audio-button' : ''}"
aria-label="Play video: {description}"
style="width: {inlineWidth}px; height: {inlineHeight}px;">
<PlayVideoIcon />
<LazyImage
alt={description}
title={description}
src={previewUrl}
fallback={oneTransparentPixel}
width={inlineWidth}
height={inlineHeight}
background="var(--loading-bg)"
{focus}
/>
{#if type === 'video'}
<LazyImage
alt={description}
title={description}
src={previewUrl}
fallback={oneTransparentPixel}
width={inlineWidth}
height={inlineHeight}
background="var(--loading-bg)"
{focus}
/>
{/if}
</button>
{:else}
<button id={elementId}
@ -72,6 +74,9 @@
background: none;
position: relative;
}
.play-audio-button {
background: var(--audio-bg);
}
/* the actual focus outline is not very visible, so use an ::after pseudo-element */
.play-video-button:focus, .show-image-button:focus {

View File

@ -118,4 +118,6 @@
--floating-button-bg-active: #{darken(rgba($main-bg-color, 0.9), 10%)};
--length-indicator-color: #{$main-theme-color};
--audio-bg: #{rgba(30, 30, 30, 0.8)};
}