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
4 changes: 3 additions & 1 deletion src/components/Dropdown.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
align-items: center;
justify-content: space-between;
gap: dgg.$space-2;
white-space: nowrap;
}

&-value {
Expand Down Expand Up @@ -73,7 +74,8 @@
}

.settings-dropdown {
width: 180px;
width: max-content;
min-width: 180px;
max-height: var(--radix-dropdown-menu-content-available-height, auto);
overflow-x: hidden;
overflow-y: auto;
Expand Down
4 changes: 4 additions & 0 deletions src/controls/bar/ControlsBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export default function ControlsBar({
isPlaying,
handlePlayPause,
showControls,
clickToPlayPause,

@TuringQuantrix TuringQuantrix Feb 19, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prop drilling here is not ideal but needed for the container and switch to share the same piece of state.

We could avoid this with a state library but that's likely overkill. Or using providers but that would break the current pattern we have for preferences.

onClickToPlayChange,
}) {
const { volume, isMuted, handleVolumeChange, handleMuteToggle } =
useVolumeControl(core);
Expand Down Expand Up @@ -72,6 +74,8 @@ export default function ControlsBar({
core={core}
container={barRef.current}
shouldShow={shouldShow}
clickToPlayPause={clickToPlayPause}
onClickToPlayChange={onClickToPlayChange}
/>

<FullscreenButton
Expand Down
9 changes: 8 additions & 1 deletion src/controls/container/Container.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useRef } from "react";
import ControlsBar from "../bar/ControlsBar.jsx";
import { useControlsVisibility } from "./useControlsVisibility.js";
import { usePlaybackControl } from "../play/usePlaybackControl.js";
import { usePreferences } from "../usePreferences.js";

export default function Container({ core, videoContainer }) {
const containerRef = useRef(null);
Expand All @@ -11,11 +12,15 @@ export default function Container({ core, videoContainer }) {
barRef,
);
const { isPlaying, handlePlayPause } = usePlaybackControl(core);
const { clickToPlayPause, setClickToPlayPause } = usePreferences();

const handleContainerClick = (e) => {
const isInControlsBar = barRef.current?.contains(e.target);
if (!isInControlsBar) {
handlePlayPause();
if (clickToPlayPause) {
handlePlayPause();
}
showControls();
}
};

Expand All @@ -33,6 +38,8 @@ export default function Container({ core, videoContainer }) {
isPlaying={isPlaying}
handlePlayPause={handlePlayPause}
showControls={showControls}
clickToPlayPause={clickToPlayPause}
onClickToPlayChange={setClickToPlayPause}
/>
</div>
);
Expand Down
15 changes: 15 additions & 0 deletions src/controls/settings/MainMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export default function MainMenu({
selectedQuality,
isIvsDebug,
onIvsDebugChange,
clickToPlayPause,
onClickToPlayChange,
}) {
return (
<>
Expand All @@ -25,6 +27,19 @@ export default function MainMenu({
</span>
</DropdownMenu.Item>

<DropdownMenu.Item
className="dropdown__item dropdown__item--nav"
onSelect={(e) => {
e.preventDefault();
}}
>
<span>Pause on Click</span>
<Switch
checked={clickToPlayPause}
onCheckedChange={onClickToPlayChange}
/>
</DropdownMenu.Item>

{process.env.NODE_ENV === "dev" && (
<DropdownMenu.Item
className="dropdown__item dropdown__item--nav"
Expand Down
10 changes: 9 additions & 1 deletion src/controls/settings/SettingsButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import { useSettings } from "./useSettings.js";
import { useQualitySelector } from "./useQualitySelector.js";
import { useIvsDebug } from "./useIvsDebug.js";

export default function SettingsButton({ core, container, shouldShow }) {
export default function SettingsButton({
core,
container,
shouldShow,
clickToPlayPause,
onClickToPlayChange,
}) {
const {
currentMenu,
handleOpenChange,
Expand Down Expand Up @@ -59,6 +65,8 @@ export default function SettingsButton({ core, container, shouldShow }) {
selectedQuality={selectedQuality}
isIvsDebug={isIvsDebug}
onIvsDebugChange={setIsIvsDebug}
clickToPlayPause={clickToPlayPause}
onClickToPlayChange={onClickToPlayChange}
/>
)}

Expand Down
33 changes: 33 additions & 0 deletions src/controls/usePreferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useState, useCallback } from "react";
const QUALITY_STORAGE_KEY = "kickstiny.preference.quality";
const VOLUME_STORAGE_KEY = "kickstiny.preference.volume";
const IVS_DEBUG_STORAGE_KEY = "kickstiny.preference.ivsDebug";
const CLICK_TO_PLAY_PAUSE_STORAGE_KEY = "kickstiny.preference.clickToPlayPause";

const DEFAULT_VOLUME = 100;

Expand Down Expand Up @@ -36,6 +37,21 @@ export function usePreferences() {
}
});

const [clickToPlayPause, setClickToPlayPauseState] = useState(() => {
try {
const stored = window.localStorage.getItem(
CLICK_TO_PLAY_PAUSE_STORAGE_KEY,
);
return stored !== null ? stored === "true" : true;
} catch (err) {
console.log(
"[Kickstiny] Unable to read click to play/pause preference",
err,
);
return true;
}
});

const setSavedQuality = useCallback((value) => {
try {
window.localStorage.setItem(QUALITY_STORAGE_KEY, value);
Expand Down Expand Up @@ -63,12 +79,29 @@ export function usePreferences() {
}
}, []);

const setClickToPlayPause = useCallback((value) => {
try {
window.localStorage.setItem(
CLICK_TO_PLAY_PAUSE_STORAGE_KEY,
value.toString(),
);
setClickToPlayPauseState(value);
} catch (err) {
console.log(
"[Kickstiny] Unable to persist click to play/pause preference",
err,
);
}
}, []);

return {
savedQuality,
savedVolume,
isIvsDebug,
clickToPlayPause,
setSavedQuality,
setSavedVolume,
setIsIvsDebug,
setClickToPlayPause,
};
}
Loading