Chore: Evaluate UiKit - TypeScript (#3939)
* Chore: Evaluate UiKit - TypeScript * minor tweak
This commit is contained in:
parent
1c70ffc614
commit
40cb3b1ae7
|
@ -74,7 +74,7 @@ interface IItem {
|
|||
|
||||
interface IModalContent {
|
||||
message?: TMessageModel;
|
||||
onClose: Function;
|
||||
onClose: () => void;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,11 +47,11 @@ const styles = StyleSheet.create({
|
|||
interface ISearchBox extends TextInputProps {
|
||||
value?: string;
|
||||
hasCancel?: boolean;
|
||||
onCancelPress?: Function;
|
||||
onCancelPress?: () => void;
|
||||
inputRef?: React.Ref<RNTextInput>;
|
||||
}
|
||||
|
||||
const CancelButton = ({ onCancelPress }: { onCancelPress?: Function }) => {
|
||||
const CancelButton = ({ onCancelPress }: { onCancelPress?: () => void }) => {
|
||||
const { theme } = useTheme();
|
||||
return (
|
||||
<Touchable onPress={onCancelPress} style={styles.cancel}>
|
||||
|
@ -84,7 +84,7 @@ const SearchBox = ({ hasCancel, onCancelPress, inputRef, ...props }: ISearchBox)
|
|||
{...props}
|
||||
/>
|
||||
</View>
|
||||
{hasCancel ? <CancelButton onCancelPress={onCancelPress} /> : null}
|
||||
{hasCancel && onCancelPress ? <CancelButton onCancelPress={onCancelPress} /> : null}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -4,8 +4,10 @@ import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
|||
import Button from '../Button';
|
||||
import I18n from '../../i18n';
|
||||
import { IActions } from './interfaces';
|
||||
import { useTheme } from '../../theme';
|
||||
|
||||
export const Actions = ({ blockId, appId, elements, parser, theme }: IActions) => {
|
||||
export const Actions = ({ blockId, appId, elements, parser }: IActions) => {
|
||||
const { theme } = useTheme();
|
||||
const [showMoreVisible, setShowMoreVisible] = useState(() => elements && elements.length > 5);
|
||||
const renderedElements = showMoreVisible ? elements?.slice(0, 5) : elements;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState } from 'react';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
import DateTimePicker from '@react-native-community/datetimepicker';
|
||||
import DateTimePicker, { Event } from '@react-native-community/datetimepicker';
|
||||
import Touchable from 'react-native-platform-touchable';
|
||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||
import moment from 'moment';
|
||||
|
@ -11,6 +11,7 @@ import { themes } from '../../constants/colors';
|
|||
import sharedStyles from '../../views/Styles';
|
||||
import { CustomIcon } from '../../lib/Icons';
|
||||
import { isAndroid } from '../../utils/deviceInfo';
|
||||
import { useTheme } from '../../theme';
|
||||
import ActivityIndicator from '../ActivityIndicator';
|
||||
import { IDatePicker } from './interfaces';
|
||||
|
||||
|
@ -36,14 +37,17 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
export const DatePicker = ({ element, language, action, context, theme, loading, value, error }: IDatePicker) => {
|
||||
export const DatePicker = ({ element, language, action, context, loading, value, error }: IDatePicker) => {
|
||||
const { theme } = useTheme();
|
||||
const [show, onShow] = useState(false);
|
||||
const initial_date = element?.initial_date;
|
||||
const placeholder = element?.placeholder;
|
||||
|
||||
const [currentDate, onChangeDate] = useState(new Date(initial_date || value));
|
||||
|
||||
const onChange = ({ nativeEvent: { timestamp } }: any, date: any) => {
|
||||
// timestamp as number exists in Event
|
||||
// @ts-ignore
|
||||
const onChange = ({ nativeEvent: { timestamp } }: Event, date?: Date) => {
|
||||
const newDate = date || new Date(timestamp);
|
||||
onChangeDate(newDate);
|
||||
action({ value: moment(newDate).format('YYYY-MM-DD') });
|
||||
|
@ -52,7 +56,9 @@ export const DatePicker = ({ element, language, action, context, theme, loading,
|
|||
}
|
||||
};
|
||||
|
||||
let button = <Button title={textParser([placeholder])} onPress={() => onShow(!show)} loading={loading} theme={theme} />;
|
||||
let button = placeholder ? (
|
||||
<Button title={textParser([placeholder])} onPress={() => onShow(!show)} loading={loading} theme={theme} />
|
||||
) : null;
|
||||
|
||||
if (context === BLOCK_CONTEXT.FORM) {
|
||||
button = (
|
||||
|
|
|
@ -6,7 +6,7 @@ import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
|||
import ImageContainer from '../message/Image';
|
||||
import Navigation from '../../lib/Navigation';
|
||||
import { IThumb, IImage, IElement } from './interfaces';
|
||||
import { TThemeMode } from '../../definitions/ITheme';
|
||||
import { IAttachment } from '../../definitions';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
image: {
|
||||
|
@ -27,23 +27,22 @@ export const Thumb = ({ element, size = 88 }: IThumb) => (
|
|||
<FastImage style={[{ width: size, height: size }, styles.image]} source={{ uri: element?.imageUrl }} />
|
||||
);
|
||||
|
||||
export const Media = ({ element, theme }: IImage) => {
|
||||
const showAttachment = (attachment: any) => Navigation.navigate('AttachmentView', { attachment });
|
||||
export const Media = ({ element }: IImage) => {
|
||||
const showAttachment = (attachment: IAttachment) => Navigation.navigate('AttachmentView', { attachment });
|
||||
const imageUrl = element?.imageUrl ?? '';
|
||||
// @ts-ignore
|
||||
// TODO: delete ts-ignore after refactor Markdown and ImageContainer
|
||||
return <ImageContainer file={{ image_url: imageUrl }} imageUrl={imageUrl} showAttachment={showAttachment} theme={theme} />;
|
||||
|
||||
return <ImageContainer file={{ image_url: imageUrl }} imageUrl={imageUrl} showAttachment={showAttachment} />;
|
||||
};
|
||||
|
||||
const genericImage = (theme: TThemeMode, element: IElement, context?: number) => {
|
||||
const genericImage = (element: IElement, context?: number) => {
|
||||
switch (context) {
|
||||
case BLOCK_CONTEXT.SECTION:
|
||||
return <Thumb element={element} />;
|
||||
case BLOCK_CONTEXT.CONTEXT:
|
||||
return <ThumbContext element={element} />;
|
||||
default:
|
||||
return <Media element={element} theme={theme} />;
|
||||
return <Media element={element} />;
|
||||
}
|
||||
};
|
||||
|
||||
export const Image = ({ element, context, theme }: IImage) => genericImage(theme, element, context);
|
||||
export const Image = ({ element, context }: IImage) => genericImage(element, context);
|
||||
|
|
|
@ -7,26 +7,23 @@ import { themes } from '../../../constants/colors';
|
|||
import { textParser } from '../utils';
|
||||
import { CustomIcon } from '../../../lib/Icons';
|
||||
import styles from './styles';
|
||||
import { IItemData } from '.';
|
||||
|
||||
interface IChip {
|
||||
item: {
|
||||
value: string;
|
||||
imageUrl: string;
|
||||
text: string;
|
||||
};
|
||||
onSelect: Function;
|
||||
item: IItemData;
|
||||
onSelect: (item: IItemData) => void;
|
||||
style?: object;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
interface IChips {
|
||||
items: [];
|
||||
onSelect: Function;
|
||||
items: IItemData[];
|
||||
onSelect: (item: IItemData) => void;
|
||||
style?: object;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
const keyExtractor = (item: any) => item.value.toString();
|
||||
const keyExtractor = (item: IItemData) => item.value.toString();
|
||||
|
||||
const Chip = ({ item, onSelect, style, theme }: IChip) => (
|
||||
<Touchable
|
||||
|
|
|
@ -9,10 +9,10 @@ import styles from './styles';
|
|||
|
||||
interface IInput {
|
||||
children?: JSX.Element;
|
||||
onPress: Function;
|
||||
onPress: () => void;
|
||||
theme: string;
|
||||
inputStyle?: object;
|
||||
disabled?: boolean | object;
|
||||
disabled?: boolean | null;
|
||||
placeholder?: string;
|
||||
loading?: boolean;
|
||||
innerInputStyle?: object;
|
||||
|
|
|
@ -8,34 +8,31 @@ import * as List from '../../List';
|
|||
import { textParser } from '../utils';
|
||||
import { themes } from '../../../constants/colors';
|
||||
import styles from './styles';
|
||||
import { IItemData } from '.';
|
||||
|
||||
interface IItem {
|
||||
item: {
|
||||
value: { name: string };
|
||||
text: { text: string };
|
||||
imageUrl: string;
|
||||
};
|
||||
selected: any;
|
||||
item: IItemData;
|
||||
selected?: string;
|
||||
onSelect: Function;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
interface IItems {
|
||||
items: [];
|
||||
selected: [];
|
||||
items: IItemData[];
|
||||
selected: string[];
|
||||
onSelect: Function;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
const keyExtractor = (item: any) => item.value.toString();
|
||||
const keyExtractor = (item: IItemData) => item.value.toString();
|
||||
|
||||
// RectButton doesn't work on modal (Android)
|
||||
const Item = ({ item, selected, onSelect, theme }: IItem) => {
|
||||
const itemName = item.value.name || item.text.text.toLowerCase();
|
||||
const itemName = item.value || item.text.text.toLowerCase();
|
||||
return (
|
||||
<Touchable
|
||||
testID={`multi-select-item-${itemName}`}
|
||||
key={item}
|
||||
key={itemName}
|
||||
onPress={() => onSelect(item)}
|
||||
style={[styles.item, { backgroundColor: themes[theme].backgroundColor }]}>
|
||||
<>
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Animated, Easing, KeyboardAvoidingView, Modal, StyleSheet, Text, TouchableWithoutFeedback, View } from 'react-native';
|
||||
import {
|
||||
Animated,
|
||||
Easing,
|
||||
KeyboardAvoidingView,
|
||||
Modal,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableWithoutFeedback,
|
||||
View,
|
||||
TextStyle
|
||||
} from 'react-native';
|
||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||
|
||||
import Button from '../../Button';
|
||||
|
@ -8,26 +18,31 @@ import { textParser } from '../utils';
|
|||
import { themes } from '../../../constants/colors';
|
||||
import I18n from '../../../i18n';
|
||||
import { isIOS } from '../../../utils/deviceInfo';
|
||||
import { useTheme } from '../../../theme';
|
||||
import { BlockContext, IText } from '../interfaces';
|
||||
import Chips from './Chips';
|
||||
import Items from './Items';
|
||||
import Input from './Input';
|
||||
import styles from './styles';
|
||||
|
||||
export interface IItemData {
|
||||
value: string;
|
||||
text: { text: string };
|
||||
imageUrl?: string;
|
||||
}
|
||||
|
||||
interface IMultiSelect {
|
||||
options: any[];
|
||||
options?: IItemData[];
|
||||
onChange: Function;
|
||||
placeholder: {
|
||||
text: string;
|
||||
};
|
||||
context?: number;
|
||||
placeholder?: IText;
|
||||
context?: BlockContext;
|
||||
loading?: boolean;
|
||||
multiselect?: boolean;
|
||||
onSearch?: () => void;
|
||||
onClose?: () => void;
|
||||
inputStyle?: object;
|
||||
inputStyle?: TextStyle;
|
||||
value?: any[];
|
||||
disabled?: boolean | object;
|
||||
theme: string;
|
||||
disabled?: boolean | null;
|
||||
innerInputStyle?: object;
|
||||
}
|
||||
|
||||
|
@ -54,9 +69,9 @@ export const MultiSelect = React.memo(
|
|||
onClose = () => {},
|
||||
disabled,
|
||||
inputStyle,
|
||||
theme,
|
||||
innerInputStyle
|
||||
}: IMultiSelect) => {
|
||||
const { theme } = useTheme();
|
||||
const [selected, select] = useState<any>(Array.isArray(values) ? values : []);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [search, onSearchChange] = useState('');
|
||||
|
@ -95,7 +110,7 @@ export const MultiSelect = React.memo(
|
|||
}).start(() => setShowContent(false));
|
||||
};
|
||||
|
||||
const onSelect = (item: any) => {
|
||||
const onSelect = (item: IItemData) => {
|
||||
const {
|
||||
value,
|
||||
text: { text }
|
||||
|
|
|
@ -6,6 +6,7 @@ import Touchable from 'react-native-platform-touchable';
|
|||
import { CustomIcon } from '../../lib/Icons';
|
||||
import ActivityIndicator from '../ActivityIndicator';
|
||||
import { themes } from '../../constants/colors';
|
||||
import { useTheme } from '../../theme';
|
||||
import { BUTTON_HIT_SLOP } from '../message/utils';
|
||||
import * as List from '../List';
|
||||
import { IOption, IOptions, IOverflow } from './interfaces';
|
||||
|
@ -43,9 +44,10 @@ const Options = ({ options, onOptionPress, parser, theme }: IOptions) => (
|
|||
/>
|
||||
);
|
||||
|
||||
const touchable: { [key: string]: any } = {};
|
||||
const touchable: { [key: string]: Touchable | null } = {};
|
||||
|
||||
export const Overflow = ({ element, loading, action, parser, theme }: IOverflow) => {
|
||||
export const Overflow = ({ element, loading, action, parser }: IOverflow) => {
|
||||
const { theme } = useTheme();
|
||||
const options = element?.options || [];
|
||||
const blockId = element?.blockId || '';
|
||||
const [show, onShow] = useState(false);
|
||||
|
@ -58,7 +60,7 @@ export const Overflow = ({ element, loading, action, parser, theme }: IOverflow)
|
|||
return (
|
||||
<>
|
||||
<Touchable
|
||||
ref={(ref: any) => (touchable[blockId] = ref)}
|
||||
ref={ref => (touchable[blockId] = ref)}
|
||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||
onPress={() => onShow(!show)}
|
||||
hitSlop={BUTTON_HIT_SLOP}
|
||||
|
@ -71,6 +73,7 @@ export const Overflow = ({ element, loading, action, parser, theme }: IOverflow)
|
|||
</Touchable>
|
||||
<Popover
|
||||
isVisible={show}
|
||||
// fromView exists in Popover Component
|
||||
/* @ts-ignore*/
|
||||
fromView={touchable[blockId]}
|
||||
onRequestClose={() => onShow(false)}>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
|||
|
||||
import { themes } from '../../constants/colors';
|
||||
import { IAccessoryComponent, IFields, ISection } from './interfaces';
|
||||
import { useTheme } from '../../theme';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
content: {
|
||||
|
@ -37,10 +38,14 @@ const Fields = ({ fields, parser, theme }: IFields) => (
|
|||
|
||||
const accessoriesRight = ['image', 'overflow'];
|
||||
|
||||
export const Section = ({ blockId, appId, text, fields, accessory, parser, theme }: ISection) => (
|
||||
<View style={[styles.content, accessory && accessoriesRight.includes(accessory.type) ? styles.row : styles.column]}>
|
||||
{text ? <View style={styles.text}>{parser.text(text)}</View> : null}
|
||||
{fields ? <Fields fields={fields} theme={theme} parser={parser} /> : null}
|
||||
{accessory ? <Accessory element={{ blockId, appId, ...accessory }} parser={parser} /> : null}
|
||||
</View>
|
||||
);
|
||||
export const Section = ({ blockId, appId, text, fields, accessory, parser }: ISection) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<View style={[styles.content, accessory && accessoriesRight.includes(accessory.type) ? styles.row : styles.column]}>
|
||||
{text ? <View style={styles.text}>{parser.text(text)}</View> : null}
|
||||
{fields ? <Fields fields={fields} theme={theme} parser={parser} /> : null}
|
||||
{accessory ? <Accessory element={{ blockId, appId, ...accessory }} parser={parser} /> : null}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,6 +8,8 @@ import { CustomIcon } from '../../lib/Icons';
|
|||
import { textParser } from './utils';
|
||||
import { isAndroid, isIOS } from '../../utils/deviceInfo';
|
||||
import ActivityIndicator from '../ActivityIndicator';
|
||||
import { useTheme } from '../../theme';
|
||||
import { IText, Option } from './interfaces';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
iosPadding: {
|
||||
|
@ -34,19 +36,16 @@ const styles = StyleSheet.create({
|
|||
});
|
||||
|
||||
interface ISelect {
|
||||
options: {
|
||||
text: string;
|
||||
value: string;
|
||||
}[];
|
||||
placeholder: string;
|
||||
options?: Option[];
|
||||
placeholder?: IText;
|
||||
onChange: Function;
|
||||
loading: boolean;
|
||||
disabled: boolean;
|
||||
disabled?: boolean;
|
||||
value: [];
|
||||
theme: string;
|
||||
}
|
||||
|
||||
export const Select = ({ options = [], placeholder, onChange, loading, disabled, value: initialValue, theme }: ISelect) => {
|
||||
export const Select = ({ options = [], placeholder, onChange, loading, disabled, value: initialValue }: ISelect) => {
|
||||
const { theme } = useTheme();
|
||||
const [selected, setSelected] = useState(!Array.isArray(initialValue) && initialValue);
|
||||
const items = options.map(option => ({ label: textParser([option.text]), value: option.value }));
|
||||
const pickerStyle = {
|
||||
|
@ -80,6 +79,7 @@ export const Select = ({ options = [], placeholder, onChange, loading, disabled,
|
|||
}}
|
||||
Icon={Icon}
|
||||
textInputProps={{
|
||||
// style property was Omitted in lib, but can be used normally
|
||||
// @ts-ignore
|
||||
style: { ...styles.pickerText, color: selected ? themes[theme].titleText : themes[theme].auxiliaryText }
|
||||
}}
|
||||
|
|
|
@ -20,7 +20,7 @@ import { Input } from './Input';
|
|||
import { DatePicker } from './DatePicker';
|
||||
import { Overflow } from './Overflow';
|
||||
import { ThemeContext } from '../../theme';
|
||||
import { BlockContext, IButton, IInputIndex, IParser, IText } from './interfaces';
|
||||
import { BlockContext, IActions, IButton, IElement, IInputIndex, IParser, ISection, IText } from './interfaces';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
input: {
|
||||
|
@ -78,35 +78,28 @@ class MessageParser extends UiKitParserMessage {
|
|||
}
|
||||
|
||||
divider() {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
// @ts-ignore
|
||||
return <Divider theme={theme} />;
|
||||
return <Divider />;
|
||||
}
|
||||
|
||||
section(args: any) {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
return <Section {...args} theme={theme} parser={this} />;
|
||||
section(args: ISection) {
|
||||
return <Section {...args} parser={this.current} />;
|
||||
}
|
||||
|
||||
actions(args: any) {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
return <Actions {...args} theme={theme} parser={this} />;
|
||||
actions(args: IActions) {
|
||||
return <Actions {...args} parser={this.current} />;
|
||||
}
|
||||
|
||||
overflow(element: any, context: any) {
|
||||
const [{ loading }, action]: any = useBlockContext(element, context);
|
||||
const { theme }: any = useContext(ThemeContext);
|
||||
return <Overflow element={element} context={context} loading={loading} action={action} theme={theme} parser={this.current} />;
|
||||
overflow(element: IElement, context: BlockContext) {
|
||||
const [{ loading }, action] = useBlockContext(element, context);
|
||||
return <Overflow element={element} context={context} loading={loading} action={action} parser={this.current} />;
|
||||
}
|
||||
|
||||
datePicker(element: any, context: any) {
|
||||
const [{ loading, value, error, language }, action]: any = useBlockContext(element, context);
|
||||
const { theme }: any = useContext(ThemeContext);
|
||||
datePicker(element: IElement, context: BlockContext) {
|
||||
const [{ loading, value, error, language }, action] = useBlockContext(element, context);
|
||||
return (
|
||||
<DatePicker
|
||||
element={element}
|
||||
language={language}
|
||||
theme={theme}
|
||||
value={value}
|
||||
action={action}
|
||||
context={context}
|
||||
|
@ -116,9 +109,8 @@ class MessageParser extends UiKitParserMessage {
|
|||
);
|
||||
}
|
||||
|
||||
image(element: any, context: any) {
|
||||
const { theme }: any = useContext(ThemeContext);
|
||||
return <Image element={element} theme={theme} context={context} />;
|
||||
image(element: IElement, context: BlockContext) {
|
||||
return <Image element={element} context={context} />;
|
||||
}
|
||||
|
||||
context(args: any) {
|
||||
|
@ -126,24 +118,19 @@ class MessageParser extends UiKitParserMessage {
|
|||
return <Context {...args} theme={theme} parser={this} />;
|
||||
}
|
||||
|
||||
multiStaticSelect(element: any, context: any) {
|
||||
const [{ loading, value }, action]: any = useBlockContext(element, context);
|
||||
const { theme } = useContext(ThemeContext);
|
||||
return (
|
||||
<MultiSelect {...element} theme={theme} value={value} onChange={action} context={context} loading={loading} multiselect />
|
||||
);
|
||||
multiStaticSelect(element: IElement, context: BlockContext) {
|
||||
const [{ loading, value }, action] = useBlockContext(element, context);
|
||||
return <MultiSelect {...element} value={value} onChange={action} context={context} loading={loading} multiselect />;
|
||||
}
|
||||
|
||||
staticSelect(element: any, context: any) {
|
||||
const [{ loading, value }, action]: any = useBlockContext(element, context);
|
||||
const { theme } = useContext(ThemeContext);
|
||||
return <Select {...element} theme={theme} value={value} onChange={action} loading={loading} />;
|
||||
staticSelect(element: IElement, context: BlockContext) {
|
||||
const [{ loading, value }, action] = useBlockContext(element, context);
|
||||
return <Select {...element} value={value} onChange={action} loading={loading} />;
|
||||
}
|
||||
|
||||
selectInput(element: any, context: any) {
|
||||
const [{ loading, value }, action]: any = useBlockContext(element, context);
|
||||
const { theme } = useContext(ThemeContext);
|
||||
return <MultiSelect {...element} theme={theme} value={value} onChange={action} context={context} loading={loading} />;
|
||||
selectInput(element: IElement, context: BlockContext) {
|
||||
const [{ loading, value }, action] = useBlockContext(element, context);
|
||||
return <MultiSelect {...element} value={value} onChange={action} context={context} loading={loading} />;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,8 +147,8 @@ class ModalParser extends UiKitParserModal {
|
|||
}
|
||||
|
||||
input({ element, blockId, appId, label, description, hint }: IInputIndex, context: number) {
|
||||
const [{ error }]: any = useBlockContext({ ...element, appId, blockId }, context);
|
||||
const { theme }: any = useContext(ThemeContext);
|
||||
const [{ error }] = useBlockContext({ ...element, appId, blockId }, context);
|
||||
const { theme } = useContext(ThemeContext);
|
||||
return (
|
||||
<Input
|
||||
parser={this.current}
|
||||
|
@ -175,17 +162,15 @@ class ModalParser extends UiKitParserModal {
|
|||
);
|
||||
}
|
||||
|
||||
image(element: any, context: any) {
|
||||
const { theme }: any = useContext(ThemeContext);
|
||||
return <Image element={element} theme={theme} context={context} />;
|
||||
image(element: IElement, context: BlockContext) {
|
||||
return <Image element={element} context={context} />;
|
||||
}
|
||||
|
||||
plainInput(element: any, context: any) {
|
||||
const [{ loading, value, error }, action]: any = useBlockContext(element, context);
|
||||
plainInput(element: IElement, context: BlockContext) {
|
||||
const [{ loading, value, error }, action] = useBlockContext(element, context);
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { multiline, actionId, placeholder } = element;
|
||||
return (
|
||||
// @ts-ignore
|
||||
<TextInput
|
||||
key={actionId}
|
||||
placeholder={plainText(placeholder)}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { TThemeMode } from '../../definitions/ITheme';
|
||||
|
||||
export enum ElementTypes {
|
||||
IMAGE = 'image',
|
||||
BUTTON = 'button',
|
||||
|
@ -87,10 +85,11 @@ export interface IElement {
|
|||
imageUrl?: string;
|
||||
appId?: string;
|
||||
blockId?: string;
|
||||
multiline?: boolean;
|
||||
}
|
||||
|
||||
export interface IText {
|
||||
type: ElementTypes;
|
||||
type?: ElementTypes;
|
||||
text: string;
|
||||
emoji?: boolean;
|
||||
}
|
||||
|
@ -98,12 +97,15 @@ export interface IText {
|
|||
export interface Option {
|
||||
text: IText;
|
||||
value: string;
|
||||
imageUrl?: string;
|
||||
}
|
||||
|
||||
export interface IButton {
|
||||
type: ElementTypes;
|
||||
text: IText;
|
||||
actionId: string;
|
||||
blockId: string;
|
||||
appId: string;
|
||||
value?: any;
|
||||
style?: any;
|
||||
}
|
||||
|
@ -177,7 +179,6 @@ export interface IParser {
|
|||
}
|
||||
export interface IActions extends Block {
|
||||
parser?: IParser;
|
||||
theme: TThemeMode;
|
||||
}
|
||||
|
||||
export interface IContext extends Block {
|
||||
|
@ -191,7 +192,6 @@ export interface IDatePicker extends Partial<Block> {
|
|||
loading: boolean;
|
||||
value: string;
|
||||
error: string;
|
||||
theme: TThemeMode;
|
||||
}
|
||||
|
||||
export interface IInput extends Partial<Block> {
|
||||
|
@ -199,7 +199,7 @@ export interface IInput extends Partial<Block> {
|
|||
description: string;
|
||||
error: string;
|
||||
hint: string;
|
||||
theme: TThemeMode;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
export interface IInputIndex {
|
||||
|
@ -217,8 +217,7 @@ export interface IThumb {
|
|||
}
|
||||
export interface IImage {
|
||||
element: IElement;
|
||||
theme: TThemeMode;
|
||||
context?: number;
|
||||
context?: BlockContext;
|
||||
}
|
||||
|
||||
// UiKit/Overflow
|
||||
|
@ -226,14 +225,13 @@ export interface IOverflow extends Partial<Block> {
|
|||
action: Function;
|
||||
loading: boolean;
|
||||
parser: IParser;
|
||||
theme: TThemeMode;
|
||||
context: number;
|
||||
}
|
||||
|
||||
interface PropsOption {
|
||||
onOptionPress: Function;
|
||||
parser: IParser;
|
||||
theme: TThemeMode;
|
||||
theme: string;
|
||||
}
|
||||
export interface IOptions extends PropsOption {
|
||||
options: Option[];
|
||||
|
@ -262,12 +260,11 @@ export interface ISection {
|
|||
text?: IText;
|
||||
accessory?: IAccessory;
|
||||
parser: IParser;
|
||||
theme: TThemeMode;
|
||||
fields?: any[];
|
||||
}
|
||||
|
||||
export interface IFields {
|
||||
parser: IParser;
|
||||
theme: TThemeMode;
|
||||
theme: string;
|
||||
fields: any[];
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
import React, { useContext, useState } from 'react';
|
||||
import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
|
||||
|
||||
import { BlockContext } from './interfaces';
|
||||
import { BlockContext, IText } from './interfaces';
|
||||
|
||||
export const textParser = ([{ text }]: any) => text;
|
||||
export const textParser = ([{ text }]: IText[]) => text;
|
||||
|
||||
export const defaultContext: any = {
|
||||
action: (...args: any) => console.log(args),
|
||||
|
@ -27,7 +27,14 @@ type TFunctionReturn = (value: any) => Promise<void>;
|
|||
|
||||
type TReturn = [TObjectReturn, TFunctionReturn];
|
||||
|
||||
export const useBlockContext = ({ blockId, actionId, appId, initialValue }: any, context: BlockContext): TReturn => {
|
||||
interface IUseBlockContext {
|
||||
blockId?: string;
|
||||
actionId: string;
|
||||
appId?: string;
|
||||
initialValue?: string;
|
||||
}
|
||||
|
||||
export const useBlockContext = ({ blockId, actionId, appId, initialValue }: IUseBlockContext, context: BlockContext): TReturn => {
|
||||
const { action, appId: appIdFromContext, viewId, state, language, errors, values = {} } = useContext(KitContext);
|
||||
const { value = initialValue } = values[actionId] || {};
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
|
|
@ -54,7 +54,6 @@ const Attachments = React.memo(
|
|||
getCustomEmoji={getCustomEmoji}
|
||||
style={style}
|
||||
isReply={isReply}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import { formatAttachmentUrl } from '../../lib/utils';
|
|||
import { themes } from '../../constants/colors';
|
||||
import MessageContext from './Context';
|
||||
import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
||||
import { useTheme } from '../../theme';
|
||||
import { IAttachment } from '../../definitions';
|
||||
|
||||
type TMessageButton = {
|
||||
|
@ -32,8 +33,7 @@ interface IMessageImage {
|
|||
showAttachment?: Function;
|
||||
style?: StyleProp<TextStyle>[];
|
||||
isReply?: boolean;
|
||||
theme: string;
|
||||
getCustomEmoji: TGetCustomEmoji;
|
||||
getCustomEmoji?: TGetCustomEmoji;
|
||||
}
|
||||
|
||||
const ImageProgress = createImageProgress(FastImage);
|
||||
|
@ -61,7 +61,8 @@ export const MessageImage = React.memo(({ img, theme }: TMessageImage) => (
|
|||
));
|
||||
|
||||
const ImageContainer = React.memo(
|
||||
({ file, imageUrl, showAttachment, getCustomEmoji, style, isReply, theme }: IMessageImage) => {
|
||||
({ file, imageUrl, showAttachment, getCustomEmoji, style, isReply }: IMessageImage) => {
|
||||
const { theme } = useTheme();
|
||||
const { baseUrl, user } = useContext(MessageContext);
|
||||
const img = imageUrl || formatAttachmentUrl(file.image_url, user.id, user.token, baseUrl);
|
||||
if (!img) {
|
||||
|
@ -100,7 +101,7 @@ const ImageContainer = React.memo(
|
|||
</Button>
|
||||
);
|
||||
},
|
||||
(prevProps, nextProps) => dequal(prevProps.file, nextProps.file) && prevProps.theme === nextProps.theme
|
||||
(prevProps, nextProps) => dequal(prevProps.file, nextProps.file)
|
||||
);
|
||||
|
||||
ImageContainer.displayName = 'MessageImageContainer';
|
||||
|
|
|
@ -2,7 +2,7 @@ import { IUser } from './IUser';
|
|||
|
||||
export interface IAttachment {
|
||||
ts?: string | Date;
|
||||
title: string;
|
||||
title?: string;
|
||||
type?: string;
|
||||
description?: string;
|
||||
title_link?: string;
|
||||
|
|
|
@ -3,7 +3,6 @@ declare module 'commonmark';
|
|||
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 '@rocket.chat/ui-kit';
|
||||
declare module '@rocket.chat/sdk';
|
||||
|
|
|
@ -84,7 +84,9 @@ class AttachmentView extends React.Component<IAttachmentViewProps, IAttachmentVi
|
|||
const attachment = route.params?.attachment;
|
||||
let { title } = attachment;
|
||||
try {
|
||||
title = decodeURI(title);
|
||||
if (title) {
|
||||
title = decodeURI(title);
|
||||
}
|
||||
} catch {
|
||||
// Do nothing
|
||||
}
|
||||
|
|
|
@ -48,14 +48,13 @@ const SelectChannel = ({
|
|||
<>
|
||||
<Text style={[styles.label, { color: themes[theme].titleText }]}>{I18n.t('Parent_channel_or_group')}</Text>
|
||||
<MultiSelect
|
||||
theme={theme}
|
||||
inputStyle={styles.inputStyle}
|
||||
onChange={onChannelSelect}
|
||||
onSearch={getChannels}
|
||||
value={initial && [initial]}
|
||||
disabled={initial}
|
||||
disabled={!!initial}
|
||||
options={channels.map(channel => ({
|
||||
value: channel,
|
||||
value: channel.name || channel.fname,
|
||||
text: { text: RocketChat.getRoomTitle(channel) },
|
||||
imageUrl: getAvatar(channel)
|
||||
}))}
|
||||
|
|
|
@ -77,7 +77,6 @@ const SelectUsers = ({
|
|||
<>
|
||||
<Text style={[styles.label, { color: themes[theme].titleText }]}>{I18n.t('Invite_users')}</Text>
|
||||
<MultiSelect
|
||||
theme={theme}
|
||||
inputStyle={styles.inputStyle}
|
||||
onSearch={getUsers}
|
||||
onChange={onUserSelect}
|
||||
|
|
|
@ -275,7 +275,6 @@ const LivechatEditView = ({
|
|||
value={tagParamSelected}
|
||||
context={BLOCK_CONTEXT.FORM}
|
||||
multiselect
|
||||
theme={theme}
|
||||
disabled={!permissions[1]}
|
||||
inputStyle={styles.multiSelect}
|
||||
/>
|
||||
|
|
|
@ -464,7 +464,6 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
|
|||
|
||||
renderSystemMessages = () => {
|
||||
const { systemMessages, enableSysMes } = this.state;
|
||||
const { theme } = this.props;
|
||||
|
||||
if (!enableSysMes) {
|
||||
return null;
|
||||
|
@ -481,7 +480,6 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
|
|||
value={systemMessages as string[]}
|
||||
context={BLOCK_CONTEXT.FORM}
|
||||
multiselect
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue