diff --git a/src/App.tsx b/src/App.tsx
index 893164a..4d9b705 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -26,7 +26,7 @@ function App() {
} />
} />
} />
- } />
+ } />
} />
} />
} />
diff --git a/src/components/presentations/PresentationMode.tsx b/src/components/presentations/PresentationMode.tsx
index df425f2..0fcaf2b 100644
--- a/src/components/presentations/PresentationMode.tsx
+++ b/src/components/presentations/PresentationMode.tsx
@@ -10,15 +10,29 @@ import { loggers } from '../../utils/logger.ts';
import './PresentationMode.css';
export const PresentationMode: React.FC = () => {
- const { presentationId } = useParams<{ presentationId: string }>();
+ const { presentationId, slideNumber } = useParams<{
+ presentationId: string;
+ slideNumber: string;
+ }>();
const navigate = useNavigate();
const [presentation, setPresentation] = useState(null);
const [theme, setTheme] = useState(null);
- const [currentSlideIndex, setCurrentSlideIndex] = useState(0);
+ const [currentSlideIndex, setCurrentSlideIndex] = useState(
+ slideNumber ? parseInt(slideNumber, 10) - 1 : 0
+ );
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
+ // Navigate to specific slide and update URL
+ const goToSlide = (slideIndex: number) => {
+ if (!presentation) return;
+
+ const clampedIndex = Math.max(0, Math.min(slideIndex, presentation.slides.length - 1));
+ setCurrentSlideIndex(clampedIndex);
+ navigate(`/presentations/${presentationId}/present/${clampedIndex + 1}`, { replace: true });
+ };
+
// Keyboard navigation handler
const handleKeyPress = useCallback((event: KeyboardEvent) => {
if (!presentation || presentation.slides.length === 0) return;
@@ -28,24 +42,22 @@ export const PresentationMode: React.FC = () => {
case 'Space':
case 'Enter':
event.preventDefault();
- setCurrentSlideIndex(prev =>
- Math.min(prev + 1, presentation.slides.length - 1)
- );
+ goToSlide(currentSlideIndex + 1);
break;
case 'ArrowLeft':
event.preventDefault();
- setCurrentSlideIndex(prev => Math.max(prev - 1, 0));
+ goToSlide(currentSlideIndex - 1);
break;
case 'Home':
event.preventDefault();
- setCurrentSlideIndex(0);
+ goToSlide(0);
break;
case 'End':
event.preventDefault();
- setCurrentSlideIndex(presentation.slides.length - 1);
+ goToSlide(presentation.slides.length - 1);
break;
case 'Escape':
@@ -55,14 +67,24 @@ export const PresentationMode: React.FC = () => {
default:
// Handle number keys for direct slide navigation
- const slideNumber = parseInt(event.key);
- if (slideNumber >= 1 && slideNumber <= presentation.slides.length) {
+ const slideNum = parseInt(event.key);
+ if (slideNum >= 1 && slideNum <= presentation.slides.length) {
event.preventDefault();
- setCurrentSlideIndex(slideNumber - 1);
+ goToSlide(slideNum - 1);
}
break;
}
- }, [presentation, navigate, presentationId]);
+ }, [presentation, currentSlideIndex, goToSlide]);
+
+ // Sync current slide index with URL parameter
+ useEffect(() => {
+ if (slideNumber) {
+ const newIndex = parseInt(slideNumber, 10) - 1;
+ if (newIndex >= 0 && newIndex !== currentSlideIndex) {
+ setCurrentSlideIndex(newIndex);
+ }
+ }
+ }, [slideNumber]);
// Set up keyboard listeners
useEffect(() => {
diff --git a/src/components/presentations/PresentationViewer.tsx b/src/components/presentations/PresentationViewer.tsx
index 25b9c27..49d335d 100644
--- a/src/components/presentations/PresentationViewer.tsx
+++ b/src/components/presentations/PresentationViewer.tsx
@@ -86,7 +86,7 @@ export const PresentationViewer: React.FC = () => {
const enterPresentationMode = () => {
if (!presentation) return;
- navigate(`/presentations/${presentationId}/present`);
+ navigate(`/presentations/${presentationId}/present/${currentSlideIndex + 1}`);
};
if (loading) {
diff --git a/src/components/presentations/PresentationsList.tsx b/src/components/presentations/PresentationsList.tsx
index 5e47cb6..ac8651b 100644
--- a/src/components/presentations/PresentationsList.tsx
+++ b/src/components/presentations/PresentationsList.tsx
@@ -213,7 +213,7 @@ export const PresentationsList: React.FC = () => {