130 lines
		
	
	
		
			No EOL
		
	
	
		
			3.3 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			No EOL
		
	
	
		
			3.3 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<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, rawText } = this.get()
 | 
						|
          let text = mediaDescriptions[index] || ''
 | 
						|
          if (rawText !== text) {
 | 
						|
            this.set({rawText: text})
 | 
						|
          }
 | 
						|
        })
 | 
						|
      },
 | 
						|
      setupSyncToStore () {
 | 
						|
        const saveStore = debounce(() => scheduleIdleTask(() => this.store.save()), 1000)
 | 
						|
 | 
						|
        this.observe('rawText', rawText => {
 | 
						|
          let { realm } = this.get()
 | 
						|
          let { index } = this.get()
 | 
						|
          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 () {
 | 
						|
        let {
 | 
						|
          realm,
 | 
						|
          index
 | 
						|
        } = this.get()
 | 
						|
        deleteMedia(realm, index)
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
</script> |