From 9d6e9fe144349e9b0dab5837c34d790f7f8d49ea Mon Sep 17 00:00:00 2001 From: Eduardo Speroni Date: Tue, 28 May 2024 10:22:18 -0300 Subject: [PATCH] feat: add `sys://` ios images --- packages/core/image-source/index.android.ts | 14 ++++++++--- packages/core/image-source/index.d.ts | 12 +++++++++ packages/core/image-source/index.ios.ts | 28 +++++++++++++++++++-- packages/core/ui/image/image-common.ts | 12 +++++++-- packages/core/utils/common.ts | 8 +++--- 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/packages/core/image-source/index.android.ts b/packages/core/image-source/index.android.ts index ca89f8524..ca36e9f4b 100644 --- a/packages/core/image-source/index.android.ts +++ b/packages/core/image-source/index.android.ts @@ -149,6 +149,14 @@ export class ImageSource implements ImageSourceDefinition { return ImageSource.fromFileSync(path); } + static fromSystemImageSync(name: string): ImageSource { + return ImageSource.fromResourceSync(name); + } + + static fromSystemImage(name: string): Promise { + return ImageSource.fromResource(name); + } + static fromDataSync(data: any): ImageSource { const bitmap = android.graphics.BitmapFactory.decodeStream(data); @@ -335,7 +343,7 @@ export class ImageSource implements ImageSourceDefinition { reject(); } }, - }) + }), ); }); } @@ -375,7 +383,7 @@ export class ImageSource implements ImageSourceDefinition { reject(); } }, - }) + }), ); }); } @@ -404,7 +412,7 @@ export class ImageSource implements ImageSourceDefinition { reject(); } }, - }) + }), ); }); } diff --git a/packages/core/image-source/index.d.ts b/packages/core/image-source/index.d.ts index 55037abc9..57e533595 100644 --- a/packages/core/image-source/index.d.ts +++ b/packages/core/image-source/index.d.ts @@ -54,6 +54,18 @@ export class ImageSource { */ static fromResource(name: string): Promise; + /** + * Loads this instance from the specified system image name. + * @param name the name of the system image + */ + static fromSystemImageSync(name: string): ImageSource; + + /** + * Loads this instance from the specified system image name asynchronously. + * @param name the name of the system image + */ + static fromSystemImage(name: string): Promise; + /** * Loads this instance from the specified file. * @param path The location of the file on the file system. diff --git a/packages/core/image-source/index.ios.ts b/packages/core/image-source/index.ios.ts index fd8fbf6df..f6d854ec8 100644 --- a/packages/core/image-source/index.ios.ts +++ b/packages/core/image-source/index.ios.ts @@ -8,7 +8,7 @@ import { Trace } from '../trace'; // Types. import { path as fsPath, knownFolders } from '../file-system'; -import { isFileOrResourcePath, RESOURCE_PREFIX, layout, releaseNativeObject } from '../utils'; +import { isFileOrResourcePath, RESOURCE_PREFIX, layout, releaseNativeObject, SYSTEM_PREFIX } from '../utils'; import { getScaledDimensions } from './image-source-common'; @@ -73,6 +73,27 @@ export class ImageSource implements ImageSourceDefinition { return http.getImage(url); } + static fromSystemImageSync(name: string): ImageSource { + const image = UIImage.systemImageNamed(name); + + return image ? new ImageSource(image) : null; + } + + static fromSystemImage(name: string): Promise { + return new Promise((resolve, reject) => { + try { + const image = UIImage.systemImageNamed(name); + if (image) { + resolve(new ImageSource(image)); + } else { + reject(new Error(`Failed to load system icon with name: ${name}`)); + } + } catch (ex) { + reject(ex); + } + }); + } + static fromResourceSync(name: string): ImageSource { const nativeSource = (UIImage).tns_safeImageNamed(name) || (UIImage).tns_safeImageNamed(`${name}.jpg`); @@ -126,7 +147,10 @@ export class ImageSource implements ImageSourceDefinition { } if (path.indexOf(RESOURCE_PREFIX) === 0) { - return ImageSource.fromResourceSync(path.substr(RESOURCE_PREFIX.length)); + return ImageSource.fromResourceSync(path.slice(RESOURCE_PREFIX.length)); + } + if (path.indexOf(SYSTEM_PREFIX) === 0) { + return ImageSource.fromSystemImageSync(path.slice(SYSTEM_PREFIX.length)); } return ImageSource.fromFileSync(path); diff --git a/packages/core/ui/image/image-common.ts b/packages/core/ui/image/image-common.ts index 91bb9a1f9..73bc24d30 100644 --- a/packages/core/ui/image/image-common.ts +++ b/packages/core/ui/image/image-common.ts @@ -4,7 +4,7 @@ import { booleanConverter } from '../core/view-base'; import { CoreTypes } from '../../core-types'; import { ImageAsset } from '../../image-asset'; import { ImageSource } from '../../image-source'; -import { isDataURI, isFontIconURI, isFileOrResourcePath, RESOURCE_PREFIX } from '../../utils'; +import { isDataURI, isFontIconURI, isFileOrResourcePath, RESOURCE_PREFIX, SYSTEM_PREFIX } from '../../utils'; import { Color } from '../../color'; import { Style } from '../styling/style'; import { Length } from '../styling/style-properties'; @@ -75,13 +75,21 @@ export abstract class ImageBase extends View implements ImageDefinition { } } else if (isFileOrResourcePath(value)) { if (value.indexOf(RESOURCE_PREFIX) === 0) { - const resPath = value.substr(RESOURCE_PREFIX.length); + const resPath = value.slice(RESOURCE_PREFIX.length); if (sync) { imageLoaded(ImageSource.fromResourceSync(resPath)); } else { this.imageSource = null; ImageSource.fromResource(resPath).then(imageLoaded); } + } else if (value.indexOf(SYSTEM_PREFIX) === 0) { + const sysPath = value.slice(SYSTEM_PREFIX.length); + if (sync) { + imageLoaded(ImageSource.fromSystemImageSync(sysPath)); + } else { + this.imageSource = null; + ImageSource.fromSystemImage(sysPath).then(imageLoaded); + } } else { if (sync) { imageLoaded(ImageSource.fromFileSync(value)); diff --git a/packages/core/utils/common.ts b/packages/core/utils/common.ts index 273f5eb90..2f8f46379 100644 --- a/packages/core/utils/common.ts +++ b/packages/core/utils/common.ts @@ -8,6 +8,7 @@ export * from './mainthread-helper'; export * from './macrotask-scheduler'; export const RESOURCE_PREFIX = 'res://'; +export const SYSTEM_PREFIX = 'sys://'; export const FILE_PREFIX = 'file:///'; export function escapeRegexSymbols(source: string): string { @@ -75,7 +76,8 @@ export function isFileOrResourcePath(path: string): boolean { return ( path.indexOf('~/') === 0 || // relative to AppRoot path.indexOf('/') === 0 || // absolute path - path.indexOf(RESOURCE_PREFIX) === 0 + path.indexOf(RESOURCE_PREFIX) === 0 || + path.indexOf(SYSTEM_PREFIX) === 0 ); // resource } @@ -215,7 +217,7 @@ export function queueGC(delay = 900, useThrottle?: boolean) { if (!throttledGC.get(delay)) { throttledGC.set( delay, - throttle(() => GC(), delay) + throttle(() => GC(), delay), ); } throttledGC.get(delay)(); @@ -226,7 +228,7 @@ export function queueGC(delay = 900, useThrottle?: boolean) { if (!debouncedGC.get(delay)) { debouncedGC.set( delay, - debounce(() => GC(), delay) + debounce(() => GC(), delay), ); } debouncedGC.get(delay)();