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}