git ssb

0+

farewellutopia-dev / patchboot



Tree: 54f45b9e3a2114fd3c234a8de046349c9a3dab1c

Files: 54f45b9e3a2114fd3c234a8de046349c9a3dab1c / src / components / PatchBoot.js

11732 bytesRaw
1
2import './AppSelector.js'
3import './AppRunner.js'
4import './SourceViewer.js'
5import { default as pull } from 'pull-stream'
6
7class PatchBoot extends HTMLElement {
8 constructor() {
9 super();
10 }
11 connectedCallback() {
12 const componentArea = this.attachShadow({ mode: 'open' })
13
14 componentArea.innerHTML = `
15 <div id="component-root">
16 <style>
17 * {
18 box-sizing: border-box;
19 overflow-wrap: anywhere;
20 }
21
22 #component-root {
23 background-color: #ffffff;
24 font-family: Inter, 'Helvetica Neue', Arial, Helvetica, sans-serif;
25 --lineColor1: #79cfd9;
26 --lineColor2: #b0bec5;
27 --topBarHeight: 45px;
28 }
29
30
31 .flex {
32 display: flex;
33 width: 100vw;
34 }
35
36 #sidebar {
37 flex-shrink: 0;
38 width: 248px;
39 border-right: 1px solid var(--lineColor1);
40 height: 100vh;
41 display: flex;
42 flex-direction: column;
43 overflow: hidden;
44 transition: width 0.3s ease-in-out, margin-left 0.3s ease-in-out;
45 background: #ffffff;
46 }
47
48 #sidebar.gone {
49 width: 0px;
50 margin-left: -1px;
51 }
52
53 #sidebar-inner {
54 width: 247px;
55 height: 100vh;
56 display: flex;
57 flex-direction: column;
58 overflow: hidden;
59 }
60
61 #close-apps,
62 #close-apps-backdrop {
63 display: none;
64 }
65
66 @media screen and (max-width: 500px) {
67 #close-apps {
68 display: block;
69 }
70
71 #close-apps-backdrop {
72 display: block;
73 content: "";
74 position: absolute;
75 background: rgba(0, 0, 0, 0.2);
76 transition: width 0.3s ease-in-out;
77 top: 0;
78 bottom: 0;
79 right: 0;
80 left: 0;
81 }
82
83 #sidebar {
84 position: absolute;
85 top: 0;
86 right: 16px;
87 bottom: 0;
88 left: 0;
89 width: unset;
90 border: none;
91 transition: right 0.3s ease-in-out;
92 box-shadow: -5px 0 10px 0 black;
93 z-index: 100;
94 }
95
96 #sidebar-inner {
97 width: calc(100vw - 16px);
98 }
99
100 #sidebar.gone,
101 #close-apps-backdrop.gone {
102 width: unset;
103 margin: 0;
104 right: 100vw;
105 }
106 }
107
108 #connecting {
109 padding: 0 0.5rem;
110 animation: 1s infinite alternate ease-in-out loading-color;
111 }
112
113 @keyframes loading-color {
114 from {
115 color: black;
116 }
117 to {
118 color: var(--lineColor1);
119 }
120 }
121
122 #connecting p {
123 margin: 0.5rem 0;
124 }
125
126 #connecting .muted {
127 color: rgba(0,0,0,0);
128 }
129
130 .waited #connecting .muted {
131 color: rgba(0, 0, 0, 0.4);
132 }
133
134 .muted {
135 color: rgba(0, 0, 0, 0.4);
136 }
137
138 .bar {
139 border-bottom: 1px solid var(--lineColor1);
140 border-radius: 0;
141 padding: 0.5rem;
142 background: #e0f7fa;
143 background: #79cfd9;
144 display: flex;
145 justify-content: space-between;
146 height: var(--topBarHeight);
147 line-height: 28px;
148 }
149
150 .bar h1 {
151 display: block;
152 font-size: 1rem;
153 margin: 0;
154 padding: 0;
155 }
156
157 #title-ext {
158 font-weight: 500;
159 }
160
161 .icons {
162 display: flex;
163 }
164
165 .icons button {
166 margin: 0 2px;
167 padding: 6px;
168 border: none;
169 border-radius: 50%;
170 height: 28px;
171 background-color: rgba(0,0,0,0.027450980392156863);
172 }
173
174 .icons button:hover {
175 background-color: rgba(0,0,0,0.13333333333333334);
176 }
177
178 .icons button svg {
179 display: block;
180 height: 16px;
181 width: 16px;
182 }
183
184 .svghover .onhover {
185 display: none;
186 }
187
188 .svghover:hover path {
189 display: none;
190 }
191
192 .svghover:hover .onhover {
193 display: unset;
194 }
195
196 #info {
197 transition: all 0.3s ease-in-out;
198 max-height: 90vh;
199 overflow-y: auto;
200 padding: 0.5rem;
201 }
202
203 #status {
204 max-height: 90vh;
205 padding: 0.5rem;
206 background: #def3f6;
207 transform: all 0.3s ease-in-out;
208 }
209
210 .hidden {
211 display: none;
212 }
213
214 #info.hidden
215 #status.hidden {
216 max-height: 0 !important;
217 border: none;
218 padding: 0;
219 margin: 0;
220 opacity: 0;
221 overflow: hidden;
222 }
223
224 #outer {
225 position: absolute;
226 right: 0;
227 left: 0;
228 bottom: 0;
229 top: 0;
230 padding: 2rem;
231 background: rgba(0, 0, 0, 0.2);
232 height: 100vh;
233 width: 100vw;
234 max-height: 100vh;
235 max-width: 100vw;
236 }
237
238 #inner {
239 background: white;
240 display: flex;
241 flex-direction: column;
242 justify-content: space-between;
243 opacity: 1;
244 height: 100%;
245 width: 100%;
246 max-height: 100%;
247 max-width: 100%;
248 box-shadow: 4px 4px 12px -8px black;
249 }
250
251 #inner * {
252 margin: 0.2rem;
253 }
254
255 #inner .main {
256 overflow: auto;
257 background: lightgray;
258 max-width: 100%;
259 flex: 1;
260 }
261
262 .modal-open {
263 overflow: hidden;
264 max-height: 100vh;
265 max-width: 100vw;
266 }
267
268 app-selector {
269 display: flex;
270 flex-direction: column;
271 flex: 0 auto;
272 max-height: calc(100vh - 45px);
273 }
274
275 .main {
276 flex-grow: 1;
277 display: flex;
278 flex-direction: column;
279 height: 100vh;
280 min-width: 45px;
281 overflow: hidden;
282 }
283
284 #view {
285 height: 100%;
286 overflow: hidden;
287 }
288
289 #view:empty {
290 height: 0;
291 }
292
293 app-runner {
294 width: 100%;
295 height: 100%;
296 display: block;
297 }
298
299 </style>
300 <div class="flex">
301 <div id="sidebar">
302 <div id="sidebar-inner">
303 <header class="bar">
304 <h1>PatchBoot</h1>
305 <div class="icons">
306 <button id="close-apps">
307 <svg width="24" viewBox="0 0 24 24">
308 <path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
309 </svg>
310 </button>
311 </div>
312 </header>
313 </div>
314 </div>
315 <div class="main">
316 <header class="bar">
317 <div class="icons">
318 <button id="toggle-apps">
319 <svg width="24" viewBox="0 0 24 24">
320 <path fill="currentColor"
321 d="M16,20H20V16H16M16,14H20V10H16M10,8H14V4H10M16,8H20V4H16M10,14H14V10H10M4,14H8V10H4M4,20H8V16H4M10,20H14V16H10M4,8H8V4H4V8Z" />
322 </svg>
323 </button>
324 </div>
325 <h1 id="title-ext"></h1>
326 <div></div>
327 </header>
328 <div id="connecting">
329 <p>Connecting to SSB</p>
330 <p class="muted"><small>If nothing happens, please make sure you have an SSB server running and the plugin
331 intstalled.</small></p>
332 </div>
333 <div id="info" class="hidden">
334 <h2>No App is Running yet</h2>
335 <p>
336 Only execute apps you trust,
337 as they’ll have full access to your SSB account.
338 </p>
339 </div>
340 <div id="status" class="hidden"></div>
341 <div id="view"></div>
342 </div>
343 </div>
344 <div id="close-apps-backdrop"></div>
345 </div>
346 `
347 const componentRoot = componentArea.getElementById('component-root')
348 const sidebar = componentArea.getElementById('sidebar')
349 const sidebarToggle = componentArea.getElementById('toggle-apps')
350 const sidebarClose = componentArea.getElementById('close-apps')
351 const sidebarCloseBackdrop = componentArea.getElementById('close-apps-backdrop')
352
353 const closeSidebar = () => {
354 console.log('closing')
355 sidebar.classList.add('gone')
356 sidebarCloseBackdrop.classList.add('gone')
357 sidebarCloseBackdrop.removeEventListener('click', closeSidebar)
358 }
359
360 const openSidebar = () => {
361 console.log('opening')
362 sidebar.classList.remove('gone')
363 sidebarCloseBackdrop.classList.remove('gone')
364 sidebarCloseBackdrop.addEventListener('click', closeSidebar)
365 }
366
367 sidebarToggle.addEventListener('click', e => {
368 console.log('toggling', sidebar.classList, sidebar.classList.contains('gone'))
369 if (sidebar.classList.contains('gone')) openSidebar()
370 else closeSidebar()
371 })
372 sidebarClose.addEventListener('click', closeSidebar)
373 sidebarCloseBackdrop.addEventListener('click', closeSidebar)
374
375 setTimeout(() => {
376 componentRoot.classList.add('waited')
377 }, 1000)
378
379 const selectionArea = componentArea.getElementById('sidebar-inner')
380 this.ssbConnect().then(sbot => {
381
382 if (componentArea.getElementById('connecting')) componentArea.getElementById('connecting').classList.add('hidden')
383 if (componentArea.getElementById('info')) componentArea.getElementById('info').classList.remove('hidden')
384
385 const selector = document.createElement('app-selector')
386 selector.sbot = sbot
387 selector.addEventListener('run', run)
388 selector.addEventListener('show-source', showSource)
389 selectionArea.appendChild(selector)
390
391 const statusBar = componentArea.getElementById('status')
392
393 const view = componentArea.getElementById('view')
394 //const shadowView = view.attachShadow({ mode: 'closed' });
395 //const shadowHtml = componentArea.createElement('html')
396 //shadowView.appendChild(shadowHtml)
397
398 function run(event) {
399 const app = event.detail
400 componentArea.getElementById('info').classList.add('hidden')
401 componentArea.getElementById('title-ext').innerHTML = app.name
402 statusBar.classList.remove('hidden')
403 statusBar.innerText = 'Loading ' + app.name
404 view.innerHTML = ''
405 const appRunner = document.createElement('app-runner')
406 appRunner.sbot = sbot
407 appRunner.app = app
408 view.appendChild(appRunner)
409
410 appRunner.addEventListener('loaded', e => {
411 statusBar.classList.add('hidden')
412 })
413 }
414
415 function showSource(event) {
416 const app = event.detail
417 console.log('showSource', app)
418 const outer = document.createElement('div')
419 outer.id = 'outer'
420 const oldTop = window.scrollY
421 const oldLeft = window.scrollX
422 window.scroll(0, 0)
423 componentRoot.classList.add('modal-open')
424 componentArea.appendChild(outer)
425 //const inner = document.createElement('div')
426 const sourceViewer = document.createElement('source-viewer')
427 sourceViewer.id = 'inner'
428 sourceViewer.app = app
429 sourceViewer.sbot = sbot
430 sourceViewer.name = app.name || app.comment || ''
431 outer.appendChild(sourceViewer)
432 const close = () => {
433 componentArea.removeChild(outer)
434 componentRoot.classList.remove('modal-open')
435 window.scroll(oldLeft, oldTop)
436 }
437 outer.addEventListener('click', close)
438 sourceViewer.addEventListener('close', close)
439 sourceViewer.addEventListener('click', e => e.stopPropagation())
440 }
441 },
442 error => {
443 console.log('An error occured', error)
444 })
445
446 }
447
448
449}
450
451customElements.define('patch-boot', PatchBoot)

Built with git-ssb-web