<div class="compose-media"> <img src="{{mediaItem.data.preview_url}}" alt="{{mediaItem.file.name}}"/> <div class="compose-media-delete"> <button class="compose-media-delete-button" aria-label="Delete {{mediaItem.file.name}}" on:click="onDeleteMedia()" > <svg class="compose-media-delete-button-svg"> <use xlink:href="#fa-times" /> </svg> </button> </div> <div class="compose-media-alt"> <input type="text" placeholder="Description" aria-label="Describe {{mediaItem.file.name}} for the visually impaired" bind:value=rawText > </div> </div> <style> .compose-media { height: 200px; overflow: hidden; flex-direction: column; position: relative; display: flex; background: var(--main-bg); } .compose-media img { object-fit: contain; object-position: center center; flex: 1; height: 100%; width: 100%; } .compose-media-alt { z-index: 10; position: absolute; bottom: 0; left: 0; right: 0; display: flex; justify-content: center; } .compose-media-alt input { width: 100%; font-size: 1.2em; background: var(--alt-input-bg); } .compose-media-alt input:focus { background: var(--main-bg); } .compose-media-delete { position: absolute; z-index: 10; top: 0; right: 0; left: 0; display: flex; justify-content: flex-end; margin: 2px; } .compose-media-delete-button { padding: 10px; background: none; border: none; } .compose-media-delete-button:hover { background: var(--toast-border); } .compose-media-delete-button-svg { fill: var(--button-text); width: 18px; height: 18px; } </style> <script> import { store } from '../../_store/store' import { deleteMedia } from '../../_actions/media' import debounce from 'lodash-es/debounce' import { scheduleIdleTask } from '../../_utils/scheduleIdleTask' export default { oncreate() { this.setupSyncFromStore() this.setupSyncToStore() }, data: () => ({ rawText: '' }), store: () => store, methods: { setupSyncFromStore() { this.observe('mediaDescriptions', mediaDescriptions => { mediaDescriptions = mediaDescriptions || [] let index = this.get('index') let text = mediaDescriptions[index] || '' if (this.get('rawText') !== text) { this.set({rawText: text}) } }) }, setupSyncToStore() { const saveStore = debounce(() => scheduleIdleTask(() => this.store.save()), 1000) this.observe('rawText', rawText => { let realm = this.get('realm') let index = this.get('index') let mediaDescriptions = store.getComposeData(realm, 'mediaDescriptions') || [] if (mediaDescriptions[index] === rawText) { return } while (mediaDescriptions.length <= index) { mediaDescriptions.push(null) } mediaDescriptions[index] = rawText store.setComposeData(realm, {mediaDescriptions}) saveStore() }, {init: false}) }, onDeleteMedia() { deleteMedia(this.get('realm'), this.get('index')) } } } </script>