|  | 
|  | 1 | +package io.udash.utils | 
|  | 2 | + | 
|  | 3 | +import java.io.IOException | 
|  | 4 | + | 
|  | 5 | +import org.scalajs.dom._ | 
|  | 6 | +import org.scalajs.dom.html.Anchor | 
|  | 7 | +import scalatags.JsDom | 
|  | 8 | + | 
|  | 9 | +import scala.scalajs.js | 
|  | 10 | +import scala.concurrent.{Future, Promise} | 
|  | 11 | +import scala.util.Try | 
|  | 12 | + | 
|  | 13 | +object FileService { | 
|  | 14 | + | 
|  | 15 | + final val OctetStreamType = "application/octet-stream" | 
|  | 16 | + | 
|  | 17 | + /** | 
|  | 18 | + * Converts specified bytes array to string that contains URL | 
|  | 19 | + * that representing the array given in the parameter with optionally specified mime-type. | 
|  | 20 | + * | 
|  | 21 | + * Keep in mind that returned URL should be revoked via `org.scalajs.dom.revokeObjectURL(url)`. | 
|  | 22 | + */ | 
|  | 23 | + def bytesAsURL(bytes: Array[Byte], mimeType: String = OctetStreamType): String = { | 
|  | 24 | + import js.typedarray._ | 
|  | 25 | + | 
|  | 26 | + val jsBytes = js.Array[js.Any](bytes.toTypedArray) | 
|  | 27 | + val blob = new Blob(jsBytes, BlobPropertyBag(mimeType)) | 
|  | 28 | + URL.createObjectURL(blob) | 
|  | 29 | + } | 
|  | 30 | + | 
|  | 31 | + /** | 
|  | 32 | + * Create an anchor element that on click downloads byte array as a file with specified name. | 
|  | 33 | + * | 
|  | 34 | + * Keep in mind that anchor's href URL should be revoked via `org.scalajs.dom.revokeObjectURL(url)`. | 
|  | 35 | + */ | 
|  | 36 | + def save(filename: String, bytes: Array[Byte], mimeType: String = OctetStreamType): JsDom.TypedTag[Anchor] = { | 
|  | 37 | + import JsDom.all._ | 
|  | 38 | + | 
|  | 39 | + val download = attr("download") | 
|  | 40 | + a(href := bytesAsURL(bytes, mimeType), download := filename) | 
|  | 41 | + } | 
|  | 42 | + | 
|  | 43 | + /** | 
|  | 44 | + * Asynchronously convert specified file to bytes array. | 
|  | 45 | + */ | 
|  | 46 | + def load(file: File): Future[Array[Byte]] = { | 
|  | 47 | + import js.typedarray._ | 
|  | 48 | + | 
|  | 49 | + val fileReader = new FileReader() | 
|  | 50 | + val promise = Promise[Array[Byte]]() | 
|  | 51 | + | 
|  | 52 | + fileReader.onerror = (e: Event) => | 
|  | 53 | + promise.failure(new IOException(e.toString)) | 
|  | 54 | + | 
|  | 55 | + fileReader.onabort = (e: Event) => | 
|  | 56 | + promise.failure(new IOException(e.toString)) | 
|  | 57 | + | 
|  | 58 | + fileReader.onload = (_: UIEvent) => | 
|  | 59 | + promise.complete(Try( | 
|  | 60 | + new Int8Array(fileReader.result.asInstanceOf[ArrayBuffer]).toArray | 
|  | 61 | + )) | 
|  | 62 | + | 
|  | 63 | + fileReader.readAsArrayBuffer(file) | 
|  | 64 | + | 
|  | 65 | + promise.future | 
|  | 66 | + } | 
|  | 67 | +} | 
0 commit comments