Add thumbnail sending to assets for map grid

This commit is contained in:
Mitchell McCaffrey 2021-04-29 15:44:57 +10:00
parent 0ccee84cbf
commit 71edf5c5c5
6 changed files with 38 additions and 48 deletions

View File

@ -11,7 +11,12 @@ import Grid from "../Grid";
function MapGrid({ map }) { function MapGrid({ map }) {
let mapSourceMap = map; let mapSourceMap = map;
const mapURL = useDataURL(mapSourceMap, defaultMapSources); const mapURL = useDataURL(
mapSourceMap,
defaultMapSources,
undefined,
map.type === "file"
);
const [mapImage, mapLoadingStatus] = useImage(mapURL); const [mapImage, mapLoadingStatus] = useImage(mapURL);
const [isImageLight, setIsImageLight] = useState(true); const [isImageLight, setIsImageLight] = useState(true);

View File

@ -1,5 +1,6 @@
import React, { useState, useContext, useCallback, useEffect } from "react"; import React, { useState, useContext, useCallback, useEffect } from "react";
import { decode } from "@msgpack/msgpack"; import * as Comlink from "comlink";
import { encode } from "@msgpack/msgpack";
import { useDatabase } from "./DatabaseContext"; import { useDatabase } from "./DatabaseContext";
@ -48,10 +49,9 @@ export function AssetsProvider({ children }) {
const getAsset = useCallback( const getAsset = useCallback(
async (assetId) => { async (assetId) => {
const packed = await worker.loadData("assets", assetId); return await database.table("assets").get(assetId);
return decode(packed);
}, },
[worker] [database]
); );
const addAssets = useCallback( const addAssets = useCallback(
@ -63,7 +63,15 @@ export function AssetsProvider({ children }) {
const putAsset = useCallback( const putAsset = useCallback(
async (asset) => { async (asset) => {
return database.table("assets").put(asset); // Attempt to use worker to put map to avoid UI lockup
const packedAsset = encode(asset);
const success = await worker.putData(
Comlink.transfer(packedAsset, [packedAsset.buffer]),
"assets"
);
if (!success) {
await database.table("assets").put(asset);
}
}, },
[database] [database]
); );

View File

@ -5,8 +5,7 @@ import React, {
useCallback, useCallback,
useRef, useRef,
} from "react"; } from "react";
import * as Comlink from "comlink"; import { decode } from "@msgpack/msgpack";
import { decode, encode } from "@msgpack/msgpack";
import { useAuth } from "./AuthContext"; import { useAuth } from "./AuthContext";
import { useDatabase } from "./DatabaseContext"; import { useDatabase } from "./DatabaseContext";
@ -215,16 +214,7 @@ export function MapDataProvider({ children }) {
*/ */
const putMap = useCallback( const putMap = useCallback(
async (map) => { async (map) => {
// Attempt to use worker to put map to avoid UI lockup await database.table("maps").put(map);
const packedMap = encode(map);
const success = await worker.putData(
Comlink.transfer(packedMap, [packedMap.buffer]),
"maps",
false
);
if (!success) {
await database.table("maps").put(map);
}
if (map.owner !== userId) { if (map.owner !== userId) {
await updateCache(); await updateCache();
} }

View File

@ -65,21 +65,12 @@ class Connection extends SimplePeer {
sendObject(object, channel, chunkId) { sendObject(object, channel, chunkId) {
try { try {
const packedData = encode(object); const packedData = encode(object);
if (packedData.byteLength > MAX_BUFFER_SIZE) { const chunks = this.chunk(packedData, chunkId);
const chunks = this.chunk(packedData, chunkId); for (let chunk of chunks) {
for (let chunk of chunks) {
if (this.dataChannels[channel]) {
this.dataChannels[channel].write(encode(chunk));
} else {
this.write(encode(chunk));
}
}
return;
} else {
if (this.dataChannels[channel]) { if (this.dataChannels[channel]) {
this.dataChannels[channel].write(packedData); this.dataChannels[channel].write(encode(chunk));
} else { } else {
this.write(packedData); this.write(encode(chunk));
} }
} }
} catch (error) { } catch (error) {

View File

@ -65,14 +65,6 @@ function NetworkedMapAndTokens({ session }) {
async function loadAssetManifestFromMap(map, mapState) { async function loadAssetManifestFromMap(map, mapState) {
const assets = {}; const assets = {};
const { owner } = map; const { owner } = map;
if (map.type === "file") {
const qualityId = map.resolutions[map.quality];
if (qualityId) {
assets[qualityId] = { id: qualityId, owner };
} else {
assets[map.file] = { id: map.file, owner };
}
}
let processedTokens = new Set(); let processedTokens = new Set();
for (let tokenState of Object.values(mapState.tokens)) { for (let tokenState of Object.values(mapState.tokens)) {
if ( if (
@ -84,6 +76,15 @@ function NetworkedMapAndTokens({ session }) {
assets[tokenState.file] = { id: tokenState.file, owner }; assets[tokenState.file] = { id: tokenState.file, owner };
} }
} }
if (map.type === "file") {
assets[map.thumbnail] = { id: map.thumbnail, owner };
const qualityId = map.resolutions[map.quality];
if (qualityId) {
assets[qualityId] = { id: qualityId, owner };
} else {
assets[map.file] = { id: map.file, owner };
}
}
setAssetManifest({ mapId: map.id, assets }, true, true); setAssetManifest({ mapId: map.id, assets }, true, true);
} }
@ -144,8 +145,8 @@ function NetworkedMapAndTokens({ session }) {
if (cachedAsset) { if (cachedAsset) {
requestingAssetsRef.current.delete(asset.id); requestingAssetsRef.current.delete(asset.id);
} else { } else {
session.sendTo(owner.sessionId, "assetRequest", asset.id);
assetLoadStart(asset.id); assetLoadStart(asset.id);
session.sendTo(owner.sessionId, "assetRequest", asset);
} }
} }
} }
@ -381,7 +382,7 @@ function NetworkedMapAndTokens({ session }) {
useEffect(() => { useEffect(() => {
async function handlePeerData({ id, data, reply }) { async function handlePeerData({ id, data, reply }) {
if (id === "assetRequest") { if (id === "assetRequest") {
const asset = await getAsset(data); const asset = await getAsset(data.id);
reply("assetResponse", asset, undefined, asset.id); reply("assetResponse", asset, undefined, asset.id);
} }

View File

@ -43,17 +43,12 @@ let service = {
* Put data into table encoded by msgpack * Put data into table encoded by msgpack
* @param {Uint8Array} data * @param {Uint8Array} data
* @param {string} table * @param {string} table
* @param {boolean} wait Whether to wait for the put to finish
*/ */
async putData(data, table, wait = true) { async putData(data, table) {
try { try {
let db = getDatabase({}); let db = getDatabase({});
const decoded = decode(data); const decoded = decode(data);
if (wait) { await db.table(table).put(decoded);
await db.table(table).put(decoded);
} else {
db.table(table).put(decoded);
}
return true; return true;
} catch { } catch {
return false; return false;