mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 12:54:38 +03:00
Fix issues navigating scene queue (#4325)
* Fix issues navigating between queue scenes * Fix queue next/previous button display * Autplay when clicking scene in queue * Sticky queue controls
This commit is contained in:
@@ -32,7 +32,7 @@ export interface IPlaylistViewer {
|
||||
export const QueueViewer: React.FC<IPlaylistViewer> = ({
|
||||
scenes,
|
||||
currentID,
|
||||
start,
|
||||
start = 0,
|
||||
continue: continuePlaylist = false,
|
||||
hasMoreScenes,
|
||||
setContinue,
|
||||
@@ -47,7 +47,7 @@ export const QueueViewer: React.FC<IPlaylistViewer> = ({
|
||||
const [lessLoading, setLessLoading] = useState(false);
|
||||
const [moreLoading, setMoreLoading] = useState(false);
|
||||
|
||||
const currentIndex = scenes?.findIndex((s) => s.id === currentID);
|
||||
const currentIndex = scenes?.findIndex((s) => s.id === currentID) ?? 0;
|
||||
|
||||
useEffect(() => {
|
||||
setLessLoading(false);
|
||||
@@ -119,7 +119,7 @@ export const QueueViewer: React.FC<IPlaylistViewer> = ({
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{(currentIndex ?? 0) > 0 ? (
|
||||
{currentIndex > 0 || start > 1 ? (
|
||||
<Button
|
||||
className="minimal"
|
||||
variant="secondary"
|
||||
@@ -130,7 +130,7 @@ export const QueueViewer: React.FC<IPlaylistViewer> = ({
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{(currentIndex ?? 0) < (scenes ?? []).length - 1 ? (
|
||||
{currentIndex < (scenes ?? []).length - 1 || hasMoreScenes ? (
|
||||
<Button
|
||||
className="minimal"
|
||||
variant="secondary"
|
||||
@@ -151,7 +151,7 @@ export const QueueViewer: React.FC<IPlaylistViewer> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div id="queue-content">
|
||||
{(start ?? 0) > 1 ? (
|
||||
{start > 1 ? (
|
||||
<div className="d-flex justify-content-center">
|
||||
<Button onClick={() => lessClicked()} disabled={lessLoading}>
|
||||
{!lessLoading ? (
|
||||
|
||||
@@ -84,7 +84,7 @@ interface IProps {
|
||||
onDelete: () => void;
|
||||
continuePlaylist: boolean;
|
||||
loadScene: (sceneID: string) => void;
|
||||
queueHasMoreScenes: () => boolean;
|
||||
queueHasMoreScenes: boolean;
|
||||
onQueueMoreScenes: () => void;
|
||||
onQueueLessScenes: () => void;
|
||||
queueStart: number;
|
||||
@@ -450,7 +450,7 @@ const ScenePage: React.FC<IProps> = ({
|
||||
onPrevious={onQueuePrevious}
|
||||
onRandom={onQueueRandom}
|
||||
start={queueStart}
|
||||
hasMoreScenes={queueHasMoreScenes()}
|
||||
hasMoreScenes={queueHasMoreScenes}
|
||||
onLessScenes={onQueueLessScenes}
|
||||
onMoreScenes={onQueueMoreScenes}
|
||||
/>
|
||||
@@ -594,9 +594,10 @@ const SceneLoader: React.FC<RouteComponentProps<ISceneParams>> = ({
|
||||
const [queueStart, setQueueStart] = useState(1);
|
||||
|
||||
const autoplay = queryParams.get("autoplay") === "true";
|
||||
const currentQueueIndex = queueScenes
|
||||
? queueScenes.findIndex((s) => s.id === id)
|
||||
: -1;
|
||||
const currentQueueIndex = useMemo(
|
||||
() => (queueScenes ? queueScenes.findIndex((s) => s.id === id) : -1),
|
||||
[queueScenes, id]
|
||||
);
|
||||
|
||||
function getSetTimestamp(fn: (value: number) => void) {
|
||||
_setTimestamp.current = fn;
|
||||
@@ -656,14 +657,16 @@ const SceneLoader: React.FC<RouteComponentProps<ISceneParams>> = ({
|
||||
const newScenes = (scenes as QueuedScene[]).concat(queueScenes);
|
||||
setQueueScenes(newScenes);
|
||||
setQueueStart(newStart);
|
||||
|
||||
return scenes;
|
||||
}
|
||||
|
||||
function queueHasMoreScenes() {
|
||||
const queueHasMoreScenes = useMemo(() => {
|
||||
return queueStart + queueScenes.length - 1 < queueTotal;
|
||||
}
|
||||
}, [queueStart, queueScenes, queueTotal]);
|
||||
|
||||
async function onQueueMoreScenes() {
|
||||
if (!sceneQueue.query || !queueHasMoreScenes()) {
|
||||
if (!sceneQueue.query || !queueHasMoreScenes) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -677,6 +680,7 @@ const SceneLoader: React.FC<RouteComponentProps<ISceneParams>> = ({
|
||||
const newScenes = queueScenes.concat(scenes as QueuedScene[]);
|
||||
setQueueScenes(newScenes);
|
||||
// don't change queue start
|
||||
return scenes;
|
||||
}
|
||||
|
||||
function loadScene(sceneID: string, autoPlay?: boolean, newPage?: number) {
|
||||
@@ -701,19 +705,42 @@ const SceneLoader: React.FC<RouteComponentProps<ISceneParams>> = ({
|
||||
}
|
||||
}
|
||||
|
||||
function onQueueNext() {
|
||||
async function onQueueNext() {
|
||||
if (!queueScenes) return;
|
||||
|
||||
if (currentQueueIndex >= 0 && currentQueueIndex < queueScenes.length - 1) {
|
||||
loadScene(queueScenes[currentQueueIndex + 1].id);
|
||||
loadScene(queueScenes[currentQueueIndex + 1].id, true);
|
||||
} else {
|
||||
// if we're at the end of the queue, load more scenes
|
||||
if (
|
||||
currentQueueIndex >= 0 &&
|
||||
currentQueueIndex === queueScenes.length - 1 &&
|
||||
queueHasMoreScenes
|
||||
) {
|
||||
const loadedScenes = await onQueueMoreScenes();
|
||||
if (loadedScenes && loadedScenes.length > 0) {
|
||||
// set the page to the next page
|
||||
const newPage = (sceneQueue.query?.currentPage ?? 0) + 1;
|
||||
loadScene(loadedScenes[0].id, true, newPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onQueuePrevious() {
|
||||
async function onQueuePrevious() {
|
||||
if (!queueScenes) return;
|
||||
|
||||
if (currentQueueIndex > 0) {
|
||||
loadScene(queueScenes[currentQueueIndex - 1].id);
|
||||
loadScene(queueScenes[currentQueueIndex - 1].id, true);
|
||||
} else {
|
||||
// if we're at the beginning of the queue, load the previous page
|
||||
if (currentQueueIndex === 0 && queueStart > 1) {
|
||||
const loadedScenes = await onQueueLessScenes();
|
||||
if (loadedScenes && loadedScenes.length > 0) {
|
||||
const newPage = (sceneQueue.query?.currentPage ?? 0) - 1;
|
||||
loadScene(loadedScenes[loadedScenes.length - 1].id, true, newPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -746,29 +773,24 @@ const SceneLoader: React.FC<RouteComponentProps<ISceneParams>> = ({
|
||||
|
||||
// load the next scene if we're continuing
|
||||
if (continuePlaylist) {
|
||||
if (
|
||||
currentQueueIndex >= 0 &&
|
||||
currentQueueIndex < queueScenes.length - 1
|
||||
) {
|
||||
loadScene(queueScenes[currentQueueIndex + 1].id, true);
|
||||
}
|
||||
onQueueNext();
|
||||
}
|
||||
}
|
||||
|
||||
function onNext() {
|
||||
if (!queueScenes) return;
|
||||
function getScenePage(sceneID: string) {
|
||||
if (!sceneQueue.query) return;
|
||||
|
||||
if (currentQueueIndex >= 0 && currentQueueIndex < queueScenes.length - 1) {
|
||||
loadScene(queueScenes[currentQueueIndex + 1].id, true);
|
||||
}
|
||||
// find the page that the scene is on
|
||||
const index = queueScenes.findIndex((s) => s.id === sceneID);
|
||||
|
||||
if (index === -1) return;
|
||||
|
||||
const perPage = sceneQueue.query.itemsPerPage;
|
||||
return Math.floor((index + queueStart - 1) / perPage) + 1;
|
||||
}
|
||||
|
||||
function onPrevious() {
|
||||
if (!queueScenes) return;
|
||||
|
||||
if (currentQueueIndex > 0) {
|
||||
loadScene(queueScenes[currentQueueIndex - 1].id, true);
|
||||
}
|
||||
function onSceneClicked(sceneID: string) {
|
||||
loadScene(sceneID, true, getScenePage(sceneID));
|
||||
}
|
||||
|
||||
if (!scene) {
|
||||
@@ -789,7 +811,7 @@ const SceneLoader: React.FC<RouteComponentProps<ISceneParams>> = ({
|
||||
onQueuePrevious={onQueuePrevious}
|
||||
onQueueRandom={onQueueRandom}
|
||||
continuePlaylist={continuePlaylist}
|
||||
loadScene={loadScene}
|
||||
loadScene={onSceneClicked}
|
||||
queueHasMoreScenes={queueHasMoreScenes}
|
||||
onQueueLessScenes={onQueueLessScenes}
|
||||
onQueueMoreScenes={onQueueMoreScenes}
|
||||
@@ -807,8 +829,8 @@ const SceneLoader: React.FC<RouteComponentProps<ISceneParams>> = ({
|
||||
initialTimestamp={initialTimestamp}
|
||||
sendSetTimestamp={getSetTimestamp}
|
||||
onComplete={onComplete}
|
||||
onNext={onNext}
|
||||
onPrevious={onPrevious}
|
||||
onNext={onQueueNext}
|
||||
onPrevious={onQueuePrevious}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -543,9 +543,13 @@ input[type="range"].blue-slider {
|
||||
#queue-viewer {
|
||||
.queue-controls {
|
||||
align-items: center;
|
||||
background-color: $body-bg;
|
||||
display: flex;
|
||||
flex: 0 1 auto;
|
||||
height: 30px;
|
||||
justify-content: space-between;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.thumbnail-container {
|
||||
|
||||
Reference in New Issue
Block a user