Skip to content
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
2 changes: 1 addition & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "tethr",
"slug": "expo-starter",
"scheme": "tethr",
"version": "1.0.3",
"version": "1.0.5",
"orientation": "portrait",
"icon": "./src/assets/splash-icon.png",
"userInterfaceStyle": "dark",
Expand Down
2 changes: 1 addition & 1 deletion src/app/addfriends.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export default function AddFriendsScreen() {
</TouchableOpacity>
</View>

<View className="flex w-full flex-col items-center gap-2">
<View className="mb-4 flex w-full flex-col items-center gap-2">
<Text className="text-center text-2xl font-bold text-white">Add Friends</Text>

<SearchBar placeholder="Search users..." value={query} onSearch={searchUsers} />
Expand Down
21 changes: 17 additions & 4 deletions src/app/auth/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'use client';

import { View, TextInput, Alert, Text, TouchableOpacity } from 'react-native';
import { useState } from 'react';
import { useState, useEffect } from 'react';
import { supabase } from '@/lib/supabase';
import { Redirect } from 'expo-router';
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
import * as SplashScreen from 'expo-splash-screen';

import Tethr from '@/components/tethr';

Expand All @@ -15,8 +16,14 @@ export default function IndexScreen() {
const [otp, setOtp] = useState('');
const [authMode, setAuthMode] = useState<'login' | 'signup'>('signup');
const [currentView, setCurrentView] = useState<'email' | 'verify' | 'authenticated'>('email');
const [loading, setLoading] = useState(false);

useEffect(() => {
SplashScreen.hideAsync();
}, []);

const OTP = async () => {
setLoading(true);
console.log(authMode);
if (authMode === 'signup') {
const { data: existingUsers, error: checkError } = await supabase
Expand Down Expand Up @@ -69,9 +76,11 @@ export default function IndexScreen() {
setCurrentView('verify');
console.log('Success! Check your email');
}
setLoading(false);
};

const verifyOTP = async () => {
setLoading(true);
const { data, error } = await supabase.auth.verifyOtp({
email: email,
token: otp,
Expand Down Expand Up @@ -103,6 +112,7 @@ export default function IndexScreen() {
setCurrentView('authenticated');
console.log('User authenticated:', data);
}
setLoading(true);
};

if (currentView === 'email') {
Expand Down Expand Up @@ -149,8 +159,11 @@ export default function IndexScreen() {
autoCapitalize="none"
/>
)}
<TouchableOpacity onPress={OTP} disabled={email.trim().length === 0}>
<Text className="py-2 text-center font-semibold text-tethr-purple">Continue</Text>
<TouchableOpacity onPress={OTP} disabled={email.trim().length === 0 || loading}>
<Text
className={`py-2 text-center font-semibold ${email.trim().length > 0 ? 'text-tethr-purple' : 'text-gray-500'}`}>
Continue
</Text>
</TouchableOpacity>
</View>

Expand Down Expand Up @@ -198,7 +211,7 @@ export default function IndexScreen() {
keyboardType="number-pad"
returnKeyType="done"
/>
<TouchableOpacity onPress={verifyOTP} disabled={otp.length !== 6}>
<TouchableOpacity onPress={verifyOTP} disabled={otp.length !== 6 || loading}>
<Text
className={`py-2 text-center font-semibold ${otp.length === 6 ? 'text-tethr-purple' : 'text-gray-500'}`}>
Verify Email
Expand Down
5 changes: 4 additions & 1 deletion src/app/main/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,16 @@ export default function RootLayout() {
initializeTaskObservers();

const unsubscribe = friendRequestObserver.subscribe((data) => {
console.log('Layout observer: reduce friends badge', data);
console.log('Layout observer: modify friends badge', data);

if (data.action === 'accept') {
setIncoming((prev) => Math.max(0, prev - 1));
} else if (data.action === 'reject') {
setIncoming((prev) => Math.max(0, prev - 1));
}
if (data.action === 'manualUpdate' && data.count) {
setIncoming(data.count);
}
});

return () => unsubscribe();
Expand Down
6 changes: 3 additions & 3 deletions src/app/main/camera/chooseGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const ChooseGroup = () => {
/>
</TouchableOpacity>
</View>
<View className="w-full items-center gap-2">
<View className="mb-4 w-full items-center gap-2">
<Text className="text-2xl font-bold text-white">Select Group</Text>

<SearchBar placeholder="Search groups..." value={query} onSearch={handleSearch} />
Expand All @@ -79,11 +79,11 @@ const ChooseGroup = () => {
</View>
)}
{!loading && (
<View className="items-center">
<View className="mb-8 flex-1 items-center">
{filtered.length === 0 ? (
<Text className="mt-4 text-center text-white">No matching groups.</Text>
) : (
<ScrollView className="mt-4 w-full" showsVerticalScrollIndicator={false}>
<ScrollView showsHorizontalScrollIndicator={false} className="w-full flex-1">
{filtered.map((group, index) => (
<TouchableOpacity
key={group.group_id}
Expand Down
8 changes: 4 additions & 4 deletions src/app/main/camera/chooseTask.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { View, Text, TouchableOpacity } from 'react-native';
import { View, Text, TouchableOpacity, ScrollView } from 'react-native';
import { router, useLocalSearchParams } from 'expo-router';
import { useState, useEffect } from 'react';
import { taskController } from '@/controllers/tasks';
Expand Down Expand Up @@ -79,7 +79,7 @@ const ChooseTask = () => {
</TouchableOpacity>
</View>

<View className="items-center">
<View className="mb-8 flex-1 items-center">
<View className="flex flex-row gap-2">
<Text className="mb-4 text-2xl font-bold text-white">Select Task for</Text>
<Text className="mb-4 text-2xl font-bold text-tethr-purple">{group_name}</Text>
Expand All @@ -90,7 +90,7 @@ const ChooseTask = () => {
{filteredTasks.length === 0 ? (
<Text className="mt-4 text-center text-white">No matching tasks.</Text>
) : (
<View className="mb-4 w-full items-center">
<ScrollView showsHorizontalScrollIndicator={false} className="w-full flex-1">
{filteredTasks.map((task, idx) => {
const taskCompleted = isCompleted(task.task_name, groupId);

Expand Down Expand Up @@ -118,7 +118,7 @@ const ChooseTask = () => {
</TouchableOpacity>
);
})}
</View>
</ScrollView>
)}
</View>
</View>
Expand Down
29 changes: 28 additions & 1 deletion src/app/main/friends.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ export default function FriendsScreen() {
getFriendsList.getOutgoingFriendRequests(),
]);

console.log(incomingRes.length);
friendRequestObserver.notify({
action: 'manualUpdate',
count: incomingRes.length,
});

const addedFriends = friendsRes ?? [];
const incomingReqs = incomingRes ?? [];
const outgoingReqs = outgoingRes ?? [];
Expand Down Expand Up @@ -140,6 +146,22 @@ export default function FriendsScreen() {
}
};

const handleRejectRequest = async (friendId: string) => {
try {
setIncoming((prev) => prev.filter((f) => f.userId !== friendId));

friendRequestObserver.notify({
action: 'reject',
friendId,
});

await getFriendsList.removeRequest(friendId);
} catch (error) {
console.error(error);
loadFriends();
}
};

const onRefresh = useCallback(async () => {
setRefreshing(true);
await loadFriends();
Expand Down Expand Up @@ -179,7 +201,7 @@ export default function FriendsScreen() {
}

return (
<View className="flex-1 flex-col bg-black pt-8">
<View className="mb-16 flex-1 flex-col bg-black pb-12 pt-8">
<Tethr side="left" />

<View className="flex w-full flex-col items-center gap-2">
Expand All @@ -203,12 +225,14 @@ export default function FriendsScreen() {
<SectionList
sections={sections}
keyExtractor={(item) => item.username}
stickySectionHeadersEnabled={false}
renderItem={({ item, section, index }) => (
<View className="flex flex-col items-center px-4">
<FriendCard
pfpUrl={item.pfpUrl}
username={item.username}
buttonText={item.buttonText}
secondButtonText={section.title === 'Incoming' ? 'close' : undefined}
userId={item.userId}
pressFunction={() => {
if (section.title === 'Friends') {
Expand All @@ -219,6 +243,9 @@ export default function FriendsScreen() {
handleRemoveRequest(item.userId);
}
}}
secondPressFunction={
section.title === 'Incoming' ? () => handleRejectRequest(item.userId) : undefined
}
cardType={getCardType(index, section.data.length)}
/>
</View>
Expand Down
13 changes: 12 additions & 1 deletion src/app/main/groups/[groupId]/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { View, Text, TouchableOpacity, ActivityIndicator, Pressable, FlatList } from 'react-native';
import { useEffect, useState } from 'react';
import { useEffect, useState, useRef } from 'react';
import { useLocalSearchParams, router } from 'expo-router';
import { FontAwesome6 } from '@expo/vector-icons';
import { taskController } from '@/controllers/tasks';
Expand Down Expand Up @@ -47,6 +47,7 @@ const GroupPage = () => {
const [myUsername, setMyUsername] = useState('');
const [photos, setPhotos] = useState<Photo[]>([]);
const [completedTasks, setCompletedTasks] = useState<string[]>([]);
const flatListRef = useRef<FlatList>(null);

useEffect(() => {
if (groupId) {
Expand Down Expand Up @@ -130,6 +131,10 @@ const GroupPage = () => {
return completedTasks.includes(taskKey);
};

const scrollToTop = () => {
flatListRef.current?.scrollToOffset({ offset: 0, animated: true });
};

if (loading) {
return (
<View className="flex-1 items-center justify-center bg-black">
Expand Down Expand Up @@ -171,6 +176,7 @@ const GroupPage = () => {
</View>
<FlatList
data={photos}
ref={flatListRef}
ListHeaderComponent={
<View className="mx-auto w-[90vw] pb-8">
<Text className="my-6 text-xl font-bold text-white">Leaderboard</Text>
Expand Down Expand Up @@ -267,6 +273,11 @@ const GroupPage = () => {
<Text className="px-4 text-center text-white">No photos in this group yet.</Text>
}
/>
<TouchableOpacity
onPress={scrollToTop}
className="absolute bottom-12 right-6 mb-4 h-10 w-14 items-center justify-center rounded-full bg-tethr-purple">
<Entypo name="chevron-up" size={24} color="white" />
</TouchableOpacity>
</View>
</View>
);
Expand Down
2 changes: 1 addition & 1 deletion src/app/main/groups/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const Index = () => {
}, [parsedObject, searchQuery]);

return (
<View className="flex-1 bg-black pt-8">
<View className="flex-1 bg-black py-8">
<View className="relative h-[10vh] w-full items-center">
<View className="absolute left-0 right-0 top-0 items-center">
<Tethr side="center" />
Expand Down
10 changes: 9 additions & 1 deletion src/app/main/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Tethr from '@/components/tethr';
import { ProfileProps, userController } from '@/controllers/userInfo';
import { useState, useCallback, useEffect } from 'react';
import { useRouter } from 'expo-router';
import { scoreUpdateObserver } from '@/controllers/observers/scoreUpdateObserver';

export default function ProfileScreen() {
const [loading, setLoading] = useState(true);
Expand All @@ -27,7 +28,14 @@ export default function ProfileScreen() {
}, []);
useEffect(() => {
loadProfile();
}, [loadProfile]);

const unsubscribe = scoreUpdateObserver.subscribe(() => {
loadProfile();
});

return () => unsubscribe();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const handleLogout = async () => {
const success = await userController.logout();
Expand Down
2 changes: 1 addition & 1 deletion src/app/main/tasks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const Index = () => {
};

return (
<View className="flex-1 bg-black pt-8">
<View className="flex-1 bg-black py-8">
<View className="relative h-[10vh] w-full items-center">
<View className="absolute left-0 right-0 top-0 items-center">
<Tethr side="center" />
Expand Down
5 changes: 0 additions & 5 deletions src/components/camera/photopreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,10 @@ const PhotoPreview = ({

if (exifOrientation === 1) {
rotation = 90;
console.log('Applying 90 rotation for landscape');
} else if (exifOrientation === 3) {
rotation = 270;
console.log('Applying 270 rotation for landscape');
} else if (exifOrientation === 8) {
rotation = 180;
console.log('Applying 180° rotation for upsidedown');
} else {
console.log('No rotation needed for portrait');
}

if (rotation !== 0) {
Expand Down
Loading