123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- import React, { Fragment, useEffect, useRef, useState } from 'react';
- import { View, Text, TouchableOpacity, LayoutAnimation, Platform, UIManager, ScrollView, FlatList, StyleSheet } from 'react-native';
- import { PopupLayout, useLayoutAction } from '~/Components/Layouts/PopupLayout';
- import { SearchBoxIcon, DefaultButton, PrimaryButton } from '~/Components/Listing/Search';
- import { DefaultAction } from '~/Components/UIControls/Popup/Context';
- import { DragDrop, DragDropProvider } from '~/Components/UIControls/dragdrop';
- import Icon from '~/Components/UIControls/Icon';
- import { Util } from '~/Utils/utils';
- if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
- UIManager.setLayoutAnimationEnabledExperimental(true);
- }
- const styles = StyleSheet.create({
- container: {
- flexDirection: 'row',
- width: '100%',
- height: '100%',
- },
- destination: {
- backgroundColor: 'white',
- borderRightWidth: 1,
- borderColor: '#dedede',
- width: '50%',
- },
- destitem: {
- backgroundColor: '#ee4035',
- padding: 10,
- margin: 5,
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between',
- borderRadius: 7,
- },
- destitemtext: {
- color: 'white',
- marginVertical: 5,
- },
- src: {
- backgroundColor: 'white',
- width: '50%',
- },
- srcitem: {
- backgroundColor: '#005b96',
- padding: 10,
- margin: 5,
- flexDirection: 'row',
- alignItems: 'center',
- borderRadius: 7,
- },
- srcitemtext: {
- color: 'white',
- marginVertical: 5,
- },
- });
- export default Popup = ({ siteId = 0, popup = DefaultAction }) => {
- const [items, setItems] = useState([]);
- const [selectItems, setSelectItems] = useState([]);
- const src = useRef();
- const dest = useRef();
- const destMeasure = useRef(null);
- const lastSelectItem = useRef();
- const lastSelectItemMeasure = useRef(null);
- const updateMeasure = async () => {
- destMeasure.current = await Util.getMeasure(dest.current);
- if (lastSelectItem.current) {
- lastSelectItemMeasure.current = await Util.getMeasure(lastSelectItem.current);
- }
- };
- const handleDraggableCheck = (e, gesture) => {
- if (e.nativeEvent.locationX <= 80) {
- src.current.setNativeProps({ scrollEnabled: false });
- updateMeasure();
- return true;
- } else {
- src.current.setNativeProps({ scrollEnabled: true });
- return false;
- }
- };
- const handleDragStart = (e, gesture) => {};
- const handleDragEnd = (gesture, item) => {
- src.current.setNativeProps({ scrollEnabled: true });
- if (selectItems.findIndex((value) => value.name == item.name) != -1) {
- return false;
- }
- if (
- !!destMeasure.current &&
- gesture.moveX >= destMeasure.current.pageX &&
- gesture.moveX <= destMeasure.current.pageX + destMeasure.current.width &&
- gesture.moveY >= destMeasure.current.pageY &&
- gesture.moveY <= destMeasure.current.pageY + destMeasure.current.height
- ) {
- if (selectItems.length > 0 && lastSelectItemMeasure.current) {
- return {
- dropX: lastSelectItemMeasure.current.pageX,
- dropY: lastSelectItemMeasure.current.pageY + lastSelectItemMeasure.current.height,
- };
- } else {
- return {
- dropX: destMeasure.current.pageX,
- dropY: destMeasure.current.pageY,
- };
- }
- }
- return false;
- };
- const appendSelected = (item) => {
- if (selectItems.findIndex((value) => value.name == item.name) != -1) return;
- LayoutAnimation.configureNext(LayoutAnimation.create(150, LayoutAnimation.Types.easeInEaseOut, LayoutAnimation.Properties.opacity));
- setSelectItems([...selectItems, { name: item.name }]);
- };
- const removeSelected = (item) => {
- const newItems = selectItems.filter((value) => value.name != item.name);
- LayoutAnimation.configureNext(LayoutAnimation.create(150, LayoutAnimation.Types.easeInEaseOut, LayoutAnimation.Properties.opacity));
- setSelectItems(newItems);
- };
- const actionHandler = (action, parameter = {}) => {
- const actions = {
- onClose: () => {
- console.log('close...');
- popup.close();
- },
- onSelect: () => {
- console.log('select...');
- const names = selectItems.map((item) => item.name).join(',');
- popup.select(names);
- },
- };
- actions[action]();
- };
- useEffect(() => {
- let list = [];
- for (let i = 1; i < 200; i++) {
- list = [...list, { id: i, name: `이름${i}` }];
- }
- setItems(list);
- }, []);
- return (
- <PopupLayout title="사용자 선택" header={Header} actionHandler={actionHandler}>
- <View style={styles.container}>
- <DragDropProvider>
- <View style={styles.destination} ref={dest}>
- <ScrollView style={{ width: '100%', height: '100%' }}>
- {selectItems.map((item, index) => {
- const last = selectItems.length - 1 == index;
- return (
- <View key={`select-item-${index}`} style={styles.destitem} ref={last ? lastSelectItem : undefined}>
- <Text style={styles.destitemtext}>{item.name}</Text>
- <TouchableOpacity onPress={() => removeSelected(item)}>
- <Icon iconFamily="AntDesign" iconName="minuscircle" size={20} color="white" />
- </TouchableOpacity>
- </View>
- );
- })}
- </ScrollView>
- </View>
- <FlatList
- style={[styles.src, { overflow: 'visible' }]}
- ref={src}
- data={items}
- keyExtractor={(item, index) => `item-${index}`}
- renderItem={({ item, index }) => {
- return (
- <DragDrop
- style={styles.srcitem}
- onDraggableCheck={handleDraggableCheck}
- onDragStart={handleDragStart}
- onDragEnd={(gesture) => {
- return handleDragEnd(gesture, item);
- }}
- hideWhenDrop={true}
- onRemove={() => {
- appendSelected(item);
- }}
- >
- <Icon iconFamily="MaterialCommunityIcons" iconName="drag" size={20} color="white" />
- <Text style={styles.srcitemtext}>{item.name}</Text>
- </DragDrop>
- );
- }}
- />
- </DragDropProvider>
- </View>
- </PopupLayout>
- );
- };
- const Header = () => {
- const { callAction } = useLayoutAction();
- return (
- <Fragment>
- <DefaultButton
- onPress={() => {
- callAction('onClose');
- }}
- >
- 닫기
- </DefaultButton>
- <PrimaryButton
- onPress={() => {
- callAction('onSelect');
- }}
- >
- 선택
- </PrimaryButton>
- </Fragment>
- );
- };
|