Spaces:
Sleeping
Sleeping
File size: 4,445 Bytes
7aec436 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
<script>
import Section from './Section.svelte';
import Button from './Button.svelte';
import {CannotAccessProjectError, OutdatedPackagerError, UnknownNetworkError, UserError} from '../common/errors';
import {error} from './stores';
import {FEEDBACK_PRIMARY} from '../packager/brand';
import {_} from '../locales/';
import ComplexMessage from './ComplexMessage.svelte';
export let modalVisible;
let modalElement;
let initiallyFocusedElement;
const getAllFocusableElements = () => Array.from(document.querySelectorAll('a, button, input, select'))
.filter((i) => !modalElement || !modalElement.contains(i));
$: {
modalVisible = !!$error;
if ($error) {
console.error($error);
document.body.setAttribute('p4-modal-visible', '');
initiallyFocusedElement = document.activeElement;
getAllFocusableElements().forEach((i) => {
i.setAttribute('p4-old-tabIndex', i.tabIndex);
i.tabIndex = -1;
});
} else {
document.body.removeAttribute('p4-modal-visible');
getAllFocusableElements().forEach((i) => {
if (i.hasAttribute('p4-old-tabIndex')) {
i.tabIndex = i.getAttribute('p4-old-tabIndex');
i.removeAttribute('p4-old-tabIndex');
}
});
if (initiallyFocusedElement) {
initiallyFocusedElement.focus();
}
}
}
$: if (modalElement) {
const button = modalElement.querySelector('button');
if (button) {
button.focus();
}
}
const closeModal = () => {
$error = null;
};
const onKeyDown = (e) => {
if (e.key === 'Escape') {
closeModal();
}
};
const refresh = () => location.reload();
</script>
<style>
:global([p4-modal-visible]) {
overflow: hidden;
}
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.75);
word-break: break-word;
}
.technical {
font-style: italic;
}
</style>
<svelte:window on:keydown={onKeyDown} />
{#if modalVisible}
<!-- All prompts can be closed using buttons in the modal, so we can ignore this warning -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="modal" on:click|self={closeModal} bind:this={modalElement}>
<Section modal>
<h2>{$_('p4.error')}</h2>
{#if $error instanceof UserError}
<p>{$error.message}</p>
<p>
<Button on:click={closeModal} text={$_('p4.close')} />
</p>
{:else if $error instanceof UnknownNetworkError}
<p>
<ComplexMessage
message={$_('p4.networkError')}
values={{
url: {
text: $error.url,
href: $error.url,
newTab: true
}
}}
/>
</p>
<p>
<Button on:click={closeModal} text={$_('p4.close')} />
</p>
{:else if $error instanceof OutdatedPackagerError}
<p>{$_('p4.outdated')}</p>
<p class="technical">{$error}</p>
<p>
<Button on:click={refresh} text={$_('p4.refresh')} />
<Button secondary on:click={closeModal} text={$_('p4.close')} />
</p>
{:else if $error instanceof CannotAccessProjectError}
<p>
{$_('p4.cannotAccessProject')}
</p>
<p>
{$_('select.unsharedProjects')}
</p>
<p>
<ComplexMessage
message={$_('select.unsharedProjectsMore')}
values={{
link: {
text: 'https://docs.turbowarp.org/unshared-projects',
href: 'https://docs.turbowarp.org/unshared-projects',
newTab: true
}
}}
/>
</p>
<p>
{$_('p4.cannotAccessProjectCaching')}
</p>
<p>
<Button on:click={closeModal} text={$_('p4.close')} />
</p>
{:else}
<p>{$_('p4.errorMessage').replace('{error}', $error)}</p>
<p>
<Button on:click={closeModal} text={$_('p4.close')} />
<a href={FEEDBACK_PRIMARY.link}>{$_('p4.reportBug')}</a>
</p>
{/if}
</Section>
</div>
{/if}
|