[IMPROVE] - migrating the UIKit container (in progress)
This commit is contained in:
parent
369b3f2ef6
commit
9a1b705471
|
@ -1,31 +1,29 @@
|
|||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||
|
||||
import Button from '../Button';
|
||||
import I18n from '../../i18n';
|
||||
|
||||
export const Actions = ({
|
||||
blockId, appId, elements, parser, theme
|
||||
}) => {
|
||||
interface IActions {
|
||||
blockId: string;
|
||||
appId: string;
|
||||
elements: any[];
|
||||
parser: any;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
export const Actions = ({ blockId, appId, elements, parser, theme }: IActions) => {
|
||||
const [showMoreVisible, setShowMoreVisible] = useState(() => elements.length > 5);
|
||||
const renderedElements = showMoreVisible ? elements.slice(0, 5) : elements;
|
||||
|
||||
const Elements = () => renderedElements
|
||||
.map(element => parser.renderActions({ blockId, appId, ...element }, BLOCK_CONTEXT.ACTION, parser));
|
||||
.map((element: any) => parser.renderActions({ blockId, appId, ...element }, BLOCK_CONTEXT.ACTION, parser));
|
||||
|
||||
return (
|
||||
<>
|
||||
{/*@ts-ignore*/}
|
||||
<Elements />
|
||||
{showMoreVisible && (<Button theme={theme} title={I18n.t('Show_more')} onPress={() => setShowMoreVisible(false)} />)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Actions.propTypes = {
|
||||
blockId: PropTypes.string,
|
||||
appId: PropTypes.string,
|
||||
elements: PropTypes.array,
|
||||
parser: PropTypes.object,
|
||||
theme: PropTypes.string
|
||||
};
|
|
@ -11,11 +11,12 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
export const Context = ({ elements, parser }) => (
|
||||
export const Context = ({ elements, parser }: any) => (
|
||||
<View style={styles.container}>
|
||||
{elements.map(element => parser.renderContext(element, BLOCK_CONTEXT.CONTEXT, parser))}
|
||||
{elements.map((element: any) => parser.renderContext(element, BLOCK_CONTEXT.CONTEXT, parser))}
|
||||
</View>
|
||||
);
|
||||
|
||||
Context.propTypes = {
|
||||
elements: PropTypes.array,
|
||||
parser: PropTypes.object
|
|
@ -1,6 +1,5 @@
|
|||
import React, { useState } from 'react';
|
||||
import { View, StyleSheet, Text } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import DateTimePicker from '@react-native-community/datetimepicker';
|
||||
import Touchable from 'react-native-platform-touchable';
|
||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||
|
@ -37,14 +36,28 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
interface IDatePicker {
|
||||
element: {
|
||||
initial_date: any;
|
||||
placeholder: string;
|
||||
};
|
||||
language: string;
|
||||
action: Function;
|
||||
context: number;
|
||||
loading: boolean;
|
||||
theme: string;
|
||||
value: string;
|
||||
error: string;
|
||||
}
|
||||
|
||||
export const DatePicker = ({
|
||||
element, language, action, context, theme, loading, value, error
|
||||
}) => {
|
||||
}: IDatePicker) => {
|
||||
const [show, onShow] = useState(false);
|
||||
const { initial_date, placeholder } = element;
|
||||
const [currentDate, onChangeDate] = useState(new Date(initial_date || value));
|
||||
|
||||
const onChange = ({ nativeEvent: { timestamp } }, date) => {
|
||||
const onChange = ({ nativeEvent: { timestamp } }: any, date: any) => {
|
||||
const newDate = date || new Date(timestamp);
|
||||
onChangeDate(newDate);
|
||||
action({ value: moment(newDate).format('YYYY-MM-DD') });
|
||||
|
@ -105,13 +118,3 @@ export const DatePicker = ({
|
|||
</>
|
||||
);
|
||||
};
|
||||
DatePicker.propTypes = {
|
||||
element: PropTypes.object,
|
||||
language: PropTypes.string,
|
||||
action: PropTypes.func,
|
||||
context: PropTypes.number,
|
||||
loading: PropTypes.bool,
|
||||
theme: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
error: PropTypes.string
|
||||
};
|
|
@ -1,7 +1,6 @@
|
|||
import React from 'react';
|
||||
import { View, StyleSheet } from 'react-native';
|
||||
import FastImage from '@rocket.chat/react-native-fast-image';
|
||||
import PropTypes from 'prop-types';
|
||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||
|
||||
import ImageContainer from '../message/Image';
|
||||
|
@ -16,21 +15,37 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
const ThumbContext = args => <View style={styles.mediaContext}><Thumb size={20} {...args} /></View>;
|
||||
type TThumb = {
|
||||
element: {
|
||||
imageUrl: string;
|
||||
};
|
||||
size?: number;
|
||||
};
|
||||
|
||||
export const Thumb = ({ element, size = 88 }) => (
|
||||
type TMedia = {
|
||||
element: {
|
||||
imageUrl: string;
|
||||
};
|
||||
theme: string;
|
||||
};
|
||||
|
||||
interface IImage {
|
||||
element: any;
|
||||
context: any;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
const ThumbContext = (args: any) => <View style={styles.mediaContext}><Thumb size={20} {...args} /></View>;
|
||||
|
||||
export const Thumb = ({ element, size = 88 }: TThumb) => (
|
||||
<FastImage
|
||||
style={[{ width: size, height: size }, styles.image]}
|
||||
source={{ uri: element.imageUrl }}
|
||||
/>
|
||||
);
|
||||
Thumb.propTypes = {
|
||||
element: PropTypes.object,
|
||||
size: PropTypes.number
|
||||
};
|
||||
|
||||
export const Media = ({ element, theme }) => {
|
||||
const showAttachment = attachment => Navigation.navigate('AttachmentView', { attachment });
|
||||
export const Media = ({ element, theme }: TMedia) => {
|
||||
const showAttachment = (attachment: any) => Navigation.navigate('AttachmentView', { attachment });
|
||||
const { imageUrl } = element;
|
||||
|
||||
return (
|
||||
|
@ -42,12 +57,8 @@ export const Media = ({ element, theme }) => {
|
|||
/>
|
||||
);
|
||||
};
|
||||
Media.propTypes = {
|
||||
element: PropTypes.object,
|
||||
theme: PropTypes.string
|
||||
};
|
||||
|
||||
const genericImage = (element, context, theme) => {
|
||||
const genericImage = (element: any, context: any, theme: string) => {
|
||||
switch (context) {
|
||||
case BLOCK_CONTEXT.SECTION:
|
||||
return <Thumb element={element} />;
|
||||
|
@ -58,4 +69,4 @@ const genericImage = (element, context, theme) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const Image = ({ element, context, theme }) => genericImage(element, context, theme);
|
||||
export const Image = ({ element, context, theme }: IImage) => genericImage(element, context, theme);
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||
|
||||
import sharedStyles from '../../views/Styles';
|
||||
|
@ -32,9 +31,19 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
interface IInput {
|
||||
element: object;
|
||||
parser: any;
|
||||
label: string;
|
||||
description: string;
|
||||
error: string;
|
||||
hint: string;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
export const Input = ({
|
||||
element, parser, label, description, error, hint, theme
|
||||
}) => (
|
||||
}: IInput) => (
|
||||
<View style={styles.container}>
|
||||
{label ? <Text style={[styles.label, { color: error ? themes[theme].dangerColor : themes[theme].titleText }]}>{label}</Text> : null}
|
||||
{description ? <Text style={[styles.description, { color: themes[theme].auxiliaryText }]}>{description}</Text> : null}
|
||||
|
@ -43,13 +52,3 @@ export const Input = ({
|
|||
{hint ? <Text style={[styles.hint, { color: themes[theme].auxiliaryText }]}>{hint}</Text> : null}
|
||||
</View>
|
||||
);
|
||||
|
||||
Input.propTypes = {
|
||||
element: PropTypes.object,
|
||||
parser: PropTypes.object,
|
||||
label: PropTypes.string,
|
||||
description: PropTypes.string,
|
||||
error: PropTypes.string,
|
||||
hint: PropTypes.string,
|
||||
theme: PropTypes.string
|
||||
};
|
|
@ -1,27 +0,0 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { UiKitMessage, UiKitModal } from './index';
|
||||
import { KitContext } from './utils';
|
||||
|
||||
export const messageBlockWithContext = context => props => (
|
||||
<KitContext.Provider value={context}>
|
||||
<MessageBlock {...props} />
|
||||
</KitContext.Provider>
|
||||
);
|
||||
|
||||
const MessageBlock = ({ blocks }) => UiKitMessage(blocks);
|
||||
MessageBlock.propTypes = {
|
||||
blocks: PropTypes.any
|
||||
};
|
||||
|
||||
export const modalBlockWithContext = context => data => (
|
||||
<KitContext.Provider value={{ ...context, ...data }}>
|
||||
<ModalBlock {...data} />
|
||||
</KitContext.Provider>
|
||||
);
|
||||
|
||||
const ModalBlock = ({ blocks }) => UiKitModal(blocks);
|
||||
ModalBlock.propTypes = {
|
||||
blocks: PropTypes.any
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
import React from 'react';
|
||||
|
||||
import { UiKitMessage, UiKitModal } from './index';
|
||||
import { KitContext } from './utils';
|
||||
|
||||
export const messageBlockWithContext = (context: any) => (props: any) => (
|
||||
<KitContext.Provider value={context}>
|
||||
<MessageBlock {...props} />
|
||||
</KitContext.Provider>
|
||||
);
|
||||
|
||||
const MessageBlock = ({ blocks }: any) => UiKitMessage(blocks);
|
||||
|
||||
export const modalBlockWithContext = (context: any) => (data: any) => (
|
||||
<KitContext.Provider value={{ ...context, ...data }}>
|
||||
<ModalBlock {...data} />
|
||||
</KitContext.Provider>
|
||||
);
|
||||
|
||||
const ModalBlock = ({ blocks }: any) => UiKitModal(blocks);
|
|
@ -10,7 +10,32 @@ import { themes } from '../../constants/colors';
|
|||
import { BUTTON_HIT_SLOP } from '../message/utils';
|
||||
import * as List from '../List';
|
||||
|
||||
const keyExtractor = item => item.value;
|
||||
type TOption = {
|
||||
option: {
|
||||
text: string;
|
||||
value: string;
|
||||
};
|
||||
onOptionPress: Function;
|
||||
parser: any;
|
||||
theme: string;
|
||||
};
|
||||
|
||||
type TOptions = {
|
||||
options: [];
|
||||
onOptionPress: Function;
|
||||
parser: object;
|
||||
theme: string;
|
||||
};
|
||||
|
||||
interface IOverflow {
|
||||
element: any;
|
||||
action: Function;
|
||||
loading: boolean;
|
||||
parser: object;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
const keyExtractor = (item: any) => item.value;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
menu: {
|
||||
|
@ -25,9 +50,7 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
const Option = ({
|
||||
option: { text, value }, onOptionPress, parser, theme
|
||||
}) => (
|
||||
const Option = ({ option: { text, value }, onOptionPress, parser, theme }: TOption) => (
|
||||
<Touchable
|
||||
onPress={() => onOptionPress({ value })}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
|
@ -36,16 +59,8 @@ const Option = ({
|
|||
<Text>{parser.text(text)}</Text>
|
||||
</Touchable>
|
||||
);
|
||||
Option.propTypes = {
|
||||
option: PropTypes.object,
|
||||
onOptionPress: PropTypes.func,
|
||||
parser: PropTypes.object,
|
||||
theme: PropTypes.string
|
||||
};
|
||||
|
||||
const Options = ({
|
||||
options, onOptionPress, parser, theme
|
||||
}) => (
|
||||
const Options = ({ options, onOptionPress, parser, theme }: TOptions) => (
|
||||
<FlatList
|
||||
data={options}
|
||||
renderItem={({ item }) => <Option option={item} onOptionPress={onOptionPress} parser={parser} theme={theme} />}
|
||||
|
@ -53,22 +68,14 @@ const Options = ({
|
|||
ItemSeparatorComponent={List.Separator}
|
||||
/>
|
||||
);
|
||||
Options.propTypes = {
|
||||
options: PropTypes.array,
|
||||
onOptionPress: PropTypes.func,
|
||||
parser: PropTypes.object,
|
||||
theme: PropTypes.string
|
||||
};
|
||||
|
||||
const touchable = {};
|
||||
|
||||
export const Overflow = ({
|
||||
element, loading, action, parser, theme
|
||||
}) => {
|
||||
export const Overflow = ({ element, loading, action, parser, theme }: IOverflow) => {
|
||||
const { options, blockId } = element;
|
||||
const [show, onShow] = useState(false);
|
||||
|
||||
const onOptionPress = ({ value }) => {
|
||||
const onOptionPress = ({ value }: any) => {
|
||||
onShow(false);
|
||||
action({ value });
|
||||
};
|
||||
|
@ -76,6 +83,7 @@ export const Overflow = ({
|
|||
return (
|
||||
<>
|
||||
<Touchable
|
||||
/*@ts-ignore*/
|
||||
ref={ref => touchable[blockId] = ref}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
onPress={() => onShow(!show)}
|
||||
|
@ -86,6 +94,7 @@ export const Overflow = ({
|
|||
</Touchable>
|
||||
<Popover
|
||||
isVisible={show}
|
||||
/*@ts-ignore*/
|
||||
fromView={touchable[blockId]}
|
||||
onRequestClose={() => onShow(false)}
|
||||
>
|
||||
|
@ -94,10 +103,3 @@ export const Overflow = ({
|
|||
</>
|
||||
);
|
||||
};
|
||||
Overflow.propTypes = {
|
||||
element: PropTypes.any,
|
||||
action: PropTypes.func,
|
||||
loading: PropTypes.bool,
|
||||
parser: PropTypes.object,
|
||||
theme: PropTypes.string
|
||||
};
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react';
|
||||
import { View, Text, StyleSheet } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||
|
||||
import { themes } from '../../constants/colors';
|
||||
|
@ -24,15 +23,36 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
const Accessory = ({
|
||||
blockId, appId, element, parser
|
||||
}) => parser.renderAccessories(
|
||||
type TAccessory = {
|
||||
blockId?: string;
|
||||
appId?: string;
|
||||
element: any;
|
||||
parser: any
|
||||
}
|
||||
|
||||
type TFields = {
|
||||
fields: any;
|
||||
parser: any;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
interface ISection {
|
||||
blockId: string;
|
||||
appId: string;
|
||||
text: object;
|
||||
fields: [];
|
||||
accessory: any;
|
||||
theme: string;
|
||||
parser: any;
|
||||
}
|
||||
|
||||
const Accessory = ({ blockId, appId, element, parser }: TAccessory) => parser.renderAccessories(
|
||||
{ blockId, appId, ...element },
|
||||
BLOCK_CONTEXT.SECTION,
|
||||
parser
|
||||
);
|
||||
|
||||
const Fields = ({ fields, parser, theme }) => fields.map(field => (
|
||||
const Fields = ({ fields, parser, theme }: TFields) => fields.map((field: any) => (
|
||||
<Text style={[styles.text, styles.field, { color: themes[theme].bodyText }]}>
|
||||
{parser.text(field)}
|
||||
</Text>
|
||||
|
@ -40,9 +60,7 @@ const Fields = ({ fields, parser, theme }) => fields.map(field => (
|
|||
|
||||
const accessoriesRight = ['image', 'overflow'];
|
||||
|
||||
export const Section = ({
|
||||
blockId, appId, text, fields, accessory, parser, theme
|
||||
}) => (
|
||||
export const Section = ({ blockId, appId, text, fields, accessory, parser, theme }: ISection) => (
|
||||
<View
|
||||
style={[
|
||||
styles.content,
|
||||
|
@ -54,12 +72,3 @@ export const Section = ({
|
|||
{accessory ? <Accessory element={{ blockId, appId, ...accessory }} parser={parser} /> : null}
|
||||
</View>
|
||||
);
|
||||
Section.propTypes = {
|
||||
blockId: PropTypes.string,
|
||||
appId: PropTypes.string,
|
||||
text: PropTypes.object,
|
||||
fields: PropTypes.array,
|
||||
accessory: PropTypes.any,
|
||||
theme: PropTypes.string,
|
||||
parser: PropTypes.object
|
||||
};
|
|
@ -34,6 +34,19 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
interface ISelect {
|
||||
options: {
|
||||
text: string;
|
||||
value: string;
|
||||
}[];
|
||||
placeholder: string;
|
||||
onChange: Function;
|
||||
loading: boolean;
|
||||
disabled: boolean;
|
||||
value: [];
|
||||
theme: string;
|
||||
}
|
||||
|
||||
export const Select = ({
|
||||
options = [],
|
||||
placeholder,
|
||||
|
@ -42,7 +55,7 @@ export const Select = ({
|
|||
disabled,
|
||||
value: initialValue,
|
||||
theme
|
||||
}) => {
|
||||
}: ISelect) => {
|
||||
const [selected, setSelected] = useState(!Array.isArray(initialValue) && initialValue);
|
||||
const items = options.map(option => ({ label: textParser([option.text]), value: option.value }));
|
||||
const pickerStyle = {
|
||||
|
@ -74,16 +87,8 @@ export const Select = ({
|
|||
inputAndroidContainer: pickerStyle
|
||||
}}
|
||||
Icon={Icon}
|
||||
// @ts-ignore
|
||||
textInputProps={{ style: { ...styles.pickerText, color: selected ? themes[theme].titleText : themes[theme].auxiliaryText } }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
Select.propTypes = {
|
||||
options: PropTypes.array,
|
||||
placeholder: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
loading: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
value: PropTypes.array,
|
||||
theme: PropTypes.string
|
||||
};
|
|
@ -2,10 +2,10 @@
|
|||
import React, { useContext, useState } from 'react';
|
||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||
|
||||
export const textParser = ([{ text }]) => text;
|
||||
export const textParser = ([{ text }]: any) => text;
|
||||
|
||||
export const defaultContext = {
|
||||
action: (...args) => console.log(args),
|
||||
export const defaultContext: any = {
|
||||
action: (...args: any) => console.log(args),
|
||||
state: console.log,
|
||||
appId: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
|
||||
errors: {}
|
||||
|
@ -15,7 +15,7 @@ export const KitContext = React.createContext(defaultContext);
|
|||
|
||||
export const useBlockContext = ({
|
||||
blockId, actionId, appId, initialValue
|
||||
}, context) => {
|
||||
}: any, context: any) => {
|
||||
const {
|
||||
action, appId: appIdFromContext, viewId, state, language, errors, values = {}
|
||||
} = useContext(KitContext);
|
||||
|
@ -27,7 +27,7 @@ export const useBlockContext = ({
|
|||
if ([BLOCK_CONTEXT.SECTION, BLOCK_CONTEXT.ACTION].includes(context)) {
|
||||
return [{
|
||||
loading, setLoading, error, value, language
|
||||
}, async({ value }) => {
|
||||
}, async({ value }: any) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await action({
|
||||
|
@ -46,7 +46,7 @@ export const useBlockContext = ({
|
|||
|
||||
return [{
|
||||
loading, setLoading, value, error, language
|
||||
}, async({ value }) => {
|
||||
}, async({ value }: any) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await state({
|
|
@ -24,11 +24,11 @@ type TMessageImage = {
|
|||
}
|
||||
|
||||
interface IMessageImage {
|
||||
file: { image_url: string; description: string; };
|
||||
file: { image_url: string; description?: string; };
|
||||
imageUrl?: string;
|
||||
showAttachment: Function;
|
||||
theme: string;
|
||||
getCustomEmoji: Function;
|
||||
getCustomEmoji?: Function;
|
||||
}
|
||||
|
||||
const ImageProgress = createImageProgress(FastImage);
|
||||
|
|
|
@ -4,4 +4,5 @@ declare module 'commonmark-react-renderer';
|
|||
declare module 'remove-markdown';
|
||||
declare module 'react-native-image-progress';
|
||||
declare module 'react-native-platform-touchable';
|
||||
declare module 'react-native-ui-lib/keyboard';
|
||||
declare module 'react-native-ui-lib/keyboard';
|
||||
declare module '@rocket.chat/ui-kit';
|
||||
|
|
Loading…
Reference in New Issue