feat(lib/assets): add api for registering custom and overriding assets
This commit is contained in:
parent
7450447c1b
commit
72bd9c00fb
2 changed files with 57 additions and 4 deletions
|
|
@ -5,9 +5,16 @@ import { AssetRegistry } from './patches'
|
|||
|
||||
import type { ReactNative as RN } from '@revenge-mod/types'
|
||||
|
||||
export type Asset = RN.AssetsRegistry.PackagerAsset
|
||||
export type Asset = ReactNativeAsset | RevengeAsset
|
||||
export type AssetId = number
|
||||
|
||||
export type ReactNativeAsset = RN.AssetsRegistry.PackagerAsset
|
||||
export interface RevengeAsset extends Pick<ReactNativeAsset, 'name' | 'width' | 'height' | 'type'> {
|
||||
uri: string
|
||||
}
|
||||
|
||||
export type RegisterableAsset = Omit<RevengeAsset, 'id'>
|
||||
|
||||
// iOS cannot display SVGs
|
||||
let _preferredType: Asset['type'] = ReactNative.Platform.OS === 'ios' ? 'png' : 'svg'
|
||||
|
||||
|
|
@ -60,3 +67,33 @@ export function getAssetsByName(name: string): Record<Asset['type'], Asset> | un
|
|||
export function setPreferredAssetType(type: Asset['type']) {
|
||||
_preferredType = type
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an asset with the given name.
|
||||
* If an asset with the same name already exists, it will be overridden if `override` is set to true.
|
||||
*
|
||||
* @param asset The asset to register.
|
||||
* @param override Whether to override the existing asset if one exists. `false` by default.
|
||||
* @throws An error if an asset with the same name and type already exists and `override` is not set to true.
|
||||
*/
|
||||
export function registerAsset(asset: RegisterableAsset, override?: boolean) {
|
||||
const { name } = asset
|
||||
|
||||
if (override) _overrides.set(name, asset)
|
||||
// Make sure to not override the asset if it already exists, unless explicitly set to override
|
||||
else if (_assets.get(name)?.[1]?.[asset.type])
|
||||
throw new Error(`Asset "${name}" with type "${asset.type}" already exists`)
|
||||
|
||||
// @ts-expect-error
|
||||
return AssetRegistry.registerAsset(asset)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an asset override.
|
||||
*
|
||||
* @param name The name of the asset to remove the override for.
|
||||
* @returns Whether the override was removed.
|
||||
*/
|
||||
export function removeAssetOverride(name: string) {
|
||||
return _overrides.delete(name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
import { _mUninited } from '@revenge-mod/modules/_/metro'
|
||||
import { waitForModules } from '@revenge-mod/modules/finders'
|
||||
import { byProps } from '@revenge-mod/modules/finders/filters'
|
||||
import { byName, byProps } from '@revenge-mod/modules/finders/filters'
|
||||
import { getModuleDependencies } from '@revenge-mod/modules/metro'
|
||||
|
||||
import { _assets, _ids } from './_internal'
|
||||
import { _assets, _ids, _overrides } from './_internal'
|
||||
|
||||
import type { ReactNative } from '@revenge-mod/types'
|
||||
import type { Asset } from '.'
|
||||
import type { Asset, ReactNativeAsset } from '.'
|
||||
|
||||
export let AssetRegistry: ReactNative.AssetsRegistry
|
||||
export let AssetRegistryModuleId: number
|
||||
|
||||
// Tracking/caching assets
|
||||
const unsubForAssetRegistry = waitForModules(byProps('registerAsset'), (arId, exports) => {
|
||||
// We want to do caching only for the re-exported asset-registry
|
||||
if (!getModuleDependencies(arId)!.length) {
|
||||
|
|
@ -33,6 +35,7 @@ const unsubForAssetRegistry = waitForModules(byProps('registerAsset'), (arId, ex
|
|||
}
|
||||
|
||||
unsubForAssetRegistry()
|
||||
AssetRegistryModuleId = arId
|
||||
|
||||
// TODO(assets/patches): conditionally run this if cache does not exist
|
||||
// More fragile way, but more performant:
|
||||
|
|
@ -45,3 +48,16 @@ const unsubForAssetRegistry = waitForModules(byProps('registerAsset'), (arId, ex
|
|||
if (deps.length === 1 && deps[0] === arId) __r(id)
|
||||
}
|
||||
})
|
||||
|
||||
// Asset overrides
|
||||
const unsubForResolveAssetSource = waitForModules(
|
||||
byName<{
|
||||
addCustomSourceTransformer: (transformer: (arg: { asset: Asset }) => ReactNativeAsset) => void
|
||||
}>('resolveAssetSource'),
|
||||
(_, resolveAssetSource) => {
|
||||
unsubForResolveAssetSource()
|
||||
|
||||
// @ts-expect-error
|
||||
resolveAssetSource.addCustomSourceTransformer(({ asset }) => _overrides.get(asset.name))
|
||||
},
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue