mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 20:34:37 +03:00
Movie scene sort (#1325)
* Add movie_scene_number sort order * Sort movie scenes by scene number by default
This commit is contained in:
@@ -673,6 +673,9 @@ func (qb *sceneQueryBuilder) setSceneSort(query *queryBuilder, findFilter *model
|
||||
sort := findFilter.GetSort("title")
|
||||
direction := findFilter.GetDirection()
|
||||
switch sort {
|
||||
case "movie_scene_number":
|
||||
query.join(moviesScenesTable, "movies_join", "scenes.id")
|
||||
query.sortAndPagination += fmt.Sprintf(" ORDER BY movies_join.scene_index %s", getSortDirection(direction))
|
||||
case "tag_count":
|
||||
query.sortAndPagination += getCountSort(sceneTable, scenesTagsTable, sceneIDColumn, direction)
|
||||
case "performer_count":
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
* Added scene queue.
|
||||
|
||||
### 🎨 Improvements
|
||||
* Sort movie scenes by scene number by default.
|
||||
* Support http request headers in scrapers.
|
||||
* Sort performers by gender in scene/image/gallery cards and details.
|
||||
* Add popover buttons for scenes/images/galleries on performer/studio/tag cards.
|
||||
|
||||
@@ -42,7 +42,9 @@ export const MovieScenesPanel: React.FC<IMovieScenesPanel> = ({ movie }) => {
|
||||
}
|
||||
|
||||
if (movie && movie.id) {
|
||||
return <SceneList filterHook={filterHook} />;
|
||||
return (
|
||||
<SceneList filterHook={filterHook} defaultSort="movie_scene_number" />
|
||||
);
|
||||
}
|
||||
return <></>;
|
||||
};
|
||||
|
||||
@@ -23,11 +23,13 @@ import { SceneCardsGrid } from "./SceneCardsGrid";
|
||||
|
||||
interface ISceneList {
|
||||
filterHook?: (filter: ListFilterModel) => ListFilterModel;
|
||||
defaultSort?: string;
|
||||
persistState?: PersistanceLevel.ALL;
|
||||
}
|
||||
|
||||
export const SceneList: React.FC<ISceneList> = ({
|
||||
filterHook,
|
||||
defaultSort,
|
||||
persistState,
|
||||
}) => {
|
||||
const history = useHistory();
|
||||
@@ -83,6 +85,7 @@ export const SceneList: React.FC<ISceneList> = ({
|
||||
zoomable: true,
|
||||
selectable: true,
|
||||
otherOperations,
|
||||
defaultSort,
|
||||
renderContent,
|
||||
renderEditDialog: renderEditScenesDialog,
|
||||
renderDeleteDialog,
|
||||
|
||||
@@ -88,6 +88,7 @@ export enum PersistanceLevel {
|
||||
interface IListHookOptions<T, E> {
|
||||
persistState?: PersistanceLevel;
|
||||
persistanceKey?: string;
|
||||
defaultSort?: string;
|
||||
filterHook?: (filter: ListFilterModel) => ListFilterModel;
|
||||
zoomable?: boolean;
|
||||
selectable?: boolean;
|
||||
@@ -431,7 +432,11 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
|
||||
const persistanceKey = options.persistanceKey ?? options.filterMode;
|
||||
|
||||
const [filter, setFilter] = useState<ListFilterModel>(
|
||||
new ListFilterModel(options.filterMode, queryString.parse(location.search))
|
||||
new ListFilterModel(
|
||||
options.filterMode,
|
||||
queryString.parse(location.search),
|
||||
options.defaultSort
|
||||
)
|
||||
);
|
||||
|
||||
const updateInterfaceConfig = useCallback(
|
||||
|
||||
@@ -111,11 +111,15 @@ export class ListFilterModel {
|
||||
return new CriterionOption(Criterion.getLabel(criterion), criterion);
|
||||
}
|
||||
|
||||
public constructor(filterMode: FilterMode, rawParms?: ParsedQuery<string>) {
|
||||
public constructor(
|
||||
filterMode: FilterMode,
|
||||
rawParms?: ParsedQuery<string>,
|
||||
defaultSort?: string
|
||||
) {
|
||||
const params = rawParms as IQueryParameters;
|
||||
switch (filterMode) {
|
||||
case FilterMode.Scenes:
|
||||
this.sortBy = "date";
|
||||
this.sortBy = defaultSort ?? "date";
|
||||
this.sortByOptions = [
|
||||
"title",
|
||||
"path",
|
||||
@@ -131,6 +135,7 @@ export class ListFilterModel {
|
||||
"tag_count",
|
||||
"performer_count",
|
||||
"random",
|
||||
"movie_scene_number",
|
||||
];
|
||||
this.displayModeOptions = [
|
||||
DisplayMode.Grid,
|
||||
@@ -159,7 +164,7 @@ export class ListFilterModel {
|
||||
];
|
||||
break;
|
||||
case FilterMode.Images:
|
||||
this.sortBy = "path";
|
||||
this.sortBy = defaultSort ?? "path";
|
||||
this.sortByOptions = [
|
||||
"title",
|
||||
"path",
|
||||
@@ -189,7 +194,7 @@ export class ListFilterModel {
|
||||
];
|
||||
break;
|
||||
case FilterMode.Performers: {
|
||||
this.sortBy = "name";
|
||||
this.sortBy = defaultSort ?? "name";
|
||||
this.sortByOptions = [
|
||||
"name",
|
||||
"height",
|
||||
@@ -239,7 +244,7 @@ export class ListFilterModel {
|
||||
break;
|
||||
}
|
||||
case FilterMode.Studios:
|
||||
this.sortBy = "name";
|
||||
this.sortBy = defaultSort ?? "name";
|
||||
this.sortByOptions = [
|
||||
"name",
|
||||
"scenes_count",
|
||||
@@ -259,7 +264,7 @@ export class ListFilterModel {
|
||||
];
|
||||
break;
|
||||
case FilterMode.Movies:
|
||||
this.sortBy = "name";
|
||||
this.sortBy = defaultSort ?? "name";
|
||||
this.sortByOptions = ["name", "scenes_count", "random"];
|
||||
this.displayModeOptions = [DisplayMode.Grid];
|
||||
this.criterionOptions = [
|
||||
@@ -270,7 +275,7 @@ export class ListFilterModel {
|
||||
];
|
||||
break;
|
||||
case FilterMode.Galleries:
|
||||
this.sortBy = "path";
|
||||
this.sortBy = defaultSort ?? "path";
|
||||
this.sortByOptions = [
|
||||
"path",
|
||||
"file_mod_time",
|
||||
@@ -302,7 +307,7 @@ export class ListFilterModel {
|
||||
];
|
||||
break;
|
||||
case FilterMode.SceneMarkers:
|
||||
this.sortBy = "title";
|
||||
this.sortBy = defaultSort ?? "title";
|
||||
this.sortByOptions = [
|
||||
"title",
|
||||
"seconds",
|
||||
@@ -319,7 +324,7 @@ export class ListFilterModel {
|
||||
];
|
||||
break;
|
||||
case FilterMode.Tags:
|
||||
this.sortBy = "name";
|
||||
this.sortBy = defaultSort ?? "name";
|
||||
// scene markers count has been disabled for now due to performance
|
||||
// issues
|
||||
this.sortByOptions = [
|
||||
|
||||
Reference in New Issue
Block a user