properly close modal stack in order on escape
This commit is contained in:
		
							parent
							
								
									939d69fe46
								
							
						
					
					
						commit
						c672236412
					
				| 
						 | 
				
			
			@ -28,6 +28,7 @@
 | 
			
		|||
        "gpt-tokenizer": "^2.0.0",
 | 
			
		||||
        "postcss": "^8.4.24",
 | 
			
		||||
        "sass": "^1.61.0",
 | 
			
		||||
        "stacking-order": "^2.0.0",
 | 
			
		||||
        "svelte": "^3.58.0",
 | 
			
		||||
        "svelte-check": "^3.4.3",
 | 
			
		||||
        "svelte-fa": "^3.0.3",
 | 
			
		||||
| 
						 | 
				
			
			@ -3976,6 +3977,12 @@
 | 
			
		|||
        "node": ">=0.10.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/stacking-order": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/stacking-order/-/stacking-order-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-nnv68iFGwrKXYlmXJKD5qBuH8D49BEv6zAgesXoKeGqMmMit6/Hyvb6R0BG9odpjqQm35YjlTsZUyB0ffbFDrg==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/string.prototype.trim": {
 | 
			
		||||
      "version": "1.2.7",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,7 @@
 | 
			
		|||
    "gpt-tokenizer": "^2.0.0",
 | 
			
		||||
    "postcss": "^8.4.24",
 | 
			
		||||
    "sass": "^1.61.0",
 | 
			
		||||
    "stacking-order": "^2.0.0",
 | 
			
		||||
    "svelte": "^3.58.0",
 | 
			
		||||
    "svelte-check": "^3.4.3",
 | 
			
		||||
    "svelte-fa": "^3.0.3",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@
 | 
			
		|||
  import NewChat from './lib/NewChat.svelte'
 | 
			
		||||
  import { chatsStorage, apiKeyStorage } from './lib/Storage.svelte'
 | 
			
		||||
  import { Modals, closeModal } from 'svelte-modals'
 | 
			
		||||
  import { triggerModalEsc } from './lib/Util.svelte'
 | 
			
		||||
 | 
			
		||||
  // The definition of the routes with some conditions
 | 
			
		||||
  const routes = {
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +52,10 @@
 | 
			
		|||
  />
 | 
			
		||||
</Modals>
 | 
			
		||||
 | 
			
		||||
<svelte:window
 | 
			
		||||
  on:keydown={(e) => triggerModalEsc(e)}
 | 
			
		||||
/>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
  .backdrop {
 | 
			
		||||
    position: fixed;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
declare namespace svelteHTML {
 | 
			
		||||
  interface HTMLAttributes<> {
 | 
			
		||||
    // Custom on:modal-esc event
 | 
			
		||||
    'on:modal-esc'?: (event: any) => any
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -139,12 +139,3 @@
 | 
			
		|||
</div>
 | 
			
		||||
 | 
			
		||||
<input style="display:none" type="file" accept=".json" on:change={(e) => importChatFromFile(e)} bind:this={chatFileInput} >
 | 
			
		||||
 | 
			
		||||
<svelte:window
 | 
			
		||||
  on:keydown={(event) => {
 | 
			
		||||
    if (event.key === 'Escape') {
 | 
			
		||||
      event.stopPropagation()
 | 
			
		||||
      showChatMenu = false
 | 
			
		||||
    }
 | 
			
		||||
  }}
 | 
			
		||||
/>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -253,7 +253,7 @@
 | 
			
		|||
</script>
 | 
			
		||||
 | 
			
		||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
 | 
			
		||||
<div class="modal chat-settings" class:is-active={showSettingsModal}>
 | 
			
		||||
<div class="modal chat-settings" class:is-active={showSettingsModal} on:modal-esc={closeSettings}>
 | 
			
		||||
  <div class="modal-background" on:click={closeSettings} />
 | 
			
		||||
  <div class="modal-card wide" on:click={() => { showProfileMenu = false }}>
 | 
			
		||||
    <header class="modal-card-head">
 | 
			
		||||
| 
						 | 
				
			
			@ -322,12 +322,3 @@
 | 
			
		|||
</div>
 | 
			
		||||
 | 
			
		||||
<input style="display:none" type="file" accept=".json" on:change={(e) => importProfileFromFile(e)} bind:this={profileFileInput} >
 | 
			
		||||
 | 
			
		||||
<svelte:window
 | 
			
		||||
  on:keydown={(event) => {
 | 
			
		||||
    if (event.key === 'Escape') {
 | 
			
		||||
      event.stopPropagation()
 | 
			
		||||
      closeSettings()
 | 
			
		||||
    }
 | 
			
		||||
  }}
 | 
			
		||||
/>
 | 
			
		||||
| 
						 | 
				
			
			@ -67,12 +67,12 @@
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  const keydown = (event:KeyboardEvent) => {
 | 
			
		||||
    if (event.key === 'Escape') {
 | 
			
		||||
      event.stopPropagation()
 | 
			
		||||
      event.preventDefault()
 | 
			
		||||
      message.content = original
 | 
			
		||||
      editing = false
 | 
			
		||||
    }
 | 
			
		||||
    // if (event.key === 'Escape') {
 | 
			
		||||
    //   event.stopPropagation()
 | 
			
		||||
    //   event.preventDefault()
 | 
			
		||||
    //   message.content = original
 | 
			
		||||
    //   editing = false
 | 
			
		||||
    // }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const scrollToMessage = (uuid:string | string[] | undefined) => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,7 @@
 | 
			
		|||
</script>
 | 
			
		||||
 | 
			
		||||
{#if isOpen}
 | 
			
		||||
<div class="modal is-active">
 | 
			
		||||
<div class="modal is-active" on:modal-esc={doCancel}>
 | 
			
		||||
  <!-- svelte-ignore a11y-click-events-have-key-events -->
 | 
			
		||||
  <div class="modal-background" on:click={doCancel} />
 | 
			
		||||
  <div class="modal-content nomax">
 | 
			
		||||
| 
						 | 
				
			
			@ -59,12 +59,3 @@
 | 
			
		|||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
{/if}
 | 
			
		||||
 | 
			
		||||
<svelte:window
 | 
			
		||||
  on:keydown={(event) => {
 | 
			
		||||
    if (event.key === 'Escape') {
 | 
			
		||||
      event.stopPropagation()
 | 
			
		||||
      doCancel()
 | 
			
		||||
    }
 | 
			
		||||
  }}
 | 
			
		||||
/>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,7 @@
 | 
			
		|||
</script>
 | 
			
		||||
 | 
			
		||||
{#if isOpen}
 | 
			
		||||
<div class="modal is-active">
 | 
			
		||||
<div class="modal is-active" on:modal-esc={doClose}>
 | 
			
		||||
  <!-- svelte-ignore a11y-click-events-have-key-events -->
 | 
			
		||||
  <div class="modal-background" on:click={doClose} />
 | 
			
		||||
  <div class="modal-content nomax">
 | 
			
		||||
| 
						 | 
				
			
			@ -97,11 +97,11 @@
 | 
			
		|||
</div>
 | 
			
		||||
{/if}
 | 
			
		||||
 | 
			
		||||
<svelte:window
 | 
			
		||||
<!-- <svelte:window
 | 
			
		||||
  on:keydown={(event) => {
 | 
			
		||||
    if (event.key === 'Escape') {
 | 
			
		||||
      event.stopPropagation()
 | 
			
		||||
      onClose()
 | 
			
		||||
    }
 | 
			
		||||
  }}
 | 
			
		||||
/>
 | 
			
		||||
/> -->
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
<script  context="module" lang="ts">
 | 
			
		||||
  import { compare } from 'stacking-order'
 | 
			
		||||
  export const sizeTextElements = () => {
 | 
			
		||||
    const els = document.querySelectorAll('textarea.auto-size')
 | 
			
		||||
    for (let i:number = 0, l = els.length; i < l; i++) autoGrowInput(els[i] as HTMLTextAreaElement)
 | 
			
		||||
| 
						 | 
				
			
			@ -27,4 +28,24 @@
 | 
			
		|||
        offset
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  export const triggerModalEsc = (event:KeyboardEvent|undefined):boolean|void => {
 | 
			
		||||
    if (!event || event.key !== 'Escape') return
 | 
			
		||||
    const stack = Array.from(document.querySelectorAll('.modal')).filter(s =>
 | 
			
		||||
      window.getComputedStyle(s).getPropertyValue('display') !== 'none'
 | 
			
		||||
    )
 | 
			
		||||
    const top:HTMLElement = stack.length === 1
 | 
			
		||||
      ? stack[0]
 | 
			
		||||
      : stack.find(m1 => {
 | 
			
		||||
        return stack.find(m2 => {
 | 
			
		||||
          return m1 !== m2 && compare(m1, m2) > 0 && m1
 | 
			
		||||
        })
 | 
			
		||||
      }) as any
 | 
			
		||||
    if (top) {
 | 
			
		||||
      // trigger modal-esc event on topmost modal when esc key is pressed
 | 
			
		||||
      const e = new CustomEvent('modal-esc', { detail: top })
 | 
			
		||||
      top.dispatchEvent(e)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
</script> 
 | 
			
		||||
		Loading…
	
		Reference in New Issue