import { TouchableOpacity, View, Text, Image, StyleSheet, StyleProp, ImageStyle, } from 'react-native' import React from 'react' import Icon from 'react-native-vector-icons/MaterialIcons' import { actionTypes } from '@adalo/constants' import { useDispatch } from 'react-redux' import { getStore } from 'ducks' import { executeAction } from 'utils/actions' import { isURL } from 'utils/formats' import { BottomButtons } from './buttons' import { ActiveActionsType, BottomButtonActionType, ButtonActionType, InactiveActionsType, InputType, ListItemProps, HeaderActionType, ToggleBinding, } from './types' export const renderIcon = ( value: string, size: number, color: string, style?: StyleProp ): JSX.Element => { if (!isURL(value)) { const name = value.replace(/_/g, '-') return } else { return ( ) } } export const ListItem = (props: ListItemProps) => { const { background, header, content, bottomText, id, _meta: meta, object, getDatasources, } = props const { color, border, borderColor, borderWidth, borderRadius, padding } = background const { profilePicture, text1, text2, text3, rightIcon1Enabled, rightIcon1, rightIcon1Color, rightIcon2Enabled, rightIcon2, rightIcon2Color, styles: { text1: text1Styles, text2: text2Styles, text3: text3Styles }, } = header const { topCaption, contentImage, styles: { topCaption: topCaptionStyles }, } = content const { leftText, rightText, enabled: bottomTextEnabled, styles: { leftText: leftTextStyles, rightText: rightTextStyles }, } = bottomText const backgroundStyles = { backgroundColor: color, borderWidth: border ? borderWidth : 0, borderColor, borderRadius, marginBottom: 4 + padding, paddingBottom: 14 + padding, paddingTop: 4 + padding, } const headerStyles = { paddingHorizontal: 4 + padding, marginBottom: 4 + padding, } const headerIconStyles = { margin: 4 + padding } const contentImageStyles = { marginTop: 4 + padding } const bottomTextContainerStyles = { paddingTop: 9 + padding, paddingHorizontal: 4 + padding, } const { datasourceId, tableId, collectionId } = meta const dispatch = useDispatch() const getBinding = (id: string): Record | null => { if (id === object.attributes.items?.id) { return meta.record } return null } const bindingsKey = `${datasourceId}.${tableId || collectionId}` const getBindings = () => ({ [bindingsKey]: id }) const runButtonAction = (actionString: BottomButtonActionType) => { const action = object.attributes?.buttons && object.attributes.buttons[actionString] if (action && object.actions) { const { actionId } = action executeAction(object.actions[actionId], { ...props, dispatch, getDatasources, getStore, getBinding, getBindings, }) } } const runHeaderAction = (actionString: HeaderActionType) => { const action = object.attributes?.buttons && object.attributes.header[actionString] if (action && object.actions && object.actions[action?.actionId]) { const { actionId } = action executeAction(object.actions[actionId], { ...props, dispatch, getDatasources, getStore, getBinding, getBindings, }) } } const runClickAction = () => { const action = object.attributes?.clickActions if (action && object.actions) { const { actionId } = action executeAction(object.actions[actionId], { ...props, dispatch, getDatasources, getStore, getBinding, getBindings, }) } } const toggleAction = (val: boolean, prop?: ToggleBinding): void => { if (!prop) { return } const { source } = prop const action = { id: 'syntheticAction', actionType: val ? actionTypes.CREATE_ASSOCIATION : actionTypes.DELETE_ASSOCIATION, options: { fieldId: source?.source?.fieldId, object1: source?.source?.source, object2: source?.value, datasourceId, tableId, }, } executeAction( { actions: [action] }, { ...props, dispatch, getDatasources, getStore, getBinding, getBindings } ) } const iconButtonAction = ( type: 'icon' | 'toggle', val: boolean, setIconState: (state: boolean) => void, button: 'leftIcon1' | 'leftIcon2' | 'rightIcon' ): void => { const inputString = `${button}Input` as InputType const property = object.attributes?.buttons && object.attributes.buttons[inputString] if (type === 'icon') { const actionString = `onPress${ button.charAt(0).toUpperCase() + button.slice(1) }` as ButtonActionType runButtonAction(actionString) } else { toggleAction(val, property) const actionString = val ? (`${button}ActiveActions` as ActiveActionsType) : (`${button}InactiveActions` as InactiveActionsType) runButtonAction(actionString) setIconState(val) } } return ( {profilePicture && ( )} {text1 && ( {text1} )} {text2 && ( {text2} )} {text3 && ( {text3} )} {rightIcon1Enabled && rightIcon1 && ( runHeaderAction('onPressRightIcon1')} > {renderIcon(rightIcon1, 24, rightIcon1Color, [ styles.headerIcon, headerIconStyles, ])} )} {rightIcon2Enabled && rightIcon2 && ( runHeaderAction('onPressRightIcon2')} > {renderIcon(rightIcon2, 24, rightIcon2Color, [ styles.headerIcon, headerIconStyles, ])} )} {topCaption && ( {topCaption} )} {!!contentImage && ( )} {bottomTextEnabled && ( {leftText} {rightText} )} runButtonAction('onPressBottomButton')} /> ) } const styles = StyleSheet.create({ item: { width: '100%', }, profilePicture: { width: 50, height: 50, borderRadius: 25, }, headerLeft: { flexDirection: 'row', alignItems: 'center', flexShrink: 1, }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }, headerText: { marginLeft: 10, justifyContent: 'center', flexShrink: 1, }, headerIconsContainer: { flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-end', }, headerIcon: { alignSelf: 'center', }, topCaption: { paddingVertical: 5, }, contentImage: { width: '100%', aspectRatio: 4 / 3, }, bottomTextContainer: { flexDirection: 'row', justifyContent: 'space-between', }, })