import { Capacitor } from '@capacitor/core';
import { ScreenBrightness } from '@capacitor-community/screen-brightness';
import { VolumeControl } from 'capacitor-volume-control';
export function swipeControls(node, props = { enabled: true, immersePlayer: () => {} }) {
if (!props.enabled) return;
const isNative = Capacitor.isNativePlatform();
let brightness = 50;
let volume = 50; // Start at middle volume (range 0-100)
let startX = 0;
let startY = 0;
let isDragging = false;
let activeControl = null;
let timeoutId;
let updateTimeoutId;
const indicators = document.createElement('div');
indicators.className = 'swipe-control-indicators';
indicators.style.cssText = `
position: absolute;
bottom: 60px;
left: 50%;
transform: translateX(-50%);
display: flex;
align-items: center;
gap: 20px;
opacity: 0;
transition: opacity 0.3s ease;
pointer-events: none;
background-color: rgba(0, 0, 0, 0.6);
color: white;
padding: 8px 12px;
border-radius: 4px;
font-family: Arial, sans-serif;
font-size: 14px;
`;
indicators.innerHTML = `
100%
`;
node.style.position = 'relative';
node.appendChild(indicators);
const brightnessValue = indicators.querySelector('.brightness-value');
const volumeValue = indicators.querySelector('.volume-value');
function handleTouchStart(event) {
if (!props.enabled) return;
if (!isNative) return;
isDragging = true;
startX = event.touches[0].clientX;
startY = event.touches[0].clientY;
const rect = node.getBoundingClientRect();
activeControl = (event.touches[0].clientX - rect.left) < rect.width / 2 ? 'brightness' : 'volume';
}
function handleTouchMove(event) {
if (!props.enabled) return;
if (!isNative || !isDragging) return;
const currentY = event.touches[0].clientY;
const deltaY = startY - currentY;
const rect = node.getBoundingClientRect();
const sensitivity = 0.5 * (200 / rect.height);
if (activeControl === 'brightness') {
brightness = Math.max(0, Math.min(100, brightness + deltaY * sensitivity));
updateBrightness();
} else if (activeControl === 'volume') {
volume = Math.max(0, Math.min(100, volume + deltaY * sensitivity));
debouncedUpdateVolume();
}
showControlsIndicator();
startY = currentY;
}
function handleTouchEnd() {
if (!props.enabled) return;
isDragging = false;
activeControl = null;
}
async function updateBrightness() {
try {
await ScreenBrightness.setBrightness({ brightness: brightness / 100 });
brightnessValue.textContent = `${Math.round(brightness)}%`;
} catch (error) {
console.error('Error updating brightness:', error);
}
}
let lastVolume = 50;
const VOLUME_CHANGE_THRESHOLD = 1;
function debouncedUpdateVolume() {
clearTimeout(updateTimeoutId);
// Update UI immediately
volumeValue.textContent = `${Math.round(volume)}%`;
updateTimeoutId = setTimeout(async () => {
if (Math.abs(volume - lastVolume) >= VOLUME_CHANGE_THRESHOLD) {
try {
await VolumeControl.setVolume({ volume: Math.round(volume), showUI: false });
lastVolume = volume;
} catch (error) {
console.error('Error updating volume:', error);
// Retry logic
setTimeout(() => debouncedUpdateVolume(), 50);
}
}
}, 33);
}
function showControlsIndicator() {
indicators.style.opacity = '1';
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
indicators.style.opacity = '0';
props.immersePlayer();
}, 500);
}
node.addEventListener('touchstart', handleTouchStart);
node.addEventListener('touchmove', handleTouchMove, { passive: false });
node.addEventListener('touchend', handleTouchEnd);
async function init() {
if (isNative) {
try {
// const { brightness: currentBrightness } = await ScreenBrightness.getBrightness();
const { volume: currentVolume } = await VolumeControl.getVolume();
brightness = 50;
volume = currentVolume;
// updateBrightness();
brightnessValue.textContent = `50%`;
debouncedUpdateVolume();
} catch (error) {
console.error('Error initializing brightness and volume:', error);
}
}
}
init();
return {
destroy() {
node.removeEventListener('touchstart', handleTouchStart);
node.removeEventListener('touchmove', handleTouchMove);
node.removeEventListener('touchend', handleTouchEnd);
clearTimeout(timeoutId);
node.removeChild(indicators);
}
};
}