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

Notice Board and QR codes #86

Merged
merged 15 commits into from
Dec 17, 2023
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: 6 additions & 0 deletions ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,10 @@ type WeekTexts = {

type MealPlan = {
[key: string]: WeekTexts;
}

type User = {
fullName: string,
phoneNumber: string,
email: string
}
3 changes: 1 addition & 2 deletions app/(login)/(groupScreen)/group.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Redirect } from 'expo-router';
import { ImageBackground, Pressable, View, Text, TextInput } from 'react-native';
import styles from '../styles';
import { useState, useRef } from 'react';
Expand Down Expand Up @@ -65,7 +64,7 @@ export default function GroupScreen() {
function getNonMainScreenTextComponent() {
return (
<View style={{alignItems: "center"}}>
<Pressable onPress={() => setCurrentState(State.buttons)}><Text style={styles.descriptiveText}>Go back</Text></Pressable>
<Pressable onPress={() => setCurrentState(State.buttons)}><Text style={[styles.descriptiveText, {marginBottom: 6}]}>Go back</Text></Pressable>
<Pressable onPress={() => logout()}><Text style={styles.descriptiveText}>Log out</Text></Pressable>
</View>
)
Expand Down
52 changes: 47 additions & 5 deletions app/(login)/(groupScreen)/joinGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
import { useState, useRef } from "react"
import { useState, useRef, useEffect } from "react"
import { View, Text, Pressable, TextInput } from "react-native"
import styles from "../styles"
import { groupHandle } from '../../../handlers/group';
import { router } from "expo-router";
import Modal from "react-native-modal";
import { BarCodeScanner } from 'expo-barcode-scanner';
import { AntDesign } from "@expo/vector-icons";

export default function getCreateComponent(){
const group = useRef(groupHandle(gun));
const [uuid, setUuid] = useState("");
const [processing, setProcessing] = useState(false)
const [error, setError] = useState(false)

function joinGroup(groupName : string){
group.current.join(groupName, (ack: Boolean) => {
const [hasPermission, setHasPermission] = useState<boolean | null>(null);
const [isModalVisible, setIsModalVisible] = useState(false);

useEffect(() => {
const getBarCodeScannerPermissions = async () => {
const { granted } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(granted);
};

getBarCodeScannerPermissions();
}, []);

const handleBarCodeScanned = ({ type, data }: { type: string, data: string }): void => {
setUuid(data)
setIsModalVisible(false)
};

function joinGroup(groupId : string){
group.current.join(groupId, (ack: Boolean) => {
if (ack){
router.replace('/shoppingList')
} else{
Expand All @@ -26,7 +46,17 @@ export default function getCreateComponent(){
<View style={{alignItems:"center"}}><Text style={styles.explainerText}> Join a group by typing its unique id </Text></View>
<Text style={styles.descriptiveText}>Group id</Text>
<View style={styles.inputBox}>
<TextInput style={styles.inputField} autoCapitalize='none' value={uuid} onChangeText={(uuid) =>{setUuid(uuid)}}/>
<TextInput style={styles.inputField} autoCapitalize='none' value={uuid} onChangeText={(uuid) =>{setUuid(uuid)}}/>
{hasPermission && <Pressable
style={styles.qrCodeIcon}
onPress={()=>{
setIsModalVisible(true)
}}>
<AntDesign
name="qrcode"
size={26}
color={'gray'}/>
</Pressable>}
</View>
<Pressable style={styles.button} onPress={() => {
if (!processing){
Expand All @@ -36,7 +66,19 @@ export default function getCreateComponent(){
}}>
<Text style={styles.descriptiveText}>Join group</Text></Pressable>
{error && <Text style={styles.error}>Wrong id</Text>}
<View style={{height:10}}/>

<Modal
animationIn='zoomIn'
animationOut='zoomOut'
isVisible={isModalVisible}
onBackdropPress={() => setIsModalVisible(false)}>
<View style={styles.modalContainer}>
<BarCodeScanner
barCodeTypes={[BarCodeScanner.Constants.BarCodeType.qr]}
onBarCodeScanned={handleBarCodeScanned}
style={{flex:1}}/>
</View>
</Modal>
</>
)
}
9 changes: 9 additions & 0 deletions app/(login)/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ const styles = StyleSheet.create({
paddingBottom: 10,
backgroundColor: 'transparent',
},
qrCodeIcon: {
width: 32,
},
modalContainer: {
justifyContent: 'center',
borderRadius: 10,
padding: 20,
height: 400
},
});

export default styles
21 changes: 9 additions & 12 deletions app/(tabs)/expenses/balance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ function expenseListCmp(cmp1 : Expense[], cmp2 : Expense[]){
return true
}


export default function BalanceScreen() {
const expenses = useRef(expensesHandle(gun));
const colorScheme = useColorScheme() ?? 'light';
Expand All @@ -33,20 +32,18 @@ export default function BalanceScreen() {
}
}

function getGroupMembers(_members: string[]): void{
if (_members != members){
setMembers(_members);
}
function getGroupMembers(member: string): void{
setMembers(prev => {
if(!prev.includes(member)){
return [...prev, member]
}
return prev
})
}

let userGroup = '';
gun.user(userPub).get('group').get('groupId').once((id: string) => {
userGroup = id;
});

useEffect(() => {
expenses.current.getExpenses(userGroup, getExpenses);
expenses.current.getGroupMembers(userGroup, getGroupMembers);
expenses.current.getExpenses(getExpenses);
expenses.current.getGroupMembers(getGroupMembers);
}, [])

let previousBalance: { user: string, amount: number }[] = [];
Expand Down
29 changes: 10 additions & 19 deletions app/(tabs)/expenses/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ function expenseListCmp(cmp1 : Expense[], cmp2 : Expense[]){
return true
};



export default function SettleScreen() {
const expenses = useRef(expensesHandle(gun));
const colorScheme = useColorScheme() ?? 'light';
Expand All @@ -51,25 +49,18 @@ export default function SettleScreen() {
}
}

function getGroupMembers(_members: string[]): void{
if (_members != members){
setMembers(_members);
}
function getGroupMembers(member: string): void{
setMembers(prev => {
if(!prev.includes(member)){
return [...prev, member]
}
return prev
})
}

let userGroup = '';
gun.user(userPub).get('group').get('groupId').once((id: string) => {
userGroup = id;
});

let username = '';
gun.user(userPub).get('fullName').once((name: string) => {
username = name;
});

useEffect(() => {
expenses.current.getExpenses(userGroup, getExpenses);
expenses.current.getGroupMembers(userGroup, getGroupMembers);
expenses.current.getExpenses(getExpenses);
expenses.current.getGroupMembers(getGroupMembers);
}, [])

let previousBalance: { user: string, amount: number }[] = [];
Expand Down Expand Up @@ -123,7 +114,7 @@ export default function SettleScreen() {
}}
onYes={() =>{
if(selectedItem != null){
expenses.current.settleExpenses(userGroup, selectedItem);
expenses.current.settleExpenses(selectedItem);
}
closeModal()
}}
Expand Down
83 changes: 70 additions & 13 deletions app/(tabs)/notice.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,95 @@
import React, { useEffect, useRef, useState } from 'react';
import { StyleSheet, TextInput, useColorScheme, SafeAreaView, ScrollView } from 'react-native';
import { StyleSheet, TextInput, useColorScheme, SafeAreaView, ScrollView, Pressable } from 'react-native';
import { Text, View } from '../../components/Themed';
import Colors from '../../constants/Colors';
import { groupHandle } from '../../handlers/group';
import { noticeHandle } from '../../handlers/notice';
import { AntDesign } from '@expo/vector-icons';
import Modal from "react-native-modal";
import { QrCodeSvg } from 'react-native-qr-svg';

export default function NoticeScreen() {
const colorScheme = useColorScheme() ?? 'light';
const group = useRef(groupHandle(gun)).current;
const group = useRef(groupHandle(gun));
const notice = useRef(noticeHandle(gun));
const [isModalVisible, setIsModalVisible] = useState(false);
const [houseRules, setHouseRules] = useState('');
const [groupId, setGroupId] = useState('')
const [groupName, setGroupName] = useState('')
const users = [
{ name: 'Test Bruger', phone: '12 34 56 78', email: '[email protected]' },
{ name: 'Andreas Alstrup', phone: '87 65 43 21', email: '[email protected]' },
];
const [users, setUsers] = useState<User[]>([])

useEffect(() => {
group.getUUID(setGroupId)
group.getGName(setGroupName)
group.current.getUUID((id) => setGroupId(id))
group.current.getGName((name) => setGroupName(name))
notice.current.onUsersUpdate((data: User) => {
setUsers(prev => {
if(!prev.includes(data)){
return [...prev, data]
}
return prev
})
})
notice.current.onHouseRulesUpdate((rules) => setHouseRules(rules))
}, [])

return (
<SafeAreaView style={[styles.container, {backgroundColor: Colors[colorScheme].background}]}>
<ScrollView>
<View>
<Text style={styles.title}>Household Rules</Text>
{groupName != '' && <Text>Group name: {groupName}</Text>}
{groupId != '' && <Text selectable={true}>Group ID: {groupId}</Text>}
<View style={styles.groupInfo}>
<View>
<Text>Group name: {groupName}</Text>
<Text selectable={true}>ID: {groupId}</Text>
</View>
<View style={{flex: 1}}>
<Pressable
style={styles.qrCodeIcon}
onPress={()=>{
setIsModalVisible(true)
}}>
<AntDesign
name="qrcode"
size={30}
color={'gray'}/>
</Pressable>
</View>
</View>
<TextInput
style={[styles.input, {color: Colors[colorScheme].text}]}
placeholder="Click to make rules"
placeholderTextColor={'gray'}
value={houseRules}
onChangeText={(text) => setHouseRules(text)}
onChangeText={(text) => {
notice.current.updateHouseRules(text)
setHouseRules(text)
}}
editable
multiline
/>
<Text style={styles.title}>Contact Information</Text>
{users.map((user, index) => (
<View key={index} style={styles.userCard}>
<Text style={styles.userName}>{user.name}</Text>
<Text>Phone: {user.phone}</Text>
<Text style={styles.userName}>{user.fullName}</Text>
<Text>Phone: {user.phoneNumber}</Text>
<Text>Email: {user.email}</Text>
</View>
))}
</View>
</ScrollView>
<Modal
style={styles.modalContainer}
animationIn='zoomIn'
animationOut='zoomOut'
isVisible={isModalVisible}
onBackdropPress={() => setIsModalVisible(false)}>
<QrCodeSvg
style={styles.modalContainer}
value={groupId}
frameSize={200}
dotColor={Colors[colorScheme].text}
backgroundColor={Colors[colorScheme].background}/>
</Modal>
</SafeAreaView>
);
}
Expand Down Expand Up @@ -81,4 +126,16 @@ const styles = StyleSheet.create({
fontSize: 16,
fontWeight: 'bold',
},
groupInfo: {
flexDirection: 'row'
},
qrCodeIcon: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
modalContainer: {
justifyContent: 'center',
alignItems: 'center',
},
});
18 changes: 11 additions & 7 deletions app/(tabs)/shoppingList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export default function ToBeBoughtScreen() {
const toggleCheckbox = () => setAlreadyBought(() => !alreadyBought);

let username = '';
gun.user(userPub).get('fullName').open((data: any) => {
gun.user(userPub).get('fullName').on((data: string) => {
username = data;
});

Expand All @@ -81,12 +81,16 @@ export default function ToBeBoughtScreen() {
)

shoppingListDB.current.onUsersUpdate(
(data : string[]) => {
setMembers(data)
if(members.length == 0)
{
setSelectedUsers(data)
}
(data : string) => {
setMembers(prev => {
if(!prev.includes(data)){
setSelectedUsers(prevSel => {
return [...prevSel, data]
})
return [...prev, data]
}
return prev
})
}
)
}, [])
Expand Down
Loading