diff --git a/app/webview/[slug].tsx b/app/webview/[slug].tsx index 3bcf681..6cf9104 100644 --- a/app/webview/[slug].tsx +++ b/app/webview/[slug].tsx @@ -87,11 +87,11 @@ export default function WebViewScreen() { } }; - const handleNavigateWebview = (slug: string) => { + const handleNavigateWebview = (slug: string, clubId?: string) => { if (slug.startsWith('club/')) { - const clubId = slug.slice('club/'.length); - if (!clubId) return; - router.push({ pathname: '/club/[id]', params: { id: clubId } }); + const slugId = slug.slice('club/'.length); + if (!slugId) return; + router.push({ pathname: '/club/[id]', params: { id: slugId, clubId } }); } else { router.push({ pathname: '/webview/[slug]', params: { slug } }); } @@ -174,6 +174,7 @@ export default function WebViewScreen() { domStorageEnabled={true} /> + ); } diff --git a/hooks/use-webview-message-handler.ts b/hooks/use-webview-message-handler.ts index 8ebc0ce..845feb8 100644 --- a/hooks/use-webview-message-handler.ts +++ b/hooks/use-webview-message-handler.ts @@ -6,7 +6,7 @@ interface UseWebViewMessageHandlerOptions { // 뒤로가기 요청 시 호출 onNavigateBack?: () => void; // 웹뷰 내 화면 이동 요청 시 호출 - onNavigateWebview?: (slug: string) => void; + onNavigateWebview?: (slug: string, clubId?: string) => void; // 알림 구독 요청 시 호출 onSubscribe?: (clubId: string, clubName?: string) => Promise | void; // 알림 구독 해제 요청 시 호출 @@ -36,7 +36,7 @@ export const useWebViewMessageHandler = ({ break; case WebViewMessageTypes.NAVIGATE_WEBVIEW: if (message.payload?.slug) { - onNavigateWebview?.(message.payload.slug); + onNavigateWebview?.(message.payload.slug, message.payload.clubId); } break; case WebViewMessageTypes.NOTIFICATION_SUBSCRIBE: diff --git a/types/webview-message.types.ts b/types/webview-message.types.ts index 0d917d4..1bf740e 100644 --- a/types/webview-message.types.ts +++ b/types/webview-message.types.ts @@ -13,7 +13,7 @@ export const WebViewMessageTypes = { export type WebViewMessage = | { type: 'NAVIGATE_BACK' } - | { type: 'NAVIGATE_WEBVIEW'; payload: { slug: string } } + | { type: 'NAVIGATE_WEBVIEW'; payload: { slug: string; clubId?: string } } | { type: 'NOTIFICATION_SUBSCRIBE'; payload: { clubId: string; clubName?: string } } | { type: 'NOTIFICATION_UNSUBSCRIBE'; payload: { clubId: string } } | { type: 'SHARE'; payload: { title: string; text: string; url: string } } diff --git a/ui/club-detail/club-detail-screen.tsx b/ui/club-detail/club-detail-screen.tsx index 511bb3a..7f66ef1 100644 --- a/ui/club-detail/club-detail-screen.tsx +++ b/ui/club-detail/club-detail-screen.tsx @@ -18,7 +18,7 @@ import styled from "styled-components/native"; export default function ClubWebViewScreen() { const router = useRouter(); - const { id, name } = useLocalSearchParams<{ id?: string; name?: string }>(); + const { id, name, clubId: objectId } = useLocalSearchParams<{ id?: string; name?: string; clubId?: string }>(); const [isLoading, setIsLoading] = useState(true); const [hasError, setHasError] = useState(false); const [showPermissionDialog, setShowPermissionDialog] = useState(false); @@ -38,15 +38,17 @@ export default function ClubWebViewScreen() { const baseUrl = `${cleanUrl}/webview/club/${id}`; let url = appendSessionId(baseUrl, sessionId); - if (id && isSubscribed(id)) { + const lookupId = typeof objectId === 'string' ? objectId : id; + if (lookupId && isSubscribed(lookupId)) { url += `&is_subscribed=true`; } return url; - }, [id, webviewUrl, sessionId, isSubscribed]); + }, [id, objectId, webviewUrl, sessionId, isSubscribed]); const subscribed = useMemo(() => { - return id ? isSubscribed(id) : false; - }, [id, isSubscribed]); + const lookupId = typeof objectId === 'string' ? objectId : id; + return lookupId ? isSubscribed(lookupId) : false; + }, [id, objectId, isSubscribed]); const userAgent = getWebViewUserAgent(); diff --git a/ui/home/home-webview-screen.tsx b/ui/home/home-webview-screen.tsx index d4cbbe9..fd26ad0 100644 --- a/ui/home/home-webview-screen.tsx +++ b/ui/home/home-webview-screen.tsx @@ -6,7 +6,7 @@ import Constants from 'expo-constants'; import { useRouter } from 'expo-router'; import * as WebBrowser from 'expo-web-browser'; import React, { useCallback, useEffect, useRef, useState } from 'react'; -import { ActivityIndicator, BackHandler, Platform, View } from 'react-native'; +import { ActivityIndicator, BackHandler, Platform, Share, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { WebView, @@ -91,9 +91,9 @@ export function HomeWebViewScreen({ onError }: HomeWebViewScreenProps) { case 'NAVIGATE_WEBVIEW': if (!loaded) break; if (payload.slug?.startsWith('club/')) { - const clubId = payload.slug.slice('club/'.length); - if (!clubId) break; - router.push({ pathname: '/club/[id]', params: { id: clubId } }); + const slugId = payload.slug.slice('club/'.length); + if (!slugId) break; + router.push({ pathname: '/club/[id]', params: { id: slugId, clubId: payload.clubId } }); } else if (payload.slug?.startsWith('promotions/')) { router.push({ pathname: '/webview/[slug]', params: { slug: 'promotions', path: `/${payload.slug}`, hideHeader: 'true' } }); } else { @@ -105,6 +105,10 @@ export function HomeWebViewScreen({ onError }: HomeWebViewScreenProps) { await WebBrowser.openBrowserAsync(payload.url); break; + case 'SHARE': + await Share.share({ title: payload.title, message: payload.text, url: payload.url }); + break; + case 'REQUEST_APP_VERSION': sendMessage({ type: 'APP_VERSION',