Skip to content
This repository has been archived by the owner on Mar 29, 2021. It is now read-only.

Support image fallback solution for token required Avatar #94

Draft
wants to merge 2 commits into
base: release_0.1.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
registry=https://msasg.pkgs.visualstudio.com/_packaging/react-native-cortana-conversation/npm/registry/
always-auth=true
1 change: 1 addition & 0 deletions dist/Components/Basic/ImageBlock.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface IProps {
onLayout?: (event: LayoutChangeEvent) => void;
onLoad?: (data: any) => void;
onError?: (error: any) => void;
avatarFallbackRender?: (diameter: number, altText: string, url: string) => React.ReactNode;
}
interface IState {
loaded: boolean;
Expand Down
13 changes: 12 additions & 1 deletion dist/Components/Basic/ImageBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,18 @@ export class ImageBlock extends React.Component {
], resizeMethod: 'resize', resizeMode: 'contain' }));
}
renderImage() {
if (UrlUtils.isSvgXml(this.props.url)) {
if (this.props.mode === 'avatar' && this.props.avatarFallbackRender) {
return React.createElement(View, { style: [
{
width: this.props.width,
height: this.props.height,
overflow: 'hidden',
},
this.borderRadius,
this.props.style
] }, this.props.avatarFallbackRender(this.props.width, this.props.alt, this.props.url));
}
else if (UrlUtils.isSvgXml(this.props.url)) {
return (React.createElement(View, { style: [
{
width: this.props.width,
Expand Down
4 changes: 4 additions & 0 deletions dist/Contexts/CardContext.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ReactNode } from 'react';
import { CardModel } from '../Models/Cards/Card';
import { TreeNode } from '../Shared/Types';
import { FormStore } from './FormStore';
Expand All @@ -13,6 +14,7 @@ export declare class CardContext extends TreeNode<CardContext> {
private onSubmitAction?;
private onCallbackAction?;
private onSelectAction?;
private avatarFallbackRender?;
readonly form: FormStore;
readonly schemas: SchemaStore;
readonly children: CardContext[];
Expand All @@ -31,6 +33,7 @@ export declare class CardContext extends TreeNode<CardContext> {
[key: string]: string;
}) => Promise<any>): void;
registerSelectActionHandler(handler: (data: any) => Promise<any>): void;
registerAvatarFallbackRenderHandler(handler: (diameter: number, altText: string, url: string) => ReactNode): void;
private findRequiredContext;
readonly errorHandler: (error: any) => void;
readonly infoHandler: (info: any) => void;
Expand All @@ -44,4 +47,5 @@ export declare class CardContext extends TreeNode<CardContext> {
[key: string]: string;
}) => Promise<any>;
readonly selectActionHandler: (data: any) => Promise<any>;
readonly avatarFallbackRenderHandler: (diameter: number, altText: string, url: string) => ReactNode;
}
10 changes: 10 additions & 0 deletions dist/Contexts/CardContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ export class CardContext extends TreeNode {
registerSelectActionHandler(handler) {
this.onSelectAction = handler;
}
registerAvatarFallbackRenderHandler(handler) {
this.avatarFallbackRender = handler;
}
findRequiredContext(selector) {
if (selector) {
if (selector(this)) {
Expand Down Expand Up @@ -129,4 +132,11 @@ export class CardContext extends TreeNode {
}
return undefined;
}
get avatarFallbackRenderHandler() {
let context = this.findRequiredContext(context => context.avatarFallbackRender !== undefined);
if (context) {
return context.avatarFallbackRender;
}
return undefined;
}
}
18 changes: 16 additions & 2 deletions dist/Views/CardElements/Image.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,21 @@ export class ImageView extends React.Component {
handler(`AdaptiveCard >> Start Load Image >> ${model.url}`);
}
}
ImageUtils.fetchSize(model.url, size || model.size, { width: maxWidth, height: maxHeight }, this.onImageSize, this.onImageSizeError);
if (model.style === 'person' && model.context.avatarFallbackRenderHandler) {
const definedSize = StyleManager.getImageSize(size || model.size);
if (typeof definedSize === 'number') {
this.onImageSize({
width: definedSize,
height: definedSize
});
}
else {
this.onImageSizeError(new Error('Avatar image size should be actual number.'));
}
}
else {
ImageUtils.fetchSize(model.url, size || model.size, { width: maxWidth, height: maxHeight }, this.onImageSize, this.onImageSizeError);
}
}
};
this.state = {
Expand All @@ -107,7 +121,7 @@ export class ImageView extends React.Component {
return DebugOutputFactory.createDebugOutputBanner(model.type + '>>' + model.url + ' is not valid', theme, 'error');
}
if (this.state.loaded) {
return (React.createElement(ImageBlock, { url: model.url, alt: model.alt, flex: this.flex, alignSelf: StyleManager.getHorizontalAlign(model.horizontalAlignment), width: this.state.width, height: this.state.height, onPress: model.selectAction ? this.onPress : undefined, onLayout: this.onLayout, onLoad: this.onImageLoad, onError: this.onImageError, marginTop: this.spacing, marginLeft: spacing, mode: model.style === 'person' ? 'avatar' : 'default' }));
return (React.createElement(ImageBlock, { url: model.url, alt: model.alt, flex: this.flex, alignSelf: StyleManager.getHorizontalAlign(model.horizontalAlignment), width: this.state.width, height: this.state.height, onPress: model.selectAction ? this.onPress : undefined, onLayout: this.onLayout, onLoad: this.onImageLoad, onError: this.onImageError, marginTop: this.spacing, marginLeft: spacing, mode: model.style === 'person' ? 'avatar' : 'default', avatarFallbackRender: model.context && model.context.avatarFallbackRenderHandler }));
}
return null;
}
Expand Down
3 changes: 2 additions & 1 deletion dist/Views/Root.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { ReactNode } from 'react';
import { CardContext } from '../Contexts/CardContext';
export interface IAdaptiveCardProps {
adaptiveCard: any;
Expand All @@ -14,6 +14,7 @@ export interface IAdaptiveCardProps {
onError?: (error: any) => void;
onInfo?: (info: any) => void;
onWarning?: (warning: any) => void;
avatarFallbackRender?: (diameter: number, altText: string, url: string) => ReactNode;
}
export declare class CardRootView extends React.Component<IAdaptiveCardProps> {
rootCardContext: CardContext;
Expand Down
1 change: 1 addition & 0 deletions dist/Views/Root.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class CardRootView extends React.Component {
this.rootCardContext.registerErrorHandler(this.props.onError);
this.rootCardContext.registerInfoHandler(this.props.onInfo);
this.rootCardContext.registerWarningHandler(this.props.onWarning);
this.rootCardContext.registerAvatarFallbackRenderHandler(this.props.avatarFallbackRender);
}
shouldComponentUpdate(nextProps) {
if (JSON.stringify(nextProps) !== JSON.stringify(this.props)) {
Expand Down
1 change: 1 addition & 0 deletions examples/AdaptiveCards/Components/Basic/ImageBlock.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface IProps {
onLayout?: (event: LayoutChangeEvent) => void;
onLoad?: (data: any) => void;
onError?: (error: any) => void;
avatarFallbackRender?: (diameter: number, altText: string, url: string) => React.ReactNode;
}
interface IState {
loaded: boolean;
Expand Down
13 changes: 12 additions & 1 deletion examples/AdaptiveCards/Components/Basic/ImageBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,18 @@ export class ImageBlock extends React.Component {
], resizeMethod: 'resize', resizeMode: 'contain' }));
}
renderImage() {
if (UrlUtils.isSvgXml(this.props.url)) {
if (this.props.mode === 'avatar' && this.props.avatarFallbackRender) {
return React.createElement(View, { style: [
{
width: this.props.width,
height: this.props.height,
overflow: 'hidden',
},
this.borderRadius,
this.props.style
] }, this.props.avatarFallbackRender(this.props.width, this.props.alt, this.props.url));
}
else if (UrlUtils.isSvgXml(this.props.url)) {
return (React.createElement(View, { style: [
{
width: this.props.width,
Expand Down
4 changes: 4 additions & 0 deletions examples/AdaptiveCards/Contexts/CardContext.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ReactNode } from 'react';
import { CardModel } from '../Models/Cards/Card';
import { TreeNode } from '../Shared/Types';
import { FormStore } from './FormStore';
Expand All @@ -13,6 +14,7 @@ export declare class CardContext extends TreeNode<CardContext> {
private onSubmitAction?;
private onCallbackAction?;
private onSelectAction?;
private avatarFallbackRender?;
readonly form: FormStore;
readonly schemas: SchemaStore;
readonly children: CardContext[];
Expand All @@ -31,6 +33,7 @@ export declare class CardContext extends TreeNode<CardContext> {
[key: string]: string;
}) => Promise<any>): void;
registerSelectActionHandler(handler: (data: any) => Promise<any>): void;
registerAvatarFallbackRenderHandler(handler: (diameter: number, altText: string, url: string) => ReactNode): void;
private findRequiredContext;
readonly errorHandler: (error: any) => void;
readonly infoHandler: (info: any) => void;
Expand All @@ -44,4 +47,5 @@ export declare class CardContext extends TreeNode<CardContext> {
[key: string]: string;
}) => Promise<any>;
readonly selectActionHandler: (data: any) => Promise<any>;
readonly avatarFallbackRenderHandler: (diameter: number, altText: string, url: string) => ReactNode;
}
10 changes: 10 additions & 0 deletions examples/AdaptiveCards/Contexts/CardContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ export class CardContext extends TreeNode {
registerSelectActionHandler(handler) {
this.onSelectAction = handler;
}
registerAvatarFallbackRenderHandler(handler) {
this.avatarFallbackRender = handler;
}
findRequiredContext(selector) {
if (selector) {
if (selector(this)) {
Expand Down Expand Up @@ -129,4 +132,11 @@ export class CardContext extends TreeNode {
}
return undefined;
}
get avatarFallbackRenderHandler() {
let context = this.findRequiredContext(context => context.avatarFallbackRender !== undefined);
if (context) {
return context.avatarFallbackRender;
}
return undefined;
}
}
18 changes: 16 additions & 2 deletions examples/AdaptiveCards/Views/CardElements/Image.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,21 @@ export class ImageView extends React.Component {
handler(`AdaptiveCard >> Start Load Image >> ${model.url}`);
}
}
ImageUtils.fetchSize(model.url, size || model.size, { width: maxWidth, height: maxHeight }, this.onImageSize, this.onImageSizeError);
if (model.style === 'person' && model.context.avatarFallbackRenderHandler) {
const definedSize = StyleManager.getImageSize(size || model.size);
if (typeof definedSize === 'number') {
this.onImageSize({
width: definedSize,
height: definedSize
});
}
else {
this.onImageSizeError(new Error('Avatar image size should be actual number.'));
}
}
else {
ImageUtils.fetchSize(model.url, size || model.size, { width: maxWidth, height: maxHeight }, this.onImageSize, this.onImageSizeError);
}
}
};
this.state = {
Expand All @@ -107,7 +121,7 @@ export class ImageView extends React.Component {
return DebugOutputFactory.createDebugOutputBanner(model.type + '>>' + model.url + ' is not valid', theme, 'error');
}
if (this.state.loaded) {
return (React.createElement(ImageBlock, { url: model.url, alt: model.alt, flex: this.flex, alignSelf: StyleManager.getHorizontalAlign(model.horizontalAlignment), width: this.state.width, height: this.state.height, onPress: model.selectAction ? this.onPress : undefined, onLayout: this.onLayout, onLoad: this.onImageLoad, onError: this.onImageError, marginTop: this.spacing, marginLeft: spacing, mode: model.style === 'person' ? 'avatar' : 'default' }));
return (React.createElement(ImageBlock, { url: model.url, alt: model.alt, flex: this.flex, alignSelf: StyleManager.getHorizontalAlign(model.horizontalAlignment), width: this.state.width, height: this.state.height, onPress: model.selectAction ? this.onPress : undefined, onLayout: this.onLayout, onLoad: this.onImageLoad, onError: this.onImageError, marginTop: this.spacing, marginLeft: spacing, mode: model.style === 'person' ? 'avatar' : 'default', avatarFallbackRender: model.context && model.context.avatarFallbackRenderHandler }));
}
return null;
}
Expand Down
3 changes: 2 additions & 1 deletion examples/AdaptiveCards/Views/Root.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { ReactNode } from 'react';
import { CardContext } from '../Contexts/CardContext';
export interface IAdaptiveCardProps {
adaptiveCard: any;
Expand All @@ -14,6 +14,7 @@ export interface IAdaptiveCardProps {
onError?: (error: any) => void;
onInfo?: (info: any) => void;
onWarning?: (warning: any) => void;
avatarFallbackRender?: (diameter: number, altText: string, url: string) => ReactNode;
}
export declare class CardRootView extends React.Component<IAdaptiveCardProps> {
rootCardContext: CardContext;
Expand Down
1 change: 1 addition & 0 deletions examples/AdaptiveCards/Views/Root.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class CardRootView extends React.Component {
this.rootCardContext.registerErrorHandler(this.props.onError);
this.rootCardContext.registerInfoHandler(this.props.onInfo);
this.rootCardContext.registerWarningHandler(this.props.onWarning);
this.rootCardContext.registerAvatarFallbackRenderHandler(this.props.avatarFallbackRender);
}
shouldComponentUpdate(nextProps) {
if (JSON.stringify(nextProps) !== JSON.stringify(this.props)) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-native-adaptivecards",
"description": "React Native implementation of AdaptiveCards.",
"version": "0.1.37",
"version": "0.1.38",
"repository": {
"url": "git+https://github.com/Microsoft/react-native-adaptivecards",
"type": "git"
Expand Down
17 changes: 16 additions & 1 deletion src/Components/Basic/ImageBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ interface IProps {
onLayout?: (event: LayoutChangeEvent) => void;
onLoad?: (data: any) => void;
onError?: (error: any) => void;
avatarFallbackRender?: (diameter: number, altText: string, url: string) => React.ReactNode;
}

interface IState {
Expand Down Expand Up @@ -137,7 +138,21 @@ export class ImageBlock extends React.Component<IProps, IState> {
}

private renderImage() {
if (UrlUtils.isSvgXml(this.props.url)) {
if (this.props.mode === 'avatar' && this.props.avatarFallbackRender) {
return <View
style={[
{
width: this.props.width,
height: this.props.height,
overflow: 'hidden',
},
this.borderRadius,
this.props.style
]}
>
{this.props.avatarFallbackRender(this.props.width, this.props.alt, this.props.url)}
</View>;
} else if (UrlUtils.isSvgXml(this.props.url)) {
return (
<View
style={[
Expand Down
20 changes: 17 additions & 3 deletions src/Contexts/CardContext.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ReactNode } from 'react';
import { CardModel } from '../Models/Cards/Card';
import { TreeNode } from '../Shared/Types';
import { FormStore } from './FormStore';
Expand All @@ -14,6 +15,7 @@ export class CardContext extends TreeNode<CardContext> {
private onSubmitAction?: (data: any) => Promise<any>;
private onCallbackAction?: (url: string, parameters: { [key: string]: string }) => Promise<any>;
private onSelectAction?: (data: any) => Promise<any>;
private avatarFallbackRender?: (diameter: number, altText: string, url: string) => ReactNode;
public readonly form: FormStore;
public readonly schemas: SchemaStore;
public readonly children: CardContext[] = [];
Expand Down Expand Up @@ -75,6 +77,10 @@ export class CardContext extends TreeNode<CardContext> {
this.onSelectAction = handler;
}

public registerAvatarFallbackRenderHandler(handler: (diameter: number, altText: string, url: string) => ReactNode) {
this.avatarFallbackRender = handler;
}

private findRequiredContext(selector: (context: CardContext) => boolean): CardContext {
if (selector) {
if (selector(this)) {
Expand All @@ -95,23 +101,23 @@ export class CardContext extends TreeNode<CardContext> {
return undefined;
}

public get infoHandler() : (info: any) => void {
public get infoHandler(): (info: any) => void {
let context = this.findRequiredContext(context => context.onInfo !== undefined);
if (context) {
return context.onInfo;
}
return undefined;
}

public get warningHandler() : (warning: any) => void {
public get warningHandler(): (warning: any) => void {
let context = this.findRequiredContext(context => context.onWarning !== undefined);
if (context) {
return context.onWarning;
}
return undefined;
}

public get focusHandler() : () => void {
public get focusHandler(): () => void {
let context = this.findRequiredContext(context => context.onFocus !== undefined);
if (context) {
return context.onFocus;
Expand Down Expand Up @@ -166,4 +172,12 @@ export class CardContext extends TreeNode<CardContext> {
}
return undefined;
}

public get avatarFallbackRenderHandler(): (diameter: number, altText: string, url: string) => ReactNode {
let context = this.findRequiredContext(context => context.avatarFallbackRender !== undefined);
if (context) {
return context.avatarFallbackRender;
}
return undefined;
}
}
Loading