diff --git a/graphql/schema/types/gallery.graphql b/graphql/schema/types/gallery.graphql index 18301a647..1c87a4b86 100644 --- a/graphql/schema/types/gallery.graphql +++ b/graphql/schema/types/gallery.graphql @@ -9,6 +9,10 @@ type Gallery { details: String rating: Int organized: Boolean! + created_at: Time! + updated_at: Time! + file_mod_time: Time + scenes: [Scene!]! studio: Studio image_count: Int! diff --git a/graphql/schema/types/image.graphql b/graphql/schema/types/image.graphql index d3beab439..9445aec92 100644 --- a/graphql/schema/types/image.graphql +++ b/graphql/schema/types/image.graphql @@ -6,6 +6,9 @@ type Image { o_counter: Int organized: Boolean! path: String! + created_at: Time! + updated_at: Time! + file_mod_time: Time file: ImageFileType! # Resolver paths: ImagePathsType! # Resolver diff --git a/graphql/schema/types/movie.graphql b/graphql/schema/types/movie.graphql index cc25b9e02..3fb156311 100644 --- a/graphql/schema/types/movie.graphql +++ b/graphql/schema/types/movie.graphql @@ -11,6 +11,8 @@ type Movie { director: String synopsis: String url: String + created_at: Time! + updated_at: Time! front_image_path: String # Resolver back_image_path: String # Resolver diff --git a/graphql/schema/types/performer.graphql b/graphql/schema/types/performer.graphql index 1e1fe3c03..35c9eb36d 100644 --- a/graphql/schema/types/performer.graphql +++ b/graphql/schema/types/performer.graphql @@ -40,6 +40,8 @@ type Performer { death_date: String hair_color: String weight: Int + created_at: Time! + updated_at: Time! } input PerformerCreateInput { diff --git a/graphql/schema/types/scene-marker.graphql b/graphql/schema/types/scene-marker.graphql index ce9fc5945..f29380f26 100644 --- a/graphql/schema/types/scene-marker.graphql +++ b/graphql/schema/types/scene-marker.graphql @@ -5,6 +5,8 @@ type SceneMarker { seconds: Float! primary_tag: Tag! tags: [Tag!]! + created_at: Time! + updated_at: Time! """The path to stream this marker""" stream: String! # Resolver diff --git a/graphql/schema/types/scene.graphql b/graphql/schema/types/scene.graphql index 1d8d12ba8..a1ec113d7 100644 --- a/graphql/schema/types/scene.graphql +++ b/graphql/schema/types/scene.graphql @@ -39,6 +39,9 @@ type Scene { path: String! phash: String interactive: Boolean! + created_at: Time! + updated_at: Time! + file_mod_time: Time file: SceneFileType! # Resolver paths: ScenePathsType! # Resolver diff --git a/graphql/schema/types/studio.graphql b/graphql/schema/types/studio.graphql index 26d280f06..364b7ad42 100644 --- a/graphql/schema/types/studio.graphql +++ b/graphql/schema/types/studio.graphql @@ -13,6 +13,8 @@ type Studio { stash_ids: [StashID!]! rating: Int details: String + created_at: Time! + updated_at: Time! } input StudioCreateInput { diff --git a/graphql/schema/types/tag.graphql b/graphql/schema/types/tag.graphql index 1b855fd36..ec47a7f1d 100644 --- a/graphql/schema/types/tag.graphql +++ b/graphql/schema/types/tag.graphql @@ -1,6 +1,8 @@ type Tag { id: ID! name: String! + created_at: Time! + updated_at: Time! image_path: String # Resolver scene_count: Int # Resolver diff --git a/pkg/api/resolver_model_gallery.go b/pkg/api/resolver_model_gallery.go index a0d5cf7c5..e564440a3 100644 --- a/pkg/api/resolver_model_gallery.go +++ b/pkg/api/resolver_model_gallery.go @@ -2,6 +2,7 @@ package api import ( "context" + "time" "github.com/stashapp/stash/pkg/image" "github.com/stashapp/stash/pkg/models" @@ -153,3 +154,15 @@ func (r *galleryResolver) ImageCount(ctx context.Context, obj *models.Gallery) ( return ret, nil } + +func (r *galleryResolver) CreatedAt(ctx context.Context, obj *models.Gallery) (*time.Time, error) { + return &obj.CreatedAt.Timestamp, nil +} + +func (r *galleryResolver) UpdatedAt(ctx context.Context, obj *models.Gallery) (*time.Time, error) { + return &obj.UpdatedAt.Timestamp, nil +} + +func (r *galleryResolver) FileModTime(ctx context.Context, obj *models.Gallery) (*time.Time, error) { + return &obj.FileModTime.Timestamp, nil +} diff --git a/pkg/api/resolver_model_image.go b/pkg/api/resolver_model_image.go index 893198f1c..854f0e338 100644 --- a/pkg/api/resolver_model_image.go +++ b/pkg/api/resolver_model_image.go @@ -2,6 +2,7 @@ package api import ( "context" + "time" "github.com/stashapp/stash/pkg/api/urlbuilders" "github.com/stashapp/stash/pkg/image" @@ -91,3 +92,15 @@ func (r *imageResolver) Performers(ctx context.Context, obj *models.Image) (ret return ret, nil } + +func (r *imageResolver) CreatedAt(ctx context.Context, obj *models.Image) (*time.Time, error) { + return &obj.CreatedAt.Timestamp, nil +} + +func (r *imageResolver) UpdatedAt(ctx context.Context, obj *models.Image) (*time.Time, error) { + return &obj.UpdatedAt.Timestamp, nil +} + +func (r *imageResolver) FileModTime(ctx context.Context, obj *models.Image) (*time.Time, error) { + return &obj.FileModTime.Timestamp, nil +} diff --git a/pkg/api/resolver_model_movie.go b/pkg/api/resolver_model_movie.go index be105eb9e..6bfa759f7 100644 --- a/pkg/api/resolver_model_movie.go +++ b/pkg/api/resolver_model_movie.go @@ -2,6 +2,7 @@ package api import ( "context" + "time" "github.com/stashapp/stash/pkg/api/urlbuilders" "github.com/stashapp/stash/pkg/models" @@ -123,3 +124,11 @@ func (r *movieResolver) SceneCount(ctx context.Context, obj *models.Movie) (ret return &res, err } + +func (r *movieResolver) CreatedAt(ctx context.Context, obj *models.Movie) (*time.Time, error) { + return &obj.CreatedAt.Timestamp, nil +} + +func (r *movieResolver) UpdatedAt(ctx context.Context, obj *models.Movie) (*time.Time, error) { + return &obj.UpdatedAt.Timestamp, nil +} diff --git a/pkg/api/resolver_model_performer.go b/pkg/api/resolver_model_performer.go index a5f8e4811..d27cce38b 100644 --- a/pkg/api/resolver_model_performer.go +++ b/pkg/api/resolver_model_performer.go @@ -2,6 +2,7 @@ package api import ( "context" + "time" "github.com/stashapp/stash/pkg/api/urlbuilders" "github.com/stashapp/stash/pkg/gallery" @@ -245,3 +246,11 @@ func (r *performerResolver) Weight(ctx context.Context, obj *models.Performer) ( } return nil, nil } + +func (r *performerResolver) CreatedAt(ctx context.Context, obj *models.Performer) (*time.Time, error) { + return &obj.CreatedAt.Timestamp, nil +} + +func (r *performerResolver) UpdatedAt(ctx context.Context, obj *models.Performer) (*time.Time, error) { + return &obj.UpdatedAt.Timestamp, nil +} diff --git a/pkg/api/resolver_model_scene.go b/pkg/api/resolver_model_scene.go index 986e40eda..de8222ef0 100644 --- a/pkg/api/resolver_model_scene.go +++ b/pkg/api/resolver_model_scene.go @@ -2,6 +2,7 @@ package api import ( "context" + "time" "github.com/stashapp/stash/pkg/api/urlbuilders" "github.com/stashapp/stash/pkg/manager/config" @@ -215,3 +216,15 @@ func (r *sceneResolver) Phash(ctx context.Context, obj *models.Scene) (*string, } return nil, nil } + +func (r *sceneResolver) CreatedAt(ctx context.Context, obj *models.Scene) (*time.Time, error) { + return &obj.CreatedAt.Timestamp, nil +} + +func (r *sceneResolver) UpdatedAt(ctx context.Context, obj *models.Scene) (*time.Time, error) { + return &obj.UpdatedAt.Timestamp, nil +} + +func (r *sceneResolver) FileModTime(ctx context.Context, obj *models.Scene) (*time.Time, error) { + return &obj.FileModTime.Timestamp, nil +} diff --git a/pkg/api/resolver_model_scene_marker.go b/pkg/api/resolver_model_scene_marker.go index 98073871b..84bd5c9f2 100644 --- a/pkg/api/resolver_model_scene_marker.go +++ b/pkg/api/resolver_model_scene_marker.go @@ -2,6 +2,7 @@ package api import ( "context" + "time" "github.com/stashapp/stash/pkg/api/urlbuilders" "github.com/stashapp/stash/pkg/models" @@ -56,3 +57,11 @@ func (r *sceneMarkerResolver) Preview(ctx context.Context, obj *models.SceneMark sceneID := int(obj.SceneID.Int64) return urlbuilders.NewSceneURLBuilder(baseURL, sceneID).GetSceneMarkerStreamPreviewURL(obj.ID), nil } + +func (r *sceneMarkerResolver) CreatedAt(ctx context.Context, obj *models.SceneMarker) (*time.Time, error) { + return &obj.CreatedAt.Timestamp, nil +} + +func (r *sceneMarkerResolver) UpdatedAt(ctx context.Context, obj *models.SceneMarker) (*time.Time, error) { + return &obj.UpdatedAt.Timestamp, nil +} diff --git a/pkg/api/resolver_model_studio.go b/pkg/api/resolver_model_studio.go index 89d2c2bea..5123fe8b1 100644 --- a/pkg/api/resolver_model_studio.go +++ b/pkg/api/resolver_model_studio.go @@ -2,6 +2,7 @@ package api import ( "context" + "time" "github.com/stashapp/stash/pkg/api/urlbuilders" "github.com/stashapp/stash/pkg/gallery" @@ -131,3 +132,11 @@ func (r *studioResolver) Details(ctx context.Context, obj *models.Studio) (*stri } return nil, nil } + +func (r *studioResolver) CreatedAt(ctx context.Context, obj *models.Studio) (*time.Time, error) { + return &obj.CreatedAt.Timestamp, nil +} + +func (r *studioResolver) UpdatedAt(ctx context.Context, obj *models.Studio) (*time.Time, error) { + return &obj.UpdatedAt.Timestamp, nil +} diff --git a/pkg/api/resolver_model_tag.go b/pkg/api/resolver_model_tag.go index a4fb2cc4e..a4ec3c46c 100644 --- a/pkg/api/resolver_model_tag.go +++ b/pkg/api/resolver_model_tag.go @@ -2,6 +2,7 @@ package api import ( "context" + "time" "github.com/stashapp/stash/pkg/api/urlbuilders" "github.com/stashapp/stash/pkg/gallery" @@ -74,3 +75,11 @@ func (r *tagResolver) ImagePath(ctx context.Context, obj *models.Tag) (*string, imagePath := urlbuilders.NewTagURLBuilder(baseURL, obj).GetTagImageURL() return &imagePath, nil } + +func (r *tagResolver) CreatedAt(ctx context.Context, obj *models.Tag) (*time.Time, error) { + return &obj.CreatedAt.Timestamp, nil +} + +func (r *tagResolver) UpdatedAt(ctx context.Context, obj *models.Tag) (*time.Time, error) { + return &obj.UpdatedAt.Timestamp, nil +} diff --git a/ui/v2.5/src/components/Changelog/versions/v080.md b/ui/v2.5/src/components/Changelog/versions/v080.md index 6df3f220f..d43c0190c 100644 --- a/ui/v2.5/src/components/Changelog/versions/v080.md +++ b/ui/v2.5/src/components/Changelog/versions/v080.md @@ -5,6 +5,7 @@ * Added [DLNA server](/settings?tab=dlna). ([#1364](https://github.com/stashapp/stash/pull/1364)) ### 🎨 Improvements +* Add `CreatedAt` and `UpdatedAt` (and `FileModTime` where applicable) to API objects. * Add Studios Performer filter criterion. ([#1405](https://github.com/stashapp/stash/pull/1405)) * Add `subtractDays` post-process scraper action. ([#1399](https://github.com/stashapp/stash/pull/1399)) * Skip scanning directories if path matches image and video exclude patterns. ([#1382](https://github.com/stashapp/stash/pull/1382)) diff --git a/ui/v2.5/src/components/Scenes/SceneDetails/PrimaryTags.tsx b/ui/v2.5/src/components/Scenes/SceneDetails/PrimaryTags.tsx index 2f78a5d33..eca9ef68b 100644 --- a/ui/v2.5/src/components/Scenes/SceneDetails/PrimaryTags.tsx +++ b/ui/v2.5/src/components/Scenes/SceneDetails/PrimaryTags.tsx @@ -16,7 +16,7 @@ export const PrimaryTags: React.FC = ({ }) => { if (!sceneMarkers?.length) return
; - const primaries: Record = {}; + const primaries: Record = {}; const primaryTags: Record = {}; sceneMarkers.forEach((m) => { if (primaryTags[m.primary_tag.id]) primaryTags[m.primary_tag.id].push(m); diff --git a/ui/v2.5/src/components/Scenes/SceneListTable.tsx b/ui/v2.5/src/components/Scenes/SceneListTable.tsx index 97496b440..2f77d94f6 100644 --- a/ui/v2.5/src/components/Scenes/SceneListTable.tsx +++ b/ui/v2.5/src/components/Scenes/SceneListTable.tsx @@ -15,7 +15,7 @@ interface ISceneListTableProps { export const SceneListTable: React.FC = ( props: ISceneListTableProps ) => { - const renderTags = (tags: GQL.Tag[]) => + const renderTags = (tags: GQL.SlimTagDataFragment[]) => tags.map((tag) => (
{tag.name}
diff --git a/ui/v2.5/src/components/Shared/MultiSet.tsx b/ui/v2.5/src/components/Shared/MultiSet.tsx index ed004431e..c99d63cd3 100644 --- a/ui/v2.5/src/components/Shared/MultiSet.tsx +++ b/ui/v2.5/src/components/Shared/MultiSet.tsx @@ -7,7 +7,7 @@ import { FilterSelect } from "./Select"; type ValidTypes = | GQL.SlimPerformerDataFragment - | GQL.Tag + | GQL.SlimTagDataFragment | GQL.SlimStudioDataFragment | GQL.SlimMovieDataFragment; diff --git a/ui/v2.5/src/components/Shared/Select.tsx b/ui/v2.5/src/components/Shared/Select.tsx index e89840bca..5858740ab 100644 --- a/ui/v2.5/src/components/Shared/Select.tsx +++ b/ui/v2.5/src/components/Shared/Select.tsx @@ -19,7 +19,7 @@ import { TextUtils } from "src/utils"; export type ValidTypes = | GQL.SlimPerformerDataFragment - | GQL.Tag + | GQL.SlimTagDataFragment | GQL.SlimStudioDataFragment | GQL.SlimMovieDataFragment; type Option = { value: string; label: string };