Skip to content

Add payments container. #14

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

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion app/containers/Home.tsx
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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>
)
}
}