Canonical repo for Dong Web (dong.vielle.dev)
0
fork

Configure Feed

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

add dong reading

+79 -6
+79 -6
src/pages/index.astro
··· 4 4 5 5 <Base title="Dong Web"> 6 6 <script> 7 - import { ViewTransitions } from "astro:transitions"; 7 + declare global { 8 + interface Uint8Array { 9 + toBase64(): string; 10 + } 11 + } 8 12 9 13 class CreateDong extends HTMLElement { 10 14 connectedCallback() { ··· 31 35 32 36 // functionality 33 37 createButton.addEventListener("click", async (e) => { 34 - // dont refresh 38 + // don't refresh 35 39 e.preventDefault(); 36 40 // quit early if no files 37 41 if ( ··· 73 77 (() => { 74 78 const value = new Uint32Array(1); 75 79 value[0] = image.size; 80 + console.log("image size: ", image.size, value); 76 81 return value; 77 82 })(), 78 83 // audio type ··· 83 88 (() => { 84 89 const value = new Uint32Array(1); 85 90 value[0] = audio.size; 91 + console.log("audio size: ", audio.size, value); 86 92 return value; 87 93 })(), 88 94 // image data ··· 124 130 const form = document.createElement("form"); 125 131 const dongSelect = document.createElement("input"); 126 132 const loadButton = document.createElement("button"); 127 - // canvas 128 - const canvas = document.createElement("canvas"); 133 + // image 134 + const image = document.createElement("img"); 129 135 130 136 dongSelect.type = "file"; 131 137 dongSelect.accept = ".dong"; 132 138 loadButton.type = "submit"; 133 139 loadButton.textContent = "Load"; 140 + image.width = 256; 141 + image.height = 256; 134 142 135 143 form.appendChild(dongSelect); 136 144 form.appendChild(loadButton); 137 145 138 146 shadow.appendChild(form); 139 - shadow.appendChild(canvas); 147 + shadow.appendChild(image); 140 148 141 149 const sheet = new CSSStyleSheet(); 142 150 sheet.replaceSync(` 143 - canvas { 151 + image { 144 152 border: 1px solid white; 145 153 } 146 154 `); 147 155 148 156 shadow.adoptedStyleSheets = [sheet]; 157 + 158 + // functionality 159 + loadButton.addEventListener("click", async (e) => { 160 + // don't refresh 161 + e.preventDefault(); 162 + // quit early if no files 163 + if (!dongSelect.files || dongSelect.files.length === 0) 164 + return console.warn("No files selected"); 165 + 166 + // get files 167 + const dongFile = dongSelect.files[0]; 168 + 169 + console.log(dongFile, dongFile.size); //, await dongFile.bytes()); 170 + 171 + // get first 2 bytes and verify 172 + const version = new Uint8Array(await dongFile.slice(0, 2).bytes()); 173 + if (version[0] !== 0xd0 || version[1] !== 2) 174 + return console.warn("Invalid file"); 175 + 176 + // get next 256 bytes and get mime type 177 + const imgMimeType: string | undefined = ( 178 + await dongFile.slice(2, 258).text() 179 + ).match(/[a-zA-Z0-9.]+\/[a-zA-Z0-9.]+/gm)?.[0]; 180 + if (!imgMimeType) return console.warn("Image mime type parse failed"); 181 + 182 + // get next 4 bytes and get image size 183 + const imgSize = new Uint32Array( 184 + (await dongFile.slice(258, 262).bytes()).buffer 185 + )[0]; 186 + 187 + // get next 256 bytes and get mime type 188 + const audMimeType: string | undefined = ( 189 + await dongFile.slice(262, 518).text() 190 + ).match(/[a-zA-Z0-9.]+\/[a-zA-Z0-9.]+/gm)?.[0]; 191 + if (!audMimeType) return console.warn("Audio mime type parse failed"); 192 + 193 + // get next 4 bytes and get image size 194 + const audSize = new Uint32Array( 195 + (await dongFile.slice(518, 522).bytes()).buffer 196 + )[0]; 197 + 198 + const imageBytes = await dongFile.slice(522, 522 + imgSize).bytes(); 199 + const audioBytes = await dongFile 200 + .slice(522 + imgSize, 522 + imgSize + audSize) 201 + .bytes(); 202 + 203 + image.src = `data:${imgMimeType};base64,${imageBytes.toBase64()}`; 204 + 205 + // audio play 206 + const audio = document.createElement("audio"); 207 + audio.src = `data:${audMimeType};base64,${audioBytes.toBase64()}`; 208 + audio.play(); 209 + 210 + console.log( 211 + imgMimeType, 212 + audMimeType, 213 + imgSize, 214 + audSize, 215 + imageBytes, 216 + audioBytes, 217 + btoa(String.fromCharCode(...imageBytes)), 218 + image, 219 + shadow 220 + ); 221 + }); 149 222 } 150 223 } 151 224