fix having multiple modal dialogs
This commit is contained in:
		
							parent
							
								
									125dd6ab75
								
							
						
					
					
						commit
						80a89a64f1
					
				
					 12 changed files with 67 additions and 17 deletions
				
			
		| 
						 | 
				
			
			@ -1,4 +1,9 @@
 | 
			
		|||
<ModalDialog :label :shown background="var(--muted-modal-bg)" muted="true">
 | 
			
		||||
<ModalDialog :label
 | 
			
		||||
             :shown
 | 
			
		||||
             background="var(--muted-modal-bg)"
 | 
			
		||||
             muted="true"
 | 
			
		||||
             className="image-modal-dialog"
 | 
			
		||||
>
 | 
			
		||||
  {{#if type === 'gifv'}}
 | 
			
		||||
    <AutoplayVideo
 | 
			
		||||
      ariaLabel="Animated GIF: {{description || ''}}"
 | 
			
		||||
| 
						 | 
				
			
			@ -17,7 +22,7 @@
 | 
			
		|||
  {{/if}}
 | 
			
		||||
</ModalDialog>
 | 
			
		||||
<style>
 | 
			
		||||
  :global(#modal-dialog img, #modal-dialog video) {
 | 
			
		||||
  :global(.image-modal-dialog img, .image-modal-dialog video) {
 | 
			
		||||
    object-fit: contain;
 | 
			
		||||
    max-width: calc(100vw - 20px);
 | 
			
		||||
    max-height: calc(100% - 20px);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
<div class="modal-dialog-backdrop {{fadedIn ? '' : 'hidden'}}"
 | 
			
		||||
<div class="{{backdropClass}}"
 | 
			
		||||
     tabindex="-1"
 | 
			
		||||
     data-a11y-dialog-hide
 | 
			
		||||
></div>
 | 
			
		||||
<div class="modal-dialog-contents {{fadedIn ? '' : 'hidden'}} {{muted ? 'muted-style' : ''}}"
 | 
			
		||||
<div class="{{contentsClass}}"
 | 
			
		||||
     role="dialog"
 | 
			
		||||
     aria-label="{{label || ''}}"
 | 
			
		||||
     ref:node
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@
 | 
			
		|||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
<style>
 | 
			
		||||
  :global(#modal-dialog[aria-hidden='true']) {
 | 
			
		||||
  :global(.modal-dialog[aria-hidden='true']) {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
  .modal-dialog-backdrop {
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +36,8 @@
 | 
			
		|||
    bottom: 0;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    background: rgba(51, 51, 51, 0.9);
 | 
			
		||||
  }
 | 
			
		||||
  .modal-dialog-backdrop.should-animate {
 | 
			
		||||
    transition: opacity 0.2s linear;
 | 
			
		||||
  }
 | 
			
		||||
  .modal-dialog-contents {
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +53,8 @@
 | 
			
		|||
    display: flex;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    max-height: calc(100% - 20px);
 | 
			
		||||
  }
 | 
			
		||||
  .modal-dialog-contents.should-animate {
 | 
			
		||||
    transition: opacity 0.2s linear;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +117,31 @@
 | 
			
		|||
<script>
 | 
			
		||||
  import A11yDialog from 'a11y-dialog'
 | 
			
		||||
 | 
			
		||||
  import { classname } from '../../_utils/classname'
 | 
			
		||||
 | 
			
		||||
  export default {
 | 
			
		||||
    data: () => ({
 | 
			
		||||
      // don't animate if we're showing a modal dialog on top of another modal dialog. it looks ugly
 | 
			
		||||
      shouldAnimate: !process.browser || document.getElementsByClassName('modal-dialog').length < 2
 | 
			
		||||
    }),
 | 
			
		||||
    computed: {
 | 
			
		||||
      backdropClass: (fadedIn, shouldAnimate) => {
 | 
			
		||||
        return classname(
 | 
			
		||||
          'modal-dialog-backdrop',
 | 
			
		||||
          !fadedIn && 'hidden',
 | 
			
		||||
          shouldAnimate && 'should-animate'
 | 
			
		||||
        )
 | 
			
		||||
      },
 | 
			
		||||
      contentsClass: (fadedIn, muted, shouldAnimate, className) => {
 | 
			
		||||
        return classname(
 | 
			
		||||
          'modal-dialog-contents',
 | 
			
		||||
          !fadedIn && 'hidden',
 | 
			
		||||
          muted && 'muted-style',
 | 
			
		||||
          shouldAnimate && 'should-animate',
 | 
			
		||||
          className
 | 
			
		||||
        )
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    oncreate() {
 | 
			
		||||
      let dialogElement = this.refs.node.parentElement
 | 
			
		||||
      let a11yDialog = new A11yDialog(dialogElement)
 | 
			
		||||
| 
						 | 
				
			
			@ -121,6 +149,7 @@
 | 
			
		|||
        a11yDialog.destroy()
 | 
			
		||||
        this.fire('close')
 | 
			
		||||
        this.destroy()
 | 
			
		||||
        document.body.removeChild(dialogElement)
 | 
			
		||||
      })
 | 
			
		||||
      this.observe('shown', shown => {
 | 
			
		||||
        if (shown) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,9 @@
 | 
			
		|||
<ModalDialog :label :shown background="var(--muted-modal-bg)" muted="true">
 | 
			
		||||
<ModalDialog :label
 | 
			
		||||
             :shown
 | 
			
		||||
             background="var(--muted-modal-bg)"
 | 
			
		||||
             muted="true"
 | 
			
		||||
             className="video-modal-dialog"
 | 
			
		||||
>
 | 
			
		||||
  <video poster="{{poster}}"
 | 
			
		||||
         src="{{src}}"
 | 
			
		||||
         width="{{width}}"
 | 
			
		||||
| 
						 | 
				
			
			@ -8,7 +13,7 @@
 | 
			
		|||
  />
 | 
			
		||||
</ModalDialog>
 | 
			
		||||
<style>
 | 
			
		||||
  :global(#modal-dialog video) {
 | 
			
		||||
  :global(.video-modal-dialog video) {
 | 
			
		||||
    object-fit: contain;
 | 
			
		||||
    max-width: calc(100vw - 20px);
 | 
			
		||||
    max-height: calc(100% - 20px);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										7
									
								
								routes/_components/dialog/createDialogElement.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								routes/_components/dialog/createDialogElement.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
export function createDialogElement () {
 | 
			
		||||
  let div = document.createElement('div')
 | 
			
		||||
  div.setAttribute('class', 'modal-dialog')
 | 
			
		||||
  div.setAttribute('aria-hidden', 'true')
 | 
			
		||||
  document.body.appendChild(div)
 | 
			
		||||
  return div
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
import ComposeDialog from './ComposeDialog.html'
 | 
			
		||||
import { createDialogElement } from './createDialogElement'
 | 
			
		||||
 | 
			
		||||
export function showComposeDialog () {
 | 
			
		||||
  let dialog = new ComposeDialog({
 | 
			
		||||
    target: document.getElementById('modal-dialog'),
 | 
			
		||||
    target: createDialogElement(),
 | 
			
		||||
    data: {
 | 
			
		||||
      label: 'Compose dialog'
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
import ConfirmationDialog from './ConfirmationDialog.html'
 | 
			
		||||
import { createDialogElement } from './createDialogElement'
 | 
			
		||||
 | 
			
		||||
export function showConfirmationDialog (options) {
 | 
			
		||||
  let dialog = new ConfirmationDialog({
 | 
			
		||||
    target: document.getElementById('modal-dialog'),
 | 
			
		||||
    target: createDialogElement(),
 | 
			
		||||
    data: Object.assign({
 | 
			
		||||
      label: 'Confirmation dialog'
 | 
			
		||||
    }, options)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
import EmojiDialog from './EmojiDialog.html'
 | 
			
		||||
import { createDialogElement } from './createDialogElement'
 | 
			
		||||
 | 
			
		||||
export function showEmojiDialog (realm) {
 | 
			
		||||
  let emojiDialog = new EmojiDialog({
 | 
			
		||||
    target: document.getElementById('modal-dialog'),
 | 
			
		||||
    target: createDialogElement(),
 | 
			
		||||
    data: {
 | 
			
		||||
      label: 'Emoji dialog',
 | 
			
		||||
      title: 'Custom emoji',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
import ImageDialog from './ImageDialog.html'
 | 
			
		||||
import { createDialogElement } from './createDialogElement'
 | 
			
		||||
 | 
			
		||||
export function showImageDialog (poster, src, type, width, height, description) {
 | 
			
		||||
  let imageDialog = new ImageDialog({
 | 
			
		||||
    target: document.getElementById('modal-dialog'),
 | 
			
		||||
    target: createDialogElement(),
 | 
			
		||||
    data: {
 | 
			
		||||
      label: 'Image dialog',
 | 
			
		||||
      poster,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
import PostPrivacyDialog from './PostPrivacyDialog.html'
 | 
			
		||||
import { createDialogElement } from './createDialogElement'
 | 
			
		||||
 | 
			
		||||
export function showPostPrivacyDialog (realm) {
 | 
			
		||||
  let dialog = new PostPrivacyDialog({
 | 
			
		||||
    target: document.getElementById('modal-dialog'),
 | 
			
		||||
    target: createDialogElement(),
 | 
			
		||||
    data: {
 | 
			
		||||
      label: 'Post privacy dialog',
 | 
			
		||||
      title: 'Post privacy',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
import StatusOptionsDialog from './StatusOptionsDialog.html'
 | 
			
		||||
import { createDialogElement } from './createDialogElement'
 | 
			
		||||
 | 
			
		||||
export function showStatusOptionsDialog (statusId) {
 | 
			
		||||
  let dialog = new StatusOptionsDialog({
 | 
			
		||||
    target: document.getElementById('modal-dialog'),
 | 
			
		||||
    target: createDialogElement(),
 | 
			
		||||
    data: {
 | 
			
		||||
      label: 'Status options dialog',
 | 
			
		||||
      title: 'Status options',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
import VideoDialog from './VideoDialog.html'
 | 
			
		||||
import { createDialogElement } from './createDialogElement'
 | 
			
		||||
 | 
			
		||||
export function showVideoDialog (poster, src, width, height, description) {
 | 
			
		||||
  let videoDialog = new VideoDialog({
 | 
			
		||||
    target: document.getElementById('modal-dialog'),
 | 
			
		||||
    target: createDialogElement(),
 | 
			
		||||
    data: {
 | 
			
		||||
      label: 'Video dialog',
 | 
			
		||||
      poster,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,9 +120,6 @@ body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-o
 | 
			
		|||
  <!-- Toast.html gets rendered here -->
 | 
			
		||||
  <div id="toast"></div>
 | 
			
		||||
 | 
			
		||||
  <!-- ModalDialog.html gets rendered here -->
 | 
			
		||||
  <div id="modal-dialog" aria-hidden="true"></div>
 | 
			
		||||
 | 
			
		||||
  <!-- LoadingMask.html gets rendered here -->
 | 
			
		||||
  <div id="loading-mask" aria-hidden="true"></div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue