Peace 5 days ago
parent bbde69c687
commit dbbf97286f
  1. 33
      every-jap-dict/App.tsx
  2. 1047
      every-jap-dict/package-lock.json
  3. 9
      every-jap-dict/package.json

@ -6,7 +6,7 @@ import { GluestackUIProvider } from '@/components/ui/gluestack-ui-provider';
import '@/global.css';
import { useWordbook, WordbookProvider } from './lib/wordbook/context';
import { Text } from './components/ui/text';
import { useMemo, useState } from 'react';
import { useMemo, useRef, useState } from 'react';
import { jaPack, languages } from './lib/providers/dictionaries';
import { Input, InputField } from './components/ui/input';
import { HStack } from './components/ui/hstack';
@ -17,7 +17,8 @@ import { Toast, ToastDescription, ToastTitle, useToast } from './components/ui/t
import mobileAds from 'react-native-google-mobile-ads';
import { Icon } from './components/ui/icon';
import { Bookmark, BookMarked, BookOpen, Search } from 'lucide-react-native';
import { Bookmark, BookmarkCheck, BookMarked, BookOpen, Search } from 'lucide-react-native';
import * as Animatable from 'react-native-animatable';
function MainScreen() {
const [q, setQ] = useState('');
@ -36,6 +37,11 @@ function MainScreen() {
const { add, items, remove, clear, loading } = useWordbook();
const baseText = (query || q).trim();
const isSaved =
!!baseText &&
items.some((it) => it.text.toLowerCase() === baseText.toLowerCase() && it.lang === pack.code);
const urls = useMemo(
() =>
providers.reduce<Record<string, string>>((acc, p) => {
@ -55,23 +61,28 @@ function MainScreen() {
const onSave = () => {
if (!canSearch) return;
Keyboard.dismiss();
add(q.trim(), pack.code);
const toastDesc = isSaved ? '이미 단어장에 있어요' : '단어장에 저장되었습니다';
if (!isSaved) add(q.trim(), pack.code);
toast.show({
id: 'onSave',
placement: 'top',
duration: 2000,
render: () => (
render: ({ id }) => {
console.log('toast render called');
return (
<View style={{ marginTop: insets.top + 12, alignItems: 'center', width: '100%' }}>
<Toast
className="rounded-full opacity-80 mx-5 py-2 flex-row items-center gap-2 shadow-lg max-w-[90%]"
nativeID={`toast-${id}`}
variant="solid"
className="rounded-full opacity-90 mx-5 px-5 py-2 flex-row items-center gap-2 shadow-lg max-w-[90%]"
>
<ToastTitle></ToastTitle>
<ToastDescription> </ToastDescription>
<ToastDescription>{toastDesc}</ToastDescription>
</Toast>
</View>
),
);
},
});
};
@ -108,6 +119,7 @@ function MainScreen() {
onSubmitEditing={onSearch}
/>
</Input>
<Animatable.View animation="tada" duration={600} useNativeDriver>
<Button
className="p-1"
onPress={onSave}
@ -116,8 +128,10 @@ function MainScreen() {
isDisabled={!canSearch}
accessibilityLabel="단어장 저장"
>
<Icon as={Bookmark} />
<Icon as={isSaved ? BookmarkCheck : Bookmark} />
</Button>
</Animatable.View>
<Button onPress={onSearch} isDisabled={!canSearch}>
<ButtonText></ButtonText>
</Button>
@ -228,6 +242,7 @@ export default function App() {
<StatusBar style="auto" />
<WordbookProvider>
<MainScreen />
<Toast />
</WordbookProvider>
</SafeAreaView>
</SafeAreaProvider>

File diff suppressed because it is too large Load Diff

@ -13,7 +13,7 @@
"@gluestack-ui/core": "^3.0.0",
"@gluestack-ui/utils": "^3.0.0",
"@legendapp/motion": "^2.4.0",
"@react-native-async-storage/async-storage": "^2.2.0",
"@react-native-async-storage/async-storage": "2.2.0",
"babel-plugin-module-resolver": "^5.0.2",
"expo": "^54.0.7",
"expo-status-bar": "~3.0.8",
@ -25,9 +25,10 @@
"react-aria": "^3.33.0",
"react-dom": "19.1.0",
"react-native": "0.81.4",
"react-native-animatable": "^1.4.0",
"react-native-google-mobile-ads": "^15.7.0",
"react-native-reanimated": "^4.1.0",
"react-native-safe-area-context": "^5.6.1",
"react-native-reanimated": "~4.1.0",
"react-native-safe-area-context": "~5.6.0",
"react-native-svg": "15.12.1",
"react-native-webview": "13.15.0",
"react-native-worklets": "0.5.1",
@ -37,7 +38,7 @@
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@expo/config-plugins": "^54.0.1",
"@expo/config-plugins": "~54.0.1",
"@types/react": "~19.1.10",
"typescript": "~5.9.2"
},

Loading…
Cancel
Save