A music player that connects to your cloud/distributed storage.
1import { defineElement, DiffuseElement } from "~/common/element.js";
2import { DEFAULT_APP_KEY, SCHEME } from "./constants.js";
3import { accountsFromTracks, buildURI } from "./common.js";
4
5/**
6 * @import {InputActions, InputSchemeProvider} from "~/components/input/types.d.ts"
7 * @import {ProxiedActions} from "~/common/worker.d.ts"
8 * @import {Track} from "~/definitions/types.d.ts"
9 */
10
11////////////////////////////////////////////
12// ELEMENT
13////////////////////////////////////////////
14
15/**
16 * @implements {ProxiedActions<InputActions>}
17 * @implements {InputSchemeProvider}
18 */
19class DropboxInput extends DiffuseElement {
20 static NAME = "diffuse/input/dropbox";
21 static WORKER_URL = "components/input/dropbox/worker.js";
22
23 SCHEME = SCHEME;
24
25 /** @type {string} */
26 appKey = DEFAULT_APP_KEY;
27
28 static observedAttributes = ["app-key"];
29
30 /**
31 * @override
32 * @param {string} name
33 * @param {string} old
34 * @param {string} next
35 */
36 attributeChangedCallback(name, old, next) {
37 super.attributeChangedCallback(name, old, next);
38 if (name === "app-key" && next !== null) this.appKey = next;
39 }
40
41 constructor() {
42 super();
43
44 /** @type {ProxiedActions<InputActions>} */
45 this.proxy = this.workerProxy();
46
47 this.artwork = this.proxy.artwork;
48 this.consult = this.proxy.consult;
49 this.detach = this.proxy.detach;
50 this.groupConsult = this.proxy.groupConsult;
51 this.list = this.proxy.list;
52 this.resolve = this.proxy.resolve;
53 }
54
55 // 🛠️
56
57 authorize() {
58 localStorage.setItem("oauth/callback/redirect_path", location.pathname + location.search);
59
60 const params = new URLSearchParams({
61 response_type: "token",
62 client_id: this.appKey,
63 redirect_uri: location.origin + "/oauth/callback/",
64 });
65
66 location.assign(`https://www.dropbox.com/oauth2/authorize?${params}`);
67 }
68
69 /** @param {Track[]} tracks */
70 sources(tracks) {
71 return Object.values(accountsFromTracks(tracks)).map((account) => ({
72 label: `Dropbox (${account.directoryPath})`,
73 uri: buildURI(account),
74 }));
75 }
76}
77
78export default DropboxInput;
79
80////////////////////////////////////////////
81// REGISTER
82////////////////////////////////////////////
83
84export const CLASS = DropboxInput;
85export const NAME = "di-dropbox";
86
87defineElement(NAME, CLASS);