Skip to content

Commit

Permalink
[feat] change modal in gov
Browse files Browse the repository at this point in the history
  • Loading branch information
blacktoast committed Dec 8, 2023
1 parent 9b02408 commit 7d2fc93
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 152 deletions.
Original file line number Diff line number Diff line change
@@ -1,75 +1,53 @@
import React, {FunctionComponent, useEffect, useRef, useState} from 'react';
import React, {useEffect, useRef, useState} from 'react';
import {observer} from 'mobx-react-lite';
import {EmitterSubscription, Keyboard, Platform, Text} from 'react-native';
import {BottomSheetFlatList, useBottomSheet} from '@gorhom/bottom-sheet';
import {TextInput} from 'react-native-gesture-handler';
import {Text} from 'react-native';
import {ScrollView, TextInput} from 'react-native-gesture-handler';
import {useStyle} from '../../../../styles';
import {BottomSheetSearchTextInput} from '../../../../components/input/bottom-sheet-search-input';
import {SearchTextInput} from '../../../../components/input/search-text-input';
import {Gutter} from '../../../../components/gutter';
import {Box} from '../../../../components/box';
import {RectButton} from '../../../../components/rect-button';
import {Column, Columns} from '../../../../components/column';
import {ChainImageFallback} from '../../../../components/image';
import {registerCardModal} from '../../../../components/modal/card';
import {EmptyView} from '../../../../components/empty-view';

export interface SelectModalItem {
key: string;
label: string | React.ReactNode;
imageUrl?: string;
}

export const GovSelectChainModal: FunctionComponent<{
items: SelectModalItem[];
placeholder?: string;
onSelect: (item: SelectModalItem) => void;
}> = observer(({items, placeholder, onSelect}) => {
const style = useStyle();
const [search, setSearch] = useState('');
const searchRef = useRef<TextInput>(null);
const bottom = useBottomSheet();
export const GovSelectChainModal = registerCardModal(
observer<{
items: SelectModalItem[];
placeholder?: string;
onSelect: (item: SelectModalItem) => void;
}>(({items, placeholder, onSelect}) => {
const style = useStyle();
const [search, setSearch] = useState('');
const searchRef = useRef<TextInput>(null);

useEffect(() => {
searchRef.current?.focus();
}, [searchRef]);
useEffect(() => {
searchRef.current?.focus();
}, [searchRef]);

//NOTE - https://github.com/gorhom/react-native-bottom-sheet/issues/1072
// android에서 키보드가 열렸을때 modal을 close 트리거 할 경우
// 키보드가 먼저 사라지면서 bottomSheet높이가 다시 설정되고 리렌더링 되는 버그가 있음
// 그래서 setTimeout으로 키보드를 먼저 닫은뒤 bottomSheet을 닫도록 설정함
useEffect(() => {
let keyboardDidHideListener: EmitterSubscription;
if (Platform.OS === 'android') {
keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => {
setTimeout(() => {
bottom.close();
}, 0);
});
}
const filtered = search
? items.filter(item => {
const trimmedSearchText = search.trim();
if (trimmedSearchText.length > 0) {
return (
typeof item.label === 'string' &&
item.label.toLowerCase().includes(trimmedSearchText.toLowerCase())
);
}
})
: items;

return () => {
if (Platform.OS === 'android') {
keyboardDidHideListener.remove();
}
};
}, [bottom]);

const filtered = search
? items.filter(item => {
const trimmedSearchText = search.trim();
if (trimmedSearchText.length > 0) {
return (
typeof item.label === 'string' &&
item.label.toLowerCase().includes(trimmedSearchText.toLowerCase())
);
}
})
: items;

return (
<React.Fragment>
<Box paddingX={12}>
<Gutter size={12} />
{Platform.OS === 'android' ? (
return (
<React.Fragment>
<Box paddingX={12}>
<Gutter size={12} />
<SearchTextInput
ref={searchRef}
value={search}
Expand All @@ -79,77 +57,60 @@ export const GovSelectChainModal: FunctionComponent<{
}}
placeholder={placeholder}
/>
) : (
<BottomSheetSearchTextInput
ref={searchRef}
value={search}
onChange={e => {
e.preventDefault();
setSearch(e.nativeEvent.text);
}}
placeholder={placeholder}
onSubmitEditing={() => {
bottom.snapToIndex(0);
}}
/>
)}

<Gutter size={12} />
</Box>
<BottomSheetFlatList
data={filtered}
renderItem={({item}) => {
return (
<RectButton
underlayColor={style.get('color-gray-550').color}
rippleColor={style.get('color-gray-550').color}
activeOpacity={1}
style={style.flatten(['background-color-gray-600'])}
onPress={async () => {
onSelect(item);
//NOTE - https://github.com/gorhom/react-native-bottom-sheet/issues/1072
// android에서 키보드가 열렸을때 modal을 close 트리거 할 경우
// 키보드가 먼저 사라지면서 bottomSheet높이가 다시 설정되고 리렌더링 되는 버그가 있음
// 그래서 setTimeout으로 키보드를 먼저 닫은뒤 bottomSheet을 닫도록 설정함
if (Platform.OS === 'android') {
if (Keyboard.isVisible()) {
Keyboard.dismiss();
return;
}
bottom.close();
return;
}
bottom.close();
}}>
<Box
paddingY={14}
paddingLeft={16}
paddingRight={8}
borderRadius={6}
height={74}
alignY="center"
alignX="center">
<Columns sum={1} alignY="center" gutter={8}>
<Box>
<ChainImageFallback
style={{
width: 32,
height: 32,
}}
src={item.imageUrl}
alt="chain icon"
/>
<Gutter size={12} />
</Box>
{
<ScrollView style={{height: 250}}>
{filtered.map(item => {
return (
<RectButton
underlayColor={style.get('color-gray-550').color}
rippleColor={style.get('color-gray-550').color}
activeOpacity={1}
style={style.flatten(['background-color-gray-600'])}
onPress={() => {
onSelect(item);

This comment has been minimized.

Copy link
@HeesungB

HeesungB Dec 8, 2023

Collaborator

@blacktoast 선택 후에 모달을 닫는 부분을 추가 부탁드립니다.

}}
key={item.key}>
<Box
paddingY={14}
paddingLeft={16}
paddingRight={8}
borderRadius={6}
height={74}
alignY="center"
alignX="center">
<Columns sum={1} alignY="center" gutter={8}>
<Box>
<ChainImageFallback
style={{
width: 32,
height: 32,
}}
src={item.imageUrl}
alt="chain icon"
/>
</Box>
<Text
style={style.flatten(['subtitle3', 'color-text-high'])}>
{item.label}
</Text>
<Column weight={1} />
</Columns>
</Box>
<Text style={style.flatten(['subtitle3', 'color-text-high'])}>
{item.label}
</Text>
<Column weight={1} />
</Columns>
</Box>
</RectButton>
);
}}
/>
</React.Fragment>
);
});
</RectButton>
);
})}
{filtered.length === 0 ? (
<React.Fragment>
<Gutter size={50} />
<EmptyView subject="chains" />
</React.Fragment>
) : null}
</ScrollView>
}
</React.Fragment>
);
}),
);
47 changes: 21 additions & 26 deletions packages/mobile/src/screen/governance/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, {FunctionComponent, useMemo, useRef} from 'react';
import React, {FunctionComponent, useMemo, useState} from 'react';
import {observer} from 'mobx-react-lite';
import {useStyle} from '../../styles';
import {PageWithScrollView} from '../../components/page';
import {Platform, StyleSheet, Text, ViewStyle} from 'react-native';
import {StyleSheet, Text, ViewStyle} from 'react-native';
import {useStore} from '../../stores';
import {Dec} from '@keplr-wallet/unit';
import {ViewToken} from '../../components/token-view';
Expand All @@ -11,8 +11,6 @@ import {useNavigation} from '@react-navigation/native';
import {StackNavProp} from '../../navigation';
import {TextButton} from '../../components/text-button';
import {ArrowRightIcon} from '../../components/icon/arrow-right';
import {BottomSheetModal} from '@gorhom/bottom-sheet';
import {Modal} from '../../components/modal';
import {
GovSelectChainModal,
SelectModalItem,
Expand All @@ -31,7 +29,7 @@ import {ChainIdHelper} from '@keplr-wallet/cosmos';
export const GovernanceScreen: FunctionComponent = observer(() => {
const style = useStyle();
const {hugeQueriesStore, queriesStore, scamProposalStore} = useStore();
const selectChainModalRef = useRef<BottomSheetModal>(null);
const [isOpenSelectChainModal, setIsOpenSelectChainModal] = useState(false);
const navigation = useNavigation<StackNavProp>();

const delegations: ViewToken[] = useMemo(
Expand Down Expand Up @@ -135,7 +133,7 @@ export const GovernanceScreen: FunctionComponent = observer(() => {
color="faint"
containerStyle={style.flatten(['padding-x-12', 'padding-y-6'])}
onPress={() => {
selectChainModalRef.current?.present();
setIsOpenSelectChainModal(true);
}}
rightIcon={
<ArrowRightIcon size={18} color={style.get('color-text-low').color} />
Expand Down Expand Up @@ -164,26 +162,23 @@ export const GovernanceScreen: FunctionComponent = observer(() => {
</React.Fragment>
);
})}
<Modal
ref={selectChainModalRef} //NOTE BottomSheetTextInput가 안드로이드일때 올바르게 동작 하지 않고
//같은 50% 일때 키보드가 있을시 모달 크기가 작아서 안드로이드 일때만 70% 으로 설정
snapPoints={Platform.OS === 'android' ? ['70%'] : ['50%']}>
<GovSelectChainModal
items={modalItems}
placeholder="search for chain"
onSelect={({key}) => {
navigation.navigate('Governance', {
screen: 'Governance.list',
params: {
chainId: key,
isGovV1Supported: viewItems.find(viewItem => {
return viewItem.chainId === key;
})?.isGovV1Supported,
},
});
}}
/>
</Modal>
<GovSelectChainModal
isOpen={isOpenSelectChainModal}
setIsOpen={setIsOpenSelectChainModal}
items={modalItems}
placeholder="search for chain"
onSelect={({key}) => {
navigation.navigate('Governance', {
screen: 'Governance.list',
params: {
chainId: key,
isGovV1Supported: viewItems.find(viewItem => {
return viewItem.chainId === key;
})?.isGovV1Supported,
},
});
}}
/>
</PageWithScrollView>
);
});
Expand Down

0 comments on commit 7d2fc93

Please sign in to comment.