From 476d5bef90febbe5a7e17bbfe1a3ff0505ce2b66 Mon Sep 17 00:00:00 2001 From: Evan Kaloudis Date: Sat, 24 Feb 2024 18:06:56 -0500 Subject: [PATCH 1/2] HopPicker: add search, filters, sort --- components/HopPicker.tsx | 148 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-) diff --git a/components/HopPicker.tsx b/components/HopPicker.tsx index 0982e88b0..908abb1d1 100644 --- a/components/HopPicker.tsx +++ b/components/HopPicker.tsx @@ -9,6 +9,7 @@ import { TouchableOpacity, TouchableHighlight } from 'react-native'; +import { SearchBar } from 'react-native-elements'; import { inject, observer } from 'mobx-react'; import { themeColor } from '../utils/ThemeUtils'; @@ -16,6 +17,9 @@ import { localeString } from '../utils/LocaleUtils'; import Button from '../components/Button'; import { ChannelItem } from './Channels/ChannelItem'; +import SortButton from '../components/Channels/SortButton'; +import { Row } from '../components/layout/Row'; +import { FilterOptions } from '../components/Channels/FilterOptions'; import Channel from '../models/Channel'; @@ -51,6 +55,98 @@ export default class ChannelPicker extends React.Component< showChannelModal: false }; + private getChannelsSortKeys = (closed?: boolean) => { + const sortKeys = []; + + if (closed) { + sortKeys.push( + { + key: `${localeString( + 'views.Channel.closeHeight' + )} (${localeString('views.Channel.SortButton.ascending')})`, + value: { param: 'closeHeight', dir: 'ASC', type: 'numeric' } + }, + { + key: `${localeString( + 'views.Channel.closeHeight' + )} (${localeString( + 'views.Channel.SortButton.descending' + )})`, + value: { + param: 'closeHeight', + dir: 'DESC', + type: 'numeric' + } + } + ); + } + + sortKeys.push( + { + key: `${localeString('views.Channel.capacity')} (${localeString( + 'views.Channel.SortButton.largestFirst' + )})`, + value: { + param: 'channelCapacity', + dir: 'DESC', + type: 'numeric' + } + }, + { + key: `${localeString('views.Channel.capacity')} (${localeString( + 'views.Channel.SortButton.smallestFirst' + )})`, + value: { param: 'channelCapacity', dir: 'ASC', type: 'numeric' } + }, + { + key: `${localeString( + 'views.Channel.inboundCapacity' + )} (${localeString('views.Channel.SortButton.largestFirst')})`, + value: { param: 'remoteBalance', dir: 'DESC', type: 'numeric' } + }, + { + key: `${localeString( + 'views.Channel.inboundCapacity' + )} (${localeString('views.Channel.SortButton.smallestFirst')})`, + value: { param: 'remoteBalance', dir: 'ASC', type: 'numeric' } + }, + { + key: `${localeString( + 'views.Channel.outboundCapacity' + )} (${localeString('views.Channel.SortButton.largestFirst')})`, + value: { param: 'localBalance', dir: 'DESC', type: 'numeric' } + }, + { + key: `${localeString( + 'views.Channel.outboundCapacity' + )} (${localeString('views.Channel.SortButton.smallestFirst')})`, + value: { param: 'localBalance', dir: 'ASC', type: 'numeric' } + }, + { + key: `${localeString( + 'views.Channel.displayName' + )} (${localeString('views.Channel.SortButton.ascending')})`, + value: { + param: 'displayName', + dir: 'ASC', + type: 'alphanumeric' + } + }, + { + key: `${localeString( + 'views.Channel.displayName' + )} (${localeString('views.Channel.SortButton.descending')})`, + value: { + param: 'displayName', + dir: 'DESC', + type: 'alphanumeric' + } + } + ); + + return sortKeys; + }; + openPicker() { stores.channelsStore.getChannels(); this.setState({ @@ -106,7 +202,15 @@ export default class ChannelPicker extends React.Component< render() { const { title, onValueChange, ChannelsStore } = this.props; const { showChannelModal, valueSet } = this.state; - const { filteredChannels, nodes, loading, getChannels } = ChannelsStore; + const { + filteredChannels, + nodes, + loading, + getChannels, + channelsType, + setSort, + search + } = ChannelsStore; const channels = filteredChannels; @@ -148,6 +252,48 @@ export default class ChannelPicker extends React.Component< )} + + + + ChannelsStore!.setSearch(value) + } + value={search} + inputStyle={{ + color: themeColor('text'), + fontFamily: 'PPNeueMontreal-Book' + }} + placeholderTextColor={themeColor( + 'secondaryText' + )} + containerStyle={{ + backgroundColor: null, + borderTopWidth: 0, + borderBottomWidth: 0, + width: '86%' + }} + inputContainerStyle={{ + borderRadius: 15, + backgroundColor: + themeColor('secondary') + }} + autoCapitalize="none" + /> + { + setSort(value); + }} + values={this.getChannelsSortKeys( + channelsType === ChannelsType.Closed + )} + /> + + + + this.renderItem(item)} From 915a3f0493b70dd514436437b389296bda23ae8d Mon Sep 17 00:00:00 2001 From: Evan Kaloudis Date: Sat, 24 Feb 2024 20:17:20 -0500 Subject: [PATCH 2/2] Channels: ChannelsFilter --- components/Channels/ChannelsFilter.tsx | 152 +++++++++++++++++++++++++ components/HopPicker.tsx | 149 +----------------------- views/Channels/ChannelsPane.tsx | 147 +----------------------- 3 files changed, 160 insertions(+), 288 deletions(-) create mode 100644 components/Channels/ChannelsFilter.tsx diff --git a/components/Channels/ChannelsFilter.tsx b/components/Channels/ChannelsFilter.tsx new file mode 100644 index 000000000..9d90c12bc --- /dev/null +++ b/components/Channels/ChannelsFilter.tsx @@ -0,0 +1,152 @@ +import { Dimensions, View } from 'react-native'; +import { SearchBar } from 'react-native-elements'; + +import { Row } from '../../components/layout/Row'; +import { FilterOptions } from '../../components/Channels/FilterOptions'; +import SortButton from '../../components/Channels/SortButton'; + +import { localeString } from '../../utils/LocaleUtils'; +import { themeColor } from '../../utils/ThemeUtils'; + +import stores from '../../stores/Stores'; +import { ChannelsType } from '../../stores/ChannelsStore'; + +const getChannelsSortKeys = (closed?: boolean) => { + const sortKeys: any = []; + + if (closed) { + sortKeys.push( + { + key: `${localeString( + 'views.Channel.closeHeight' + )} (${localeString('views.Channel.SortButton.ascending')})`, + value: { param: 'closeHeight', dir: 'ASC', type: 'numeric' } + }, + { + key: `${localeString( + 'views.Channel.closeHeight' + )} (${localeString('views.Channel.SortButton.descending')})`, + value: { + param: 'closeHeight', + dir: 'DESC', + type: 'numeric' + } + } + ); + } + + sortKeys.push( + { + key: `${localeString('views.Channel.capacity')} (${localeString( + 'views.Channel.SortButton.largestFirst' + )})`, + value: { + param: 'channelCapacity', + dir: 'DESC', + type: 'numeric' + } + }, + { + key: `${localeString('views.Channel.capacity')} (${localeString( + 'views.Channel.SortButton.smallestFirst' + )})`, + value: { param: 'channelCapacity', dir: 'ASC', type: 'numeric' } + }, + { + key: `${localeString( + 'views.Channel.inboundCapacity' + )} (${localeString('views.Channel.SortButton.largestFirst')})`, + value: { param: 'remoteBalance', dir: 'DESC', type: 'numeric' } + }, + { + key: `${localeString( + 'views.Channel.inboundCapacity' + )} (${localeString('views.Channel.SortButton.smallestFirst')})`, + value: { param: 'remoteBalance', dir: 'ASC', type: 'numeric' } + }, + { + key: `${localeString( + 'views.Channel.outboundCapacity' + )} (${localeString('views.Channel.SortButton.largestFirst')})`, + value: { param: 'localBalance', dir: 'DESC', type: 'numeric' } + }, + { + key: `${localeString( + 'views.Channel.outboundCapacity' + )} (${localeString('views.Channel.SortButton.smallestFirst')})`, + value: { param: 'localBalance', dir: 'ASC', type: 'numeric' } + }, + { + key: `${localeString('views.Channel.displayName')} (${localeString( + 'views.Channel.SortButton.ascending' + )})`, + value: { + param: 'displayName', + dir: 'ASC', + type: 'alphanumeric' + } + }, + { + key: `${localeString('views.Channel.displayName')} (${localeString( + 'views.Channel.SortButton.descending' + )})`, + value: { + param: 'displayName', + dir: 'DESC', + type: 'alphanumeric' + } + } + ); + + return sortKeys; +}; + +interface ChannelsFilterProps { + width?: string | number; +} + +const ChannelsFilter = (props: ChannelsFilterProps) => { + const { channelsStore } = stores; + const { search, setSort, channelsType } = channelsStore; + const windowWidth = Dimensions.get('window').width; + return ( + + + + channelsStore!.setSearch(value) + } + value={search} + inputStyle={{ + color: themeColor('text'), + fontFamily: 'PPNeueMontreal-Book' + }} + placeholderTextColor={themeColor('secondaryText')} + containerStyle={{ + backgroundColor: null, + borderTopWidth: 0, + borderBottomWidth: 0, + width: props.width || windowWidth - 55 + }} + inputContainerStyle={{ + borderRadius: 15, + backgroundColor: themeColor('secondary') + }} + autoCapitalize="none" + /> + { + setSort(value); + }} + values={getChannelsSortKeys( + channelsType === ChannelsType.Closed + )} + /> + + + + ); +}; + +export default ChannelsFilter; diff --git a/components/HopPicker.tsx b/components/HopPicker.tsx index 908abb1d1..ec3420585 100644 --- a/components/HopPicker.tsx +++ b/components/HopPicker.tsx @@ -9,7 +9,6 @@ import { TouchableOpacity, TouchableHighlight } from 'react-native'; -import { SearchBar } from 'react-native-elements'; import { inject, observer } from 'mobx-react'; import { themeColor } from '../utils/ThemeUtils'; @@ -17,9 +16,7 @@ import { localeString } from '../utils/LocaleUtils'; import Button from '../components/Button'; import { ChannelItem } from './Channels/ChannelItem'; -import SortButton from '../components/Channels/SortButton'; -import { Row } from '../components/layout/Row'; -import { FilterOptions } from '../components/Channels/FilterOptions'; +import ChannelsFilter from './Channels/ChannelsFilter'; import Channel from '../models/Channel'; @@ -55,98 +52,6 @@ export default class ChannelPicker extends React.Component< showChannelModal: false }; - private getChannelsSortKeys = (closed?: boolean) => { - const sortKeys = []; - - if (closed) { - sortKeys.push( - { - key: `${localeString( - 'views.Channel.closeHeight' - )} (${localeString('views.Channel.SortButton.ascending')})`, - value: { param: 'closeHeight', dir: 'ASC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.closeHeight' - )} (${localeString( - 'views.Channel.SortButton.descending' - )})`, - value: { - param: 'closeHeight', - dir: 'DESC', - type: 'numeric' - } - } - ); - } - - sortKeys.push( - { - key: `${localeString('views.Channel.capacity')} (${localeString( - 'views.Channel.SortButton.largestFirst' - )})`, - value: { - param: 'channelCapacity', - dir: 'DESC', - type: 'numeric' - } - }, - { - key: `${localeString('views.Channel.capacity')} (${localeString( - 'views.Channel.SortButton.smallestFirst' - )})`, - value: { param: 'channelCapacity', dir: 'ASC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.inboundCapacity' - )} (${localeString('views.Channel.SortButton.largestFirst')})`, - value: { param: 'remoteBalance', dir: 'DESC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.inboundCapacity' - )} (${localeString('views.Channel.SortButton.smallestFirst')})`, - value: { param: 'remoteBalance', dir: 'ASC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.outboundCapacity' - )} (${localeString('views.Channel.SortButton.largestFirst')})`, - value: { param: 'localBalance', dir: 'DESC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.outboundCapacity' - )} (${localeString('views.Channel.SortButton.smallestFirst')})`, - value: { param: 'localBalance', dir: 'ASC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.displayName' - )} (${localeString('views.Channel.SortButton.ascending')})`, - value: { - param: 'displayName', - dir: 'ASC', - type: 'alphanumeric' - } - }, - { - key: `${localeString( - 'views.Channel.displayName' - )} (${localeString('views.Channel.SortButton.descending')})`, - value: { - param: 'displayName', - dir: 'DESC', - type: 'alphanumeric' - } - } - ); - - return sortKeys; - }; - openPicker() { stores.channelsStore.getChannels(); this.setState({ @@ -202,15 +107,7 @@ export default class ChannelPicker extends React.Component< render() { const { title, onValueChange, ChannelsStore } = this.props; const { showChannelModal, valueSet } = this.state; - const { - filteredChannels, - nodes, - loading, - getChannels, - channelsType, - setSort, - search - } = ChannelsStore; + const { filteredChannels, nodes, loading, getChannels } = ChannelsStore; const channels = filteredChannels; @@ -252,47 +149,7 @@ export default class ChannelPicker extends React.Component< )} - - - - ChannelsStore!.setSearch(value) - } - value={search} - inputStyle={{ - color: themeColor('text'), - fontFamily: 'PPNeueMontreal-Book' - }} - placeholderTextColor={themeColor( - 'secondaryText' - )} - containerStyle={{ - backgroundColor: null, - borderTopWidth: 0, - borderBottomWidth: 0, - width: '86%' - }} - inputContainerStyle={{ - borderRadius: 15, - backgroundColor: - themeColor('secondary') - }} - autoCapitalize="none" - /> - { - setSort(value); - }} - values={this.getChannelsSortKeys( - channelsType === ChannelsType.Closed - )} - /> - - - + { - private getChannelsSortKeys = (closed?: boolean) => { - const sortKeys = []; - - if (closed) { - sortKeys.push( - { - key: `${localeString( - 'views.Channel.closeHeight' - )} (${localeString('views.Channel.SortButton.ascending')})`, - value: { param: 'closeHeight', dir: 'ASC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.closeHeight' - )} (${localeString( - 'views.Channel.SortButton.descending' - )})`, - value: { - param: 'closeHeight', - dir: 'DESC', - type: 'numeric' - } - } - ); - } - - sortKeys.push( - { - key: `${localeString('views.Channel.capacity')} (${localeString( - 'views.Channel.SortButton.largestFirst' - )})`, - value: { - param: 'channelCapacity', - dir: 'DESC', - type: 'numeric' - } - }, - { - key: `${localeString('views.Channel.capacity')} (${localeString( - 'views.Channel.SortButton.smallestFirst' - )})`, - value: { param: 'channelCapacity', dir: 'ASC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.inboundCapacity' - )} (${localeString('views.Channel.SortButton.largestFirst')})`, - value: { param: 'remoteBalance', dir: 'DESC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.inboundCapacity' - )} (${localeString('views.Channel.SortButton.smallestFirst')})`, - value: { param: 'remoteBalance', dir: 'ASC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.outboundCapacity' - )} (${localeString('views.Channel.SortButton.largestFirst')})`, - value: { param: 'localBalance', dir: 'DESC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.outboundCapacity' - )} (${localeString('views.Channel.SortButton.smallestFirst')})`, - value: { param: 'localBalance', dir: 'ASC', type: 'numeric' } - }, - { - key: `${localeString( - 'views.Channel.displayName' - )} (${localeString('views.Channel.SortButton.ascending')})`, - value: { - param: 'displayName', - dir: 'ASC', - type: 'alphanumeric' - } - }, - { - key: `${localeString( - 'views.Channel.displayName' - )} (${localeString('views.Channel.SortButton.descending')})`, - value: { - param: 'displayName', - dir: 'DESC', - type: 'alphanumeric' - } - } - ); - - return sortKeys; - }; - renderItem = ({ item }: { item: Channel }) => { const { ChannelsStore, navigation } = this.props; - const { largestChannelSats, channelsType } = ChannelsStore; + const { largestChannelSats, channelsType } = ChannelsStore!; const getStatus = () => { if (item.isActive) { @@ -231,10 +135,8 @@ export default class ChannelsPane extends React.PureComponent { filteredChannels, filteredPendingChannels, filteredClosedChannels, - setSort, showSearch, - channelsType, - search + channelsType } = ChannelsStore!; const lurkerMode: boolean = @@ -263,8 +165,6 @@ export default class ChannelsPane extends React.PureComponent { break; } - const windowWidth = Dimensions.get('window').width; - return ( { totalOffline={totalOffline} lurkerMode={lurkerMode} /> - {showSearch && ( - - - - { - setSort(value); - }} - values={this.getChannelsSortKeys( - channelsType === ChannelsType.Closed - )} - /> - - - - )} + {showSearch && } {loading ? (