Skip to content
This repository has been archived by the owner on Sep 27, 2022. It is now read-only.

WIP: New HomeScreen and App's navigation #253

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open
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
12 changes: 8 additions & 4 deletions App.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import { connect, Provider } from 'react-redux';
import SpinnerOverlay from 'react-native-loading-spinner-overlay';
import AppLoader from './src/screens/AppLoader';
import ChangelogScreen from './src/screens/Settings/ChangelogScreen';
import AuthNavigator from './src/navigations/Auth/AuthNavigator';
import AuthNavigator from './src/navigations/AuthNavigator';
import store from './src/redux/store';
import colors from './src/styles/colors';
import MainNavigator from './src/navigations/MainNavigator';
import BiometricAuthScreen from './src/screens/Auth/BiometricAuthScreen';
import MainNavigator from './src/navigations/MainNavigator';

const styles = StyleSheet.create({
defaultFontFamily: {
Expand Down Expand Up @@ -53,13 +53,17 @@ YellowBox.ignoreWarnings(['Async Storage', 'WebView']);

const AppContainer = createAppContainer(AppNavigator);

const paddingTop = StatusBar.currentHeight || 20;
const paddingTop = Platform.OS === 'ios' ? 20 : StatusBar.currentHeight;

const mapStateToProps = ({ config }) => ({ config });

const ConnectedApp = connect(mapStateToProps)(({ config }) => (
<SafeAreaView style={{ flex: 1, paddingTop, backgroundColor: colors.backgroundBlock }}>
<StatusBar backgroundColor={colors.primary} translucent />
<StatusBar
translucent
backgroundColor={colors.background}
barStyle={colors.generalAspect === 'light' ? 'dark-content' : 'light-content'}
/>
<SpinnerOverlay {...config.spinner} />
<AppContainer screenProps={{ config }} />
</SafeAreaView>
Expand Down
6 changes: 5 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { AppRegistry } from 'react-native';
import { AppRegistry, Platform, UIManager } from 'react-native';
import App from './App';

if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
UIManager.setLayoutAnimationEnabledExperimental(true);
}

AppRegistry.registerComponent('PayUTC', () => App);
4 changes: 3 additions & 1 deletion src/components/BlockTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default class BlockTemplate extends React.Component {
roundedTop,
roundedBottom,
onPress,
onLongPress,
disabled,
customBackground,
style,
Expand All @@ -51,8 +52,9 @@ export default class BlockTemplate extends React.Component {
return (
<TouchableOpacity
onPress={onPress}
onLongPress={onLongPress}
disabled={disabled}
activeOpacity={onPress ? 0.2 : 1}
activeOpacity={onPress ? 0.6 : 1}
style={[
{
backgroundColor: customBackground || colors.backgroundBlock,
Expand Down
63 changes: 44 additions & 19 deletions src/components/History/HistoryList.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
*/

import React from 'react';
import { Text } from 'react-native';
import Item from './Item';
import { Text, View } from 'react-native';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
import TransactionList from './TransactionList';
import BlockTemplate from '../BlockTemplate';
import List from '../List';
import colors from '../../styles/colors';
Expand All @@ -21,37 +22,46 @@ export default class HistoryList extends React.Component {

this.state = {
slice: DEFAULT_SLICE,
selected: null,
};

this.showMore = this.showMore.bind(this);
this.renderFooter = this.renderFooter.bind(this);
this.renderTransactionList = this.renderTransactionList.bind(this);
}

componentDidUpdate(prevProps) {
const { loading } = this.props;
const { loading, slice } = this.props;

if (!prevProps.loading && loading) {
this.setState({ slice: DEFAULT_SLICE });
this.setState({ slice });
}
}

static renderItem(item, index, last = false) {
return (
<Item
transaction={item}
customBackground={index % 2 === 0 ? colors.backgroundBlockAlt : colors.backgroundBlock}
roundedBottom={last}
/>
);
}

showMore() {
const { slice } = this.props;

this.setState(prevState => ({
...prevState,
slice: prevState.slice + DEFAULT_SLICE,
slice: prevState.slice + (slice || DEFAULT_SLICE),
}));
}

renderTransactionList(items, index, last = false) {
const { selected } = this.state;

return (
<View style={{ marginBottom: last ? 0 : 10 }}>
<TransactionList
transactions={items}
expand={selected === index}
select={() => this.setState({ selected: index })}
unselect={() => this.setState({ selected: null })}
/>
</View>
);
}

renderFooter() {
const { items, loading } = this.props;
const { slice } = this.state;
Expand All @@ -61,10 +71,12 @@ export default class HistoryList extends React.Component {

return (
<BlockTemplate
roundedTop
roundedBottom
onPress={this.showMore}
disabled={disabled}
customBackground={colors.backgroundBlockAlt}
customBackground={colors.backgroundBlock}
style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}
>
<Text
style={{
Expand All @@ -75,6 +87,11 @@ export default class HistoryList extends React.Component {
>
{t('show_more')}
</Text>
<FontAwesomeIcon
icon={['fas', 'chevron-down']}
size={16}
color={disabled ? colors.disabled : colors.primary}
/>
</BlockTemplate>
);
}
Expand All @@ -83,14 +100,22 @@ export default class HistoryList extends React.Component {
const { items, title, loading } = this.props;
const { slice } = this.state;

const itemsByDate = items.reduce((r, a) => {
r[a.date] = r[a.date] || [];
r[a.date].push(a);
return r;
}, Object.create(null));

return (
<List
title={title}
items={items.slice(0, slice)}
items={Object.values(itemsByDate)
.filter(item => item.length > 0)
.slice(0, slice)}
loading={loading}
renderItem={HistoryList.renderItem}
renderItem={this.renderTransactionList}
renderFooter={this.renderFooter}
keyExtractor={item => item.id.toString()}
keyExtractor={item => item[0].id.toString()}
notRoundedTop
noBottomBorder
/>
Expand Down
142 changes: 104 additions & 38 deletions src/components/History/Transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,122 @@
* @license GPL-3.0
*/

import React from 'react';
import { Text, View } from 'react-native';
import React, { Component } from 'react';
import { LayoutAnimation, Text, View } from 'react-native';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
import { History as t } from '../../utils/i18n';
import colors from '../../styles/colors';
import { floatToEuro } from '../../utils/amount';
import { beautifyDateTime } from '../../utils/date';

export default function Transaction({
title,
amount,
quantity,
date,
location,
message,
positive,
}) {
return (
<View>
<Text style={{ fontSize: 10, color: colors.secondary, marginBottom: 3 }}>
{beautifyDateTime(date)} {location ? `• ${location}` : null}
</Text>
<View>
import { beautifyDate, beautifyDateTime } from '../../utils/date';

export default class Transaction extends Component {
static getTransactionIcon = type => {
switch (type.toUpperCase()) {
case 'PURCHASE':
return 'shopping-basket';
case 'TRANSFER':
return 'share';
case 'REFILL':
return 'plus-circle';
default:
return '';
}
};

render() {
const {
id,
type,
title,
amount,
quantity,
date,
location,
message,
positive,
productId,
expanded,
} = this.props;
const tintColor = positive
? colors.more
: type.toUpperCase() === 'TRANSFER'
? colors.transfer
: colors.secondary;

return (
<View
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
flexWrap: 'wrap',
}}
onLayout={() => {
LayoutAnimation.configureNext(LayoutAnimation.create(100, 'linear', 'opacity'));
}}
>
<FontAwesomeIcon
icon={['fas', Transaction.getTransactionIcon(type)]}
size={20}
color={`${tintColor}95`}
style={{ alignSelf: 'center' }}
/>

<View
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
flexWrap: 'wrap',
}}
>
<View style={{ flex: 1, flexWrap: 'wrap', marginRight: 10 }}>
<Text style={{ fontSize: 14, fontWeight: 'bold', color: colors.secondary }}>
{title} {quantity && quantity > 1 ? `x${quantity}` : null}
style={{ borderLeftWidth: 1, borderLeftColor: `${tintColor}15`, marginHorizontal: 10 }}
/>

<View style={{ flex: 1, flexWrap: 'wrap', marginRight: 10 }}>
<Text style={{ fontSize: 15, fontWeight: 'bold', color: tintColor }}>
{title} {quantity && quantity > 1 ? `x${quantity}` : null}
</Text>

<Text style={{ fontSize: 10, color: tintColor, marginBottom: 3 }}>
{expanded ? beautifyDateTime(date) : beautifyDate(date)}{' '}
{location ? `• ${location}` : null}
</Text>

{message ? (
<Text
numberOfLines={expanded ? null : 2}
style={{ fontSize: 12, color: `${tintColor}95`, marginTop: 3 }}
>
{message}
</Text>
{message ? (
<Text numberOfLines={2} style={{ fontSize: 12, color: colors.secondary }}>
{message}
) : null}

{expanded ? (
<>
<Text
numberOfLines={expanded ? null : 2}
style={{ fontSize: 12, color: `${tintColor}95`, marginTop: 3 }}
>
{t('transaction_*', { number: id })}
</Text>
) : null}
</View>
{productId ? (
<Text
numberOfLines={expanded ? null : 2}
style={{ fontSize: 12, color: `${tintColor}95` }}
>
{t('product_*', { number: productId })}
</Text>
) : null}
</>
) : null}
</View>

<View style={{ alignSelf: 'center' }}>
<Text
style={{
fontSize: 14,
fontSize: 15,
fontWeight: 'bold',
color: positive ? colors.more : colors.less,
color: tintColor,
}}
>
{positive ? '+' : '-'} {floatToEuro(amount / 100)}
</Text>
</View>
</View>
</View>
);
);
}
}
Loading