diff --git a/app.config.ts b/app.config.ts
index cb6a15f..2eb2b35 100644
--- a/app.config.ts
+++ b/app.config.ts
@@ -39,8 +39,9 @@ export default ({config}: ConfigContext): ExpoConfig => ({
[
'expo-build-properties',
{
- ios: {newArchEnabled: true},
- android: {newArchEnabled: true},
+ // https://github.com/software-mansion/react-native-screens/issues/2219
+ // ios: {newArchEnabled: true},
+ // android: {newArchEnabled: true},
},
],
// @ts-ignore
@@ -59,6 +60,14 @@ export default ({config}: ConfigContext): ExpoConfig => ({
],
},
],
+ [
+ 'expo-notifications',
+ {
+ icon: './assets/notification-icon.png',
+ color: '#ffffff',
+ defaultChannel: 'default',
+ },
+ ],
],
experiments: {
typedRoutes: true,
@@ -94,6 +103,7 @@ export default ({config}: ConfigContext): ExpoConfig => ({
entitlements: {
'com.apple.developer.applesignin': ['Default'],
},
+ googleServicesFile: process.env.GOOGLE_SERVICES_IOS,
infoPlist: {
LSApplicationQueriesSchemes: ['mailto'],
CFBundleAllowMixedLocalizations: true,
@@ -107,7 +117,7 @@ export default ({config}: ConfigContext): ExpoConfig => ({
},
},
android: {
- googleServicesFile: process.env.GOOGLE_SERVICES_JSON,
+ googleServicesFile: process.env.GOOGLE_SERVICES_ANDROID,
userInterfaceStyle: 'automatic',
permissions: [
'RECEIVE_BOOT_COMPLETED',
@@ -117,6 +127,7 @@ export default ({config}: ConfigContext): ExpoConfig => ({
'WRITE_EXTERNAL_STORAGE',
'NOTIFICATIONS',
'USER_FACING_NOTIFICATIONS',
+ 'SCHEDULE_EXACT_ALARM',
],
adaptiveIcon: {
foregroundImage: './assets/adaptive_icon.png',
diff --git a/app/(app)/(tabs)/_layout.tsx b/app/(app)/(tabs)/_layout.tsx
index 2f92323..de5e173 100644
--- a/app/(app)/(tabs)/_layout.tsx
+++ b/app/(app)/(tabs)/_layout.tsx
@@ -1,10 +1,12 @@
import {Pressable, View} from 'react-native';
import {Icon, useDooboo} from 'dooboo-ui';
import {Link, Redirect, Tabs, useRouter} from 'expo-router';
-import {useRecoilValue} from 'recoil';
+import {useRecoilState} from 'recoil';
import {authRecoilState} from '../../../src/recoil/atoms';
import {t} from '../../../src/STRINGS';
+import {useEffect, useRef} from 'react';
+import * as Notifications from 'expo-notifications';
function SettingsMenu(): JSX.Element {
const {theme} = useDooboo();
@@ -12,7 +14,7 @@ function SettingsMenu(): JSX.Element {
return (
- push('settings')}>
+ push('/settings')}>
{({pressed}) => (
();
+
+ useEffect(() => {
+ if (!authId) return;
+ notificationResponseListener.current =
+ Notifications.addNotificationResponseReceivedListener((response) => {
+ console.log(JSON.stringify(response.notification.request));
+ });
+
+ return () => {
+ notificationResponseListener.current &&
+ Notifications.removeNotificationSubscription(
+ notificationResponseListener.current,
+ );
+ };
+ }, [authId, setAuth]);
if (!authId) {
return ;
diff --git a/app/(app)/(tabs)/profile.tsx b/app/(app)/(tabs)/profile.tsx
index be25a61..ffedf42 100644
--- a/app/(app)/(tabs)/profile.tsx
+++ b/app/(app)/(tabs)/profile.tsx
@@ -1,6 +1,6 @@
import styled from '@emotion/native';
import {Stack} from 'expo-router';
-import {Icon, Typography} from 'dooboo-ui';
+import {Icon, Typography, useDooboo} from 'dooboo-ui';
import {t} from '../../../src/STRINGS';
import {useRecoilValue} from 'recoil';
import {authRecoilState} from '../../../src/recoil/atoms';
@@ -81,7 +81,7 @@ const TagContainer = styled.View`
`;
const Tag = styled.View`
- background-color: ${({theme}) => theme.role.accent};
+ background-color: ${({theme}) => theme.role.link};
border-radius: 20px;
padding: 6px 12px;
margin-right: 8px;
@@ -89,12 +89,13 @@ const Tag = styled.View`
`;
const TagText = styled.Text`
- color: ${({theme}) => theme.text.basic};
+ color: ${({theme}) => theme.text.contrast};
font-size: 14px;
`;
export default function Profile(): JSX.Element {
const {user, tags} = useRecoilValue(authRecoilState);
+ const {theme} = useDooboo();
return (
@@ -109,7 +110,7 @@ export default function Profile(): JSX.Element {
source={user?.avatar_url ? {uri: user?.avatar_url} : IC_ICON}
/>
{user?.display_name || ''}
- {user?.introduction || ''}
+ {user?.introduction ? {user?.introduction} : null}
@@ -122,7 +123,7 @@ export default function Profile(): JSX.Element {
gap: 4px;
`}
>
-
+
{user?.github_id || ''}
@@ -131,26 +132,36 @@ export default function Profile(): JSX.Element {
{user?.affiliation || ''}
-
-
- {t('onboarding.desiredConnection')}
- {user?.desired_connection || ''}
-
-
- {t('onboarding.futureExpectations')}
- {user?.future_expectations || ''}
-
-
-
- {t('onboarding.userTags')}:
-
- {tags?.map((tag, index) => (
-
- {tag}
-
- ))}
-
-
+
+ {user?.desired_connection || user?.future_expectations ? (
+
+ {user?.desired_connection ? (
+
+ {t('onboarding.desiredConnection')}
+ {user?.desired_connection || ''}
+
+ ) : null}
+ {user?.future_expectations ? (
+
+ {t('onboarding.futureExpectations')}
+ {user?.future_expectations || ''}
+
+ ) : null}
+
+ ) : null}
+
+ {tags?.length ? (
+
+ {t('onboarding.userTags')}
+
+ {tags.map((tag, index) => (
+
+ {tag}
+
+ ))}
+
+
+ ) : null}
diff --git a/app/(app)/onboarding.tsx b/app/(app)/onboarding.tsx
index 0193a30..63a0bcc 100644
--- a/app/(app)/onboarding.tsx
+++ b/app/(app)/onboarding.tsx
@@ -6,7 +6,6 @@ import * as yup from 'yup';
import {Controller, SubmitHandler, useForm} from 'react-hook-form';
import {
ActivityIndicator,
- Alert,
KeyboardAvoidingView,
Platform,
Pressable,
@@ -30,6 +29,7 @@ import {useRecoilState} from 'recoil';
import {authRecoilState} from '../../src/recoil/atoms';
import {ImageInsertArgs} from '../../src/types';
import FallbackComponent from '../../src/components/uis/FallbackComponent';
+import {showAlert} from '../../src/utils/alert';
const Container = styled.SafeAreaView`
flex: 1;
@@ -55,11 +55,11 @@ const Content = styled.View`
`;
const schema = yup.object().shape({
- display_name: yup.string().required(t('common.requiredField')),
+ display_name: yup.string().required(t('common.requiredField')).min(2).max(20),
+ github_id: yup.string().required(t('common.requiredField')),
+ affiliation: yup.string().required(t('common.requiredField')),
avatar_url: yup.string(),
meetup_id: yup.string(),
- affiliation: yup.string(),
- github_id: yup.string(),
other_sns_urls: yup.array().of(yup.string()),
tags: yup.array().of(yup.string()),
desired_connection: yup.string(),
@@ -115,7 +115,7 @@ export default function Onboarding(): JSX.Element {
let image: ImageInsertArgs | undefined = {};
- if (profileImg) {
+ if (profileImg && !profileImg.startsWith('http')) {
const destPath = `users/${authId}`;
image = await uploadFileToSupabase({
@@ -148,7 +148,7 @@ export default function Onboarding(): JSX.Element {
return;
}
- Alert.alert((error as Error)?.message || '');
+ showAlert((error as Error)?.message || '');
}
};
@@ -295,7 +295,7 @@ export default function Onboarding(): JSX.Element {
displayNameError
? displayNameError
: errors.display_name
- ? errors.display_name.message
+ ? t('error.displayNameInvalid')
: ''
}
/>
@@ -304,9 +304,10 @@ export default function Onboarding(): JSX.Element {
/>
(
)}
rules={{validate: (value) => !!value}}
/>
(
)}
rules={{validate: (value) => !!value}}
/>
(
)}
rules={{validate: (value) => !!value}}
diff --git a/app/(app)/picture.tsx b/app/(app)/picture.tsx
index 38d344a..5f34f11 100644
--- a/app/(app)/picture.tsx
+++ b/app/(app)/picture.tsx
@@ -17,7 +17,14 @@ export default function Picture(): JSX.Element {
const [loading, setLoading] = useState(true);
if (!imageUrl || typeof imageUrl !== 'string') {
- return ;
+ return (
+ <>
+
+
+ >
+ );
}
return (
diff --git a/app/(app)/post/[id]/update.tsx b/app/(app)/post/[id]/update.tsx
index 8edb120..30bf4cc 100644
--- a/app/(app)/post/[id]/update.tsx
+++ b/app/(app)/post/[id]/update.tsx
@@ -9,6 +9,7 @@ import {
KeyboardAvoidingView,
Platform,
Pressable,
+ View,
} from 'react-native';
import ErrorFallback from '../../../../src/components/uis/FallbackComponent';
import {useRecoilValue} from 'recoil';
@@ -156,7 +157,7 @@ export default function PostUpdate(): JSX.Element {
return (
+
diff --git a/app/(app)/post/write.tsx b/app/(app)/post/write.tsx
index 76883ea..fdcc273 100644
--- a/app/(app)/post/write.tsx
+++ b/app/(app)/post/write.tsx
@@ -10,6 +10,7 @@ import {
KeyboardAvoidingView,
Platform,
Pressable,
+ View,
} from 'react-native';
import {useRecoilValue} from 'recoil';
import {authRecoilState} from '../../../src/recoil/atoms';
@@ -131,7 +132,7 @@ export default function PostWrite(): JSX.Element {
/>
+
diff --git a/app/(app)/settings/login-info.tsx b/app/(app)/settings/login-info.tsx
index 7d88072..4cd4380 100644
--- a/app/(app)/settings/login-info.tsx
+++ b/app/(app)/settings/login-info.tsx
@@ -14,6 +14,7 @@ import type {User} from '../../../src/types';
import {showConfirm} from '../../../src/utils/alert';
import {AsyncStorageKey} from '../../../src/utils/constants';
import CustomLoadingIndicator from '../../../src/components/uis/CustomLoadingIndicator';
+import { fetchDeletePushToken } from '../../../src/apis/pushTokenQueries';
const Content = styled.View`
flex: 1;
@@ -93,10 +94,16 @@ export default function LoginInfo(): JSX.Element {
const {back, replace} = useRouter();
const {theme, alertDialog} = useDooboo();
const {bottom} = useSafeAreaInsets();
- const auth = useRecoilValue(authRecoilState);
+ const {authId, user, pushToken} = useRecoilValue(authRecoilState);
const handleSignOut = async (): Promise => {
- // RNOnesignal?.logout();
+ if (pushToken && authId) {
+ await fetchDeletePushToken({
+ authId,
+ expoPushToken: pushToken,
+ })
+ }
+
await AsyncStorage.removeItem(AsyncStorageKey.Token);
supabase.auth.signOut();
back();
@@ -104,7 +111,7 @@ export default function LoginInfo(): JSX.Element {
};
const handleWithdrawUser = async (): Promise => {
- if (!auth) {
+ if (!user || !authId) {
return;
}
@@ -120,13 +127,13 @@ export default function LoginInfo(): JSX.Element {
await supabase
.from('users')
.update({deleted_at: new Date().toISOString()})
- .eq('id', auth);
+ .eq('id', authId);
supabase.auth.signOut();
replace('/');
};
- if (!auth.user) {
+ if (!user) {
return (
<>
@@ -148,8 +155,8 @@ export default function LoginInfo(): JSX.Element {
{t('loginInfo.loginMethod')}