A music player that connects to your cloud/distributed storage.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4 131 lines 3.7 kB view raw
1import { computed } from "~/common/signal.js"; 2import { OutputTransformer } from "../../base.js"; 3import { defineElement } from "~/common/element.js"; 4 5/** 6 * @import { OutputManagerDeputy } from "~/components/output/types.d.ts" 7 * @import { Facet, PlaylistItem, Setting, Track } from "~/definitions/types.d.ts" 8 */ 9 10/** 11 * @extends {OutputTransformer<Uint8Array>} 12 */ 13class JsonStringOutputTransformer extends OutputTransformer { 14 constructor() { 15 super(); 16 17 const base = this.base(); 18 19 /** @type {OutputManagerDeputy} */ 20 const manager = { 21 facets: { 22 ...base.facets, 23 collection: computed(() => { 24 const col = base.facets.collection(); 25 if (col.state !== "loaded") return col; 26 /** @type {Facet[]} */ 27 const data = parseArray(col.data); 28 return { state: "loaded", data }; 29 }), 30 save: async (newFacets) => { 31 const json = JSON.stringify(newFacets); 32 const encoder = new TextEncoder(); 33 const bytes = encoder.encode(json); 34 await base.facets.save(bytes); 35 }, 36 }, 37 playlistItems: { 38 ...base.playlistItems, 39 collection: computed(() => { 40 const col = base.playlistItems.collection(); 41 if (col.state !== "loaded") return col; 42 /** @type {PlaylistItem[]} */ 43 const data = parseArray(col.data); 44 return { state: "loaded", data }; 45 }), 46 save: async (newPlaylistItems) => { 47 const json = JSON.stringify(newPlaylistItems); 48 const encoder = new TextEncoder(); 49 const bytes = encoder.encode(json); 50 await base.playlistItems.save(bytes); 51 }, 52 }, 53 settings: { 54 ...base.settings, 55 collection: computed(() => { 56 const col = base.settings.collection(); 57 if (col.state !== "loaded") return col; 58 /** @type {Setting[]} */ 59 const data = parseArray(col.data); 60 return { state: "loaded", data }; 61 }), 62 save: async (newSettings) => { 63 const json = JSON.stringify(newSettings); 64 const encoder = new TextEncoder(); 65 const bytes = encoder.encode(json); 66 await base.settings.save(bytes); 67 }, 68 }, 69 tracks: { 70 ...base.tracks, 71 collection: computed(() => { 72 const col = base.tracks.collection(); 73 if (col.state !== "loaded") return col; 74 /** @type {Track[]} */ 75 const data = parseArray(col.data); 76 return { state: "loaded", data }; 77 }), 78 save: async (newTracks) => { 79 const json = JSON.stringify(newTracks); 80 const encoder = new TextEncoder(); 81 const bytes = encoder.encode(json); 82 await base.tracks.save(bytes); 83 }, 84 }, 85 86 // Other 87 ready: base.ready, 88 }; 89 90 // Assign manager properties to class 91 this.facets = manager.facets; 92 this.playlistItems = manager.playlistItems; 93 this.settings = manager.settings; 94 this.tracks = manager.tracks; 95 this.ready = manager.ready; 96 } 97} 98 99/** 100 * @param {Uint8Array | string | undefined} data 101 */ 102function parseArray(data) { 103 let json; 104 105 if (data instanceof Uint8Array) { 106 const decoder = new TextDecoder(); 107 json = decoder.decode(data); 108 } else if (data === undefined) { 109 return []; 110 } else { 111 json = data; 112 } 113 114 try { 115 return JSON.parse(json); 116 } catch (err) { 117 console.error(err); 118 return []; 119 } 120} 121 122export default JsonStringOutputTransformer; 123 124//////////////////////////////////////////// 125// REGISTER 126//////////////////////////////////////////// 127 128export const CLASS = JsonStringOutputTransformer; 129export const NAME = "dtob-json"; 130 131defineElement(NAME, CLASS);