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.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default ({ config }: ConfigContext): ExpoConfig =>
owner: 'eten-genesis',
name: getAppName(appVariant),
slug: 'langquest',
version: '2.0.1',
version: '2.0.3',
orientation: 'portrait',
icon: iconLight,
scheme: getScheme(appVariant),
Expand Down
21 changes: 12 additions & 9 deletions app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { DarkTheme, DefaultTheme } from '@react-navigation/native';
import { StatusBar } from 'expo-status-bar';

import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
import { KeyboardProvider } from 'react-native-keyboard-controller';
import {
configureReanimatedLogger,
ReanimatedLogLevel
Expand Down Expand Up @@ -136,15 +137,17 @@ export default function RootLayout() {
<AudioProvider>
<SafeAreaProvider>
<GestureHandlerRootView style={{ flex: 1 }}>
<StatusBar style={systemBarsStyle} />
{/* OTA Update Banner - shown before login and after */}
<UpdateBanner />
<BottomSheetModalProvider>
<ThemeProvider value={NAV_THEME[scheme]}>
<Stack screenOptions={{ headerShown: false }} />
<PortalHost />
</ThemeProvider>
</BottomSheetModalProvider>
<KeyboardProvider>
<StatusBar style={systemBarsStyle} />
{/* OTA Update Banner - shown before login and after */}
<UpdateBanner />
<BottomSheetModalProvider>
<ThemeProvider value={NAV_THEME[scheme]}>
<Stack screenOptions={{ headerShown: false }} />
<PortalHost />
</ThemeProvider>
</BottomSheetModalProvider>
</KeyboardProvider>
</GestureHandlerRootView>
</SafeAreaProvider>
</AudioProvider>
Expand Down
37 changes: 13 additions & 24 deletions components/AuthModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ import { AuthNavigator } from '@/navigators/AuthNavigator';
import { useThemeColor } from '@/utils/styleUtils';
import { XIcon } from 'lucide-react-native';
import React from 'react';
import {
KeyboardAvoidingView,
Modal,
Platform,
Pressable,
View
} from 'react-native';
import { Modal, Pressable, View } from 'react-native';
import { Icon } from './ui/icon';

interface AuthModalProps {
Expand All @@ -32,24 +26,19 @@ export function AuthModal({
presentationStyle="pageSheet"
onRequestClose={onClose}
>
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
className="flex-1"
>
<View style={{ flex: 1, backgroundColor }} className="flex-1">
{/* Close button */}
<View className="absolute right-4 top-4 z-10">
<Pressable
onPress={onClose}
className="rounded-full bg-background/80 p-2"
hitSlop={{ top: 10, right: 10, bottom: 10, left: 10 }}
>
<Icon as={XIcon} size={24} className="text-foreground" />
</Pressable>
</View>
<AuthNavigator key={initialView} initialView={initialView} />
<View style={{ backgroundColor }} className="flex-1">
{/* Close button */}
<View className="absolute right-4 top-4 z-10">
<Pressable
onPress={onClose}
className="rounded-full bg-background/80 p-2"
hitSlop={10}
>
<Icon as={XIcon} size={24} className="text-foreground" />
</Pressable>
</View>
</KeyboardAvoidingView>
<AuthNavigator key={initialView} initialView={initialView} />
</View>
</Modal>
);
}
204 changes: 104 additions & 100 deletions components/NewReportModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ import { XIcon } from 'lucide-react-native';
import React, { useMemo, useState } from 'react';
import {
Alert,
KeyboardAvoidingView,
Modal,
Pressable,
ScrollView,
TouchableWithoutFeedback,
View
} from 'react-native';
import {
KeyboardAwareScrollView,
KeyboardToolbar
} from 'react-native-keyboard-controller';

interface ReportModalProps {
isVisible: boolean;
Expand Down Expand Up @@ -171,117 +173,119 @@ export const ReportModal: React.FC<ReportModalProps> = ({
>
<TouchableWithoutFeedback onPress={onClose}>
<Pressable className="flex-1 items-center justify-center bg-black/50">
<KeyboardAvoidingView behavior="padding">
<TouchableWithoutFeedback onPress={(e) => e.stopPropagation()}>
<View className="w-[90%] max-w-md rounded-lg bg-background p-6">
<View className="mb-4 flex-row items-center justify-between">
<Text variant="h3">{modalTitle}</Text>
<Pressable className="p-1" onPress={onClose}>
<Icon as={XIcon} size={24} className="text-foreground" />
</Pressable>
</View>
<TouchableWithoutFeedback onPress={(e) => e.stopPropagation()}>
<View className="w-[90%] max-w-md rounded-lg bg-background p-6">
<View className="mb-4 flex-row items-center justify-between">
<Text variant="h3">{modalTitle}</Text>
<Pressable className="p-1" onPress={onClose}>
<Icon as={XIcon} size={24} className="text-foreground" />
</Pressable>
</View>

<ScrollView
className="max-h-[80%]"
showsVerticalScrollIndicator
contentContainerStyle={{ paddingRight: 8 }}
>
<View className="gap-4">
<View>
<Text variant="large" className="mb-2">
{t('selectReasonLabel')}
</Text>
<RadioGroup
value={reason ?? undefined}
onValueChange={(value) =>
handleReasonSelect(
value as (typeof reasonOptions)[number]
)
}
>
{reportReasons.map((option) => (
<RadioGroupItem
key={option.value}
value={option.value}
label={option.label}
/>
))}
</RadioGroup>
</View>
<KeyboardAwareScrollView
style={{ maxHeight: '80%' }}
contentContainerStyle={{ paddingRight: 8 }}
bottomOffset={96}
extraKeyboardSpace={20}
>
<View className="gap-4">
<View>
<Text variant="large" className="mb-2">
{t('selectReasonLabel')}
</Text>
<RadioGroup
value={reason ?? undefined}
onValueChange={(value) =>
handleReasonSelect(
value as (typeof reasonOptions)[number]
)
}
>
{reportReasons.map((option) => (
<RadioGroupItem
key={option.value}
value={option.value}
label={option.label}
/>
))}
</RadioGroup>
</View>

<View>
<Text variant="large" className="mb-2">
{t('additionalDetails')}
</Text>
<Textarea
placeholder={t('additionalDetailsPlaceholder')}
value={details}
onChangeText={setDetails}
drawerInput={false}
/>
</View>
<View>
<Text variant="large" className="mb-2">
{t('additionalDetails')}
</Text>
<Textarea
placeholder={t('additionalDetailsPlaceholder')}
value={details}
onChangeText={setDetails}
drawerInput={false}
/>
</View>

{/* Blocking options */}
<View className="gap-3 border-t border-input pt-4">
<Text variant="large" className="mb-2">
{t('options')}
</Text>
{/* Block content option - only for authenticated users */}
{isAuthenticated ? (
<>
{/* Blocking options */}
<View className="gap-3 border-t border-input pt-4">
<Text variant="large" className="mb-2">
{t('options')}
</Text>
{/* Block content option - only for authenticated users */}
{isAuthenticated ? (
<>
<View className="flex-row items-center justify-between">
<Label className="flex-1">
{t('blockThisContent')}
</Label>
<Switch
checked={blockContentOption}
onCheckedChange={setBlockContentOption}
/>
</View>

{creatorId && creatorId !== currentUser?.id && (
<View className="flex-row items-center justify-between">
<Label className="flex-1">
{t('blockThisContent')}
{t('blockThisUser')}
</Label>
<Switch
checked={blockContentOption}
onCheckedChange={setBlockContentOption}
checked={blockUserOption}
onCheckedChange={setBlockUserOption}
/>
</View>

{creatorId && creatorId !== currentUser?.id && (
<View className="flex-row items-center justify-between">
<Label className="flex-1">
{t('blockThisUser')}
</Label>
<Switch
checked={blockUserOption}
onCheckedChange={setBlockUserOption}
/>
</View>
)}
</>
) : (
<View className="rounded-md bg-primary/10 p-4">
<Text variant="small" className="leading-5">
{t('blockContentLoginMessage') ||
'We store information about what to block on your account. Please register to ensure blocked content can be properly hidden.'}
</Text>
</View>
)}
</View>
)}
</>
) : (
<View className="rounded-md bg-primary/10 p-4">
<Text variant="small" className="leading-5">
{t('blockContentLoginMessage') ||
'We store information about what to block on your account. Please register to ensure blocked content can be properly hidden.'}
</Text>
</View>
)}
</View>
</ScrollView>
</View>
</KeyboardAwareScrollView>

<Button
className="mt-4"
onPress={handleSubmit}
disabled={
!reason || report.isCreatingReport || hasAlreadyReported
}
loading={report.isCreatingReport}
>
<Text>
{report.isCreatingReport
? t('submitting')
: t('submitReport')}
</Text>
</Button>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
<Button
className="mt-4"
onPress={handleSubmit}
disabled={
!reason || report.isCreatingReport || hasAlreadyReported
}
loading={report.isCreatingReport}
>
<Text>
{report.isCreatingReport
? t('submitting')
: t('submitReport')}
</Text>
</Button>
</View>
</TouchableWithoutFeedback>
</Pressable>
</TouchableWithoutFeedback>
<KeyboardToolbar>
<KeyboardToolbar.Done />
</KeyboardToolbar>
</Modal>
);
};
Loading
Loading