-
Notifications
You must be signed in to change notification settings - Fork 1
[Feat] 라우팅 발생 시 웹뷰 여부에 따른 별도 핸들링 구현 #196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "192-feat-\uB77C\uC6B0\uD305-\uBC1C\uC0DD-\uC2DC-\uC6F9\uBDF0-\uC5EC\uBD80\uC5D0-\uB530\uB978-\uBCC4\uB3C4-\uD578\uB4E4\uB9C1-\uAD6C\uD604"
Changes from all commits
7f44886
f3bed10
2f6b6bf
b8df994
48d375f
b6ef8a7
406e4a2
342269e
6f295db
1a2a64f
652ff33
619e611
f09f056
25ee468
e14ccd3
e30dabf
8d9d167
7c53cda
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import WebView, { WebViewMessageEvent } from "react-native-webview"; | ||
|
|
||
| import { ROUTES } from "@/constants/routes"; | ||
| import { useHandleNavigationActions } from "@/hooks/useHandleNavigationActions"; | ||
| import { getBaseUrl } from "@/utils/getBaseUrl"; | ||
|
|
||
| export default function DashboardScreen() { | ||
| const baseUrl = getBaseUrl(); | ||
| const handleNavigationActions = useHandleNavigationActions(); | ||
|
|
||
| const requestOnMessage = (e: WebViewMessageEvent) => { | ||
| handleNavigationActions(e); | ||
| }; | ||
|
|
||
| return <WebView className="flex-1" source={{ uri: `${baseUrl}${ROUTES.DASHBOARD}` }} onMessage={requestOnMessage} />; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import { WebView, WebViewMessageEvent } from "react-native-webview"; | ||
|
|
||
| import { useHandleNavigationActions } from "@/hooks/useHandleNavigationActions"; | ||
| import { getBaseUrl } from "@/utils/getBaseUrl"; | ||
|
|
||
| export default function HomeScreen() { | ||
| // TODO : login상태에 따른 분기 처리 설정 | ||
|
|
||
| const baseUrl = getBaseUrl(); | ||
| const handleNavigationActions = useHandleNavigationActions(); | ||
|
|
||
| const requestOnMessage = (e: WebViewMessageEvent) => { | ||
| handleNavigationActions(e); | ||
| }; | ||
|
|
||
| return <WebView className="flex-1" source={{ uri: `${baseUrl}` }} onMessage={requestOnMessage} />; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import WebView, { WebViewMessageEvent } from "react-native-webview"; | ||
|
|
||
| import { ROUTES } from "@/constants/routes"; | ||
| import { useHandleNavigationActions } from "@/hooks/useHandleNavigationActions"; | ||
| import { getBaseUrl } from "@/utils/getBaseUrl"; | ||
|
|
||
| export default function MeetingsScreen() { | ||
| const baseUrl = getBaseUrl(); | ||
| const handleNavigationActions = useHandleNavigationActions(); | ||
|
|
||
| const requestOnMessage = (e: WebViewMessageEvent) => { | ||
| handleNavigationActions(e); | ||
| }; | ||
|
|
||
| return <WebView className="flex-1" source={{ uri: `${baseUrl}${ROUTES.MEETINGS}` }} onMessage={requestOnMessage} />; | ||
| } | ||
|
Comment on lines
+1
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion WebView 로직 재사용성 개선 필요 여러 라우트 파일에서 동일한 WebView 로직이 반복되고 있습니다. 이는 유지보수성을 저하시키고 코드 중복을 야기합니다. 공통 WebView 래퍼 컴포넌트를 생성하여 코드 중복을 제거하는 것을 추천드립니다: // components/common/AppWebView.tsx
interface AppWebViewProps {
route: string;
onMessage?: (event: WebViewMessageEvent) => void;
}
export function AppWebView({ route, onMessage }: AppWebViewProps) {
const baseUrl = getBaseUrl();
const [isLoading, setIsLoading] = useState(true);
return (
<>
<WebView
className="flex-1"
source={{ uri: `${baseUrl}${route}` }}
onMessage={onMessage}
onLoadStart={() => setIsLoading(true)}
onLoadEnd={() => setIsLoading(false)}
onError={(syntheticEvent) => {
const { nativeEvent } = syntheticEvent;
console.warn('WebView error: ', nativeEvent);
}}
/>
{isLoading && <LoadingSpinner />}
</>
);
}이후 각 스크린에서 다음과 같이 사용할 수 있습니다: export default function MeetingsScreen() {
const handleNavigationActions = useHandleNavigationActions();
return <AppWebView route={ROUTES.MEETINGS} onMessage={handleNavigationActions} />;
} |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import WebView, { WebViewMessageEvent } from "react-native-webview"; | ||
|
|
||
| import { ROUTES } from "@/constants/routes"; | ||
| import { useHandleNavigationActions } from "@/hooks/useHandleNavigationActions"; | ||
| import { getBaseUrl } from "@/utils/getBaseUrl"; | ||
|
|
||
| export default function SeatsScreen() { | ||
| const baseUrl = getBaseUrl(); | ||
| const handleNavigationActions = useHandleNavigationActions(); | ||
|
|
||
| const requestOnMessage = (e: WebViewMessageEvent) => { | ||
| handleNavigationActions(e); | ||
| }; | ||
|
|
||
| return <WebView className="flex-1" source={{ uri: `${baseUrl}${ROUTES.SEATS}` }} onMessage={requestOnMessage} />; | ||
| } | ||
|
Comment on lines
+1
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion WebView 로직을 재사용 가능한 커스텀 훅으로 분리해주세요.
새로운 커스텀 훅을 생성해주세요 ( interface UseWebViewScreenProps {
path?: string;
}
export const useWebViewScreen = ({ path = '' }: UseWebViewScreenProps) => {
const baseUrl = getBaseUrl();
const handleNavigationActions = useHandleNavigationActions();
const requestOnMessage = (e: WebViewMessageEvent) => {
handleNavigationActions(e);
};
return {
uri: `${baseUrl}${path}`,
onMessage: requestOnMessage,
};
};그리고 각 스크린에서 다음과 같이 사용: export default function SeatsScreen() {
const webViewProps = useWebViewScreen({ path: ROUTES.SEATS });
return (
<ErrorBoundary fallback={<ErrorScreen />}>
<WebView
className="flex-1"
source={{ uri: webViewProps.uri }}
onMessage={webViewProps.onMessage}
onError={handleError}
renderLoading={() => <LoadingSpinner />}
startInLoadingState
/>
</ErrorBoundary>
);
} |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import WebView, { WebViewMessageEvent } from "react-native-webview"; | ||
|
|
||
| import { ROUTES } from "@/constants/routes"; | ||
| import { useHandleNavigationActions } from "@/hooks/useHandleNavigationActions"; | ||
| import { getBaseUrl } from "@/utils/getBaseUrl"; | ||
|
|
||
| export default function SettingsScreen() { | ||
| const baseUrl = getBaseUrl(); | ||
| const handleNavigationActions = useHandleNavigationActions(); | ||
|
|
||
| const requestOnMessage = (e: WebViewMessageEvent) => { | ||
| handleNavigationActions(e); | ||
| }; | ||
| return <WebView className="flex-1" source={{ uri: `${baseUrl}${ROUTES.SETTINGS}` }} onMessage={requestOnMessage} />; | ||
| } | ||
|
Comment on lines
+7
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion WebView 구현에 대한 개선 제안 WebView 컴포넌트에 다음과 같은 필수적인 기능들이 누락되어 있습니다:
다음과 같이 개선하는 것을 추천드립니다: export default function SettingsScreen() {
const baseUrl = getBaseUrl();
const handleNavigationActions = useHandleNavigationActions();
+ const [isLoading, setIsLoading] = useState(true);
const requestOnMessage = (e: WebViewMessageEvent) => {
handleNavigationActions(e);
};
- return <WebView className="flex-1" source={{ uri: `${baseUrl}${ROUTES.SETTINGS}` }} onMessage={requestOnMessage} />;
+ return (
+ <>
+ <WebView
+ className="flex-1"
+ source={{ uri: `${baseUrl}${ROUTES.SETTINGS}` }}
+ onMessage={requestOnMessage}
+ onLoadStart={() => setIsLoading(true)}
+ onLoadEnd={() => setIsLoading(false)}
+ onError={(syntheticEvent) => {
+ const { nativeEvent } = syntheticEvent;
+ console.warn('WebView error: ', nativeEvent);
+ }}
+ />
+ {isLoading && <LoadingSpinner />}
+ </>
+ );
|
||
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,36 +3,38 @@ import { useFonts } from "expo-font"; | |||||||||||||||||||||||||||||||||||
| import { Stack } from "expo-router"; | ||||||||||||||||||||||||||||||||||||
| import * as SplashScreen from "expo-splash-screen"; | ||||||||||||||||||||||||||||||||||||
| import { useEffect } from "react"; | ||||||||||||||||||||||||||||||||||||
| import "react-native-reanimated"; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| import { DIR_NAME, ROUTES } from "@/constants/routes"; | ||||||||||||||||||||||||||||||||||||
| import { useColorScheme } from "@/hooks/useColorScheme"; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| import "react-native-reanimated"; | ||||||||||||||||||||||||||||||||||||
| import "@repo/ui/styles/globals.css"; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Prevent the splash screen from auto-hiding before asset loading is complete. | ||||||||||||||||||||||||||||||||||||
| // TODO : splash 적용할건지? | ||||||||||||||||||||||||||||||||||||
| SplashScreen.preventAutoHideAsync(); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| export default function RootLayout() { | ||||||||||||||||||||||||||||||||||||
| const colorScheme = useColorScheme(); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| const [loaded] = useFonts({ | ||||||||||||||||||||||||||||||||||||
| SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"), | ||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||||||||||||
| if (loaded) { | ||||||||||||||||||||||||||||||||||||
| SplashScreen.hideAsync(); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| if (loaded) SplashScreen.hideAsync(); | ||||||||||||||||||||||||||||||||||||
| }, [loaded]); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if (!loaded) { | ||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| if (!loaded) return null; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||
| <ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}> | ||||||||||||||||||||||||||||||||||||
| <Stack> | ||||||||||||||||||||||||||||||||||||
| <Stack.Screen name="(tabs)" options={{ headerShown: false }} /> | ||||||||||||||||||||||||||||||||||||
| <Stack.Screen name="+not-found" /> | ||||||||||||||||||||||||||||||||||||
| <Stack screenOptions={{ headerShown: false, animation: "default" }}> | ||||||||||||||||||||||||||||||||||||
| <Stack.Screen name={`${DIR_NAME}${ROUTES.HOME}`} /> | ||||||||||||||||||||||||||||||||||||
| <Stack.Screen name={`${DIR_NAME}${ROUTES.DASHBOARD}`} /> | ||||||||||||||||||||||||||||||||||||
| <Stack.Screen name={`${DIR_NAME}${ROUTES.MEETINGS}`} /> | ||||||||||||||||||||||||||||||||||||
| <Stack.Screen name={`${DIR_NAME}${ROUTES.SEATS}`} /> | ||||||||||||||||||||||||||||||||||||
| <Stack.Screen name={`${DIR_NAME}${ROUTES.SETTINGS}`} /> | ||||||||||||||||||||||||||||||||||||
| <Stack.Screen name={ROUTES.NOT_FOUND} /> | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+31
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 라우트 상수의 타입 안전성 강화 필요
다음과 같이 개선하는 것을 제안합니다: +type RouteNames = keyof typeof ROUTES;
+
<Stack screenOptions={{ headerShown: false, animation: "default" }}>
- <Stack.Screen name={`${DIR_NAME}${ROUTES.HOME}`} />
- <Stack.Screen name={`${DIR_NAME}${ROUTES.DASHBOARD}`} />
- <Stack.Screen name={`${DIR_NAME}${ROUTES.MEETINGS}`} />
- <Stack.Screen name={`${DIR_NAME}${ROUTES.SEATS}`} />
- <Stack.Screen name={`${DIR_NAME}${ROUTES.SETTINGS}`} />
- <Stack.Screen name={ROUTES.NOT_FOUND} />
+ {(Object.keys(ROUTES) as RouteNames[]).map((route) => (
+ <Stack.Screen
+ key={route}
+ name={route === 'NOT_FOUND' ? ROUTES[route] : `${DIR_NAME}${ROUTES[route]}`}
+ />
+ ))}
</Stack>📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||
| </Stack> | ||||||||||||||||||||||||||||||||||||
| </ThemeProvider> | ||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.