forked from cybrespace/pinafore
		
	
		
			
				
	
	
		
			126 lines
		
	
	
		
			No EOL
		
	
	
		
			3.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			No EOL
		
	
	
		
			3.2 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 = 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> |