From de576915d554da83578c6092631047b3be299202 Mon Sep 17 00:00:00 2001
From: tapframe <85391825+tapframe@users.noreply.github.com>
Date: Tue, 27 Jan 2026 00:41:53 +0530
Subject: [PATCH] added buffer indicator
---
src/components/player/AndroidVideoPlayer.tsx | 14 ++++++++++--
src/components/player/KSPlayerCore.tsx | 22 +++++++++++++++----
.../player/controls/PlayerControls.tsx | 20 +++++++++++------
src/components/player/utils/playerStyles.ts | 2 +-
4 files changed, 44 insertions(+), 14 deletions(-)
diff --git a/src/components/player/AndroidVideoPlayer.tsx b/src/components/player/AndroidVideoPlayer.tsx
index cd3bbd46..f260021c 100644
--- a/src/components/player/AndroidVideoPlayer.tsx
+++ b/src/components/player/AndroidVideoPlayer.tsx
@@ -1,5 +1,5 @@
import React, { useRef, useEffect, useMemo, useCallback, useState } from 'react';
-import { View, StyleSheet, Platform, Animated, ToastAndroid } from 'react-native';
+import { View, StyleSheet, Platform, Animated, ToastAndroid, ActivityIndicator } from 'react-native';
import { toast } from '@backpackapp-io/react-native-toast';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useNavigation, useRoute, RouteProp } from '@react-navigation/native';
@@ -787,7 +787,9 @@ const AndroidVideoPlayer: React.FC = () => {
modals.setErrorDetails(displayError);
modals.setShowErrorModal(true);
}}
- onBuffer={(buf) => playerState.setIsBuffering(buf.isBuffering)}
+ onBuffer={(buf) => {
+ playerState.setIsBuffering(buf.isBuffering);
+ }}
onTracksChanged={(data) => {
console.log('[AndroidVideoPlayer] onTracksChanged:', data);
if (data?.audioTracks) {
@@ -879,6 +881,13 @@ const AndroidVideoPlayer: React.FC = () => {
formatTime={formatTime}
/>
+ {/* Buffering Indicator (Visible when controls are hidden) */}
+ {playerState.isBuffering && !playerState.showControls && (
+
+
+
+ )}
+
{
playerBackend={useExoPlayer ? 'ExoPlayer' : 'MPV'}
onSwitchToMPV={handleManualSwitchToMPV}
useExoPlayer={useExoPlayer}
+ isBuffering={playerState.isBuffering}
/>
{
await traktAutosync.handlePlaybackEnd(duration, duration, 'ended');
}}
onError={handleError}
- onBuffer={setIsBuffering}
+ onBuffer={(b) => {
+ setIsBuffering(b);
+ }}
onReadyForDisplay={() => setIsPlayerReady(true)}
- onPlaybackStalled={() => setIsBuffering(true)}
- onPlaybackResume={() => setIsBuffering(false)}
+ onPlaybackStalled={() => {
+ setIsBuffering(true);
+ }}
+ onPlaybackResume={() => {
+ setIsBuffering(false);
+ }}
screenWidth={screenDimensions.width}
screenHeight={screenDimensions.height}
customVideoStyles={{ width: '100%', height: '100%' }}
@@ -817,6 +823,13 @@ const KSPlayerCore: React.FC = () => {
{/* UI Controls */}
{isVideoLoaded && (
+ {/* Buffering Indicator (Visible when controls are hidden) */}
+ {isBuffering && !showControls && (
+
+
+
+ )}
+
{
isAirPlayActive={isAirPlayActive}
allowsAirPlay={allowsAirPlay}
onAirPlayPress={() => ksPlayerRef.current?.showAirPlayPicker()}
+ isBuffering={isBuffering}
/>
)}
diff --git a/src/components/player/controls/PlayerControls.tsx b/src/components/player/controls/PlayerControls.tsx
index eb7ad749..9ff3eb08 100644
--- a/src/components/player/controls/PlayerControls.tsx
+++ b/src/components/player/controls/PlayerControls.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { View, Text, TouchableOpacity, Animated, StyleSheet, Platform, Dimensions } from 'react-native';
+import { View, Text, TouchableOpacity, Animated, StyleSheet, Platform, Dimensions, ActivityIndicator } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import Feather from 'react-native-vector-icons/Feather';
import { LinearGradient } from 'expo-linear-gradient';
@@ -54,6 +54,7 @@ interface PlayerControlsProps {
// MPV Switch (Android only)
onSwitchToMPV?: () => void;
useExoPlayer?: boolean;
+ isBuffering?: boolean;
}
export const PlayerControls: React.FC = ({
@@ -98,6 +99,7 @@ export const PlayerControls: React.FC = ({
onAirPlayPress,
onSwitchToMPV,
useExoPlayer,
+ isBuffering = false,
}) => {
const { currentTheme } = useTheme();
const { t } = useTranslation();
@@ -463,7 +465,7 @@ export const PlayerControls: React.FC = ({
= ({
transform: [{ scale: playIconScale }],
opacity: playIconOpacity
}}>
-
+ {isBuffering ? (
+
+ ) : (
+
+ )}
diff --git a/src/components/player/utils/playerStyles.ts b/src/components/player/utils/playerStyles.ts
index a4418e84..35dd6f7c 100644
--- a/src/components/player/utils/playerStyles.ts
+++ b/src/components/player/utils/playerStyles.ts
@@ -23,7 +23,7 @@ const qualityPadH = isTV ? 10 : isLargeTablet ? 9 : isTablet ? 8 : 8;
const qualityPadV = isTV ? 4 : isLargeTablet ? 3 : isTablet ? 3 : 2;
const qualityRadius = isTV ? 6 : isLargeTablet ? 5 : isTablet ? 4 : 4;
const qualityTextFont = isTV ? 13 : isLargeTablet ? 12 : isTablet ? 11 : 11;
-const controlsGap = isTV ? 56 : isLargeTablet ? 48 : isTablet ? 44 : 40;
+const controlsGap = isTV ? 140 : isLargeTablet ? 110 : isTablet ? 90 : 70;
const controlsTranslateY = isTV ? -48 : isLargeTablet ? -42 : isTablet ? -36 : -30;
const skipTextFont = isTV ? 14 : isLargeTablet ? 13 : isTablet ? 12 : 12;
const sliderBottom = isTV ? 60 : isLargeTablet ? 50 : isTablet ? 45 : 35;