Skip to content
This repository was archived by the owner on Dec 27, 2022. It is now read-only.

Commit aa622e8

Browse files
committed
Add missing file commit (drive-view/index.js)
1 parent 45551cc commit aa622e8

1 file changed

Lines changed: 215 additions & 0 deletions

File tree

app/userland/drive-view/index.js

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
import { LitElement, html, css } from 'beaker://app-stdlib/vendor/lit-element/lit-element.js'
2+
import { repeat } from 'beaker://app-stdlib/vendor/lit-element/lit-html/directives/repeat.js'
3+
4+
class DriveView extends LitElement {
5+
static get styles () {
6+
return css`
7+
:host {
8+
--sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Ubuntu, Cantarell, "Oxygen Sans", "Helvetica Neue", sans-serif;
9+
--monospace: Consolas, 'Lucida Console', Monaco, monospace;
10+
11+
display: block;
12+
max-width: 800px;
13+
margin: 0 auto;
14+
padding: 0 30px;
15+
min-height: calc(100vh - 20px);
16+
font-family: var(--sans-serif);
17+
}
18+
19+
a {
20+
text-decoration: none;
21+
color: #2864dc;
22+
}
23+
24+
a:hover {
25+
text-decoration: underline;
26+
}
27+
28+
hr {
29+
border: 0;
30+
border-top: 1px solid #dde;
31+
}
32+
33+
header {
34+
padding: 20px 0 20px;
35+
}
36+
37+
header h1,
38+
header p {
39+
margin: 0 0 10px;
40+
line-height: 1;
41+
}
42+
43+
header h1 {
44+
letter-spacing: 0.75px;
45+
}
46+
47+
header p {
48+
font-size: 13px;
49+
letter-spacing: 0.25px;
50+
color: #556;
51+
}
52+
53+
header img {
54+
object-fit: cover;
55+
border-radius: 4px;
56+
height: 25px;
57+
width: 26px;
58+
position: relative;
59+
top: 1px;
60+
}
61+
62+
header .ctrls {
63+
float: right;
64+
font-size: 14px;
65+
}
66+
67+
main h4 {
68+
font-family: var(--monospace);
69+
margin: 0;
70+
font-size: 13px;
71+
letter-spacing: 0.75px;
72+
background: #f3f3f8;
73+
border-radius: 4px;
74+
padding: 4px 8px;
75+
}
76+
77+
.entries {
78+
display: grid;
79+
grid-template-columns: repeat(4, minmax(0, 1fr));
80+
grid-gap: 20px;
81+
margin: 20px 0;
82+
font-size: 14px;
83+
letter-spacing: 0.75px;
84+
}
85+
86+
.entries > div {
87+
white-space: nowrap;
88+
overflow: hidden;
89+
text-overflow: ellipsis;
90+
}
91+
92+
.entries .fa-fw {
93+
color: #556;
94+
}
95+
96+
.prompt {
97+
margin: 30px 0;
98+
font-size: 13px;
99+
border: 1px solid #dde;
100+
padding: 10px;
101+
border-radius: 4px;
102+
}
103+
`
104+
}
105+
106+
constructor () {
107+
super()
108+
this.drive = new Hyperdrive(location)
109+
this.info = undefined
110+
this.entries = []
111+
this.load()
112+
}
113+
114+
async load () {
115+
this.info = await this.drive.getInfo()
116+
var entries = await this.drive.readdir(location.pathname, {includeStats: true})
117+
entries.sort((a, b) => {
118+
return a.name.localeCompare(b.name)
119+
})
120+
this.directories = entries.filter(entry => entry.stat.isDirectory())
121+
this.files = entries.filter(entry => !entry.stat.isDirectory())
122+
this.requestUpdate()
123+
}
124+
125+
render () {
126+
if (!this.info) return html``
127+
return html`
128+
<link rel="stylesheet" href="beaker://app-stdlib/css/fontawesome.css">
129+
<header>
130+
<div class="ctrls">
131+
<span class="fas fa-fw fa-folder"></span>
132+
<a href="http://hyperdrive.network/${location.hostname}${location.pathname}" target="_blank">Open in files explorer</a>
133+
&nbsp;
134+
<span class="fas fa-fw fa-list-alt"></span>
135+
<a href="#" @click=${this.onClickEditProperties}>Properties</a>
136+
</div>
137+
<h1>
138+
<img src="/thumb" @error=${e => {e.currentTarget.style.display = 'none'}}>
139+
${this.info.title}
140+
</h1>
141+
<p class="description">${this.info.description || html`<em>No description</em>`}</p>
142+
<p class="type">${this.info.type || 'files drive'}</p>
143+
</header>
144+
<main>
145+
<h4>${location.pathname}</h4>
146+
<div class="entries">
147+
${location.pathname !== '/' ? html`
148+
<div>
149+
<span class="fa-fw far fa-folder"></span>
150+
<a href=".." title="Go up a directory">..</a>
151+
</div>
152+
` : ''}
153+
${repeat(this.directories, entry => this.renderEntry(entry))}
154+
${repeat(this.files, entry => this.renderEntry(entry))}
155+
</div>
156+
${this.info.writable ? html`
157+
<div class="prompt">
158+
<strong>Advanced:</strong> Create an <a @click=${e => this.onCreateIndex(e, 'md')} href="#">index.md</a>
159+
or <a @click=${e => this.onCreateIndex(e, 'html')} href="#">index.html</a> in this directory.
160+
</div>
161+
` : ''}
162+
</main>
163+
`
164+
}
165+
166+
renderEntry (entry) {
167+
if (entry.stat.mount && entry.stat.mount.key) {
168+
return html`
169+
<div>
170+
<span class="fa-fw fas fa-external-link-square-alt"></span>
171+
<a href="hd://${entry.stat.mount.key}" title=${entry.name}>
172+
${entry.name}
173+
</a>
174+
</div>
175+
`
176+
}
177+
return html`
178+
<div>
179+
<span class="fa-fw far fa-${entry.stat.isDirectory() ? 'folder' : 'file-alt'}"></span>
180+
<a href="./${entry.name}${entry.stat.isDirectory() ? '/' : ''}" title=${entry.name}>
181+
${entry.name}
182+
</a>
183+
</div>
184+
`
185+
}
186+
187+
async onClickEditProperties (e) {
188+
e.preventDefault()
189+
await navigator.drivePropertiesDialog(location.origin)
190+
this.load()
191+
}
192+
193+
async onCreateIndex (e, ext) {
194+
e.preventDefault()
195+
var title = location.pathname === '/' ? this.info.title : location.pathname.split('/').filter(Boolean).pop()
196+
if (ext === 'md') {
197+
await this.drive.writeFile(location.pathname + 'index.md', `# ${title}`)
198+
} else {
199+
await this.drive.writeFile(location.pathname + 'index.html', `<!doctype html>
200+
<html>
201+
<head>
202+
<title>${title}</title>
203+
</head>
204+
<body>
205+
</body>
206+
</html>`)
207+
}
208+
// TEMPORARY API please do not depend on this in your applications
209+
window.__beakerOpenEditor()
210+
location.reload()
211+
}
212+
}
213+
214+
customElements.define('drive-view', DriveView)
215+
document.body.append(new DriveView())

0 commit comments

Comments
 (0)