Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2025-07-18 18:14:54 -05:00
parent b0c0b2c543
commit 941107f71d
5 changed files with 95 additions and 131 deletions

View File

@ -1,11 +1,11 @@
vite.svg,499162500000,699a02e0e68a579f687d364bbbe7633161244f35af068220aee37b1b33dfb3c7
index.html,1752878330027,5f203c00faf9fcc6e4b55be0b7ffa09282fc25dc3a7624baf25b7f6b43a06595
assets/swipe-back-g3JVbAcT.js,1752878330027,07abc4e68422342d6ba852b5cf93f08d37d594a29c0f8172471242ecbecacd47
assets/status-tap-C7usLbRw.js,1752878330027,faeed28b943d98d69228f71c2de4d6d63c177dc89155e315f482c62bf188ab19
assets/md.transition-B9W-8lgj.js,1752878330027,78652f50e41d7eff5a7fd00e89bb7e334a7374fa046174e39398a874d2c15fdc
assets/input-shims-DVm_rrIi.js,1752878330027,541fc90a960a383cbfa6fd1a75c3c9f17455f20614e82362aa83aeb89ee1cad1
assets/ios.transition-BIV5Z5Yc.js,1752878330027,b3510ecbd37d95bcce04934d72822d2f2b4d8c64fa0eff6262fa3b5bd20d4490
assets/index7-CZh37Dt9.js,1752878330027,036646be1f60e2114fbfd8a091b9e395ffa6ebf3188331bf54f576e62b393e8d
assets/index-B7vPvsG_.css,1752878330026,dbc57fb127dc9dde819d6ce6a258663f05013f29ec8905f282fe0087d44faaff
assets/focus-visible-supuXXMI.js,1752878330028,df9266429356671847fa2c8123e1564bae645f75df3094f0055c365fa2beae28
assets/index-D2b6SXwC.js,1752878330028,184886780ed3e8ccad54be62237fcb6fc9fefcec6110306d8f46184faebe69a9
index.html,1752880425099,3a9ff00c2fe67bff1d22bcc3cc350fe57f13ce7d96e0a0b0831b810c3ae4f383
assets/swipe-back-Cn4amxp6.js,1752880425099,293102efce4c0ebfa19f0113958fb5c5b38654c7e86ba695e2ab773ddf43825a
assets/status-tap-oQwstaDy.js,1752880425099,7801b76a10c12c5e19d0aaf9ad8966e816479d4ac5ec10270999be4a7c2c6609
assets/ios.transition-B2qy1sQZ.js,1752880425103,bc9e64075ed6cea888f669b0814ccc5b444a8e3c0e16e2faa2abc738c8bfe2f4
assets/md.transition-BsNej5jc.js,1752880425102,7aa0dc9dabdd1b380bed881251283974f97b2579f3c291326ace89d21e44a9eb
assets/input-shims-Do83niGH.js,1752880425099,6fe1bea0b42a375dccb36a672f85ce47ffba6269f2eff1d006e241c615733144
assets/index7-Tu8W0Nty.js,1752880425099,b5ab642da21be8211c86d4d3711e683192a1e7c5abe533782aa2735277254993
assets/focus-visible-supuXXMI.js,1752880425104,df9266429356671847fa2c8123e1564bae645f75df3094f0055c365fa2beae28
assets/index-CIlFtBnY.css,1752880425099,8249b3e00a114a2826408f28ca203fd75157b2e0c376588cc30170ebb5c4cb18
assets/index-C9D3R5Ik.js,1752880425100,e69e0e2e53eddc844e5f71df421c9bfd01f054468db1f97053cca0462591b178

View File

@ -64,16 +64,29 @@ const Navigation: React.FC = () => {
top: 0,
height: '100vh',
width: '256px',
backgroundColor: 'white',
backgroundColor: 'var(--ion-background-color)',
boxShadow: '2px 0 8px rgba(0,0,0,0.1)',
zIndex: 1000,
borderRight: '1px solid #e5e7eb',
borderRight: '1px solid var(--ion-border-color)',
overflowY: 'auto'
}}
>
<div style={{ padding: '16px', borderBottom: '1px solid #e5e7eb', backgroundColor: '#f9fafb' }}>
<h2 style={{ fontSize: '18px', fontWeight: '600', color: '#1f2937', margin: 0 }}>Karaoke</h2>
<p style={{ fontSize: '14px', color: '#6b7280', margin: '4px 0 0 0' }}>Singer: Matt</p>
<div style={{
padding: '16px',
borderBottom: '1px solid var(--ion-border-color)',
backgroundColor: 'var(--ion-color-light)'
}}>
<h2 style={{
fontSize: '18px',
fontWeight: '600',
color: 'var(--ion-text-color)',
margin: 0
}}>Karaoke</h2>
<p style={{
fontSize: '14px',
color: 'var(--ion-color-medium)',
margin: '4px 0 0 0'
}}>Singer: Matt</p>
</div>
<nav style={{ marginTop: '16px' }}>
{navItems.map((item) => (
@ -85,14 +98,14 @@ const Navigation: React.FC = () => {
alignItems: 'center',
padding: '12px 16px',
cursor: 'pointer',
backgroundColor: location.pathname === item.path ? '#dbeafe' : 'transparent',
color: location.pathname === item.path ? '#2563eb' : '#374151',
borderRight: location.pathname === item.path ? '2px solid #2563eb' : 'none',
backgroundColor: location.pathname === item.path ? 'var(--ion-color-primary-tint)' : 'transparent',
color: location.pathname === item.path ? 'var(--ion-color-primary)' : 'var(--ion-text-color)',
borderRight: location.pathname === item.path ? '2px solid var(--ion-color-primary)' : 'none',
transition: 'background-color 0.2s, color 0.2s'
}}
onMouseEnter={(e) => {
if (location.pathname !== item.path) {
e.currentTarget.style.backgroundColor = '#f3f4f6';
e.currentTarget.style.backgroundColor = 'var(--ion-color-light)';
}
}}
onMouseLeave={(e) => {
@ -115,7 +128,7 @@ const Navigation: React.FC = () => {
{/* Player Controls */}
<div style={{ marginTop: 'auto', padding: '16px' }}>
<PlayerControls variant="dark" />
<PlayerControls />
</div>
</div>
);
@ -135,9 +148,22 @@ const Navigation: React.FC = () => {
>
<IonHeader>
<IonToolbar>
<div style={{ padding: '16px', borderBottom: '1px solid #e5e7eb', backgroundColor: '#f9fafb' }}>
<h2 style={{ fontSize: '18px', fontWeight: '600', color: '#1f2937', margin: 0 }}>Karaoke</h2>
<p style={{ fontSize: '14px', color: '#6b7280', margin: '4px 0 0 0' }}>Singer: Matt</p>
<div style={{
padding: '16px',
borderBottom: '1px solid var(--ion-border-color)',
backgroundColor: 'var(--ion-color-light)'
}}>
<h2 style={{
fontSize: '18px',
fontWeight: '600',
color: 'var(--ion-text-color)',
margin: 0
}}>Karaoke</h2>
<p style={{
fontSize: '14px',
color: 'var(--ion-color-medium)',
margin: '4px 0 0 0'
}}>Singer: Matt</p>
</div>
</IonToolbar>
</IonHeader>
@ -158,7 +184,7 @@ const Navigation: React.FC = () => {
{/* Player Controls for Mobile */}
<div style={{ padding: '16px' }}>
<PlayerControls variant="dark" />
<PlayerControls />
</div>
</IonContent>
</IonMenu>

View File

@ -1,25 +1,23 @@
import React from 'react';
import { IonCard, IonCardContent, IonChip, IonIcon } from '@ionic/react';
import { playOutline, pauseOutline, stopOutline, play, pause, stop } from 'ionicons/icons';
import ActionButton from './ActionButton';
import { play, pause, stop } from 'ionicons/icons';
import { useAppSelector } from '../../redux';
import { selectPlayerState, selectIsAdmin, selectQueueLength } from '../../redux';
import { selectIsAdmin, selectPlayerState, selectQueueLength, selectControllerName } from '../../redux';
import { playerService } from '../../firebase/services';
import { selectControllerName } from '../../redux';
import { debugLog } from '../../utils/logger';
import { useToast } from '../../hooks/useToast';
import { PlayerState } from '../../types';
import ActionButton from './ActionButton';
import { useToast } from '../../hooks/useToast';
import { debugLog } from '../../utils/logger';
interface PlayerControlsProps {
className?: string;
variant?: 'light' | 'dark';
}
const PlayerControls: React.FC<PlayerControlsProps> = ({ className = '', variant = 'light' }) => {
const playerState = useAppSelector(selectPlayerState);
const PlayerControls: React.FC<PlayerControlsProps> = ({ className = '' }) => {
const isAdmin = useAppSelector(selectIsAdmin);
const controllerName = useAppSelector(selectControllerName);
const playerState = useAppSelector(selectPlayerState);
const queueLength = useAppSelector(selectQueueLength);
const controllerName = useAppSelector(selectControllerName);
const { showSuccess, showError } = useToast();
// Debug logging
@ -85,92 +83,12 @@ const PlayerControls: React.FC<PlayerControlsProps> = ({ className = '', variant
}
};
const getStatusText = () => {
switch (currentState) {
case PlayerState.playing:
return 'Currently Playing';
case PlayerState.paused:
return 'Currently Paused';
default:
return 'Currently Stopped';
}
};
// Dark mode variant
if (variant === 'dark') {
return (
<div className={`bg-black text-white ${className}`}>
{/* Status Text */}
<h3 className="text-lg font-bold">{getStatusText()}</h3>
{/* Control Buttons */}
<div>
{currentState === PlayerState.playing ? (
<div
className="flex items-center cursor-pointer hover:bg-gray-800"
style={{ padding: '12px 0px' }}
onClick={handlePause}
>
<IonIcon
icon={pauseOutline}
style={{
marginRight: '12px',
fontSize: '24px'
}}
/>
<span style={{ fontWeight: '500' }}>Pause</span>
</div>
) : (
<div
className="flex items-center cursor-pointer hover:bg-gray-800"
style={{ padding: '12px 0px' }}
onClick={handlePlay}
>
<IonIcon
icon={playOutline}
style={{
marginRight: '12px',
fontSize: '24px'
}}
/>
<span style={{ fontWeight: '500' }}>Play</span>
</div>
)}
{currentState !== PlayerState.stopped && (
<div
className="flex items-center cursor-pointer hover:bg-gray-800"
style={{ padding: '12px 0px' }}
onClick={handleStop}
>
<IonIcon
icon={stopOutline}
style={{
marginRight: '12px',
fontSize: '24px'
}}
/>
<span style={{ fontWeight: '500' }}>Stop</span>
</div>
)}
</div>
{!hasSongsInQueue && (
<div style={{ padding: '12px 0px' }} className="text-xs text-gray-400">
Add songs to queue to enable playback controls
</div>
)}
</div>
);
}
// Light mode variant (original)
return (
<IonCard className={className}>
<IonCardContent>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<h3 className="text-lg font-medium text-gray-900">Player Controls</h3>
<h3 className="text-lg font-medium">Player Controls</h3>
<IonChip color={getStateColor()}>
{currentState}
</IonChip>
@ -208,7 +126,7 @@ const PlayerControls: React.FC<PlayerControlsProps> = ({ className = '', variant
)}
</div>
<div className="mt-3 text-xs text-gray-500 text-center">
<div className="mt-3 text-xs text-center">
Admin controls - Only visible to admin users
{!hasSongsInQueue && (
<div className="mt-1 text-orange-600">

View File

@ -11,11 +11,26 @@
@import '@ionic/react/css/flex-utils.css';
@import '@ionic/react/css/display.css';
/* Dark mode support - system preference */
@import '@ionic/react/css/palettes/dark.system.css';
/* Tailwind CSS - comes after Ionic to avoid overriding essential Ionic styles */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Dark mode detection */
@media (prefers-color-scheme: dark) {
:root {
--ion-color-primary: #3880ff;
--ion-color-primary-rgb: 56, 128, 255;
--ion-color-primary-contrast: #ffffff;
--ion-color-primary-contrast-rgb: 255, 255, 255;
--ion-color-primary-shade: #3171e0;
--ion-color-primary-tint: #4c8dff;
}
}
/* Ensure menu button is visible */
ion-menu-button {
--color: var(--ion-color-primary);
@ -36,7 +51,7 @@ ion-menu {
/* Ensure modal content is visible */
ion-modal ion-content {
--background: var(--ion-background-color, #ffffff);
--background: var(--ion-background-color);
}
ion-modal ion-list {
@ -45,7 +60,7 @@ ion-modal ion-list {
/* Ensure content is visible and properly styled */
ion-content {
--background: var(--ion-background-color, #ffffff);
--background: var(--ion-background-color);
}
ion-list {
@ -55,7 +70,7 @@ ion-list {
/* Ensure items are properly displayed */
ion-item {
--background: transparent;
--color: var(--ion-text-color, #000000);
--color: var(--ion-text-color);
}
/* Settings page specific styling */
@ -107,7 +122,7 @@ ion-modal .ion-input-label,
ion-modal ion-label {
font-weight: bold !important;
font-size: 1rem !important;
color: #111827 !important;
color: var(--ion-text-color) !important;
margin-bottom: 0.5rem !important;
display: block !important;
}
@ -123,7 +138,7 @@ ion-modal ion-button {
.bold-label {
font-weight: bold !important;
font-size: 1rem !important;
color: #111827 !important;
color: var(--ion-text-color) !important;
margin-bottom: 0.5rem !important;
display: block !important;
}
@ -131,27 +146,25 @@ ion-modal ion-button {
/* Bold song title styling */
.bold-title {
font-weight: bold !important;
color: #111827 !important;
color: var(--ion-text-color) !important;
}
/* Override Ionic label text color for song titles */
ion-item ion-label .bold-title {
color: #111827 !important;
color: var(--ion-text-color) !important;
}
/* Input field styling to match search box */
.visible-input {
border: 1px solid #d1d5db !important;
border: 1px solid var(--ion-border-color, #d1d5db) !important;
border-radius: 8px !important;
padding: 0 12px !important;
background: #ffffff !important;
background: var(--ion-background-color) !important;
}
.visible-input ion-input {
border: 1px solid #d1d5db !important;
border: 1px solid var(--ion-border-color, #d1d5db) !important;
border-radius: 8px !important;
padding: 0 12px !important;
background: #ffffff !important;
background: var(--ion-background-color) !important;
}

View File

@ -6,8 +6,15 @@ import App from './App.tsx'
import { Provider } from 'react-redux';
import { store } from './redux/store';
// Initialize Ionic React
setupIonicReact();
// Initialize Ionic React with dark mode support
setupIonicReact({
mode: 'ios', // Use iOS mode for consistent styling
innerHTMLTemplatesEnabled: true,
// Enable automatic dark mode detection
_forceStatusbarPadding: false,
// Enable dark mode
animated: true,
});
createRoot(document.getElementById('root')!).render(
<StrictMode>