feat(mobile): Expo → RN CLI 전환 + Android 빌드 성공

RN 0.85 + React 19 기반 apps/mobile-rn 프로젝트 생성.
6개 화면 이식 (Login, Dash, History, Record, Talk, Settings).
@react-navigation/native + bottom-tabs 네비게이션 구성.
Windows NDK CMake libc++_shared 링크 버그 워크아라운드 포함.
Galaxy Fold (SM_F956N) 무선 디버깅 APK 설치 확인.
This commit is contained in:
yunchan8804 2026-04-13 21:13:40 +09:00
parent 55eb62189a
commit bf36a9d97d
68 changed files with 13955 additions and 9375 deletions

View file

@ -0,0 +1,55 @@
// src/lib/auth-context.tsx — Auth provider using Supabase
import { createContext, useContext, useEffect, useState, useCallback } from 'react'
import type { ReactNode } from 'react'
import type { User, Session } from '@supabase/supabase-js'
import { supabase } from './supabase'
interface AuthContextValue {
user: User | null
session: Session | null
loading: boolean
devBypass: () => void
}
const AuthContext = createContext<AuthContextValue>({
user: null,
session: null,
loading: true,
devBypass: () => {},
})
export function AuthProvider({ children }: { children: ReactNode }): React.ReactElement {
const [user, setUser] = useState<User | null>(null)
const [session, setSession] = useState<Session | null>(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
supabase.auth.getSession().then(({ data: { session: s } }) => {
setSession(s)
setUser(s?.user ?? null)
setLoading(false)
})
const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, s) => {
setSession(s)
setUser(s?.user ?? null)
})
return () => subscription.unsubscribe()
}, [])
const devBypass = useCallback(() => {
setUser({ id: 'dev-user', email: 'dev@d3ro.local' } as User)
setLoading(false)
}, [])
return (
<AuthContext.Provider value={{ user, session, loading, devBypass }}>
{children}
</AuthContext.Provider>
)
}
export function useAuth(): AuthContextValue {
return useContext(AuthContext)
}

View file

@ -0,0 +1,25 @@
// src/lib/supabase.ts — Supabase client for RN
import 'react-native-url-polyfill/auto'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { createClient, type SupabaseClient } from '@supabase/supabase-js'
// TODO: move to env config or supabase-config.ts
const SUPABASE_URL = ''
const SUPABASE_ANON_KEY = ''
export const supabase: SupabaseClient = createClient(
SUPABASE_URL,
SUPABASE_ANON_KEY,
{
auth: {
storage: AsyncStorage,
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: false,
},
}
)
export function isSupabaseConfigured(): boolean {
return SUPABASE_URL.length > 0 && SUPABASE_ANON_KEY.length > 0
}