mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-18 05:18:39 +08:00
async image loading from data, files and resources for ios
Use the tns_safeDecodeImageNamedCompletion from the widgets framework Add loadMode on Image with sync and async options for local images
This commit is contained in:

committed by
Panayot Cankov

parent
b8785afd74
commit
1b395aac7f
@ -42,12 +42,7 @@ export var test_settingImageSource = function () {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export var test_SettingImageSrc = function (done) {
|
function runImageTest(done, image: ImageModule.Image, src: string) {
|
||||||
// >> img-create-src
|
|
||||||
var image = new ImageModule.Image();
|
|
||||||
image.src = "https://www.google.com/images/errors/logo_sm_2.png";
|
|
||||||
// << img-create-src
|
|
||||||
|
|
||||||
image.src = null;
|
image.src = null;
|
||||||
|
|
||||||
var testModel = new ObservableModule.Observable();
|
var testModel = new ObservableModule.Observable();
|
||||||
@ -61,10 +56,16 @@ export var test_SettingImageSrc = function (done) {
|
|||||||
TKUnit.assertTrue(!image.isLoading, "Image.isLoading should be false.");
|
TKUnit.assertTrue(!image.isLoading, "Image.isLoading should be false.");
|
||||||
TKUnit.assertTrue(!testModel.get("imageIsLoading"), "imageIsLoading on viewModel should be false.");
|
TKUnit.assertTrue(!testModel.get("imageIsLoading"), "imageIsLoading on viewModel should be false.");
|
||||||
TKUnit.assertTrue(imageIsLoaded, "imageIsLoading should be true.");
|
TKUnit.assertTrue(imageIsLoaded, "imageIsLoading should be true.");
|
||||||
done(null);
|
if (done) {
|
||||||
|
done(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
done(e);
|
if (done) {
|
||||||
|
done(e);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -74,53 +75,55 @@ export var test_SettingImageSrc = function (done) {
|
|||||||
twoWay: true
|
twoWay: true
|
||||||
}, testModel);
|
}, testModel);
|
||||||
|
|
||||||
image.src = "https://www.google.com/images/errors/logo_sm_2.png";
|
image.src = src;
|
||||||
testModel.on(ObservableModule.Observable.propertyChangeEvent, handler);
|
testModel.on(ObservableModule.Observable.propertyChangeEvent, handler);
|
||||||
TKUnit.assertTrue(image.isLoading, "Image.isLoading should be true.");
|
if (done) {
|
||||||
TKUnit.assertTrue(testModel.get("imageIsLoading"), "model.isLoading should be true.");
|
TKUnit.assertTrue(image.isLoading, "Image.isLoading should be true.");
|
||||||
|
TKUnit.assertTrue(testModel.get("imageIsLoading"), "model.isLoading should be true.");
|
||||||
|
} else {
|
||||||
|
// Since it is synchronous check immediately.
|
||||||
|
handler(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export var test_SettingImageSrcToFileWithinApp = function (done) {
|
export var test_SettingImageSrc = function (done) {
|
||||||
|
// >> img-create-src
|
||||||
|
var image = new ImageModule.Image();
|
||||||
|
image.src = "https://www.google.com/images/errors/logo_sm_2.png";
|
||||||
|
// << img-create-src
|
||||||
|
runImageTest(done, image, image.src)
|
||||||
|
}
|
||||||
|
|
||||||
|
export var test_SettingImageSrcToFileWithinApp = function () {
|
||||||
// >> img-create-local
|
// >> img-create-local
|
||||||
var image = new ImageModule.Image();
|
var image = new ImageModule.Image();
|
||||||
image.src = "~/logo.png";
|
image.src = "~/logo.png";
|
||||||
// << img-create-local
|
// << img-create-local
|
||||||
|
|
||||||
var testFunc = function (views: Array<ViewModule.View>) {
|
runImageTest(null, image, image.src)
|
||||||
var testImage = <ImageModule.Image> views[0];
|
|
||||||
TKUnit.waitUntilReady(() => !testImage.isLoading, 3);
|
|
||||||
try {
|
|
||||||
TKUnit.assertTrue(!testImage.isLoading, "isLoading should be false.");
|
|
||||||
done(null);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
done(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
helper.buildUIAndRunTest(image, testFunc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export var test_SettingImageSrcToDataURI = function (done) {
|
export var test_SettingImageSrcToDataURI = function () {
|
||||||
// >> img-create-datauri
|
// >> img-create-datauri
|
||||||
var image = new ImageModule.Image();
|
var image = new ImageModule.Image();
|
||||||
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAAXNSR0IArs4c6QAAABxpRE9UAAAAAgAAAAAAAAACAAAAKAAAAAIAAAACAAAARiS4uJEAAAASSURBVBgZYvjPwABHSMz/DAAAAAD//0GWpK0AAAAOSURBVGNgYPiPhBgQAACEvQv1D5y/pAAAAABJRU5ErkJggg==";
|
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAAXNSR0IArs4c6QAAABxpRE9UAAAAAgAAAAAAAAACAAAAKAAAAAIAAAACAAAARiS4uJEAAAASSURBVBgZYvjPwABHSMz/DAAAAAD//0GWpK0AAAAOSURBVGNgYPiPhBgQAACEvQv1D5y/pAAAAABJRU5ErkJggg==";
|
||||||
// << img-create-datauri
|
// << img-create-datauri
|
||||||
|
|
||||||
var testFunc = function (views: Array<ViewModule.View>) {
|
runImageTest(null, image, image.src)
|
||||||
var testImage = <ImageModule.Image>views[0];
|
}
|
||||||
TKUnit.waitUntilReady(() => !testImage.isLoading, 3);
|
|
||||||
try {
|
|
||||||
TKUnit.assertTrue(!testImage.isLoading, "isLoading should be false.");
|
|
||||||
TKUnit.assertNotNull(testImage.imageSource);
|
|
||||||
done(null);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
done(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
helper.buildUIAndRunTest(image, testFunc);
|
export var test_SettingImageSrcToFileWithinAppAsync = function (done) {
|
||||||
|
var image = new ImageModule.Image();
|
||||||
|
image.loadMode = "async";
|
||||||
|
image.src = "~/logo.png";
|
||||||
|
runImageTest(done, image, image.src)
|
||||||
|
}
|
||||||
|
|
||||||
|
export var test_SettingImageSrcToDataURIAsync = function (done) {
|
||||||
|
var image = new ImageModule.Image();
|
||||||
|
image.loadMode = "async";
|
||||||
|
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAAXNSR0IArs4c6QAAABxpRE9UAAAAAgAAAAAAAAACAAAAKAAAAAIAAAACAAAARiS4uJEAAAASSURBVBgZYvjPwABHSMz/DAAAAAD//0GWpK0AAAAOSURBVGNgYPiPhBgQAACEvQv1D5y/pAAAAABJRU5ErkJggg==";
|
||||||
|
runImageTest(done, image, image.src)
|
||||||
}
|
}
|
||||||
|
|
||||||
export var test_SettingStretch_AspectFit = function () {
|
export var test_SettingStretch_AspectFit = function () {
|
||||||
|
@ -98,27 +98,14 @@ export function request(options: http.HttpRequestOptions): Promise<http.HttpResp
|
|||||||
},
|
},
|
||||||
toImage: () => {
|
toImage: () => {
|
||||||
ensureImageSource();
|
ensureImageSource();
|
||||||
if (UIImage.imageWithData["async"]) {
|
return new Promise((resolve, reject) => {
|
||||||
return UIImage.imageWithData["async"](UIImage, [data])
|
(<any>UIImage).tns_decodeImageWithDataCompletion(data, image => {
|
||||||
.then(image => {
|
if (image) {
|
||||||
if (!image) {
|
resolve(imageSource.fromNativeSource(image))
|
||||||
throw new Error("Response content may not be converted to an Image");
|
} else {
|
||||||
}
|
reject(new Error("Response content may not be converted to an Image"));
|
||||||
|
}
|
||||||
var source = new imageSource.ImageSource();
|
});
|
||||||
source.setNativeSource(image);
|
|
||||||
return source;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise<any>((resolveImage, rejectImage) => {
|
|
||||||
var img = imageSource.fromData(data);
|
|
||||||
if (img instanceof imageSource.ImageSource) {
|
|
||||||
resolveImage(img);
|
|
||||||
} else {
|
|
||||||
rejectImage(new Error("Response content may not be converted to an Image"));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
toFile: (destinationFilePath?: string) => {
|
toFile: (destinationFilePath?: string) => {
|
||||||
|
@ -33,12 +33,9 @@ export function getJSON<T>(arg: any): Promise<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getImage(arg: any): Promise<image.ImageSource> {
|
export function getImage(arg: any): Promise<image.ImageSource> {
|
||||||
return new Promise<image.ImageSource>((resolve, reject) => {
|
return httpRequest
|
||||||
httpRequest.request(typeof arg === "string" ? { url: arg, method: "GET" } : arg)
|
.request(typeof arg === "string" ? { url: arg, method: "GET" } : arg)
|
||||||
.then(r => {
|
.then(responce => responce.content.toImage());
|
||||||
r.content.toImage().then(source => resolve(source), e => reject(e));
|
|
||||||
}, e => reject(e));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFile(arg: any, destinationFilePath?: string): Promise<any> {
|
export function getFile(arg: any, destinationFilePath?: string): Promise<any> {
|
||||||
|
@ -44,7 +44,7 @@ export class ImageSource implements definition.ImageSource {
|
|||||||
// Load BitmapDrawable with getDrawable to make use of Android internal caching
|
// Load BitmapDrawable with getDrawable to make use of Android internal caching
|
||||||
var bitmapDrawable = <android.graphics.drawable.BitmapDrawable>res.getDrawable(identifier);
|
var bitmapDrawable = <android.graphics.drawable.BitmapDrawable>res.getDrawable(identifier);
|
||||||
if (bitmapDrawable && bitmapDrawable.getBitmap) {
|
if (bitmapDrawable && bitmapDrawable.getBitmap) {
|
||||||
this.android = bitmapDrawable.getBitmap();
|
this.android = bitmapDrawable.getBitmap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,6 +52,12 @@ export class ImageSource implements definition.ImageSource {
|
|||||||
return this.android != null;
|
return this.android != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fromResource(name: string): Promise<boolean> {
|
||||||
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
|
resolve(this.loadFromResource(name));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public loadFromFile(path: string): boolean {
|
public loadFromFile(path: string): boolean {
|
||||||
ensureFS();
|
ensureFS();
|
||||||
|
|
||||||
@ -64,11 +70,23 @@ export class ImageSource implements definition.ImageSource {
|
|||||||
return this.android != null;
|
return this.android != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fromFile(path: string): Promise<boolean> {
|
||||||
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
|
resolve(this.loadFromFile(path));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public loadFromData(data: any): boolean {
|
public loadFromData(data: any): boolean {
|
||||||
this.android = android.graphics.BitmapFactory.decodeStream(data);
|
this.android = android.graphics.BitmapFactory.decodeStream(data);
|
||||||
return this.android != null;
|
return this.android != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fromData(data: any): Promise<boolean> {
|
||||||
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
|
resolve(this.loadFromData(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public loadFromBase64(source: string): boolean {
|
public loadFromBase64(source: string): boolean {
|
||||||
if (types.isString(source)) {
|
if (types.isString(source)) {
|
||||||
var bytes = android.util.Base64.decode(source, android.util.Base64.DEFAULT);
|
var bytes = android.util.Base64.decode(source, android.util.Base64.DEFAULT);
|
||||||
@ -77,6 +95,12 @@ export class ImageSource implements definition.ImageSource {
|
|||||||
return this.android != null;
|
return this.android != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fromBase64(data: any): Promise<boolean> {
|
||||||
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
|
resolve(this.loadFromBase64(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public setNativeSource(source: any): boolean {
|
public setNativeSource(source: any): boolean {
|
||||||
this.android = source;
|
this.android = source;
|
||||||
return source != null;
|
return source != null;
|
||||||
|
24
image-source/image-source.d.ts
vendored
24
image-source/image-source.d.ts
vendored
@ -33,24 +33,48 @@ declare module "image-source" {
|
|||||||
*/
|
*/
|
||||||
loadFromResource(name: string): boolean;
|
loadFromResource(name: string): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads this instance from the specified resource name asynchronously.
|
||||||
|
* @param name The name of the resource (without its extension).
|
||||||
|
*/
|
||||||
|
fromResource(name: string): Promise<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads this instance from the specified file.
|
* Loads this instance from the specified file.
|
||||||
* @param path The location of the file on the file system.
|
* @param path The location of the file on the file system.
|
||||||
*/
|
*/
|
||||||
loadFromFile(path: string): boolean;
|
loadFromFile(path: string): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads this instance from the specified file asynchronously.
|
||||||
|
* @param path The location of the file on the file system.
|
||||||
|
*/
|
||||||
|
fromFile(path: string): Promise<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads this instance from the specified native image data.
|
* Loads this instance from the specified native image data.
|
||||||
* @param data The native data (byte array) to load the image from. This will be either Stream for Android or NSData for iOS.
|
* @param data The native data (byte array) to load the image from. This will be either Stream for Android or NSData for iOS.
|
||||||
*/
|
*/
|
||||||
loadFromData(data: any): boolean;
|
loadFromData(data: any): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads this instance from the specified native image data asynchronously.
|
||||||
|
* @param data The native data (byte array) to load the image from. This will be either Stream for Android or NSData for iOS.
|
||||||
|
*/
|
||||||
|
fromData(data: any): Promise<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads this instance from the specified native image data.
|
* Loads this instance from the specified native image data.
|
||||||
* @param source The Base64 string to load the image from.
|
* @param source The Base64 string to load the image from.
|
||||||
*/
|
*/
|
||||||
loadFromBase64(source: string): boolean;
|
loadFromBase64(source: string): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads this instance from the specified native image data asynchronously.
|
||||||
|
* @param source The Base64 string to load the image from.
|
||||||
|
*/
|
||||||
|
fromBase64(source: string): Promise<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the provided native source object (typically a Bitmap).
|
* Sets the provided native source object (typically a Bitmap).
|
||||||
* This will update either the android or ios properties, depending on the target os.
|
* This will update either the android or ios properties, depending on the target os.
|
||||||
|
@ -11,10 +11,30 @@ export class ImageSource implements definition.ImageSource {
|
|||||||
public ios: UIImage;
|
public ios: UIImage;
|
||||||
|
|
||||||
public loadFromResource(name: string): boolean {
|
public loadFromResource(name: string): boolean {
|
||||||
this.ios = UIImage.imageNamed(name) || UIImage.imageNamed(`${name}.jpg`);
|
this.ios = (<any>UIImage).tns_safeImageNamed(name) || (<any>UIImage).tns_safeImageNamed(`${name}.jpg`);
|
||||||
return this.ios != null;
|
return this.ios != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fromResource(name: string): Promise<boolean> {
|
||||||
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
(<any>UIImage).tns_safeDecodeImageNamedCompletion(name, image => {
|
||||||
|
if (image) {
|
||||||
|
this.ios = image;
|
||||||
|
resolve(true);
|
||||||
|
} else {
|
||||||
|
(<any>UIImage).tns_safeDecodeImageNamedCompletion(`${name}.jpg`, image => {
|
||||||
|
this.ios = image;
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
reject(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public loadFromFile(path: string): boolean {
|
public loadFromFile(path: string): boolean {
|
||||||
var fileName = types.isString(path) ? path.trim() : "";
|
var fileName = types.isString(path) ? path.trim() : "";
|
||||||
|
|
||||||
@ -26,19 +46,67 @@ export class ImageSource implements definition.ImageSource {
|
|||||||
return this.ios != null;
|
return this.ios != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fromFile(path: string): Promise<boolean> {
|
||||||
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
var fileName = types.isString(path) ? path.trim() : "";
|
||||||
|
|
||||||
|
if (fileName.indexOf("~/") === 0) {
|
||||||
|
fileName = fs.path.join(fs.knownFolders.currentApp().path, fileName.replace("~/", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
(<any>UIImage).tns_decodeImageWidthContentsOfFileCompletion(fileName, image => {
|
||||||
|
this.ios = image;
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
reject(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public loadFromData(data: any): boolean {
|
public loadFromData(data: any): boolean {
|
||||||
this.ios = UIImage.imageWithData(data);
|
this.ios = UIImage.imageWithData(data);
|
||||||
return this.ios != null;
|
return this.ios != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fromData(data: any): Promise<boolean> {
|
||||||
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
(<any>UIImage).tns_decodeImageWithDataCompletion(data, image => {
|
||||||
|
this.ios = image;
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
reject(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public loadFromBase64(source: string): boolean {
|
public loadFromBase64(source: string): boolean {
|
||||||
if (types.isString(source)) {
|
if (types.isString(source)) {
|
||||||
var data = NSData.alloc().initWithBase64EncodedStringOptions(source, NSDataBase64DecodingOptions.NSDataBase64DecodingIgnoreUnknownCharacters);
|
var data = NSData.alloc().initWithBase64EncodedStringOptions(source, NSDataBase64DecodingOptions.NSDataBase64DecodingIgnoreUnknownCharacters);
|
||||||
this.ios = UIImage.imageWithData(data);
|
this.ios = UIImage.imageWithData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.ios != null;
|
return this.ios != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fromBase64(source: string): Promise<boolean> {
|
||||||
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
var data = NSData.alloc().initWithBase64EncodedStringOptions(source, NSDataBase64DecodingOptions.NSDataBase64DecodingIgnoreUnknownCharacters);
|
||||||
|
UIImage.imageWithData["async"](UIImage, [data]).then(image => {
|
||||||
|
this.ios = image;
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (ex) {
|
||||||
|
reject(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public setNativeSource(source: any): boolean {
|
public setNativeSource(source: any): boolean {
|
||||||
this.ios = source;
|
this.ios = source;
|
||||||
return source != null;
|
return source != null;
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
},
|
},
|
||||||
"typings": "tns-core-modules.d.ts",
|
"typings": "tns-core-modules.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tns-core-modules-widgets": "2.0.0"
|
"tns-core-modules-widgets": "next"
|
||||||
},
|
},
|
||||||
"nativescript": {
|
"nativescript": {
|
||||||
"platforms": {
|
"platforms": {
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
"declaration": false,
|
"declaration": false,
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"noImplicitUseStrict": true,
|
"noImplicitUseStrict": true,
|
||||||
"experimentalDecorators": true
|
"experimentalDecorators": true,
|
||||||
|
"diagnostics": false
|
||||||
},
|
},
|
||||||
"filesGlob": [
|
"filesGlob": [
|
||||||
"**/*.ts",
|
"**/*.ts",
|
||||||
@ -695,8 +696,8 @@
|
|||||||
"ui/transition/transition.android.ts",
|
"ui/transition/transition.android.ts",
|
||||||
"ui/transition/transition.d.ts",
|
"ui/transition/transition.d.ts",
|
||||||
"ui/transition/transition.ios.ts",
|
"ui/transition/transition.ios.ts",
|
||||||
"ui/transition/fade-transition.d.ts",
|
"ui/transition/fade-transition.d.ts",
|
||||||
"ui/transition/slide-transition.d.ts",
|
"ui/transition/slide-transition.d.ts",
|
||||||
"ui/utils.d.ts",
|
"ui/utils.d.ts",
|
||||||
"ui/utils.ios.ts",
|
"ui/utils.ios.ts",
|
||||||
"ui/web-view/web-view-common.ts",
|
"ui/web-view/web-view-common.ts",
|
||||||
|
@ -11,6 +11,10 @@ import * as types from "utils/types";
|
|||||||
|
|
||||||
var SRC = "src";
|
var SRC = "src";
|
||||||
var IMAGE_SOURCE = "imageSource";
|
var IMAGE_SOURCE = "imageSource";
|
||||||
|
var LOAD_MODE = "loadMode";
|
||||||
|
|
||||||
|
var SYNC = "sync";
|
||||||
|
var ASYNC = "async";
|
||||||
|
|
||||||
var IMAGE = "Image";
|
var IMAGE = "Image";
|
||||||
var ISLOADING = "isLoading";
|
var ISLOADING = "isLoading";
|
||||||
@ -21,41 +25,8 @@ var AffectsLayout = platform.device.os === platform.platformNames.android ? depe
|
|||||||
|
|
||||||
function onSrcPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
function onSrcPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||||
var image = <Image>data.object;
|
var image = <Image>data.object;
|
||||||
var value = data.newValue;
|
// Check for delay...
|
||||||
|
image._createImageSourceFromSrc();
|
||||||
if (types.isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
image.imageSource = null;
|
|
||||||
image["_url"] = value;
|
|
||||||
|
|
||||||
image._setValue(Image.isLoadingProperty, true);
|
|
||||||
|
|
||||||
if (utils.isDataURI(value)) {
|
|
||||||
var base64Data = value.split(",")[1];
|
|
||||||
if (types.isDefined(base64Data)) {
|
|
||||||
image.imageSource = imageSource.fromBase64(base64Data);
|
|
||||||
image._setValue(Image.isLoadingProperty, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (imageSource.isFileOrResourcePath(value)) {
|
|
||||||
image.imageSource = imageSource.fromFileOrResource(value);
|
|
||||||
image._setValue(Image.isLoadingProperty, false);
|
|
||||||
} else {
|
|
||||||
imageSource.fromUrl(value).then((r) => {
|
|
||||||
if (image["_url"] === value) {
|
|
||||||
image.imageSource = r;
|
|
||||||
image._setValue(Image.isLoadingProperty, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (value instanceof imageSource.ImageSource) {
|
|
||||||
// Support binding the imageSource trough the src property
|
|
||||||
image.imageSource = value;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
image.imageSource = imageSource.fromNativeSource(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Image extends view.View implements definition.Image {
|
export class Image extends view.View implements definition.Image {
|
||||||
@ -73,6 +44,9 @@ export class Image extends view.View implements definition.Image {
|
|||||||
public static stretchProperty = new dependencyObservable.Property(STRETCH, IMAGE,
|
public static stretchProperty = new dependencyObservable.Property(STRETCH, IMAGE,
|
||||||
new proxy.PropertyMetadata(enums.Stretch.aspectFit, AffectsLayout));
|
new proxy.PropertyMetadata(enums.Stretch.aspectFit, AffectsLayout));
|
||||||
|
|
||||||
|
public static loadModeProperty = new dependencyObservable.Property(LOAD_MODE, IMAGE,
|
||||||
|
new proxy.PropertyMetadata(SYNC, 0, null, (value) => value === SYNC || value === ASYNC, null));
|
||||||
|
|
||||||
get imageSource(): imageSource.ImageSource {
|
get imageSource(): imageSource.ImageSource {
|
||||||
return this._getValue(Image.imageSourceProperty);
|
return this._getValue(Image.imageSourceProperty);
|
||||||
}
|
}
|
||||||
@ -98,7 +72,80 @@ export class Image extends view.View implements definition.Image {
|
|||||||
this._setValue(Image.stretchProperty, value);
|
this._setValue(Image.stretchProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get loadMode(): "sync" | "async" {
|
||||||
|
return this._getValue(Image.loadModeProperty);
|
||||||
|
}
|
||||||
|
set loadMode(value: "sync" | "async") {
|
||||||
|
this._setValue(Image.loadModeProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
public _setNativeImage(nativeImage: any) {
|
public _setNativeImage(nativeImage: any) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
_createImageSourceFromSrc(): void {
|
||||||
|
var value = this.src;
|
||||||
|
if (types.isString(value)) {
|
||||||
|
value = value.trim();
|
||||||
|
this.imageSource = null;
|
||||||
|
this["_url"] = value;
|
||||||
|
|
||||||
|
this._setValue(Image.isLoadingProperty, true);
|
||||||
|
|
||||||
|
var source = new imageSource.ImageSource();
|
||||||
|
var imageLoaded = () => {
|
||||||
|
this.imageSource = source;
|
||||||
|
this._setValue(Image.isLoadingProperty, false);
|
||||||
|
}
|
||||||
|
if (utils.isDataURI(value)) {
|
||||||
|
var base64Data = value.split(",")[1];
|
||||||
|
if (types.isDefined(base64Data)) {
|
||||||
|
if (this.loadMode === SYNC) {
|
||||||
|
source.loadFromBase64(base64Data);
|
||||||
|
imageLoaded();
|
||||||
|
} else if (this.loadMode === ASYNC) {
|
||||||
|
source.fromBase64(base64Data).then(imageLoaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (imageSource.isFileOrResourcePath(value)) {
|
||||||
|
if (value.indexOf(utils.RESOURCE_PREFIX) === 0) {
|
||||||
|
let resPath = value.substr(utils.RESOURCE_PREFIX.length);
|
||||||
|
if (this.loadMode === SYNC) {
|
||||||
|
source.loadFromResource(resPath);
|
||||||
|
imageLoaded();
|
||||||
|
} else if (this.loadMode === ASYNC) {
|
||||||
|
this.imageSource = null;
|
||||||
|
source.fromResource(resPath).then(imageLoaded);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.loadMode === SYNC) {
|
||||||
|
source.loadFromFile(value);
|
||||||
|
imageLoaded();
|
||||||
|
} else if (this.loadMode === ASYNC) {
|
||||||
|
this.imageSource = null;
|
||||||
|
source.fromFile(value).then(imageLoaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.imageSource = null;
|
||||||
|
imageSource.fromUrl(value).then((r) => {
|
||||||
|
if (this["_url"] === value) {
|
||||||
|
this.imageSource = r;
|
||||||
|
this._setValue(Image.isLoadingProperty, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (value instanceof imageSource.ImageSource) {
|
||||||
|
// Support binding the imageSource trough the src property
|
||||||
|
this.imageSource = value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.imageSource = imageSource.fromNativeSource(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
7
ui/image/image.d.ts
vendored
7
ui/image/image.d.ts
vendored
@ -44,5 +44,12 @@ declare module "ui/image" {
|
|||||||
* Gets or sets the image stretch mode.
|
* Gets or sets the image stretch mode.
|
||||||
*/
|
*/
|
||||||
stretch: string;
|
stretch: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets or sets the loading strategy for images on the local file system:
|
||||||
|
* - **sync** *(default)* - blocks the UI if necessary to display immediately, good for small icons.
|
||||||
|
* - **async** - will try to load in the background, may appear with short delay, good for large images.
|
||||||
|
*/
|
||||||
|
loadMode: "sync" | "async";
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user