blob: abec000ce8ecf04b1fd4bdc2e24a016623e1879a [file] [log] [blame]
Adrià Vilanova Martíneze5263f12022-05-29 19:22:13 +02001import {css, html, LitElement} from 'lit';
2import {map} from 'lit/directives/map.js';
3import {unsafeHTML} from 'lit/directives/unsafe-html.js';
4
5import {msg} from '../../../common/i18n.js';
6import credits from '../../credits.json5';
7import i18nCredits from '../../i18n-credits.json5';
8import {DIALOG_STYLES} from '../../shared/dialog-styles.js';
9import {SHARED_STYLES} from '../../shared/shared-styles.js';
10
11export class CreditsDialog extends LitElement {
12 static get styles() {
13 return [
14 SHARED_STYLES,
15 DIALOG_STYLES,
16 css`
17 dialog {
18 max-height: 430px;
19 width: 400px;
20 }
21
22 dialog[open] {
23 display: flex;
24 flex-direction: column;
25 }
26
27 .content_area h4 {
28 margin-bottom: 0;
29 }
30
31 .entry {
32 position: relative;
33 }
34
35 .entry a.homepage {
36 position: absolute;
37 inset-inline-end: 16px;
38 font-size: 14px;
39 }
40
41 p,
42 span {
43 font-size: 14px;
44 }
45
46 p.author {
47 margin-top: 7px;
48 }
49
50 #translators .name {
51 font-weight: bold;
52 }
53
54 .createdby {
55 font-style: italic;
56 }
57 `,
58 ];
59 }
60
61 constructor() {
62 super();
63 this.addEventListener('show-credits-dialog', this.showDialog);
64 }
65
66 render() {
67 let translators = map(i18nCredits, contributor => {
68 let languagesArray =
69 contributor?.languages?.map?.(lang => lang?.name ?? 'undefined');
70 let languages =
71 languagesArray.length > 0 ? ': ' + languagesArray.join(', ') : '';
72 return html`
73 <li>
74 <span class="name">${contributor?.name}</span>${languages}
75 </li>
76 `;
77 });
78
79 let homepageMsg = msg('options_credits_homepage');
80 let creditsByMsg = msg('options_credits_by');
81
82 let otherCredits = map(credits, c => {
83 let url = c.url ? html`
84 <a href=${c?.url} target="_blank" class="homepage">
85 ${homepageMsg}
86 </a>` :
87 undefined;
88 let license = c.license ? ' - ' + c.license : '';
89 let author = c.author ? html`
90 <p class="author">
91 ${creditsByMsg} ${c.author}${license}
92 </p>
93 ` :
94 undefined;
95
96 return html`
97 <div class="entry">
98 ${url}
99 <h4>${c?.name}</h4>
100 ${author}
101 </div>
102 `;
103 });
104
105 return html`
106 <dialog>
107 <div class="scrollable">
108 <h3>${msg('options_credits')}</h3>
109 <div class="entry createdby">
110 <div>${unsafeHTML(msg('options_credits_createdby'))}</div>
111 </div>
112 <div class="entry">
113 <a href="https://gtranslate.avm99963.com/" class="homepage" target="_blank">
114 ${msg('options_credits_homepage')}
115 </a>
116 <h4>${msg('options_credits_translations')}</h4>
117 <div>${msg('options_credits_translations_paragraph')}</div>
118 <ul id="translators">
119 ${translators}
120 </ul>
121 </div>
122 <div class="content_area">
123 ${otherCredits}
124 </div>
125 </div>
126 <div class="action_buttons">
127 <button id="credits_ok" @click="${this.closeDialog}">
128 ${msg('options_ok')}
129 </button>
130 </div>
131 </dialog>
132 `;
133 }
134
135 showDialog() {
136 let dialog = this.renderRoot.querySelector('dialog');
137 dialog.showModal();
138 dialog.querySelector('.scrollable').scrollTo(0, 0);
139 dialog.querySelector('#credits_ok').focus();
140 }
141
142 closeDialog() {
143 this.renderRoot.querySelector('dialog').close();
144 }
145}
146customElements.define('credits-dialog', CreditsDialog);