feat: some code reafactor + change page and buses list interval is added

master
TyFonDev 2024-01-10 19:47:43 -03:00
parent 465a220a97
commit 5782b43b3b
16 changed files with 3451 additions and 204 deletions

View File

@ -3,6 +3,7 @@ import useDevices from '../useDevices';
import AuthRepositoryImpl from '../../repositories/AuthRepositoryImpl';
import DevicesRepositoryImpl from '../../repositories/DevicesRepositoryImpl';
jest.useFakeTimers();
describe('useDevices tests', () => {
beforeAll(() => {
jest.spyOn(AuthRepositoryImpl.prototype, 'auth').mockResolvedValue('token');
@ -96,7 +97,6 @@ describe('useDevices tests', () => {
const mockDate = new Date('2023-01-01T14:00:00Z');
const spy = jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
const {result} = renderHook(() => useDevices());
await waitFor(() => {
expect(result.current.state.lines).toMatchObject([
{

View File

@ -6,15 +6,10 @@ import AuthRepositoryImpl from '../repositories/AuthRepositoryImpl';
import AuthAPI from '../api/clients/AuthAPI';
import LineDetail from '../../domain/repositories/LineDetail';
import {Line} from '../../presentation/screens/BusStopInfoScreen';
import BusStopInfoService from '../../domain/services/BusStopInfoService';
import RemoteConfigKeys from '../../utils/RemoteConfigKeys';
export enum Status {
LOADING = 'LOADING',
SUCCESS = 'SUCCESS',
ERROR = 'ERROR',
}
import {Line} from '../../presentation/components/Table';
import Status from '../../utils/Status';
interface State {
status: Status;
@ -40,8 +35,11 @@ const useDevices = () => {
const baseURL = remoteConfig().getString(RemoteConfigKeys.BASE_URL);
const username = remoteConfig().getString(RemoteConfigKeys.USER);
const password = remoteConfig().getString(RemoteConfigKeys.PASS);
const updateInterval = remoteConfig().getNumber(
RemoteConfigKeys.UPDATE_INTERVAL,
const changePageInterval = remoteConfig().getNumber(
RemoteConfigKeys.CHANGE_PAGE_INTERVAL,
);
const updateBusesListInterval = remoteConfig().getNumber(
RemoteConfigKeys.UPDATE_BUSES_LIST_INTERVAL,
);
const deviceApi = useMemo(() => new DevicesAPI(baseURL), [baseURL]);
@ -182,7 +180,19 @@ const useDevices = () => {
};
init();
}, [authRepository, devicesRepository, password, username]);
const interval = setInterval(init, updateBusesListInterval);
return () => {
clearInterval(interval);
};
}, [
authRepository,
devicesRepository,
password,
username,
updateBusesListInterval,
]);
useEffect(() => {
setDisplayedLines(state.lines, state.stopMessage, state.stopName);
@ -201,12 +211,12 @@ const useDevices = () => {
: (prevState.currentIndex || 1 + 21) % state.lines.length,
};
});
}, 5000);
}, changePageInterval);
return () => {
clearInterval(interval);
};
}, [state.lines, state.status, updateInterval]);
}, [state.lines, state.status, changePageInterval]);
return {state};
};

View File

@ -0,0 +1,46 @@
import {useCallback, useEffect, useState} from 'react';
import remoteConfig from '@react-native-firebase/remote-config';
import Status from '../../utils/Status';
const useRemoteConfig = () => {
const [status, setStatus] = useState(Status.LOADING);
const getString = useCallback(
(key: string) => remoteConfig().getString(key),
[],
);
useEffect(() => {
const init = async () => {
try {
await remoteConfig().setConfigSettings({
minimumFetchIntervalMillis: 3600000,
});
// TODO: Add default values for remote config
await remoteConfig().setDefaults({
BASE_URL: '',
HEADER_IMAGE_URL: '',
USER: '',
PASS: '',
CHANGE_PAGE_INTERVAL: 0,
UPDATE_BUSES_LIST_INTERVAL: 0,
});
const isActivated = await remoteConfig().fetchAndActivate();
if (isActivated) {
setStatus(Status.SUCCESS);
}
} catch (error) {
setStatus(Status.ERROR);
}
};
init();
}, []);
return {status, getString};
};
export default useRemoteConfig;

View File

@ -0,0 +1,24 @@
import {View, ActivityIndicator, StyleProp} from 'react-native';
import {ViewStyle} from 'react-native';
import Table, {Line} from './Table';
import Status from '../../utils/Status';
interface BusListProps {
buses: Line[];
status: Status;
style?: StyleProp<ViewStyle>;
}
const BusList = ({buses, status, style}: BusListProps) => {
return (
<View style={style}>
{status === Status.LOADING ? (
<ActivityIndicator testID="LOADING" />
) : (
<Table data={buses} />
)}
</View>
);
};
export default BusList;

View File

@ -21,7 +21,7 @@ const Header = ({title, subTitle, style, image}: HeaderProps) => {
<View style={styles.iconContainer}>
<Image
source={{
uri: 'https://cdn-icons-png.flaticon.com/512/8371/8371047.png',
uri: image,
}}
style={styles.icon}
/>

View File

@ -0,0 +1,138 @@
import {View, Text, StyleSheet} from 'react-native';
export interface Line {
lineNumber: string;
lineLetter: string;
letterColor: string;
backgroundColor: string;
estimatedArrivalTimeInMinutes: string;
lineDescription: string;
}
export interface TableProps {
data: Line[];
}
const Table = ({data}: TableProps) => {
const rows = 7;
const columns = 3;
const baseTableData: Line[][] = Array.from({length: rows}, () =>
new Array(columns).fill({
lineNumber: '',
lineLetter: '',
letterColor: '',
backgroundColor: '',
estimatedArrivalTimeInMinutes: '',
}),
);
data.map((item, index) => {
const row = Math.floor(index / columns);
const column = index % columns;
baseTableData[row][column] = item;
});
return (
<View style={tableStyles.table}>
{baseTableData.map((row, rowIndex) => (
<View key={rowIndex} style={tableStyles.row}>
{row.map((cell, cellIndex) => {
if (cell.lineNumber === '') {
return <View style={tableStyles.cell} key={cellIndex} />;
}
const [first, second] = cell.lineDescription.split('-');
return (
<View style={[tableStyles.cell]} key={cellIndex}>
<View style={tableStyles.lineInformationContainer}>
<Text style={tableStyles.lineNumber}>{cell.lineNumber}</Text>
<View
style={[
tableStyles.letterContainer,
{backgroundColor: `#${cell.backgroundColor}` || 'grey'},
]}>
<Text style={tableStyles.lineLetter}>
{cell.lineLetter}
</Text>
</View>
</View>
<View
style={[
tableStyles.timeContainer,
{backgroundColor: `#${cell.backgroundColor}` || 'grey'},
]}>
<Text style={tableStyles.time} numberOfLines={1}>
{first}
</Text>
<Text style={tableStyles.time} numberOfLines={1}>
{second}
</Text>
<Text style={tableStyles.time}>
{cell.estimatedArrivalTimeInMinutes}
</Text>
</View>
</View>
);
})}
</View>
))}
</View>
);
};
const tableStyles = StyleSheet.create({
table: {
flex: 1,
backgroundColor: 'white',
},
row: {
flex: 1,
flexDirection: 'row',
},
cell: {
flex: 1,
borderWidth: 1,
flexDirection: 'column',
borderColor: 'grey',
},
lineInformationContainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
timeContainer: {
alignItems: 'center',
backgroundColor: 'blue',
},
lineNumber: {
fontSize: 20,
marginRight: 8,
fontWeight: 'bold',
color: 'grey',
},
lineLetter: {
fontSize: 14,
color: 'white',
fontWeight: 'bold',
},
letterContainer: {
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 50,
},
time: {
fontSize: 12,
fontWeight: 'bold',
color: 'white',
},
lineDescription: {
fontSize: 12,
fontWeight: 'bold',
color: 'white',
},
});
export default Table;

View File

@ -0,0 +1,149 @@
export default [
{
backgroundColor: 'b10086',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'N',
lineNumber: '10',
lineDescription: 'Vía Láctea - Los Bloques',
},
{
backgroundColor: '0d7215',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'O',
lineNumber: '10',
lineDescription: 'Vía Láctea - Pobl. Porvenir',
},
{
backgroundColor: '0071ca',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'P',
lineNumber: '10',
lineDescription: 'Vía Láctea - Leonera',
},
{
backgroundColor: '4e0963',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'L',
lineNumber: '10',
lineDescription: 'Vía Láctea - Los Bloques',
},
{
backgroundColor: 'ad0101',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'Q',
lineNumber: '11',
lineDescription: 'Vía Futuro - Los Bloques',
},
{
backgroundColor: 'b10086',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'R',
lineNumber: '11',
lineDescription: 'Vía Futuro - Porvenir',
},
{
backgroundColor: 'ce5504',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'S',
lineNumber: '13',
lineDescription: 'Vía Siglo XXI - Leonera',
},
{
backgroundColor: 'ce5504',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'T',
lineNumber: '14',
lineDescription: 'Chiguayante Sur - Coquimbo',
},
{
backgroundColor: 'cc9b00',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'U',
lineNumber: '14',
lineDescription: 'Chiguayante Sur - Los Altos',
},
{
backgroundColor: 'ad0101',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'V',
lineNumber: '16',
lineDescription: 'Vía Universo - Leonera',
},
{
backgroundColor: '0d7215',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'W',
lineNumber: '17',
lineDescription: 'Expresos Chiguayante - Leonera',
},
{
backgroundColor: 'ce5504',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'X',
lineNumber: '17',
lineDescription: 'Expresos Chiguayante - Leonera',
},
{
backgroundColor: '0071ca',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'Y',
lineNumber: '18',
lineDescription: 'Buses Palomares - Hualqui',
},
{
backgroundColor: 'b10086',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'M',
lineNumber: '20',
lineDescription: 'Nueva Llacolén - San Pedro Costa',
},
{
backgroundColor: '0071ca',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'A',
lineNumber: '20',
lineDescription: 'Nueva Llacolén - Boca Sur',
},
{
backgroundColor: 'ce5504',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'B',
lineNumber: '21',
lineDescription: 'Riviera Biobío - Candelaria',
},
{
backgroundColor: '0071ca',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'F',
lineNumber: '24',
lineDescription: 'San Remo - Candelaria',
},
{
backgroundColor: '0d7215',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'Q',
lineNumber: '30',
lineDescription: 'Ruta Las Playas - Higueras',
},
{
backgroundColor: '049684',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'R',
lineNumber: '30',
lineDescription: 'Ruta Las Playas - Higueras',
},
{
backgroundColor: 'ce5504',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'Y',
lineNumber: '57',
lineDescription: 'Denavi Sur - Cosmito',
},
{
backgroundColor: 'ce5504',
estimatedArrivalTimeInMinutes: 'Más de 10 minutos',
lineLetter: 'P',
lineNumber: '57',
lineDescription: 'Denavi Sur - San Vicente',
},
];

View File

@ -0,0 +1,27 @@
import {render} from '@testing-library/react-native';
import BusList from '../BusList';
import Status from '../../../utils/Status';
describe('BusList tests', () => {
it('should be defined', () => {
expect(BusList).toBeTruthy();
});
it('should render correctly with status LOADING', () => {
const {toJSON, getByTestId} = render(
<BusList buses={[]} status={Status.LOADING} />,
);
expect(toJSON()).toMatchSnapshot();
expect(getByTestId('LOADING')).toBeTruthy();
});
it('should render correctly with status SUCCESS', () => {
const {toJSON, queryByTestId} = render(
<BusList buses={[]} status={Status.SUCCESS} />,
);
expect(toJSON()).toMatchSnapshot();
expect(queryByTestId('LOADING')).toBeNull();
});
});

View File

@ -7,13 +7,17 @@ describe('Header tests', () => {
});
it('should render correctly', () => {
const {toJSON} = render(<Header title="Title" subTitle="Subtitle" />);
const {toJSON} = render(
<Header title="Title" subTitle="Subtitle" image="https://urlimage.cl" />,
);
expect(toJSON()).toMatchSnapshot();
});
it('should render a title and a subtitle', () => {
const {getByText} = render(<Header title="Title" subTitle="Subtitle" />);
const {getByText} = render(
<Header title="Title" subTitle="Subtitle" image="https://urlimage.cl" />,
);
expect(getByText('Title')).toBeDefined();
expect(getByText('Subtitle')).toBeDefined();

View File

@ -0,0 +1,21 @@
import {render} from '@testing-library/react-native';
import Table, {Line} from '../Table';
import lineListMock from '../__mocks__/LineList';
describe('Table tests', () => {
it('should be defined', () => {
expect(Table).toBeDefined();
});
it('should render correctly', () => {
const {toJSON} = render(<Table data={lineListMock as Line[]} />);
expect(toJSON()).toMatchSnapshot();
});
it('should render correctly with empty data', () => {
const {toJSON} = render(<Table data={[]} />);
expect(toJSON()).toMatchSnapshot();
});
});

View File

@ -0,0 +1,296 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`BusList tests should render correctly with status LOADING 1`] = `
<View>
<ActivityIndicator
testID="LOADING"
/>
</View>
`;
exports[`BusList tests should render correctly with status SUCCESS 1`] = `
<View>
<View
style={
{
"backgroundColor": "white",
"flex": 1,
}
}
>
<View
style={
{
"flex": 1,
"flexDirection": "row",
}
}
>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
</View>
<View
style={
{
"flex": 1,
"flexDirection": "row",
}
}
>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
</View>
<View
style={
{
"flex": 1,
"flexDirection": "row",
}
}
>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
</View>
<View
style={
{
"flex": 1,
"flexDirection": "row",
}
}
>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
</View>
<View
style={
{
"flex": 1,
"flexDirection": "row",
}
}
>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
</View>
<View
style={
{
"flex": 1,
"flexDirection": "row",
}
}
>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
</View>
<View
style={
{
"flex": 1,
"flexDirection": "row",
}
}
>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
<View
style={
{
"borderColor": "grey",
"borderWidth": 1,
"flex": 1,
"flexDirection": "column",
}
}
/>
</View>
</View>
</View>
`;

View File

@ -29,7 +29,7 @@ exports[`Header tests should render correctly 1`] = `
<Image
source={
{
"uri": "https://cdn-icons-png.flaticon.com/512/8371/8371047.png",
"uri": "https://urlimage.cl",
}
}
style={

File diff suppressed because it is too large Load Diff

View File

@ -1,131 +1,25 @@
import {ActivityIndicator, StyleSheet, View} from 'react-native';
import Container from '../components/Container';
import Header from '../components/Header';
import {Text} from 'react-native';
import useDevices, {Status} from '../../infraestructure/hooks/useDevices';
import useDevices from '../../infraestructure/hooks/useDevices';
import Banner from '../components/Banner';
import {useEffect, useState} from 'react';
import remoteConfig from '@react-native-firebase/remote-config';
import RemoteConfigKeys from '../../utils/RemoteConfigKeys';
import BusList from '../components/BusList';
import useRemoteConfig from '../../infraestructure/hooks/useRemoteConfig';
import Status from '../../utils/Status';
export interface Line {
lineNumber: string;
lineLetter: string;
letterColor: string;
backgroundColor: string;
estimatedArrivalTimeInMinutes: string;
lineDescription: string;
}
interface TableProps {
data: Line[];
}
const Table = ({data}: TableProps) => {
const rows = 7;
const columns = 3;
const baseTableData: Line[][] = Array.from({length: rows}, () =>
new Array(columns).fill({
lineNumber: '',
lineLetter: '',
letterColor: '',
backgroundColor: '',
estimatedArrivalTimeInMinutes: '',
}),
);
data.map((item, index) => {
const row = Math.floor(index / columns);
const column = index % columns;
baseTableData[row][column] = item;
});
return (
<View style={tableStyles.table}>
{baseTableData.map((row, rowIndex) => (
<View key={rowIndex} style={tableStyles.row}>
{row.map((cell, cellIndex) => {
if (cell.lineNumber === '') {
return <View style={tableStyles.cell} key={cellIndex} />;
}
const [first, second] = cell.lineDescription.split('-');
return (
<View style={[tableStyles.cell]} key={cellIndex}>
<View style={tableStyles.lineInformationContainer}>
<Text style={tableStyles.lineNumber}>{cell.lineNumber}</Text>
<View
style={[
tableStyles.letterContainer,
{backgroundColor: `#${cell.backgroundColor}` || 'grey'},
]}>
<Text style={tableStyles.lineLetter}>
{cell.lineLetter}
</Text>
</View>
</View>
<View
style={[
tableStyles.timeContainer,
{backgroundColor: `#${cell.backgroundColor}` || 'grey'},
]}>
<Text style={tableStyles.time} numberOfLines={1}>
{first}
</Text>
<Text style={tableStyles.time} numberOfLines={1}>
{second}
</Text>
<Text style={tableStyles.time}>
{cell.estimatedArrivalTimeInMinutes}
</Text>
</View>
</View>
);
})}
</View>
))}
</View>
);
};
const BANNER_TEXT = 'Buses que se detienen en esta parada';
const BusStopInfoScreen = () => {
const {
state: {status, displayedLines, stopName},
} = useDevices();
const [isLoading, setIsLoading] = useState(true);
const image = remoteConfig().getString(RemoteConfigKeys.HEADER_IMAGE_URL);
const {status, displayedLines, stopName} = useDevices().state;
const {status: remoteConfigStatus, getString} = useRemoteConfig();
useEffect(() => {
const init = async () => {
await remoteConfig().setConfigSettings({
minimumFetchIntervalMillis: 3600000,
});
const image = getString(RemoteConfigKeys.HEADER_IMAGE_URL);
const [first, second] = stopName.split('-');
const title = first ? first.trim() : '';
const subTitle = second ? second.trim() : '';
await remoteConfig().setDefaults({
BASE_URL: '',
HEADER_IMAGE_URL: '',
UPDATE_INTERVAL: 0,
USER: '',
PASS: '',
});
const isActivated = await remoteConfig().fetchAndActivate();
if (isActivated) {
setIsLoading(false);
}
};
init();
}, []);
const splitStopName = stopName.split('-');
let title = splitStopName[0] ? `${splitStopName[0].trim()}` : '';
const subTitle = splitStopName[1] ? `${splitStopName[1].trim()}` : '';
if (isLoading) {
if (remoteConfigStatus === Status.LOADING) {
return (
<Container style={styles.container}>
<ActivityIndicator />
@ -141,18 +35,12 @@ const BusStopInfoScreen = () => {
title={title}
image={image}
/>
<Banner
style={styles.bannerContainer}
text="Buses que se detienen en esta parada"
<Banner style={styles.bannerContainer} text={BANNER_TEXT} />
<BusList
buses={displayedLines}
style={styles.bodyContainer}
status={status}
/>
<View style={styles.bodyContainer}>
{status === Status.LOADING ? (
<ActivityIndicator />
) : (
<Table data={displayedLines} />
)}
</View>
<View style={styles.footerContainer}>
{/* {TODO implement footer} */}
</View>
@ -176,67 +64,10 @@ const styles = StyleSheet.create({
flex: 10,
justifyContent: 'center',
},
busContainer: {
backgroundColor: 'brown',
flexDirection: 'column',
},
footerContainer: {
flex: 1,
backgroundColor: 'grey',
},
});
const tableStyles = StyleSheet.create({
table: {
flex: 1,
backgroundColor: 'white',
},
row: {
flex: 1,
flexDirection: 'row',
},
cell: {
flex: 1,
borderWidth: 1,
flexDirection: 'column',
borderColor: 'grey',
},
lineInformationContainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
timeContainer: {
alignItems: 'center',
backgroundColor: 'blue',
},
lineNumber: {
fontSize: 20,
marginRight: 8,
fontWeight: 'bold',
color: 'grey',
},
lineLetter: {
fontSize: 14,
color: 'white',
fontWeight: 'bold',
},
letterContainer: {
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 50,
},
time: {
fontSize: 12,
fontWeight: 'bold',
color: 'white',
},
lineDescription: {
fontSize: 12,
fontWeight: 'bold',
color: 'white',
},
});
export default BusStopInfoScreen;

View File

@ -1,8 +1,10 @@
enum RemoteConfigKeys {
BASE_URL = 'BASE_URL',
HEADER_IMAGE_URL = 'HEADER_IMAGE_URL',
UPDATE_INTERVAL = 'UPDATE_INTERVAL',
CHANGE_PAGE_INTERVAL = 'CHANGE_PAGE_INTERVAL',
UPDATE_BUSES_LIST_INTERVAL = 'UPDATE_BUSES_LIST_INTERVAL',
USER = 'USER',
PASS = 'PASSWORD',
}
export default RemoteConfigKeys;

View File

@ -0,0 +1,7 @@
enum Status {
LOADING,
SUCCESS,
ERROR,
}
export default Status;