Create a section in the history panel to reset scene activity (#5168)

Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
Ian McKenzie 2024-08-28 20:34:22 -07:00 committed by GitHub
parent 68738bd227
commit 96fdd94a01
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 184 additions and 1 deletions

View file

@ -276,6 +276,13 @@ type Mutation {
"Sets the resume time point (if provided) and adds the provided duration to the scene's play duration"
sceneSaveActivity(id: ID!, resume_time: Float, playDuration: Float): Boolean!
"Resets the resume time point and play duration"
sceneResetActivity(
id: ID!
reset_resume: Boolean
reset_duration: Boolean
): Boolean!
"Increments the play count for the scene. Returns the new play count value."
sceneIncrementPlayCount(id: ID!): Int!
@deprecated(reason: "Use sceneAddPlay instead")

View file

@ -847,6 +847,24 @@ func (r *mutationResolver) SceneSaveActivity(ctx context.Context, id string, res
return ret, nil
}
func (r *mutationResolver) SceneResetActivity(ctx context.Context, id string, resetResume *bool, resetDuration *bool) (ret bool, err error) {
sceneID, err := strconv.Atoi(id)
if err != nil {
return false, fmt.Errorf("converting id: %w", err)
}
if err := r.withTxn(ctx, func(ctx context.Context) error {
qb := r.repository.Scene
ret, err = qb.ResetActivity(ctx, sceneID, utils.IsTrue(resetResume), utils.IsTrue(resetDuration))
return err
}); err != nil {
return false, err
}
return ret, nil
}
// deprecated
func (r *mutationResolver) SceneIncrementPlayCount(ctx context.Context, id string) (ret int, err error) {
sceneID, err := strconv.Atoi(id)

View file

@ -1267,6 +1267,27 @@ func (_m *SceneReaderWriter) QueryCount(ctx context.Context, sceneFilter *models
return r0, r1
}
// ResetActivity provides a mock function with given fields: ctx, sceneID, resetResume, resetDuration
func (_m *SceneReaderWriter) ResetActivity(ctx context.Context, sceneID int, resetResume bool, resetDuration bool) (bool, error) {
ret := _m.Called(ctx, sceneID, resetResume, resetDuration)
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context, int, bool, bool) bool); ok {
r0 = rf(ctx, sceneID, resetResume, resetDuration)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int, bool, bool) error); ok {
r1 = rf(ctx, sceneID, resetResume, resetDuration)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ResetO provides a mock function with given fields: ctx, id
func (_m *SceneReaderWriter) ResetO(ctx context.Context, id int) (int, error) {
ret := _m.Called(ctx, id)

View file

@ -137,6 +137,7 @@ type SceneWriter interface {
OHistoryWriter
ViewHistoryWriter
SaveActivity(ctx context.Context, sceneID int, resumeTime *float64, playDuration *float64) (bool, error)
ResetActivity(ctx context.Context, sceneID int, resetResume bool, resetDuration bool) (bool, error)
}
// SceneReaderWriter provides all scene methods.

View file

@ -1234,6 +1234,30 @@ func (qb *SceneStore) SaveActivity(ctx context.Context, id int, resumeTime *floa
return true, nil
}
func (qb *SceneStore) ResetActivity(ctx context.Context, id int, resetResume bool, resetDuration bool) (bool, error) {
if err := qb.tableMgr.checkIDExists(ctx, id); err != nil {
return false, err
}
record := goqu.Record{}
if resetResume {
record["resume_time"] = 0.0
}
if resetDuration {
record["play_duration"] = 0.0
}
if len(record) > 0 {
if err := qb.tableMgr.updateByID(ctx, id, record); err != nil {
return false, err
}
}
return true, nil
}
func (qb *SceneStore) GetURLs(ctx context.Context, sceneID int) ([]string, error) {
return scenesURLsTableMgr.get(ctx, sceneID)
}

View file

@ -34,6 +34,18 @@ mutation SceneSaveActivity(
)
}
mutation SceneResetActivity(
$id: ID!
$reset_resume: Boolean!
$reset_duration: Boolean!
) {
sceneResetActivity(
id: $id
reset_resume: $reset_resume
reset_duration: $reset_duration
)
}
mutation SceneAddPlay($id: ID!, $times: [Timestamp!]) {
sceneAddPlay(id: $id, times: $times) {
count

View file

@ -18,8 +18,10 @@ import {
useSceneIncrementPlayCount,
useSceneResetO,
useSceneResetPlayCount,
useSceneResetActivity,
} from "src/core/StashService";
import * as GQL from "src/core/generated-graphql";
import { useToast } from "src/hooks/Toast";
import { TextField } from "src/utils/field";
import TextUtils from "src/utils/text";
@ -72,9 +74,19 @@ const History: React.FC<{
const HistoryMenu: React.FC<{
hasHistory: boolean;
showResetResumeDuration: boolean;
onAddDate: () => void;
onClearDates: () => void;
}> = ({ hasHistory, onAddDate, onClearDates }) => {
resetResume: () => void;
resetDuration: () => void;
}> = ({
hasHistory,
showResetResumeDuration,
onAddDate,
onClearDates,
resetResume,
resetDuration,
}) => {
const intl = useIntl();
return (
@ -101,6 +113,22 @@ const HistoryMenu: React.FC<{
<FormattedMessage id="actions.clear_date_data" />
</Dropdown.Item>
)}
{showResetResumeDuration && (
<Dropdown.Item
className="bg-secondary text-white"
onClick={() => resetResume()}
>
<FormattedMessage id="actions.reset_resume_time" />
</Dropdown.Item>
)}
{showResetResumeDuration && (
<Dropdown.Item
className="bg-secondary text-white"
onClick={() => resetDuration()}
>
<FormattedMessage id="actions.reset_play_duration" />
</Dropdown.Item>
)}
</Dropdown.Menu>
</Dropdown>
);
@ -142,6 +170,7 @@ interface ISceneHistoryProps {
export const SceneHistoryPanel: React.FC<ISceneHistoryProps> = ({ scene }) => {
const intl = useIntl();
const Toast = useToast();
const [dialogs, setDialogs] = React.useState({
playHistory: false,
@ -160,6 +189,8 @@ export const SceneHistoryPanel: React.FC<ISceneHistoryProps> = ({ scene }) => {
const [incrementOCount] = useSceneIncrementO(scene.id);
const [decrementOCount] = useSceneDecrementO(scene.id);
const [resetO] = useSceneResetO(scene.id);
const [resetResume] = useSceneResetActivity(scene.id, true, false);
const [resetDuration] = useSceneResetActivity(scene.id, false, true);
function dateStringToISOString(time: string) {
const date = TextUtils.stringToFuzzyDateTime(time);
@ -221,6 +252,52 @@ export const SceneHistoryPanel: React.FC<ISceneHistoryProps> = ({ scene }) => {
});
}
async function handleResetResume() {
try {
await resetResume({
variables: {
id: scene.id,
reset_resume: true,
reset_duration: false,
},
});
Toast.success(
intl.formatMessage(
{ id: "toast.updated_entity" },
{
entity: intl.formatMessage({ id: "scene" }).toLocaleLowerCase(),
}
)
);
} catch (e) {
Toast.error(e);
}
}
async function handleResetDuration() {
try {
await resetDuration({
variables: {
id: scene.id,
reset_resume: false,
reset_duration: true,
},
});
Toast.success(
intl.formatMessage(
{ id: "toast.updated_entity" },
{
entity: intl.formatMessage({ id: "scene" }).toLocaleLowerCase(),
}
)
);
} catch (e) {
Toast.error(e);
}
}
function maybeRenderDialogs() {
return (
<>
@ -296,8 +373,11 @@ export const SceneHistoryPanel: React.FC<ISceneHistoryProps> = ({ scene }) => {
</Button>
<HistoryMenu
hasHistory={playHistory.length > 0}
showResetResumeDuration={true}
onAddDate={() => setDialogPartial({ addPlay: true })}
onClearDates={() => setDialogPartial({ playHistory: true })}
resetResume={() => handleResetResume()}
resetDuration={() => handleResetDuration()}
/>
</span>
</h5>
@ -336,8 +416,11 @@ export const SceneHistoryPanel: React.FC<ISceneHistoryProps> = ({ scene }) => {
</Button>
<HistoryMenu
hasHistory={oHistory.length > 0}
showResetResumeDuration={false}
onAddDate={() => setDialogPartial({ addO: true })}
onClearDates={() => setDialogPartial({ oHistory: true })}
resetResume={() => handleResetResume()}
resetDuration={() => handleResetDuration()}
/>
</span>
</h5>

View file

@ -786,6 +786,21 @@ export const useSceneResetO = (id: string) =>
},
});
export const useSceneResetActivity = (
id: string,
reset_resume: boolean,
reset_duration: boolean
) =>
GQL.useSceneResetActivityMutation({
variables: { id, reset_resume, reset_duration },
update(cache, result) {
if (!result.data?.sceneResetActivity) return;
evictTypeFields(cache, sceneMutationImpactedTypeFields);
evictQueries(cache, sceneMutationImpactedQueries);
},
});
export const useSceneGenerateScreenshot = () =>
GQL.useSceneGenerateScreenshotMutation();

View file

@ -94,6 +94,8 @@
"remove_from_gallery": "Remove from Gallery",
"rename_gen_files": "Rename generated files",
"rescan": "Rescan",
"reset_play_duration": "Reset play duration",
"reset_resume_time": "Reset resume time",
"reset_cover": "Restore Default Cover",
"reshuffle": "Reshuffle",
"running": "running",