-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a Data Provider to manage images
- Loading branch information
1 parent
9e1864a
commit 00dbce6
Showing
5 changed files
with
91 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
spra-web/src/main/scala/net/wiringbits/spra/ui/web/facades/DataProvider.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,19 @@ | ||
package net.wiringbits.spra.ui.web.facades | ||
|
||
import scala.scalajs.js | ||
import scala.scalajs.js.annotation.JSImport | ||
|
||
@js.native | ||
trait DataProvider extends js.Object | ||
|
||
@js.native | ||
@JSImport("ra-data-simple-rest", JSImport.Default) | ||
// https://www.npmjs.com/package/ra-data-simple-rest | ||
def simpleRestProvider(url: String): DataProvider = js.native | ||
|
||
@js.native | ||
@JSImport("react-admin", "withLifecycleCallbacks") | ||
// https://marmelab.com/react-admin/withLifecycleCallbacks.html | ||
object WithLifecycleCallbacks extends js.Object { | ||
def apply(dataProvider: DataProvider, callbacks: js.Array[js.Object]): DataProvider = js.native | ||
} |
30 changes: 26 additions & 4 deletions
30
spra-web/src/main/scala/net/wiringbits/spra/ui/web/facades/package.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,32 @@ | ||
package net.wiringbits.spra.ui.web | ||
|
||
import scala.scalajs.js | ||
import scala.scalajs.js.annotation.JSImport | ||
import net.wiringbits.spra.ui.web.utils.Images.* | ||
import org.scalajs.dom.File | ||
|
||
package object facades { | ||
@js.native | ||
@JSImport("ra-data-simple-rest", JSImport.Default) | ||
def simpleRestProvider(url: String): DataProvider = js.native | ||
def createDataProvider(url: String): DataProvider = { | ||
val baseDataProvider = simpleRestProvider(url) | ||
WithLifecycleCallbacks( | ||
baseDataProvider, | ||
js.Array( | ||
js.Dynamic.literal( | ||
resource = "images", | ||
afterRead = (record: js.Dynamic, dataProvider: js.Any) => { | ||
val hexImage = record.data.asInstanceOf[String] | ||
val urlImage = convertHexToImage(hexImage) | ||
record.updateDynamic("data")(urlImage) | ||
record | ||
}, | ||
beforeSave = (data: js.Dynamic, dataProvider: js.Any) => { | ||
val rawFile = data.data.rawFile.asInstanceOf[File] | ||
convertImageToByteArray(rawFile).`then` { value => | ||
data.updateDynamic("data")(value.asInstanceOf[js.Any]) | ||
data | ||
} | ||
} | ||
) | ||
) | ||
) | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
spra-web/src/main/scala/net/wiringbits/spra/ui/web/utils/Images.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package net.wiringbits.spra.ui.web.utils | ||
|
||
import org.scalajs.dom | ||
import org.scalajs.dom.{Blob, File} | ||
import scala.util.{Failure, Success, Try} | ||
import scala.scalajs.js.Promise | ||
import scala.scalajs.js.typedarray.{ArrayBuffer, Int8Array, Uint8Array} | ||
import scala.scalajs.js | ||
|
||
object Images { | ||
def convertImageToByteArray(image: dom.File): js.Promise[String] = { | ||
new js.Promise[String]((resolve, reject) => { | ||
val reader = new dom.FileReader() | ||
reader.onload = { (e: dom.Event) => | ||
val arrayBuffer = reader.result.asInstanceOf[ArrayBuffer] | ||
val byteArray = new Int8Array(arrayBuffer).toArray | ||
resolve(byteArray.mkString("[", ", ", "]")) | ||
} | ||
reader.onerror = { (e: dom.Event) => | ||
reject(new js.Error("Failed to read file")) | ||
} | ||
reader.readAsArrayBuffer(image) | ||
}) | ||
} | ||
|
||
def convertHexToImage(imageHex: String): String = { | ||
// Remove the "0x" prefix from the hex string, as it's not part of the actual image data | ||
val hex = imageHex.tail.tail | ||
val imageBinary: Array[Byte] = | ||
if ((hex.length % 2) == 1) | ||
Array.empty | ||
else | ||
Try(hex.grouped(2).map { hex => Integer.parseInt(hex, 16).toByte }.toArray) match { | ||
case Success(value) => value | ||
case Failure(_) => Array.empty | ||
} | ||
val byteArray = Uint8Array(js.Array(imageBinary.map(_.toShort): _*)) | ||
dom.URL.createObjectURL(dom.Blob(js.Array(byteArray.buffer))) | ||
} | ||
} |