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
7 changes: 5 additions & 2 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"useIgnoreFile": false
},
"files": {
"include": ["src/**/*.{js,ts,tsx}", "example/src/**/*.{js,ts,tsx}"],
"include": ["src/**/*", "example/src/**/*"],
"ignoreUnknown": false,
"ignore": ["lib", "node_modules", "ios", "android"]
},
Expand All @@ -20,7 +20,10 @@
"linter": {
"enabled": true,
"rules": {
"recommended": true
"recommended": true,
"suspicious": {
"noExplicitAny": "warn"
}
}
},
"javascript": {
Expand Down
27 changes: 13 additions & 14 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useRef, useState } from 'react';
import { useCallback, useRef, useState } from 'react';
import { Alert, SafeAreaView, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import {
type PlayerControls,
Expand All @@ -20,7 +20,7 @@ function App() {
const [isMuted, setIsMuted] = useState(false);
const [videoId, setVideoId] = useState('AbZH7XWDW_k');

const handleReady = async () => {
const handleReady = useCallback(async () => {
console.log('Player is ready!');
Alert.alert('알림', 'YouTube 플레이어가 준비되었습니다!');

Expand All @@ -36,7 +36,7 @@ function App() {
} catch (error) {
console.error('Error getting player info:', error);
}
};
}, []);

const handleStateChange = (state: PlayerState) => {
console.log('Player state changed:', state);
Expand Down Expand Up @@ -64,31 +64,31 @@ function App() {
}
};

const handleProgress = (progress: ProgressData) => {
const handleProgress = useCallback((progress: ProgressData) => {
setCurrentTime(progress.currentTime);
setDuration(progress.duration);
setLoadedFraction(progress.loadedFraction);
};
}, []);

const handleError = (error: YouTubeError) => {
const handleError = useCallback((error: YouTubeError) => {
console.error('Player error:', error);
Alert.alert('에러', `플레이어 오류 (${error.code}): ${error.message}`);
};
}, []);

const handlePlaybackRateChange = (rate: number) => {
const handlePlaybackRateChange = useCallback((rate: number) => {
console.log('Playback rate changed:', rate);
setPlaybackRate(rate);
};
}, []);

const handlePlaybackQualityChange = (quality: string) => {
const handlePlaybackQualityChange = useCallback((quality: string) => {
console.log('Playback quality changed:', quality);
Alert.alert('품질 변경', `재생 품질이 ${quality}로 변경되었습니다`);
};
}, []);

const handleAutoplayBlocked = () => {
const handleAutoplayBlocked = useCallback(() => {
console.log('Autoplay was blocked');
Alert.alert('알림', '자동재생이 브라우저에 의해 차단되었습니다');
};
}, []);

const formatTime = (seconds: number): string => {
const mins = Math.floor(seconds / 60);
Expand Down Expand Up @@ -157,7 +157,6 @@ function App() {
controls: true,
playsinline: true,
rel: false,
modestbranding: true,
}}
onReady={handleReady}
onStateChange={handleStateChange}
Expand Down
20 changes: 7 additions & 13 deletions src/YoutubePlayer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import useCreateLocalPlayerHtml from './hooks/useCreateLocalPlayerHtml';
import type { MessageData } from './types/message';
import { type PlayerControls, PlayerState, type YoutubePlayerProps } from './types/youtube';
import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
import { Dimensions, StyleSheet, View } from 'react-native';
import { Dimensions, StyleSheet } from 'react-native';
import WebView, { type WebViewMessageEvent } from 'react-native-webview';
import YoutubePlayerWrapper from './YoutubePlayerWrapper';
import useCreateLocalPlayerHtml from './hooks/useCreateLocalPlayerHtml';
import type { MessageData } from './types/message';
import type { PlayerControls, YoutubePlayerProps } from './types/youtube';

const { width: screenWidth } = Dimensions.get('window');

Expand All @@ -29,7 +30,6 @@ const YoutubePlayer = forwardRef<PlayerControls, YoutubePlayerProps>(
muted: false,
playsinline: true,
rel: false,
modestbranding: true,
},
},
ref,
Expand All @@ -38,7 +38,6 @@ const YoutubePlayer = forwardRef<PlayerControls, YoutubePlayerProps>(

const webViewRef = useRef<WebView>(null);
const [isReady, setIsReady] = useState(false);
const [_, setCurrentState] = useState<PlayerState>(PlayerState.UNSTARTED);
const commandIdRef = useRef(0);
const pendingCommandsRef = useRef<Map<string, (result: unknown) => void>>(new Map());

Expand All @@ -59,7 +58,6 @@ const YoutubePlayer = forwardRef<PlayerControls, YoutubePlayerProps>(

if (data.type === 'stateChange') {
const state = data.state;
setCurrentState(state);
onStateChange?.(state);
return;
}
Expand Down Expand Up @@ -203,7 +201,7 @@ const YoutubePlayer = forwardRef<PlayerControls, YoutubePlayerProps>(
}, [isReady, sendCommand]);

return (
<View style={[styles.container, { width, height }, style]}>
<YoutubePlayerWrapper width={width} height={height} style={style}>
<WebView
ref={webViewRef}
source={{ html: createPlayerHTML() }}
Expand All @@ -228,16 +226,12 @@ const YoutubePlayer = forwardRef<PlayerControls, YoutubePlayerProps>(
mixedContentMode="compatibility"
thirdPartyCookiesEnabled={false}
/>
</View>
</YoutubePlayerWrapper>
);
},
);

const styles = StyleSheet.create({
container: {
backgroundColor: '#000',
overflow: 'hidden',
},
webView: {
flex: 1,
backgroundColor: 'transparent',
Expand Down
Loading