tangled
alpha
login
or
join now
tokono.ma
/
diffuse
5
fork
atom
A music player that connects to your cloud/distributed storage.
5
fork
atom
overview
issues
4
pulls
pipelines
feat: relative urls pls
Steven Vandevelde
4 months ago
bfa3e774
ac32c32e
+53
-31
13 changed files
expand all
collapse all
unified
split
src
_includes
layouts
diffuse.vto
components
input
opensubsonic
element.js
orchestrator
process-tracks
element.js
output
polymorphic
indexed-db
element.js
processor
metadata
element.js
search
element.js
transformer
output
string
json
element.js
favicons
browserconfig.xml
index.vto
themes
webamp
browser
element.js
index.css
index.vto
window
element.js
+3
-3
src/_includes/layouts/diffuse.vto
···
13
<title>{{title}}</title>
14
15
<!-- Favicons & Mobile -->
16
-
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
17
-
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
18
-
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
19
<!-- TODO: <link rel="manifest" href="site.webmanifest" />-->
20
<link rel="mask-icon" href="safari-pinned-tab.svg" color="#8a90a9" />
21
<meta name="msapplication-TileColor" content="#8a90a9" />
···
13
<title>{{title}}</title>
14
15
<!-- Favicons & Mobile -->
16
+
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png" />
17
+
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png" />
18
+
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png" />
19
<!-- TODO: <link rel="manifest" href="site.webmanifest" />-->
20
<link rel="mask-icon" href="safari-pinned-tab.svg" color="#8a90a9" />
21
<meta name="msapplication-TileColor" content="#8a90a9" />
+3
-1
src/components/input/opensubsonic/element.js
···
49
*/
50
worker(group) {
51
const name = `diffuse/input/opensubsonic/${group || crypto.randomUUID()}`;
52
-
const url = "/components/input/opensubsonic/worker.js";
0
0
53
54
return new Worker(url, { name, type: "module" });
55
}
···
49
*/
50
worker(group) {
51
const name = `diffuse/input/opensubsonic/${group || crypto.randomUUID()}`;
52
+
const url = import.meta.resolve(
53
+
"./components/input/opensubsonic/worker.js",
54
+
);
55
56
return new Worker(url, { name, type: "module" });
57
}
+12
-7
src/components/orchestrator/process-tracks/element.js
···
25
26
// Setup worker
27
const name = `diffuse/orchestrator/process-tracks/${this.group}`;
28
-
const url = "/components/orchestrator/process-tracks/worker.js";
0
0
0
29
const worker = new Worker(url, { name, type: "module" });
30
31
/** @type {InputElement} */
···
38
this.metadataProcessor = query(this, "metadata-processor-selector");
39
40
// Create new workers specially for track processing
41
-
this.#external = {
0
0
0
42
input: portProvider(this.input.worker()),
43
metadataProcessor: portProvider(this.metadataProcessor.worker()),
44
-
};
45
46
// Worker proxy
47
this.#process = use("process", worker, {
···
81
// ACTIONS
82
83
async process() {
84
-
await customElements.whenDefined(this.input.localName);
85
-
await customElements.whenDefined(this.metadataProcessor.localName);
86
87
// Start
88
this.#isProcessing.value = true;
···
92
93
// Establish channel between external workers and our processing worker
94
const ports = {
95
-
input: this.#external.input(),
96
-
metadataProcessor: this.#external.metadataProcessor(),
97
};
98
99
// Send everything to worker
···
25
26
// Setup worker
27
const name = `diffuse/orchestrator/process-tracks/${this.group}`;
28
+
const url = import.meta.resolve(
29
+
"./components/orchestrator/process-tracks/worker.js",
30
+
);
31
+
32
const worker = new Worker(url, { name, type: "module" });
33
34
/** @type {InputElement} */
···
41
this.metadataProcessor = query(this, "metadata-processor-selector");
42
43
// Create new workers specially for track processing
44
+
this.#external = Promise.all([
45
+
customElements.whenDefined(this.input.localName),
46
+
customElements.whenDefined(this.metadataProcessor.localName),
47
+
]).then(() => ({
48
input: portProvider(this.input.worker()),
49
metadataProcessor: portProvider(this.metadataProcessor.worker()),
50
+
}));
51
52
// Worker proxy
53
this.#process = use("process", worker, {
···
87
// ACTIONS
88
89
async process() {
90
+
const ext = await this.#external;
0
91
92
// Start
93
this.#isProcessing.value = true;
···
97
98
// Establish channel between external workers and our processing worker
99
const ports = {
100
+
input: ext.input(),
101
+
metadataProcessor: ext.metadataProcessor(),
102
};
103
104
// Send everything to worker
+4
-1
src/components/output/polymorphic/indexed-db/element.js
···
19
20
// Setup worker
21
const name = `diffuse/output/polymorphic/indexed-db/${this.group}`;
22
-
const url = "/components/output/polymorphic/indexed-db/worker.js";
0
0
0
23
const worker = new Worker(url, { name, type: "module" });
24
25
// Manager
···
19
20
// Setup worker
21
const name = `diffuse/output/polymorphic/indexed-db/${this.group}`;
22
+
const url = import.meta.resolve(
23
+
"./components/output/polymorphic/indexed-db/worker.js",
24
+
);
25
+
26
const worker = new Worker(url, { name, type: "module" });
27
28
// Manager
+4
-1
src/components/processor/metadata/element.js
···
34
*/
35
worker(group) {
36
const name = `diffuse/processor/metadata/${group || crypto.randomUUID()}`;
37
-
const url = "/components/processor/metadata/worker.js";
0
0
0
38
return new Worker(url, { name, type: "module" });
39
}
40
}
···
34
*/
35
worker(group) {
36
const name = `diffuse/processor/metadata/${group || crypto.randomUUID()}`;
37
+
const url = import.meta.resolve(
38
+
"./components/processor/metadata/worker.js",
39
+
);
40
+
41
return new Worker(url, { name, type: "module" });
42
}
43
}
+3
-1
src/components/processor/search/element.js
···
18
19
// Setup worker
20
const name = `diffuse/processor/search/${this.group}`;
21
-
const url = "/components/processor/search/worker.js";
0
0
22
23
let port;
24
···
18
19
// Setup worker
20
const name = `diffuse/processor/search/${this.group}`;
21
+
const url = import.meta.resolve(
22
+
"./components/processor/search/worker.js",
23
+
);
24
25
let port;
26
+10
-3
src/components/transformer/output/string/json/element.js
···
1
import { DiffuseElement, query } from "@common/element.js";
2
-
import { computed } from "@common/signal.js";
3
4
/**
5
* @import { OutputElement, OutputManager } from "../../../../output/types.d.ts"
···
13
/** @type {OutputElement<string>} */
14
this.output = query(this, "output-selector");
15
0
0
0
0
0
0
0
16
/** @type {OutputManager<Track[]>} */
17
const manager = {
18
tracks: {
19
collection: computed(() => {
20
-
const json = this.output.tracks?.collection() || [];
21
22
// In addition to the above, Some polymorphic outputs
23
// use an empty array as the default return value.
···
40
await customElements.whenDefined(this.output.localName);
41
await this.output.tracks.save(json);
42
},
43
-
state: () => this.output.tracks.state(),
44
},
45
};
46
···
1
import { DiffuseElement, query } from "@common/element.js";
2
+
import { computed, signal } from "@common/signal.js";
3
4
/**
5
* @import { OutputElement, OutputManager } from "../../../../output/types.d.ts"
···
13
/** @type {OutputElement<string>} */
14
this.output = query(this, "output-selector");
15
16
+
// whenDefined signal
17
+
const $defined = signal(false);
18
+
19
+
customElements.whenDefined(this.output.localName).then(
20
+
() => $defined.value = true,
21
+
);
22
+
23
/** @type {OutputManager<Track[]>} */
24
const manager = {
25
tracks: {
26
collection: computed(() => {
27
+
const json = $defined.value ? this.output.tracks?.collection() : [];
28
29
// In addition to the above, Some polymorphic outputs
30
// use an empty array as the default return value.
···
47
await customElements.whenDefined(this.output.localName);
48
await this.output.tracks.save(json);
49
},
50
+
state: computed(() => this.output.tracks.state()),
51
},
52
};
53
+1
-1
src/favicons/browserconfig.xml
···
2
<browserconfig>
3
<msapplication>
4
<tile>
5
-
<square150x150logo src="/mstile-150x150.png"/>
6
<TileColor>#8a90a9</TileColor>
7
</tile>
8
</msapplication>
···
2
<browserconfig>
3
<msapplication>
4
<tile>
5
+
<square150x150logo src="mstile-150x150.png"/>
6
<TileColor>#8a90a9</TileColor>
7
</tile>
8
</msapplication>
+2
-2
src/index.vto
···
119
<svg viewBox="0 0 902 134" width="160">
120
<title>Diffuse</title>
121
<use
122
-
xlink:href="/images/diffuse-current.svg#diffuse"
123
-
href="/images/diffuse-current.svg#diffuse"></use>
124
</svg>
125
</h1>
126
<p>
···
119
<svg viewBox="0 0 902 134" width="160">
120
<title>Diffuse</title>
121
<use
122
+
xlink:href="images/diffuse-current.svg#diffuse"
123
+
href="images/diffuse-current.svg#diffuse"></use>
124
</svg>
125
</h1>
126
<p>
+1
-1
src/themes/webamp/browser/element.js
···
80
const tracks = this.output.tracks?.collection() || [];
81
82
return html`
83
-
<link rel="stylesheet" href="/styles/vendor/98.css" />
84
85
<style>
86
@import "./98-vars.css";
···
80
const tracks = this.output.tracks?.collection() || [];
81
82
return html`
83
+
<link rel="stylesheet" href="../../styles/vendor/98.css" />
84
85
<style>
86
@import "./98-vars.css";
+2
-2
src/themes/webamp/index.css
···
4
5
@font-face {
6
font-family: "Pixelated MS Sans Serif";
7
-
src: url("/fonts/ms_sans_serif.woff2") format("woff2");
8
font-weight: normal;
9
font-style: normal;
10
}
11
12
@font-face {
13
font-family: "Pixelated MS Sans Serif";
14
-
src: url("/fonts/ms_sans_serif_bold.woff2") format("woff2");
15
font-weight: 700;
16
font-style: normal;
17
}
···
4
5
@font-face {
6
font-family: "Pixelated MS Sans Serif";
7
+
src: url("../../fonts/ms_sans_serif.woff2") format("woff2");
8
font-weight: normal;
9
font-style: normal;
10
}
11
12
@font-face {
13
font-family: "Pixelated MS Sans Serif";
14
+
src: url("../../fonts/ms_sans_serif_bold.woff2") format("woff2");
15
font-weight: 700;
16
font-style: normal;
17
}
+7
-7
src/themes/webamp/index.vto
···
18
<dtw-window-manager>
19
<!-- INPUT -->
20
<dtw-window id="input-window">
21
-
<span slot="title-icon"><img src="/images/icons/windows_98/cd_audio_cd_a-0.png" height="14" /></span>
22
<span slot="title">Manage audio inputs</span>
23
<p>👀</p>
24
</dtw-window>
25
26
<!-- OUTPUT -->
27
<dtw-window id="output-window">
28
-
<span slot="title-icon"><img src="/images/icons/windows_98/computer_user_pencil-0.png" height="14" /></span>
29
<span slot="title">Manage user data</span>
30
<p>👀</p>
31
</dtw-window>
32
33
<!-- BROWSER -->
34
<dtw-window id="browser-window" open>
35
-
<span slot="title-icon"><img src="/images/icons/windows_98/directory_explorer-4.png" height="14" /></span>
36
<span slot="title">Browse collection</span>
37
<dtw-browser
38
input-selector="di-opensubsonic"
···
45
<section class="desktop">
46
<!-- WINAMP -->
47
<a class="button desktop__item" id="desktop-winamp">
48
-
<img src="/images/icons/windows_98/winamp2-32x32.png" height="32" />
49
<label>Winamp</label>
50
</a>
51
52
<!-- INPUT -->
53
<a class="button desktop__item">
54
-
<img src="/images/icons/windows_98/cd_audio_cd_a-4.png" height="32" />
55
<label for="input-window">Manage audio inputs</label>
56
</a>
57
58
<!-- OUTPUT -->
59
<a class="button desktop__item">
60
-
<img src="/images/icons/windows_98/computer_user_pencil-0.png" height="32" />
61
<label for="output-window">Manage user data</label>
62
</a>
63
64
<!-- BROWSE -->
65
<a class="button desktop__item">
66
-
<img src="/images/icons/windows_98/directory_explorer-5.png" height="32" />
67
<label for="browser-window">Browse collection</label>
68
</a>
69
</section>
···
18
<dtw-window-manager>
19
<!-- INPUT -->
20
<dtw-window id="input-window">
21
+
<span slot="title-icon"><img src="../../images/icons/windows_98/cd_audio_cd_a-0.png" height="14" /></span>
22
<span slot="title">Manage audio inputs</span>
23
<p>👀</p>
24
</dtw-window>
25
26
<!-- OUTPUT -->
27
<dtw-window id="output-window">
28
+
<span slot="title-icon"><img src="../../images/icons/windows_98/computer_user_pencil-0.png" height="14" /></span>
29
<span slot="title">Manage user data</span>
30
<p>👀</p>
31
</dtw-window>
32
33
<!-- BROWSER -->
34
<dtw-window id="browser-window" open>
35
+
<span slot="title-icon"><img src="../../images/icons/windows_98/directory_explorer-4.png" height="14" /></span>
36
<span slot="title">Browse collection</span>
37
<dtw-browser
38
input-selector="di-opensubsonic"
···
45
<section class="desktop">
46
<!-- WINAMP -->
47
<a class="button desktop__item" id="desktop-winamp">
48
+
<img src="../../images/icons/windows_98/winamp2-32x32.png" height="32" />
49
<label>Winamp</label>
50
</a>
51
52
<!-- INPUT -->
53
<a class="button desktop__item">
54
+
<img src="../../images/icons/windows_98/cd_audio_cd_a-4.png" height="32" />
55
<label for="input-window">Manage audio inputs</label>
56
</a>
57
58
<!-- OUTPUT -->
59
<a class="button desktop__item">
60
+
<img src="../../images/icons/windows_98/computer_user_pencil-0.png" height="32" />
61
<label for="output-window">Manage user data</label>
62
</a>
63
64
<!-- BROWSE -->
65
<a class="button desktop__item">
66
+
<img src="../../images/icons/windows_98/directory_explorer-5.png" height="32" />
67
<label for="browser-window">Browse collection</label>
68
</a>
69
</section>
+1
-1
src/themes/webamp/window/element.js
···
35
*/
36
render({ html }) {
37
return html`
38
-
<link rel="stylesheet" href="/styles/vendor/98.css" />
39
40
<style>
41
dialog {
···
35
*/
36
render({ html }) {
37
return html`
38
+
<link rel="stylesheet" href="../../styles/vendor/98.css" />
39
40
<style>
41
dialog {