Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add payments container. #14

Merged
merged 1 commit into from Jul 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion app/containers/Home.tsx
Expand Up @@ -11,6 +11,7 @@ import layoutStyles from '../styles/layout'
import CurrentUserQuery, { GET_CURRENT_USER_QUERY } from '../queries/CurrentUser'
import { User } from '../Types'
import Balance from './Balance'
import Payments from './Payments'

export default class Home extends React.Component<NavigationScreenProps> {
static navigationOptions = {
Expand Down Expand Up @@ -71,7 +72,10 @@ export default class Home extends React.Component<NavigationScreenProps> {
asset={anchorXUSD} />
</View>
<View>
<Text style={s.tc}>Hola {data.me.username}, your Stellar account is {data.me.stellarAccount}</Text>
<Payments
accountId={data.me.stellarAccount}
asset={anchorXUSD}
/>
</View>
</Content>
</Container>)
Expand Down
170 changes: 170 additions & 0 deletions app/containers/Payments.tsx
@@ -0,0 +1,170 @@
import * as React from 'react'
import { View, StyleSheet, FlatList } from 'react-native'

import { Container, Content, Text, Button, Spinner } from 'native-base';
import { styles as s } from "react-native-style-tachyons";

import { Asset, PaymentOperationRecord, Server, Network } from 'stellar-sdk'

import Payment from '../components/Payment';

interface Props {
accountId: string
asset?: Asset
}

interface State {
loadMore: boolean
payments: PaymentOperationRecord[]
loading: boolean
closeStreaming?: any
}


export default class Payments extends React.Component<Props, State> {
constructor(props: Props) {
super(props)

this.state = {
loadMore: true,
payments: [],
loading: false
}
}

async loadPayments(cursor?: string) {
const { accountId, asset } = this.props
const { payments } = this.state
Network.useTestNetwork()
const stellarServer = new Server('https://horizon-testnet.stellar.org')

let builder = stellarServer
.payments()
.forAccount(accountId)
.order('desc')

if (cursor) {
builder.cursor(cursor)
}

const { records } = await builder.call()

if (asset) {
return records.filter((payment) => payment.asset_code === asset.code && payment.asset_issuer === asset.issuer)
} else {
return records
}
}

listenForPayments(cursor = 'now') {
const { closeStreaming } = this.state

if (closeStreaming) {
try {
closeStreaming()
} catch (e) {
console.log('error closing streaming')
}
}

const { accountId } = this.props

Network.useTestNetwork()
const server = new Server('https://horizon-testnet.stellar.org')

let handleMessage = (payment: PaymentOperationRecord) => {
const { asset } = this.props
const { payments } = this.state

if (payment.asset_code === asset.code && payment.asset_issuer === asset.issuer) {
this.setState({
payments: [payment, ...payments]
})
}
}

this.setState({
closeStreaming: server.payments()
.cursor(cursor)
.forAccount(accountId)
.stream({
onmessage: handleMessage
})
})
}

async componentDidMount() {
const payments = await this.loadPayments()

this.setState({
payments
})

this.listenForPayments()
}

componentWillUnmount() {
const { closeStreaming } = this.state

try {
closeStreaming && closeStreaming()
} catch (e) {
console.log('error closing streaming')
}
}

async fetchMoreData() {
const { accountId } = this.props
const { payments } = this.state

const cursor = payments[payments.length - 1].id

this.setState({
loading: true
})

const nextPage = await this.loadPayments(cursor)

const state = {
loadMore: true,
payments: [...payments, ...nextPage],
loading: false
}

if (nextPage.length === 0) {
state.loadMore = false
}

this.setState(state)
}

render() {
const { accountId } = this.props
const { loadMore, payments, loading } = this.state

return (
<Container style={{ backgroundColor: '#F5FCFF' }} >
<FlatList
data={payments}
renderItem={({ item }) => <Payment key={item.id} payment={item} account={accountId} />}
keyExtractor={(item) => item.id}
onEndReachedThreshold={0.2}
onEndReached={({ distanceFromEnd }) => {
if (!loadMore || loading) {
return
}

return this.fetchMoreData()
}}
refreshing={loading}
ListFooterComponent={loading && <Spinner color="blue" />}
onRefresh={() => {
if (payments.length > 0) {
this.listenForPayments(payments[0].id)
}
}}
/>
</Container>
)
}
}