From e74ab0a921b179202065e66decb28ec383820bc4 Mon Sep 17 00:00:00 2001 From: Atul R Date: Fri, 29 Nov 2019 20:46:34 +0100 Subject: [PATCH] Adds AnimatedImage component (#79) --- package-lock.json | 6 +- package.json | 2 +- .../AnimatedImage/RNAnimatedImage.ts | 55 +++++++++++++++++++ src/components/AnimatedImage/index.ts | 49 +++++++++++++++++ src/components/Image/RNImage.ts | 24 +++++--- src/components/Image/index.ts | 3 +- src/demo.tsx | 11 +++- src/index.ts | 1 + 8 files changed, 136 insertions(+), 15 deletions(-) create mode 100644 src/components/AnimatedImage/RNAnimatedImage.ts create mode 100644 src/components/AnimatedImage/index.ts diff --git a/package-lock.json b/package-lock.json index ec5d1ee1..ed0c6856 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@nodegui/nodegui": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/@nodegui/nodegui/-/nodegui-0.6.9.tgz", - "integrity": "sha512-owFlHzlpQbj5oPwZrV5kd3fEflohaYrJfBD/8AUIpbSRAMKtde/qHzSdPjXe3r4+hbT8PQn9ROzMsEPdukgl9w==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@nodegui/nodegui/-/nodegui-0.7.0.tgz", + "integrity": "sha512-8F1IrGgDiZeDynME0wYZZwR4vtqIgp2jCPoyUpLpxOqnBWpD3MzsIiSJHqZ4MQcjuReHSFinXaa45X+Y8ZHG3w==", "dev": true, "requires": { "@nodegui/qode": "^1.0.6", diff --git a/package.json b/package.json index f2aa93fd..dd69dba0 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "react": "^16.9.0" }, "devDependencies": { - "@nodegui/nodegui": "^0.6.9", + "@nodegui/nodegui": "^0.7.0", "@types/node": "^12.0.10", "prettier": "^1.18.2", "react": "^16.9.0", diff --git a/src/components/AnimatedImage/RNAnimatedImage.ts b/src/components/AnimatedImage/RNAnimatedImage.ts new file mode 100644 index 00000000..5ada3e42 --- /dev/null +++ b/src/components/AnimatedImage/RNAnimatedImage.ts @@ -0,0 +1,55 @@ +import { QLabel, NodeWidget, QMovie, QSize } from "@nodegui/nodegui"; +import { TextProps, setTextProps } from "../Text/RNText"; +import { RNWidget } from "../config"; +import { throwUnsupported } from "../../utils/helpers"; + +export interface AnimatedImageProps extends TextProps { + src?: string; +} + +const setAnimatedImageProps = ( + widget: RNAnimatedImage, + newProps: AnimatedImageProps, + oldProps: AnimatedImageProps +) => { + const setter: AnimatedImageProps = { + set src(imageUrl: string) { + if (!imageUrl) { + return; + } + const movie = new QMovie(); + movie.setFileName(imageUrl); + widget.setMovie(movie); + const size = widget.size(); + movie.setScaledSize(size); + } + }; + Object.assign(setter, newProps); + setTextProps(widget, newProps, oldProps); +}; + +/** + * @ignore + */ +export class RNAnimatedImage extends QLabel implements RNWidget { + setProps(newProps: AnimatedImageProps, oldProps: AnimatedImageProps): void { + setAnimatedImageProps(this, newProps, oldProps); + } + appendInitialChild(child: NodeWidget): void { + throwUnsupported(this); + } + appendChild(child: NodeWidget): void { + throwUnsupported(this); + } + insertBefore(child: NodeWidget, beforeChild: NodeWidget): void { + throwUnsupported(this); + } + removeChild(child: NodeWidget): void { + throwUnsupported(this); + } + static tagName = "animatedimage"; + scaleMovie(size: QSize) { + const movie = this.movie(); + movie?.setScaledSize(size); + } +} diff --git a/src/components/AnimatedImage/index.ts b/src/components/AnimatedImage/index.ts new file mode 100644 index 00000000..ee3317e8 --- /dev/null +++ b/src/components/AnimatedImage/index.ts @@ -0,0 +1,49 @@ +import { Fiber } from "react-reconciler"; +import { registerComponent, ComponentConfig } from "../config"; +import { RNAnimatedImage, AnimatedImageProps } from "./RNAnimatedImage"; +import { AppContainer } from "../../reconciler"; +import { QLabelEvents } from "@nodegui/nodegui"; + +class AnimatedImageConfig extends ComponentConfig { + tagName = RNAnimatedImage.tagName; + shouldSetTextContent(nextProps: AnimatedImageProps): boolean { + return true; + } + createInstance( + newProps: AnimatedImageProps, + rootInstance: AppContainer, + context: any, + workInProgress: Fiber + ): RNAnimatedImage { + const widget = new RNAnimatedImage(); + widget.setProps(newProps, {}); + widget.movie()?.start(); + widget.addEventListener(QLabelEvents.Resize, () => { + widget.scaleMovie(widget.size()); + }); + return widget; + } + commitMount( + instance: RNAnimatedImage, + newProps: AnimatedImageProps, + internalInstanceHandle: any + ): void { + if (newProps.visible !== false) { + instance.show(); + } + return; + } + commitUpdate( + instance: RNAnimatedImage, + updatePayload: any, + oldProps: AnimatedImageProps, + newProps: AnimatedImageProps, + finishedWork: Fiber + ): void { + instance.setProps(newProps, oldProps); + } +} + +export const AnimatedImage = registerComponent( + new AnimatedImageConfig() +); diff --git a/src/components/Image/RNImage.ts b/src/components/Image/RNImage.ts index 02bebf1c..ae6d2362 100644 --- a/src/components/Image/RNImage.ts +++ b/src/components/Image/RNImage.ts @@ -1,4 +1,10 @@ -import { QLabel, QPixmap, AspectRatioMode, NodeWidget } from "@nodegui/nodegui"; +import { + QLabel, + QPixmap, + AspectRatioMode, + NodeWidget, + QSize +} from "@nodegui/nodegui"; import { TextProps, setTextProps } from "../Text/RNText"; import { RNWidget } from "../config"; import { throwUnsupported } from "../../utils/helpers"; @@ -21,7 +27,7 @@ const setImageProps = ( const pixMap = new QPixmap(imageUrl); widget.setPixmap(pixMap); const size = widget.size(); - widget.scalePixmap(size.width(), size.height()); + widget.scalePixmap(size); }, set aspectRatioMode(mode: AspectRatioMode) { widget.setAspectRatioMode(mode); @@ -58,15 +64,19 @@ export class RNImage extends QLabel implements RNWidget { super.setPixmap(pixmap); this.originalPixmap = pixmap; }; - setAspectRatioMode = (mode: AspectRatioMode) => { + setAspectRatioMode(mode: AspectRatioMode) { // react:✓ TODO://getter this.aspectRatioMode = mode; - }; - scalePixmap = (width: number, height: number) => { + } + scalePixmap(size: QSize) { if (this.originalPixmap) { return super.setPixmap( - this.originalPixmap.scaled(width, height, this.aspectRatioMode) + this.originalPixmap.scaled( + size.width(), + size.height(), + this.aspectRatioMode + ) ); } - }; + } } diff --git a/src/components/Image/index.ts b/src/components/Image/index.ts index 1ad8faf2..7d8a37ee 100644 --- a/src/components/Image/index.ts +++ b/src/components/Image/index.ts @@ -17,8 +17,7 @@ class ImageConfig extends ComponentConfig { const widget = new RNImage(); widget.setProps(newProps, {}); widget.addEventListener(QLabelEvents.Resize, () => { - const size = widget.size(); - widget.scalePixmap(size.width(), size.height()); + widget.scalePixmap(widget.size()); }); return widget; } diff --git a/src/demo.tsx b/src/demo.tsx index ae17b8b6..d29a0f57 100644 --- a/src/demo.tsx +++ b/src/demo.tsx @@ -1,12 +1,19 @@ import React from "react"; import { Renderer, Button, Window, View } from "./index"; +import { AnimatedImage } from "./components/AnimatedImage"; const App = () => { return ( -