UNPKG

create-expo-cljs-app

Version:

Create a react native application with Expo and Shadow-CLJS!

115 lines (105 loc) 3.21 kB
import { Platform, UnavailabilityError } from 'expo-modules-core'; import invariant from 'invariant'; import { Dimensions } from 'react-native'; type PackagerAsset = { __packager_asset: boolean; fileSystemLocation: string; httpServerLocation: string; width?: number; height?: number; scales: number[]; hash: string; name: string; type: string; }; function getBasePath({ httpServerLocation }: PackagerAsset): string { if (httpServerLocation[0] === '/') { return httpServerLocation.substr(1); } return httpServerLocation; } export type ResolvedAssetSource = { __packager_asset: boolean; width?: number; height?: number; uri: string; scale: number; }; function getScale(): number { return Dimensions.get('window').scale; } function getScaledAssetPath(asset): string { const scale = AssetSourceResolver.pickScale(asset.scales, getScale()); const scaleSuffix = scale === 1 ? '' : '@' + scale + 'x'; const assetDir = getBasePath(asset); return assetDir + '/' + asset.name + scaleSuffix + (asset.type ? `.${asset.type}` : ''); } export default class AssetSourceResolver { serverUrl?: string | null; // where the jsbundle is being run from jsbundleUrl?: string | null; // the asset to resolve asset: PackagerAsset; constructor( serverUrl: string | undefined | null, jsbundleUrl: string | undefined | null, asset: PackagerAsset ) { this.serverUrl = serverUrl; this.jsbundleUrl = jsbundleUrl; this.asset = asset; } isLoadedFromServer(): boolean { return !!this.serverUrl; } isLoadedFromFileSystem(): boolean { return !!(this.jsbundleUrl && this.jsbundleUrl.startsWith('file://')); } defaultAsset(): ResolvedAssetSource { if (this.isLoadedFromServer()) { return this.assetServerURL(); } return this.scaledAssetURLNearBundle(); } assetServerURL(): ResolvedAssetSource { invariant(!!this.serverUrl, 'need server to load from'); return this.fromSource( this.serverUrl + getScaledAssetPath(this.asset) + '?platform=' + Platform.OS + '&hash=' + this.asset.hash ); } scaledAssetPath(): ResolvedAssetSource { return this.fromSource(getScaledAssetPath(this.asset)); } scaledAssetURLNearBundle(): ResolvedAssetSource { const path = this.jsbundleUrl || ''; return this.fromSource(path + getScaledAssetPath(this.asset)); } resourceIdentifierWithoutScale(): ResolvedAssetSource { throw new UnavailabilityError('react-native', 'resourceIdentifierWithoutScale()'); } drawableFolderInBundle(): ResolvedAssetSource { throw new UnavailabilityError('react-native', 'drawableFolderInBundle()'); } fromSource(source: string): ResolvedAssetSource { return { __packager_asset: true, width: this.asset.width, height: this.asset.height, uri: source, scale: AssetSourceResolver.pickScale(this.asset.scales, getScale()), }; } static pickScale(scales: number[], deviceScale: number): number { for (let i = 0; i < scales.length; i++) { if (scales[i] >= deviceScale) { return scales[i]; } } return scales[scales.length - 1] || 1; } }