Add support for favorite Studios (#4675)

* Backend changes
* Add favorite icon to studio cards
* Add favorite button to studio page
* Add studio favorite filtering
This commit is contained in:
WithoutPants
2024-03-14 11:17:44 +11:00
committed by GitHub
parent e5929389b4
commit 8c454582c7
25 changed files with 185 additions and 52 deletions

View File

@@ -18,6 +18,7 @@ type Studio struct {
CreatedAt json.JSONTime `json:"created_at,omitempty"`
UpdatedAt json.JSONTime `json:"updated_at,omitempty"`
Rating int `json:"rating,omitempty"`
Favorite bool `json:"favorite,omitempty"`
Details string `json:"details,omitempty"`
Aliases []string `json:"aliases,omitempty"`
StashIDs []models.StashID `json:"stash_ids,omitempty"`

View File

@@ -14,6 +14,7 @@ type Studio struct {
UpdatedAt time.Time `json:"updated_at"`
// Rating expressed in 1-100 scale
Rating *int `json:"rating"`
Favorite bool `json:"favorite"`
Details string `json:"details"`
IgnoreAutoTag bool `json:"ignore_auto_tag"`
@@ -37,6 +38,7 @@ type StudioPartial struct {
ParentID OptionalInt
// Rating expressed in 1-100 scale
Rating OptionalInt
Favorite OptionalBool
Details OptionalString
CreatedAt OptionalTime
UpdatedAt OptionalTime

View File

@@ -16,6 +16,8 @@ type StudioFilterType struct {
IsMissing *string `json:"is_missing"`
// Filter by rating expressed as 1-100
Rating100 *IntCriterionInput `json:"rating100"`
// Filter by favorite
Favorite *bool `json:"favorite"`
// Filter by scene count
SceneCount *IntCriterionInput `json:"scene_count"`
// Filter by image count
@@ -44,6 +46,7 @@ type StudioCreateInput struct {
Image *string `json:"image"`
StashIds []StashID `json:"stash_ids"`
Rating100 *int `json:"rating100"`
Favorite *bool `json:"favorite"`
Details *string `json:"details"`
Aliases []string `json:"aliases"`
IgnoreAutoTag *bool `json:"ignore_auto_tag"`
@@ -58,6 +61,7 @@ type StudioUpdateInput struct {
Image *string `json:"image"`
StashIds []StashID `json:"stash_ids"`
Rating100 *int `json:"rating100"`
Favorite *bool `json:"favorite"`
Details *string `json:"details"`
Aliases []string `json:"aliases"`
IgnoreAutoTag *bool `json:"ignore_auto_tag"`

View File

@@ -30,7 +30,7 @@ const (
dbConnTimeout = 30
)
var appSchemaVersion uint = 55
var appSchemaVersion uint = 56
//go:embed migrations/*.sql
var migrationsBox embed.FS

View File

@@ -0,0 +1 @@
ALTER TABLE `studios` ADD COLUMN `favorite` boolean not null default '0';

View File

@@ -1610,6 +1610,11 @@ func createStudioFromModel(ctx context.Context, sqb *sqlite.StudioStore, studio
return nil
}
func getStudioBoolValue(index int) bool {
index = index % 2
return index == 1
}
// createStudios creates n studios with plain Name and o studios with camel cased NaMe included
func createStudios(ctx context.Context, n int, o int) error {
sqb := db.Studio
@@ -1630,6 +1635,7 @@ func createStudios(ctx context.Context, n int, o int) error {
studio := models.Studio{
Name: name,
URL: getStudioStringValue(index, urlField),
Favorite: getStudioBoolValue(index),
IgnoreAutoTag: getIgnoreAutoTag(i),
}
// only add aliases for some scenes

View File

@@ -36,6 +36,7 @@ type studioRow struct {
UpdatedAt Timestamp `db:"updated_at"`
// expressed as 1-100
Rating null.Int `db:"rating"`
Favorite bool `db:"favorite"`
Details zero.String `db:"details"`
IgnoreAutoTag bool `db:"ignore_auto_tag"`
@@ -51,6 +52,7 @@ func (r *studioRow) fromStudio(o models.Studio) {
r.CreatedAt = Timestamp{Timestamp: o.CreatedAt}
r.UpdatedAt = Timestamp{Timestamp: o.UpdatedAt}
r.Rating = intFromPtr(o.Rating)
r.Favorite = o.Favorite
r.Details = zero.StringFrom(o.Details)
r.IgnoreAutoTag = o.IgnoreAutoTag
}
@@ -64,6 +66,7 @@ func (r *studioRow) resolve() *models.Studio {
CreatedAt: r.CreatedAt.Timestamp,
UpdatedAt: r.UpdatedAt.Timestamp,
Rating: nullIntPtr(r.Rating),
Favorite: r.Favorite,
Details: r.Details.String,
IgnoreAutoTag: r.IgnoreAutoTag,
}
@@ -82,6 +85,7 @@ func (r *studioRowRecord) fromPartial(o models.StudioPartial) {
r.setTimestamp("created_at", o.CreatedAt)
r.setTimestamp("updated_at", o.UpdatedAt)
r.setNullInt("rating", o.Rating)
r.setBool("favorite", o.Favorite)
r.setNullString("details", o.Details)
r.setBool("ignore_auto_tag", o.IgnoreAutoTag)
}
@@ -496,6 +500,7 @@ func (qb *StudioStore) makeFilter(ctx context.Context, studioFilter *models.Stud
query.handleCriterion(ctx, stringCriterionHandler(studioFilter.Details, studioTable+".details"))
query.handleCriterion(ctx, stringCriterionHandler(studioFilter.URL, studioTable+".url"))
query.handleCriterion(ctx, intCriterionHandler(studioFilter.Rating100, studioTable+".rating", nil))
query.handleCriterion(ctx, boolCriterionHandler(studioFilter.Favorite, studioTable+".favorite", nil))
query.handleCriterion(ctx, boolCriterionHandler(studioFilter.IgnoreAutoTag, studioTable+".ignore_auto_tag", nil))
query.handleCriterion(ctx, criterionHandlerFunc(func(ctx context.Context, f *filterBuilder) {

View File

@@ -24,6 +24,7 @@ func ToJSON(ctx context.Context, reader FinderImageStashIDGetter, studio *models
Name: studio.Name,
URL: studio.URL,
Details: studio.Details,
Favorite: studio.Favorite,
IgnoreAutoTag: studio.IgnoreAutoTag,
CreatedAt: json.JSONTime{Time: studio.CreatedAt},
UpdatedAt: json.JSONTime{Time: studio.UpdatedAt},

View File

@@ -62,6 +62,7 @@ func createFullStudio(id int, parentID int) models.Studio {
Name: studioName,
URL: url,
Details: details,
Favorite: true,
CreatedAt: createTime,
UpdatedAt: updateTime,
Rating: &rating,
@@ -89,9 +90,10 @@ func createEmptyStudio(id int) models.Studio {
func createFullJSONStudio(parentStudio, image string, aliases []string) *jsonschema.Studio {
return &jsonschema.Studio{
Name: studioName,
URL: url,
Details: details,
Name: studioName,
URL: url,
Details: details,
Favorite: true,
CreatedAt: json.JSONTime{
Time: createTime,
},

View File

@@ -144,6 +144,7 @@ func studioJSONtoStudio(studioJSON jsonschema.Studio) models.Studio {
URL: studioJSON.URL,
Aliases: models.NewRelatedStrings(studioJSON.Aliases),
Details: studioJSON.Details,
Favorite: studioJSON.Favorite,
IgnoreAutoTag: studioJSON.IgnoreAutoTag,
CreatedAt: studioJSON.CreatedAt.GetTime(),
UpdatedAt: studioJSON.UpdatedAt.GetTime(),