Skip to content

Commit

Permalink
Add mobile app connection to local database and remove PointsContext …
Browse files Browse the repository at this point in the history
…from mobile (Szops#54)
  • Loading branch information
michalprzytarski authored Apr 4, 2022
1 parent 1b6732a commit 4a375b1
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 82 deletions.
5 changes: 1 addition & 4 deletions mobile/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import React from 'react';
import {SafeAreaView, StatusBar} from 'react-native';
import MainTabNavigator from './src/navigation/MainTabNavigator';
import {tintColor, navDarkColor} from './src/constants/colors';
import PointsContextProvider from './src/context/PointsContextProvider';
import LanguageContextProvider from './src/context/LanguageContextProvider';
import {useEffect} from 'react';
import {PermissionsAndroid, Alert} from 'react-native';
Expand Down Expand Up @@ -45,9 +44,7 @@ export default function App() {
backgroundColor={tintColor}
/>
<LanguageContextProvider>
<PointsContextProvider>
<MainTabNavigator />
</PointsContextProvider>
<MainTabNavigator />
</LanguageContextProvider>
</SafeAreaView>
);
Expand Down
6 changes: 3 additions & 3 deletions mobile/src/api/szopPoints.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {Alert} from 'react-native';

const host = `https://szop.herokuapp.com/api`;
const host = `https://szop.herokuapp.com/api/`;

export const getVersion = async () => {
return await fetch(`${host}/version`)
return await fetch(`${host}version`)
.then(res => {
if (!res.ok) throw Error(`Couldn't fetch data from that source!`);
return res.json();
Expand All @@ -15,7 +15,7 @@ export const getVersion = async () => {
};

export const getPoints = async () => {
return await fetch(`${host}/all-point`)
return await fetch(`${host}all-point`)
.then(res => {
if (!res.ok) throw Error(`Couldn't fetch data from that source!`);
return res.json();
Expand Down
13 changes: 8 additions & 5 deletions mobile/src/components/PointListItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import {CardWrapper} from './Wrapper';
import React, {useState} from 'react';
import {tintColor, switchFalse, thumbColor} from '../constants/colors';

export default function PointListItem({address, description, dates, item}) {
const [isEnabled, setIsEnabled] = useState(false);
const toggleSwitch = () => setIsEnabled(previousState => !previousState);
export default function PointListItem({point}) {
const toggleSwitch = async () => {
return point.isNotificationsEnabled
? await point.turnOffNotifications()
: await point.turnOnNotifications();
};
return (
<CardWrapper>
<HugeText>{address}</HugeText>
<HugeText>{point.street}</HugeText>
<Switch
trackColor={{false: switchFalse, true: tintColor}}
thumbColor={thumbColor}
onValueChange={toggleSwitch}
value={isEnabled}
value={point.isNotificationsEnabled}
/>
</CardWrapper>
);
Expand Down
2 changes: 1 addition & 1 deletion mobile/src/components/PointsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import PointListItem from './PointListItem';

export default function PointsList({points, searchPhrase}) {
const renderItem = item => <PointListItem address={item.street} />;
const renderItem = item => <PointListItem point={item} />;
return (
<FlatList
data={points.filter(p =>
Expand Down
23 changes: 21 additions & 2 deletions mobile/src/components/SzopMarker.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';
import {Marker} from 'react-native-maps';
import {tintColor} from '../constants/colors';
import Icon from 'react-native-vector-icons/MaterialIcons';
import {View} from 'react-native';

const SzopMarker = ({point}) => {
return (
Expand All @@ -11,8 +13,25 @@ const SzopMarker = ({point}) => {
latitude: point.latitude,
longitude: point.longitude,
}}
pinColor={tintColor}
/>
pinColor={point.isNotificationsEnabled ? 'green' : tintColor}>
{/* Marker jest testowy, jak tylko zrobimy sensowne grafiki,to je podmienimy i zrobimy z tego ładny komponent */}
<View style={{position: 'relative'}}>
<Icon
name="pets"
// kolor będzie zależny od tego, czy w najbliższy, czasie będzie tu szop, ale tego jeszcze nie mamy, więc jest testowo po powiadomieniach
color={point.isNotificationsEnabled ? tintColor : 'black'}
size={26}
/>
{point.isNotificationsEnabled && (
<Icon
style={{position: 'absolute', right: 0, bottom: 0}}
name="notifications"
color={'gold'}
size={12}
/>
)}
</View>
</Marker>
);
};

Expand Down
24 changes: 0 additions & 24 deletions mobile/src/context/PointsContextProvider.js

This file was deleted.

15 changes: 8 additions & 7 deletions mobile/src/database/PointsDAO.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ const openingDates = database.collections.get('opening_dates');
const listNames = {SZOP: 'szop', PSZOK: 'pszok'};

export default {
observePointsLists: () => pointsLists.query().observe(),
getPointsLists: () => pointsLists.query(),
getPoints: () => points.query(),

createSzopPointsList: async ({version, list}) => {
await database.write(async () => {
Expand All @@ -18,12 +19,12 @@ export default {
return pointsList;
})
.then(pointsList => {
if (list !== undefined)
Promise.all(
list.map(async point => {
await pointsList.callWriter(() => pointsList.addPoint(point));
}),
);
// if (list !== undefined)
Promise.all(
list.map(async point => {
await pointsList.callWriter(() => pointsList.addPoint(point));
}),
);
});
});
},
Expand Down
5 changes: 2 additions & 3 deletions mobile/src/database/model/Point.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,18 @@ export default class Point extends Model {
@children('opening_dates') openingDates;

@writer async turnOnNotifications() {
await this.update(point => {
return await this.update(point => {
point.isNotificationsEnabled = true;
});
}
@writer async turnOffNotifications() {
await this.update(point => {
return await this.update(point => {
point.isNotificationsEnabled = false;
});
}
@writer async addOpeningDate(date) {
return this.collections.get('opening_dates').create(openingDate => {
openingDate.point.set(this);
//openingDate.point = 2.0; //.set(this);
openingDate.date = date;
});
}
Expand Down
42 changes: 19 additions & 23 deletions mobile/src/database/model/PointsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,24 @@ export default class PointsList extends Model {
);

@writer async addPoint(pointData) {
return await this.collections
.get('points')
.create(point => {
point.pointsList.set(this);
point.pointId = pointData.pointId;
point.street = pointData.street;
point.sector = pointData.sector;
point.estate = pointData.estate;
point.latitude = pointData.latitude;
point.longitude = pointData.longitude;
point.description = pointData.description;
point.isNotificationsEnabled = false;
return point;
})
.then(point => {
Promise.all(
pointData.openingDateTimes.map(async date => {
let b = date.split(/\D+/);
--b[1]; // month {0, ... , 11}, not {1, ... , 12}
await this.callWriter(() => point.addOpeningDate(Date.UTC(...b)));
}),
);
});
return await this.collections.get('points').create(point => {
point.pointsList.set(this);
point.pointId = pointData.pointId;
point.street = pointData.street;
point.sector = pointData.sector;
point.estate = pointData.estate;
point.latitude = pointData.latitude;
point.longitude = pointData.longitude;
point.description = pointData.description;
point.isNotificationsEnabled = false;

Promise.all(
pointData.openingDateTimes.map(async date => {
let b = date.split(/\D+/);
--b[1]; // month {0, ... , 11}, not {1, ... , 12}
await this.callWriter(() => point.addOpeningDate(Date.UTC(...b)));
}),
);
});
}
}
23 changes: 21 additions & 2 deletions mobile/src/screens/HelloSzopScreen.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
import styled from 'styled-components';
import React, {useContext} from 'react';
import {Button} from 'react-native';
import {LanguageContext} from '../context/LanguageContextProvider';
import {ScreenWrapper} from '../components/Wrapper';
import {HomeCard} from '../components/HomeCard';
import {HomeBanner} from '../components/HomeBanner';
import {TextInput, Button, Alert} from 'react-native';
import PushNotification from 'react-native-push-notification';
import {getPoints} from '../api/szopPoints';
import PointsDAO from '../database/PointsDAO';
export const helloSzopScreenName = 'HelloSzopScreen';

const StyledScrollView = styled.ScrollView`
width: 90%;
`;

export default function HelloSzopScreen() {
const [input, setInput] = React.useState();
const [input2, setInput2] = React.useState();

const {text, selectedLanguage, setSelectedLanguage} =
useContext(LanguageContext);

const [input, setInput] = React.useState();
const [input2, setInput2] = React.useState();
const deleteDataabse = async () => await PointsDAO.deleteAllLists();

const updateDataabse = async () => {
await PointsDAO.deleteAllLists();
await getPoints()
.then(points =>
PointsDAO.createSzopPointsList({version: 'unknown', list: points}),
)
.catch(error => alert(error.message));
};


return (
<ScreenWrapper home>
Expand All @@ -31,6 +46,10 @@ export default function HelloSzopScreen() {
<HomeCard />
<HomeCard last />

{/* Przyciski tylko do demo, później zrobimy automatyczne pobieranie w useEffect */}
<Button title="Pobierz bazę danych" onPress={updateDataabse} />
<Button title="Usuń bazę danych" onPress={deleteDataabse} />

{/* Tylko do demo */}
<TextInput
placeholder="Godzina"
Expand Down
12 changes: 8 additions & 4 deletions mobile/src/screens/MapScreen.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import {Button} from 'react-native';
import React, {useContext, useState} from 'react';
import {LanguageContext} from '../context/LanguageContextProvider';
import {PointsContext} from '../context/PointsContextProvider';
import Map from '../components/Map';
import {ScreenWrapper} from '../components/Wrapper';
import withObservables from '@nozbe/with-observables';
import PointsDAO from '../database/PointsDAO';

export const mapScreenName = 'MapScreen';

const MapScreen = () => {
const MapScreen = ({points}) => {
const [shouldLoadMap, setShouldLoadMap] = useState(false);

const {text} = useContext(LanguageContext);
const {points} = useContext(PointsContext);

const initialRegion = {
latitude: 51.11108,
Expand All @@ -36,4 +36,8 @@ const MapScreen = () => {
);
};

export default MapScreen;
export default withObservables(['points'], ({points}) => ({
points: PointsDAO.getPoints().observeWithColumns([
'is_notifications_enabled',
]),
}))(MapScreen);
14 changes: 10 additions & 4 deletions mobile/src/screens/PointsListScreen.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import styled from 'styled-components';
import React, {useContext, useState} from 'react';
import React, {useState} from 'react';
import PointsList from '../components/PointsList';
import image from '../images/listImage.jpg';
import {PointsContext} from '../context/PointsContextProvider';
import LoadingScreen from './LoadingScreen';
import {ScreenWrapper} from '../components/Wrapper';
import {ListHeader} from '../components/ListHeader';
import PointsDAO from '../database/PointsDAO';
import withObservables from '@nozbe/with-observables';

export const PointsListScreenName = 'PointsListScreen';

Expand All @@ -20,9 +21,8 @@ const ListImageWrapper = styled.View`
width: 100%;
`;

export default function PointsListScreen() {
function PointsListScreen({points}) {
const [searchPhrase, setSearchPhrase] = useState('');
const {points} = useContext(PointsContext);

return points === null ? (
<LoadingScreen />
Expand All @@ -41,3 +41,9 @@ export default function PointsListScreen() {
</ScreenWrapper>
);
}

export default withObservables(['points'], ({points}) => ({
points: PointsDAO.getPoints().observeWithColumns([
'is_notifications_enabled',
]),
}))(PointsListScreen);

0 comments on commit 4a375b1

Please sign in to comment.