GT2/Ejectable/node_modules/expo-asset/build/Asset.js

161 lines
5.5 KiB
JavaScript

import { Platform } from '@unimodules/core';
import { getAssetByID } from './AssetRegistry';
import * as AssetSources from './AssetSources';
import * as AssetUris from './AssetUris';
import { getEmbeddedAssetUri } from './EmbeddedAssets';
import * as ImageAssets from './ImageAssets';
import { downloadAsync, IS_ENV_WITH_UPDATES_ENABLED } from './PlatformUtils';
import resolveAssetSource from './resolveAssetSource';
export class Asset {
constructor({ name, type, hash = null, uri, width, height }) {
this.hash = null;
this.localUri = null;
this.width = null;
this.height = null;
this.downloading = false;
this.downloaded = false;
this._downloadCallbacks = [];
this.name = name;
this.type = type;
this.hash = hash;
this.uri = uri;
if (typeof width === 'number') {
this.width = width;
}
if (typeof height === 'number') {
this.height = height;
}
if (hash) {
this.localUri = getEmbeddedAssetUri(hash, type);
if (this.localUri) {
this.downloaded = true;
}
}
if (Platform.OS === 'web') {
if (!name) {
this.name = AssetUris.getFilename(uri);
}
if (!type) {
this.type = AssetUris.getFileExtension(uri);
}
}
}
static loadAsync(moduleId) {
const moduleIds = Array.isArray(moduleId) ? moduleId : [moduleId];
return Promise.all(moduleIds.map(moduleId => Asset.fromModule(moduleId).downloadAsync()));
}
static fromModule(virtualAssetModule) {
if (typeof virtualAssetModule === 'string') {
return Asset.fromURI(virtualAssetModule);
}
const meta = getAssetByID(virtualAssetModule);
if (!meta) {
throw new Error(`Module "${virtualAssetModule}" is missing from the asset registry`);
}
// Outside of the managed env we need the moduleId to initialize the asset
// because resolveAssetSource depends on it
if (!IS_ENV_WITH_UPDATES_ENABLED) {
const { uri } = resolveAssetSource(virtualAssetModule);
const asset = new Asset({
name: meta.name,
type: meta.type,
hash: meta.hash,
uri,
width: meta.width,
height: meta.height,
});
// TODO: FileSystem should probably support 'downloading' from drawable
// resources But for now it doesn't (it only supports raw resources) and
// React Native's Image works fine with drawable resource names for
// images.
if (Platform.OS === 'android' && !uri.includes(':') && (meta.width || meta.height)) {
asset.localUri = asset.uri;
asset.downloaded = true;
}
Asset.byHash[meta.hash] = asset;
return asset;
}
return Asset.fromMetadata(meta);
}
static fromMetadata(meta) {
// The hash of the whole asset, not to be confused with the hash of a specific file returned
// from `selectAssetSource`
const metaHash = meta.hash;
if (Asset.byHash[metaHash]) {
return Asset.byHash[metaHash];
}
const { uri, hash } = AssetSources.selectAssetSource(meta);
const asset = new Asset({
name: meta.name,
type: meta.type,
hash,
uri,
width: meta.width,
height: meta.height,
});
Asset.byHash[metaHash] = asset;
return asset;
}
static fromURI(uri) {
if (Asset.byUri[uri]) {
return Asset.byUri[uri];
}
// Possibly a Base64-encoded URI
let type = '';
if (uri.indexOf(';base64') > -1) {
type = uri.split(';')[0].split('/')[1];
}
else {
const extension = AssetUris.getFileExtension(uri);
type = extension.startsWith('.') ? extension.substring(1) : extension;
}
const asset = new Asset({
name: '',
type,
hash: null,
uri,
});
Asset.byUri[uri] = asset;
return asset;
}
async downloadAsync() {
if (this.downloaded) {
return this;
}
if (this.downloading) {
await new Promise((resolve, reject) => {
this._downloadCallbacks.push({ resolve, reject });
});
return this;
}
this.downloading = true;
try {
if (Platform.OS === 'web') {
if (ImageAssets.isImageType(this.type)) {
const { width, height, name } = await ImageAssets.getImageInfoAsync(this.uri);
this.width = width;
this.height = height;
this.name = name;
}
else {
this.name = AssetUris.getFilename(this.uri);
}
}
this.localUri = await downloadAsync(this.uri, this.hash, this.type, this.name);
this.downloaded = true;
this._downloadCallbacks.forEach(({ resolve }) => resolve());
}
catch (e) {
this._downloadCallbacks.forEach(({ reject }) => reject(e));
throw e;
}
finally {
this.downloading = false;
this._downloadCallbacks = [];
}
return this;
}
}
Asset.byHash = {};
Asset.byUri = {};
//# sourceMappingURL=Asset.js.map