mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 04:14:39 +03:00
Merge branch 'master' into delete_scene
This commit is contained in:
@@ -4,8 +4,16 @@ fragment ConfigGeneralData on ConfigGeneralResult {
|
|||||||
generatedPath
|
generatedPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fragment ConfigInterfaceData on ConfigInterfaceResult {
|
||||||
|
css
|
||||||
|
cssEnabled
|
||||||
|
}
|
||||||
|
|
||||||
fragment ConfigData on ConfigResult {
|
fragment ConfigData on ConfigResult {
|
||||||
general {
|
general {
|
||||||
...ConfigGeneralData
|
...ConfigGeneralData
|
||||||
}
|
}
|
||||||
|
interface {
|
||||||
|
...ConfigInterfaceData
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,3 +3,9 @@ mutation ConfigureGeneral($input: ConfigGeneralInput!) {
|
|||||||
...ConfigGeneralData
|
...ConfigGeneralData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutation ConfigureInterface($input: ConfigInterfaceInput!) {
|
||||||
|
configureInterface(input: $input) {
|
||||||
|
...ConfigInterfaceData
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -92,6 +92,7 @@ type Mutation {
|
|||||||
|
|
||||||
"""Change general configuration options"""
|
"""Change general configuration options"""
|
||||||
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
|
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
|
||||||
|
configureInterface(input: ConfigInterfaceInput!): ConfigInterfaceResult!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Subscription {
|
type Subscription {
|
||||||
|
|||||||
@@ -16,7 +16,20 @@ type ConfigGeneralResult {
|
|||||||
generatedPath: String!
|
generatedPath: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input ConfigInterfaceInput {
|
||||||
|
"""Custom CSS"""
|
||||||
|
css: String
|
||||||
|
cssEnabled: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfigInterfaceResult {
|
||||||
|
"""Custom CSS"""
|
||||||
|
css: String
|
||||||
|
cssEnabled: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
"""All configuration settings"""
|
"""All configuration settings"""
|
||||||
type ConfigResult {
|
type ConfigResult {
|
||||||
general: ConfigGeneralResult!
|
general: ConfigGeneralResult!
|
||||||
|
interface: ConfigInterfaceResult!
|
||||||
}
|
}
|
||||||
@@ -3,10 +3,11 @@ package api
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/stashapp/stash/pkg/manager/config"
|
"github.com/stashapp/stash/pkg/manager/config"
|
||||||
"github.com/stashapp/stash/pkg/models"
|
"github.com/stashapp/stash/pkg/models"
|
||||||
"github.com/stashapp/stash/pkg/utils"
|
"github.com/stashapp/stash/pkg/utils"
|
||||||
"path/filepath"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *mutationResolver) ConfigureGeneral(ctx context.Context, input models.ConfigGeneralInput) (*models.ConfigGeneralResult, error) {
|
func (r *mutationResolver) ConfigureGeneral(ctx context.Context, input models.ConfigGeneralInput) (*models.ConfigGeneralResult, error) {
|
||||||
@@ -41,3 +42,23 @@ func (r *mutationResolver) ConfigureGeneral(ctx context.Context, input models.Co
|
|||||||
|
|
||||||
return makeConfigGeneralResult(), nil
|
return makeConfigGeneralResult(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) ConfigureInterface(ctx context.Context, input models.ConfigInterfaceInput) (*models.ConfigInterfaceResult, error) {
|
||||||
|
css := ""
|
||||||
|
|
||||||
|
if input.CSS != nil {
|
||||||
|
css = *input.CSS
|
||||||
|
}
|
||||||
|
|
||||||
|
config.SetCSS(css)
|
||||||
|
|
||||||
|
if input.CSSEnabled != nil {
|
||||||
|
config.Set(config.CSSEnabled, *input.CSSEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := config.Write(); err != nil {
|
||||||
|
return makeConfigInterfaceResult(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
return makeConfigInterfaceResult(), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/stashapp/stash/pkg/manager/config"
|
"github.com/stashapp/stash/pkg/manager/config"
|
||||||
"github.com/stashapp/stash/pkg/models"
|
"github.com/stashapp/stash/pkg/models"
|
||||||
"github.com/stashapp/stash/pkg/utils"
|
"github.com/stashapp/stash/pkg/utils"
|
||||||
@@ -21,7 +22,8 @@ func (r *queryResolver) Directories(ctx context.Context, path *string) ([]string
|
|||||||
|
|
||||||
func makeConfigResult() *models.ConfigResult {
|
func makeConfigResult() *models.ConfigResult {
|
||||||
return &models.ConfigResult{
|
return &models.ConfigResult{
|
||||||
General: makeConfigGeneralResult(),
|
General: makeConfigGeneralResult(),
|
||||||
|
Interface: makeConfigInterfaceResult(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,3 +34,12 @@ func makeConfigGeneralResult() *models.ConfigGeneralResult {
|
|||||||
GeneratedPath: config.GetGeneratedPath(),
|
GeneratedPath: config.GetGeneratedPath(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeConfigInterfaceResult() *models.ConfigInterfaceResult {
|
||||||
|
css := config.GetCSS()
|
||||||
|
cssEnabled := config.GetCSSEnabled()
|
||||||
|
return &models.ConfigInterfaceResult{
|
||||||
|
CSS: &css,
|
||||||
|
CSSEnabled: &cssEnabled,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,15 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime/debug"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/99designs/gqlgen/handler"
|
"github.com/99designs/gqlgen/handler"
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"github.com/go-chi/chi/middleware"
|
"github.com/go-chi/chi/middleware"
|
||||||
@@ -16,14 +25,6 @@ import (
|
|||||||
"github.com/stashapp/stash/pkg/manager/paths"
|
"github.com/stashapp/stash/pkg/manager/paths"
|
||||||
"github.com/stashapp/stash/pkg/models"
|
"github.com/stashapp/stash/pkg/models"
|
||||||
"github.com/stashapp/stash/pkg/utils"
|
"github.com/stashapp/stash/pkg/utils"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime/debug"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var uiBox *packr.Box
|
var uiBox *packr.Box
|
||||||
@@ -72,6 +73,21 @@ func Start() {
|
|||||||
r.Mount("/scene", sceneRoutes{}.Routes())
|
r.Mount("/scene", sceneRoutes{}.Routes())
|
||||||
r.Mount("/studio", studioRoutes{}.Routes())
|
r.Mount("/studio", studioRoutes{}.Routes())
|
||||||
|
|
||||||
|
r.HandleFunc("/css", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !config.GetCSSEnabled() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// search for custom.css in current directory, then $HOME/.stash
|
||||||
|
fn := config.GetCSSPath()
|
||||||
|
exists, _ := utils.FileExists(fn)
|
||||||
|
if !exists {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
http.ServeFile(w, r, fn)
|
||||||
|
})
|
||||||
|
|
||||||
// Serve the setup UI
|
// Serve the setup UI
|
||||||
r.HandleFunc("/setup*", func(w http.ResponseWriter, r *http.Request) {
|
r.HandleFunc("/setup*", func(w http.ResponseWriter, r *http.Request) {
|
||||||
ext := path.Ext(r.URL.Path)
|
ext := path.Ext(r.URL.Path)
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"github.com/stashapp/stash/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const Stash = "stash"
|
const Stash = "stash"
|
||||||
@@ -15,6 +18,8 @@ const Database = "database"
|
|||||||
const Host = "host"
|
const Host = "host"
|
||||||
const Port = "port"
|
const Port = "port"
|
||||||
|
|
||||||
|
const CSSEnabled = "cssEnabled"
|
||||||
|
|
||||||
func Set(key string, value interface{}) {
|
func Set(key string, value interface{}) {
|
||||||
viper.Set(key, value)
|
viper.Set(key, value)
|
||||||
}
|
}
|
||||||
@@ -51,6 +56,46 @@ func GetPort() int {
|
|||||||
return viper.GetInt(Port)
|
return viper.GetInt(Port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetCSSPath() string {
|
||||||
|
// search for custom.css in current directory, then $HOME/.stash
|
||||||
|
fn := "custom.css"
|
||||||
|
exists, _ := utils.FileExists(fn)
|
||||||
|
if !exists {
|
||||||
|
fn = "$HOME/.stash/" + fn
|
||||||
|
}
|
||||||
|
|
||||||
|
return fn
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCSS() string {
|
||||||
|
fn := GetCSSPath()
|
||||||
|
|
||||||
|
exists, _ := utils.FileExists(fn)
|
||||||
|
if !exists {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := ioutil.ReadFile(fn)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetCSS(css string) {
|
||||||
|
fn := GetCSSPath()
|
||||||
|
|
||||||
|
buf := []byte(css)
|
||||||
|
|
||||||
|
ioutil.WriteFile(fn, buf, 0777)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCSSEnabled() bool {
|
||||||
|
return viper.GetBool(CSSEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
func IsValid() bool {
|
func IsValid() bool {
|
||||||
setPaths := viper.IsSet(Stash) && viper.IsSet(Cache) && viper.IsSet(Generated) && viper.IsSet(Metadata)
|
setPaths := viper.IsSet(Stash) && viper.IsSet(Cache) && viper.IsSet(Generated) && viper.IsSet(Metadata)
|
||||||
// TODO: check valid paths
|
// TODO: check valid paths
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package manager
|
package manager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"net"
|
||||||
"github.com/fsnotify/fsnotify"
|
"sync"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/stashapp/stash/pkg/ffmpeg"
|
"github.com/stashapp/stash/pkg/ffmpeg"
|
||||||
@@ -10,8 +11,6 @@ import (
|
|||||||
"github.com/stashapp/stash/pkg/manager/config"
|
"github.com/stashapp/stash/pkg/manager/config"
|
||||||
"github.com/stashapp/stash/pkg/manager/paths"
|
"github.com/stashapp/stash/pkg/manager/paths"
|
||||||
"github.com/stashapp/stash/pkg/utils"
|
"github.com/stashapp/stash/pkg/utils"
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type singleton struct {
|
type singleton struct {
|
||||||
@@ -71,12 +70,15 @@ func initConfig() {
|
|||||||
// Set generated to the metadata path for backwards compat
|
// Set generated to the metadata path for backwards compat
|
||||||
viper.SetDefault(config.Generated, viper.GetString(config.Metadata))
|
viper.SetDefault(config.Generated, viper.GetString(config.Metadata))
|
||||||
|
|
||||||
|
// Disabling config watching due to race condition issue
|
||||||
|
// See: https://github.com/spf13/viper/issues/174
|
||||||
|
// Changes to the config outside the system will require a restart
|
||||||
// Watch for changes
|
// Watch for changes
|
||||||
viper.WatchConfig()
|
// viper.WatchConfig()
|
||||||
viper.OnConfigChange(func(e fsnotify.Event) {
|
// viper.OnConfigChange(func(e fsnotify.Event) {
|
||||||
fmt.Println("Config file changed:", e.Name)
|
// fmt.Println("Config file changed:", e.Name)
|
||||||
instance.refreshConfig()
|
// instance.refreshConfig()
|
||||||
})
|
// })
|
||||||
|
|
||||||
//viper.Set("stash", []string{"/", "/stuff"})
|
//viper.Set("stash", []string{"/", "/stuff"})
|
||||||
//viper.WriteConfig()
|
//viper.WriteConfig()
|
||||||
@@ -92,14 +94,14 @@ func initFlags() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func initEnvs() {
|
func initEnvs() {
|
||||||
viper.SetEnvPrefix("stash") // will be uppercased automatically
|
viper.SetEnvPrefix("stash") // will be uppercased automatically
|
||||||
viper.BindEnv("host") // STASH_HOST
|
viper.BindEnv("host") // STASH_HOST
|
||||||
viper.BindEnv("port") // STASH_PORT
|
viper.BindEnv("port") // STASH_PORT
|
||||||
viper.BindEnv("stash") // STASH_STASH
|
viper.BindEnv("stash") // STASH_STASH
|
||||||
viper.BindEnv("generated") // STASH_GENERATED
|
viper.BindEnv("generated") // STASH_GENERATED
|
||||||
viper.BindEnv("metadata") // STASH_METADATA
|
viper.BindEnv("metadata") // STASH_METADATA
|
||||||
viper.BindEnv("cache") // STASH_CACHE
|
viper.BindEnv("cache") // STASH_CACHE
|
||||||
}
|
}
|
||||||
|
|
||||||
func initFFMPEG() {
|
func initFFMPEG() {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ func (t *ScanTask) scanGallery() {
|
|||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
gallery, _ = qb.FindByChecksum(checksum, tx)
|
gallery, _ = qb.FindByChecksum(checksum, tx)
|
||||||
if gallery != nil {
|
if gallery != nil {
|
||||||
exists, _ := utils.FileExists(t.FilePath)
|
exists, _ := utils.FileExists(gallery.Path)
|
||||||
if exists {
|
if exists {
|
||||||
logger.Infof("%s already exists. Duplicate of %s ", t.FilePath, gallery.Path)
|
logger.Infof("%s already exists. Duplicate of %s ", t.FilePath, gallery.Path)
|
||||||
} else {
|
} else {
|
||||||
@@ -102,7 +102,7 @@ func (t *ScanTask) scanScene() {
|
|||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
if scene != nil {
|
if scene != nil {
|
||||||
exists, _ := utils.FileExists(t.FilePath)
|
exists, _ := utils.FileExists(scene.Path)
|
||||||
if exists {
|
if exists {
|
||||||
logger.Infof("%s already exists. Duplicate of %s ", t.FilePath, scene.Path)
|
logger.Infof("%s already exists. Duplicate of %s ", t.FilePath, scene.Path)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -56,8 +56,14 @@ type ComplexityRoot struct {
|
|||||||
Stashes func(childComplexity int) int
|
Stashes func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfigInterfaceResult struct {
|
||||||
|
CSS func(childComplexity int) int
|
||||||
|
CSSEnabled func(childComplexity int) int
|
||||||
|
}
|
||||||
|
|
||||||
ConfigResult struct {
|
ConfigResult struct {
|
||||||
General func(childComplexity int) int
|
General func(childComplexity int) int
|
||||||
|
Interface func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
FindGalleriesResultType struct {
|
FindGalleriesResultType struct {
|
||||||
@@ -107,6 +113,7 @@ type ComplexityRoot struct {
|
|||||||
|
|
||||||
Mutation struct {
|
Mutation struct {
|
||||||
ConfigureGeneral func(childComplexity int, input ConfigGeneralInput) int
|
ConfigureGeneral func(childComplexity int, input ConfigGeneralInput) int
|
||||||
|
ConfigureInterface func(childComplexity int, input ConfigInterfaceInput) int
|
||||||
PerformerCreate func(childComplexity int, input PerformerCreateInput) int
|
PerformerCreate func(childComplexity int, input PerformerCreateInput) int
|
||||||
PerformerDestroy func(childComplexity int, input PerformerDestroyInput) int
|
PerformerDestroy func(childComplexity int, input PerformerDestroyInput) int
|
||||||
PerformerUpdate func(childComplexity int, input PerformerUpdateInput) int
|
PerformerUpdate func(childComplexity int, input PerformerUpdateInput) int
|
||||||
@@ -300,6 +307,7 @@ type MutationResolver interface {
|
|||||||
TagUpdate(ctx context.Context, input TagUpdateInput) (*Tag, error)
|
TagUpdate(ctx context.Context, input TagUpdateInput) (*Tag, error)
|
||||||
TagDestroy(ctx context.Context, input TagDestroyInput) (bool, error)
|
TagDestroy(ctx context.Context, input TagDestroyInput) (bool, error)
|
||||||
ConfigureGeneral(ctx context.Context, input ConfigGeneralInput) (*ConfigGeneralResult, error)
|
ConfigureGeneral(ctx context.Context, input ConfigGeneralInput) (*ConfigGeneralResult, error)
|
||||||
|
ConfigureInterface(ctx context.Context, input ConfigInterfaceInput) (*ConfigInterfaceResult, error)
|
||||||
}
|
}
|
||||||
type PerformerResolver interface {
|
type PerformerResolver interface {
|
||||||
Name(ctx context.Context, obj *Performer) (*string, error)
|
Name(ctx context.Context, obj *Performer) (*string, error)
|
||||||
@@ -426,6 +434,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||||||
|
|
||||||
return e.complexity.ConfigGeneralResult.Stashes(childComplexity), true
|
return e.complexity.ConfigGeneralResult.Stashes(childComplexity), true
|
||||||
|
|
||||||
|
case "ConfigInterfaceResult.css":
|
||||||
|
if e.complexity.ConfigInterfaceResult.CSS == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.ConfigInterfaceResult.CSS(childComplexity), true
|
||||||
|
|
||||||
|
case "ConfigInterfaceResult.cssEnabled":
|
||||||
|
if e.complexity.ConfigInterfaceResult.CSSEnabled == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.ConfigInterfaceResult.CSSEnabled(childComplexity), true
|
||||||
|
|
||||||
case "ConfigResult.general":
|
case "ConfigResult.general":
|
||||||
if e.complexity.ConfigResult.General == nil {
|
if e.complexity.ConfigResult.General == nil {
|
||||||
break
|
break
|
||||||
@@ -433,6 +455,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||||||
|
|
||||||
return e.complexity.ConfigResult.General(childComplexity), true
|
return e.complexity.ConfigResult.General(childComplexity), true
|
||||||
|
|
||||||
|
case "ConfigResult.interface":
|
||||||
|
if e.complexity.ConfigResult.Interface == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.ConfigResult.Interface(childComplexity), true
|
||||||
|
|
||||||
case "FindGalleriesResultType.count":
|
case "FindGalleriesResultType.count":
|
||||||
if e.complexity.FindGalleriesResultType.Count == nil {
|
if e.complexity.FindGalleriesResultType.Count == nil {
|
||||||
break
|
break
|
||||||
@@ -592,6 +621,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||||||
|
|
||||||
return e.complexity.Mutation.ConfigureGeneral(childComplexity, args["input"].(ConfigGeneralInput)), true
|
return e.complexity.Mutation.ConfigureGeneral(childComplexity, args["input"].(ConfigGeneralInput)), true
|
||||||
|
|
||||||
|
case "Mutation.configureInterface":
|
||||||
|
if e.complexity.Mutation.ConfigureInterface == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
args, err := ec.field_Mutation_configureInterface_args(context.TODO(), rawArgs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Mutation.ConfigureInterface(childComplexity, args["input"].(ConfigInterfaceInput)), true
|
||||||
|
|
||||||
case "Mutation.performerCreate":
|
case "Mutation.performerCreate":
|
||||||
if e.complexity.Mutation.PerformerCreate == nil {
|
if e.complexity.Mutation.PerformerCreate == nil {
|
||||||
break
|
break
|
||||||
@@ -1895,6 +1936,7 @@ type Mutation {
|
|||||||
|
|
||||||
"""Change general configuration options"""
|
"""Change general configuration options"""
|
||||||
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
|
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
|
||||||
|
configureInterface(input: ConfigInterfaceInput!): ConfigInterfaceResult!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Subscription {
|
type Subscription {
|
||||||
@@ -1925,9 +1967,22 @@ type ConfigGeneralResult {
|
|||||||
generatedPath: String!
|
generatedPath: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input ConfigInterfaceInput {
|
||||||
|
"""Custom CSS"""
|
||||||
|
css: String
|
||||||
|
cssEnabled: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfigInterfaceResult {
|
||||||
|
"""Custom CSS"""
|
||||||
|
css: String
|
||||||
|
cssEnabled: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
"""All configuration settings"""
|
"""All configuration settings"""
|
||||||
type ConfigResult {
|
type ConfigResult {
|
||||||
general: ConfigGeneralResult!
|
general: ConfigGeneralResult!
|
||||||
|
interface: ConfigInterfaceResult!
|
||||||
}`},
|
}`},
|
||||||
&ast.Source{Name: "graphql/schema/types/filters.graphql", Input: `enum SortDirectionEnum {
|
&ast.Source{Name: "graphql/schema/types/filters.graphql", Input: `enum SortDirectionEnum {
|
||||||
ASC
|
ASC
|
||||||
@@ -2315,6 +2370,20 @@ func (ec *executionContext) field_Mutation_configureGeneral_args(ctx context.Con
|
|||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) field_Mutation_configureInterface_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
|
var err error
|
||||||
|
args := map[string]interface{}{}
|
||||||
|
var arg0 ConfigInterfaceInput
|
||||||
|
if tmp, ok := rawArgs["input"]; ok {
|
||||||
|
arg0, err = ec.unmarshalNConfigInterfaceInput2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigInterfaceInput(ctx, tmp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args["input"] = arg0
|
||||||
|
return args, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) field_Mutation_performerCreate_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
func (ec *executionContext) field_Mutation_performerCreate_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
var err error
|
var err error
|
||||||
args := map[string]interface{}{}
|
args := map[string]interface{}{}
|
||||||
@@ -2952,6 +3021,54 @@ func (ec *executionContext) _ConfigGeneralResult_generatedPath(ctx context.Conte
|
|||||||
return ec.marshalNString2string(ctx, field.Selections, res)
|
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _ConfigInterfaceResult_css(ctx context.Context, field graphql.CollectedField, obj *ConfigInterfaceResult) graphql.Marshaler {
|
||||||
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
|
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
||||||
|
rctx := &graphql.ResolverContext{
|
||||||
|
Object: "ConfigInterfaceResult",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
}
|
||||||
|
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||||
|
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||||
|
resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.CSS, nil
|
||||||
|
})
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*string)
|
||||||
|
rctx.Result = res
|
||||||
|
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _ConfigInterfaceResult_cssEnabled(ctx context.Context, field graphql.CollectedField, obj *ConfigInterfaceResult) graphql.Marshaler {
|
||||||
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
|
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
||||||
|
rctx := &graphql.ResolverContext{
|
||||||
|
Object: "ConfigInterfaceResult",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
}
|
||||||
|
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||||
|
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||||
|
resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.CSSEnabled, nil
|
||||||
|
})
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*bool)
|
||||||
|
rctx.Result = res
|
||||||
|
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||||
|
return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _ConfigResult_general(ctx context.Context, field graphql.CollectedField, obj *ConfigResult) graphql.Marshaler {
|
func (ec *executionContext) _ConfigResult_general(ctx context.Context, field graphql.CollectedField, obj *ConfigResult) graphql.Marshaler {
|
||||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
||||||
@@ -2979,6 +3096,33 @@ func (ec *executionContext) _ConfigResult_general(ctx context.Context, field gra
|
|||||||
return ec.marshalNConfigGeneralResult2ᚖgithubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigGeneralResult(ctx, field.Selections, res)
|
return ec.marshalNConfigGeneralResult2ᚖgithubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigGeneralResult(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _ConfigResult_interface(ctx context.Context, field graphql.CollectedField, obj *ConfigResult) graphql.Marshaler {
|
||||||
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
|
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
||||||
|
rctx := &graphql.ResolverContext{
|
||||||
|
Object: "ConfigResult",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
}
|
||||||
|
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||||
|
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||||
|
resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Interface, nil
|
||||||
|
})
|
||||||
|
if resTmp == nil {
|
||||||
|
if !ec.HasError(rctx) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*ConfigInterfaceResult)
|
||||||
|
rctx.Result = res
|
||||||
|
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||||
|
return ec.marshalNConfigInterfaceResult2ᚖgithubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigInterfaceResult(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _FindGalleriesResultType_count(ctx context.Context, field graphql.CollectedField, obj *FindGalleriesResultType) graphql.Marshaler {
|
func (ec *executionContext) _FindGalleriesResultType_count(ctx context.Context, field graphql.CollectedField, obj *FindGalleriesResultType) graphql.Marshaler {
|
||||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
||||||
@@ -4020,6 +4164,40 @@ func (ec *executionContext) _Mutation_configureGeneral(ctx context.Context, fiel
|
|||||||
return ec.marshalNConfigGeneralResult2ᚖgithubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigGeneralResult(ctx, field.Selections, res)
|
return ec.marshalNConfigGeneralResult2ᚖgithubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigGeneralResult(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Mutation_configureInterface(ctx context.Context, field graphql.CollectedField) graphql.Marshaler {
|
||||||
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
|
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
||||||
|
rctx := &graphql.ResolverContext{
|
||||||
|
Object: "Mutation",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: true,
|
||||||
|
}
|
||||||
|
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||||
|
rawArgs := field.ArgumentMap(ec.Variables)
|
||||||
|
args, err := ec.field_Mutation_configureInterface_args(ctx, rawArgs)
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
rctx.Args = args
|
||||||
|
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||||
|
resTmp := ec.FieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return ec.resolvers.Mutation().ConfigureInterface(rctx, args["input"].(ConfigInterfaceInput))
|
||||||
|
})
|
||||||
|
if resTmp == nil {
|
||||||
|
if !ec.HasError(rctx) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*ConfigInterfaceResult)
|
||||||
|
rctx.Result = res
|
||||||
|
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||||
|
return ec.marshalNConfigInterfaceResult2ᚖgithubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigInterfaceResult(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Performer_id(ctx context.Context, field graphql.CollectedField, obj *Performer) graphql.Marshaler {
|
func (ec *executionContext) _Performer_id(ctx context.Context, field graphql.CollectedField, obj *Performer) graphql.Marshaler {
|
||||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
|
||||||
@@ -8118,6 +8296,30 @@ func (ec *executionContext) unmarshalInputConfigGeneralInput(ctx context.Context
|
|||||||
return it, nil
|
return it, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalInputConfigInterfaceInput(ctx context.Context, v interface{}) (ConfigInterfaceInput, error) {
|
||||||
|
var it ConfigInterfaceInput
|
||||||
|
var asMap = v.(map[string]interface{})
|
||||||
|
|
||||||
|
for k, v := range asMap {
|
||||||
|
switch k {
|
||||||
|
case "css":
|
||||||
|
var err error
|
||||||
|
it.CSS, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
case "cssEnabled":
|
||||||
|
var err error
|
||||||
|
it.CSSEnabled, err = ec.unmarshalOBoolean2ᚖbool(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return it, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalInputFindFilterType(ctx context.Context, v interface{}) (FindFilterType, error) {
|
func (ec *executionContext) unmarshalInputFindFilterType(ctx context.Context, v interface{}) (FindFilterType, error) {
|
||||||
var it FindFilterType
|
var it FindFilterType
|
||||||
var asMap = v.(map[string]interface{})
|
var asMap = v.(map[string]interface{})
|
||||||
@@ -8967,6 +9169,32 @@ func (ec *executionContext) _ConfigGeneralResult(ctx context.Context, sel ast.Se
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var configInterfaceResultImplementors = []string{"ConfigInterfaceResult"}
|
||||||
|
|
||||||
|
func (ec *executionContext) _ConfigInterfaceResult(ctx context.Context, sel ast.SelectionSet, obj *ConfigInterfaceResult) graphql.Marshaler {
|
||||||
|
fields := graphql.CollectFields(ec.RequestContext, sel, configInterfaceResultImplementors)
|
||||||
|
|
||||||
|
out := graphql.NewFieldSet(fields)
|
||||||
|
var invalids uint32
|
||||||
|
for i, field := range fields {
|
||||||
|
switch field.Name {
|
||||||
|
case "__typename":
|
||||||
|
out.Values[i] = graphql.MarshalString("ConfigInterfaceResult")
|
||||||
|
case "css":
|
||||||
|
out.Values[i] = ec._ConfigInterfaceResult_css(ctx, field, obj)
|
||||||
|
case "cssEnabled":
|
||||||
|
out.Values[i] = ec._ConfigInterfaceResult_cssEnabled(ctx, field, obj)
|
||||||
|
default:
|
||||||
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.Dispatch()
|
||||||
|
if invalids > 0 {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
var configResultImplementors = []string{"ConfigResult"}
|
var configResultImplementors = []string{"ConfigResult"}
|
||||||
|
|
||||||
func (ec *executionContext) _ConfigResult(ctx context.Context, sel ast.SelectionSet, obj *ConfigResult) graphql.Marshaler {
|
func (ec *executionContext) _ConfigResult(ctx context.Context, sel ast.SelectionSet, obj *ConfigResult) graphql.Marshaler {
|
||||||
@@ -8983,6 +9211,11 @@ func (ec *executionContext) _ConfigResult(ctx context.Context, sel ast.Selection
|
|||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
invalids++
|
invalids++
|
||||||
}
|
}
|
||||||
|
case "interface":
|
||||||
|
out.Values[i] = ec._ConfigResult_interface(ctx, field, obj)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
invalids++
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
panic("unknown field " + strconv.Quote(field.Name))
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
}
|
}
|
||||||
@@ -9347,6 +9580,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
|
|||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
invalids++
|
invalids++
|
||||||
}
|
}
|
||||||
|
case "configureInterface":
|
||||||
|
out.Values[i] = ec._Mutation_configureInterface(ctx, field)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
invalids++
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
panic("unknown field " + strconv.Quote(field.Name))
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
}
|
}
|
||||||
@@ -10947,6 +11185,24 @@ func (ec *executionContext) marshalNConfigGeneralResult2ᚖgithubᚗcomᚋstasha
|
|||||||
return ec._ConfigGeneralResult(ctx, sel, v)
|
return ec._ConfigGeneralResult(ctx, sel, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalNConfigInterfaceInput2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigInterfaceInput(ctx context.Context, v interface{}) (ConfigInterfaceInput, error) {
|
||||||
|
return ec.unmarshalInputConfigInterfaceInput(ctx, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNConfigInterfaceResult2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigInterfaceResult(ctx context.Context, sel ast.SelectionSet, v ConfigInterfaceResult) graphql.Marshaler {
|
||||||
|
return ec._ConfigInterfaceResult(ctx, sel, &v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNConfigInterfaceResult2ᚖgithubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigInterfaceResult(ctx context.Context, sel ast.SelectionSet, v *ConfigInterfaceResult) graphql.Marshaler {
|
||||||
|
if v == nil {
|
||||||
|
if !ec.HasError(graphql.GetResolverContext(ctx)) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return ec._ConfigInterfaceResult(ctx, sel, v)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalNConfigResult2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigResult(ctx context.Context, sel ast.SelectionSet, v ConfigResult) graphql.Marshaler {
|
func (ec *executionContext) marshalNConfigResult2githubᚗcomᚋstashappᚋstashᚋpkgᚋmodelsᚐConfigResult(ctx context.Context, sel ast.SelectionSet, v ConfigResult) graphql.Marshaler {
|
||||||
return ec._ConfigResult(ctx, sel, &v)
|
return ec._ConfigResult(ctx, sel, &v)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,22 @@ type ConfigGeneralResult struct {
|
|||||||
GeneratedPath string `json:"generatedPath"`
|
GeneratedPath string `json:"generatedPath"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ConfigInterfaceInput struct {
|
||||||
|
// Custom CSS
|
||||||
|
CSS *string `json:"css"`
|
||||||
|
CSSEnabled *bool `json:"cssEnabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfigInterfaceResult struct {
|
||||||
|
// Custom CSS
|
||||||
|
CSS *string `json:"css"`
|
||||||
|
CSSEnabled *bool `json:"cssEnabled"`
|
||||||
|
}
|
||||||
|
|
||||||
// All configuration settings
|
// All configuration settings
|
||||||
type ConfigResult struct {
|
type ConfigResult struct {
|
||||||
General *ConfigGeneralResult `json:"general"`
|
General *ConfigGeneralResult `json:"general"`
|
||||||
|
Interface *ConfigInterfaceResult `json:"interface"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FindFilterType struct {
|
type FindFilterType struct {
|
||||||
|
|||||||
@@ -1,19 +1,54 @@
|
|||||||
import {
|
import {
|
||||||
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
|
Divider,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
H4,
|
H4,
|
||||||
|
Spinner,
|
||||||
|
TextArea
|
||||||
} from "@blueprintjs/core";
|
} from "@blueprintjs/core";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import React, { FunctionComponent } from "react";
|
import React, { FunctionComponent, useEffect, useState } from "react";
|
||||||
import { useInterfaceLocalForage } from "../../hooks/LocalForage";
|
import { useInterfaceLocalForage } from "../../hooks/LocalForage";
|
||||||
|
import { StashService } from "../../core/StashService";
|
||||||
|
import { ErrorUtils } from "../../utils/errors";
|
||||||
|
import { ToastUtils } from "../../utils/toasts";
|
||||||
|
|
||||||
interface IProps {}
|
interface IProps {}
|
||||||
|
|
||||||
export const SettingsInterfacePanel: FunctionComponent<IProps> = () => {
|
export const SettingsInterfacePanel: FunctionComponent<IProps> = () => {
|
||||||
const {data, setData} = useInterfaceLocalForage();
|
const {data, setData} = useInterfaceLocalForage();
|
||||||
|
const config = StashService.useConfiguration();
|
||||||
|
const [css, setCSS] = useState<string>();
|
||||||
|
const [cssEnabled, setCSSEnabled] = useState<boolean>();
|
||||||
|
|
||||||
|
const updateInterfaceConfig = StashService.useConfigureInterface({
|
||||||
|
css,
|
||||||
|
cssEnabled
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!config.data || !config.data.configuration || !!config.error) { return; }
|
||||||
|
if (!!config.data.configuration.interface) {
|
||||||
|
setCSS(config.data.configuration.interface.css || "");
|
||||||
|
setCSSEnabled(config.data.configuration.interface.cssEnabled || false);
|
||||||
|
}
|
||||||
|
}, [config.data]);
|
||||||
|
|
||||||
|
async function onSave() {
|
||||||
|
try {
|
||||||
|
const result = await updateInterfaceConfig();
|
||||||
|
console.log(result);
|
||||||
|
ToastUtils.success("Updated config");
|
||||||
|
} catch (e) {
|
||||||
|
ErrorUtils.handle(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{!!config.error ? <h1>{config.error.message}</h1> : undefined}
|
||||||
|
{(!config.data || !config.data.configuration || config.loading) ? <Spinner size={Spinner.SIZE_LARGE} /> : undefined}
|
||||||
<H4>User Interface</H4>
|
<H4>User Interface</H4>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label="Scene / Marker Wall"
|
label="Scene / Marker Wall"
|
||||||
@@ -40,6 +75,29 @@ export const SettingsInterfacePanel: FunctionComponent<IProps> = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup
|
||||||
|
label="Custom CSS"
|
||||||
|
helperText="Page must be reloaded for changes to take effect."
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
checked={cssEnabled}
|
||||||
|
label="Custom CSS enabled"
|
||||||
|
onChange={() => {
|
||||||
|
setCSSEnabled(!cssEnabled)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextArea
|
||||||
|
value={css}
|
||||||
|
onChange={(e: any) => setCSS(e.target.value)}
|
||||||
|
fill={true}
|
||||||
|
rows={16}>
|
||||||
|
</TextArea>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
<Button intent="primary" onClick={() => onSave()}>Save</Button>
|
||||||
|
</FormGroup>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import React, { FunctionComponent, useRef, useState } from "react";
|
import React, { FunctionComponent, useRef, useState, useEffect } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import * as GQL from "../../core/generated-graphql";
|
import * as GQL from "../../core/generated-graphql";
|
||||||
import { useInterfaceLocalForage } from "../../hooks/LocalForage";
|
import { useInterfaceLocalForage } from "../../hooks/LocalForage";
|
||||||
@@ -17,6 +17,10 @@ interface IWallItemProps {
|
|||||||
|
|
||||||
export const WallItem: FunctionComponent<IWallItemProps> = (props: IWallItemProps) => {
|
export const WallItem: FunctionComponent<IWallItemProps> = (props: IWallItemProps) => {
|
||||||
const [videoPath, setVideoPath] = useState<string | undefined>(undefined);
|
const [videoPath, setVideoPath] = useState<string | undefined>(undefined);
|
||||||
|
const [previewPath, setPreviewPath] = useState<string>("");
|
||||||
|
const [screenshotPath, setScreenshotPath] = useState<string>("");
|
||||||
|
const [title, setTitle] = useState<string>("");
|
||||||
|
const [tags, setTags] = useState<JSX.Element[]>([]);
|
||||||
const videoHoverHook = VideoHoverHook.useVideoHover({resetOnMouseLeave: true});
|
const videoHoverHook = VideoHoverHook.useVideoHover({resetOnMouseLeave: true});
|
||||||
const interfaceSettings = useInterfaceLocalForage();
|
const interfaceSettings = useInterfaceLocalForage();
|
||||||
const showTextContainer = !!interfaceSettings.data ? interfaceSettings.data.wall.textContainerEnabled : true;
|
const showTextContainer = !!interfaceSettings.data ? interfaceSettings.data.wall.textContainerEnabled : true;
|
||||||
@@ -68,18 +72,25 @@ export const WallItem: FunctionComponent<IWallItemProps> = (props: IWallItemProp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let previewSrc: string = "";
|
useEffect(() => {
|
||||||
let title: string = "";
|
if (!!props.sceneMarker) {
|
||||||
let tags: JSX.Element[] = [];
|
setPreviewPath(props.sceneMarker.preview);
|
||||||
if (!!props.sceneMarker) {
|
setTitle(`${props.sceneMarker!.title} - ${TextUtils.secondsToTimestamp(props.sceneMarker.seconds)}`);
|
||||||
previewSrc = props.sceneMarker.preview;
|
const thisTags = props.sceneMarker.tags.map((tag) => (<span key={tag.id}>{tag.name}</span>));
|
||||||
title = `${props.sceneMarker!.title} - ${TextUtils.secondsToTimestamp(props.sceneMarker.seconds)}`;
|
thisTags.unshift(<span key={props.sceneMarker.primary_tag.id}>{props.sceneMarker.primary_tag.name}</span>);
|
||||||
tags = props.sceneMarker.tags.map((tag) => (<span key={tag.id}>{tag.name}</span>));
|
setTags(thisTags);
|
||||||
tags.unshift(<span key={props.sceneMarker.primary_tag.id}>{props.sceneMarker.primary_tag.name}</span>);
|
} else if (!!props.scene) {
|
||||||
} else if (!!props.scene) {
|
setPreviewPath(props.scene.paths.webp || "");
|
||||||
previewSrc = props.scene.paths.webp || "";
|
setScreenshotPath(props.scene.paths.screenshot || "");
|
||||||
title = props.scene.title || "";
|
setTitle(props.scene.title || "");
|
||||||
// tags = props.scene.tags.map((tag) => (<span key={tag.id}>{tag.name}</span>));
|
// tags = props.scene.tags.map((tag) => (<span key={tag.id}>{tag.name}</span>));
|
||||||
|
}
|
||||||
|
}, [props.sceneMarker, props.scene]);
|
||||||
|
|
||||||
|
function previewNotFound() {
|
||||||
|
if (previewPath !== screenshotPath) {
|
||||||
|
setPreviewPath(screenshotPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const className = ["scene-wall-item-container"];
|
const className = ["scene-wall-item-container"];
|
||||||
@@ -99,12 +110,13 @@ export const WallItem: FunctionComponent<IWallItemProps> = (props: IWallItemProp
|
|||||||
<Link onClick={() => onClick()} to={linkSrc}>
|
<Link onClick={() => onClick()} to={linkSrc}>
|
||||||
<video
|
<video
|
||||||
src={videoPath}
|
src={videoPath}
|
||||||
|
poster={screenshotPath}
|
||||||
style={videoHoverHook.isHovering.current ? {} : {display: "none"}}
|
style={videoHoverHook.isHovering.current ? {} : {display: "none"}}
|
||||||
autoPlay={true}
|
autoPlay={true}
|
||||||
loop={true}
|
loop={true}
|
||||||
ref={videoHoverHook.videoEl}
|
ref={videoHoverHook.videoEl}
|
||||||
/>
|
/>
|
||||||
<img src={previewSrc} />
|
<img src={previewPath || screenshotPath} onError={() => previewNotFound()} />
|
||||||
{showTextContainer ?
|
{showTextContainer ?
|
||||||
<div className="scene-wall-item-text-container">
|
<div className="scene-wall-item-text-container">
|
||||||
<div style={{lineHeight: 1}}>
|
<div style={{lineHeight: 1}}>
|
||||||
|
|||||||
@@ -166,6 +166,10 @@ export class StashService {
|
|||||||
return GQL.useConfigureGeneral({ variables: { input }, refetchQueries: ["Configuration"] });
|
return GQL.useConfigureGeneral({ variables: { input }, refetchQueries: ["Configuration"] });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static useConfigureInterface(input: GQL.ConfigInterfaceInput) {
|
||||||
|
return GQL.useConfigureInterface({ variables: { input }, refetchQueries: ["Configuration"] });
|
||||||
|
}
|
||||||
|
|
||||||
public static queryScrapeFreeones(performerName: string) {
|
public static queryScrapeFreeones(performerName: string) {
|
||||||
return StashService.client.query<GQL.ScrapeFreeonesQuery>({
|
return StashService.client.query<GQL.ScrapeFreeonesQuery>({
|
||||||
query: GQL.ScrapeFreeonesDocument,
|
query: GQL.ScrapeFreeonesDocument,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// Generated in 2019-08-15T18:05:18+10:00
|
// Generated in 2019-08-23T07:28:41+10:00
|
||||||
export type Maybe<T> = T | undefined;
|
export type Maybe<T> = T | undefined;
|
||||||
|
|
||||||
export interface SceneFilterType {
|
export interface SceneFilterType {
|
||||||
@@ -245,6 +245,13 @@ export interface ConfigGeneralInput {
|
|||||||
generatedPath?: Maybe<string>;
|
generatedPath?: Maybe<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ConfigInterfaceInput {
|
||||||
|
/** Custom CSS */
|
||||||
|
css?: Maybe<string>;
|
||||||
|
|
||||||
|
cssEnabled?: Maybe<boolean>;
|
||||||
|
}
|
||||||
|
|
||||||
export enum CriterionModifier {
|
export enum CriterionModifier {
|
||||||
Equals = "EQUALS",
|
Equals = "EQUALS",
|
||||||
NotEquals = "NOT_EQUALS",
|
NotEquals = "NOT_EQUALS",
|
||||||
@@ -285,6 +292,18 @@ export type ConfigureGeneralMutation = {
|
|||||||
|
|
||||||
export type ConfigureGeneralConfigureGeneral = ConfigGeneralDataFragment;
|
export type ConfigureGeneralConfigureGeneral = ConfigGeneralDataFragment;
|
||||||
|
|
||||||
|
export type ConfigureInterfaceVariables = {
|
||||||
|
input: ConfigInterfaceInput;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ConfigureInterfaceMutation = {
|
||||||
|
__typename?: "Mutation";
|
||||||
|
|
||||||
|
configureInterface: ConfigureInterfaceConfigureInterface;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ConfigureInterfaceConfigureInterface = ConfigInterfaceDataFragment;
|
||||||
|
|
||||||
export type PerformerCreateVariables = {
|
export type PerformerCreateVariables = {
|
||||||
name?: Maybe<string>;
|
name?: Maybe<string>;
|
||||||
url?: Maybe<string>;
|
url?: Maybe<string>;
|
||||||
@@ -952,14 +971,26 @@ export type ConfigGeneralDataFragment = {
|
|||||||
generatedPath: string;
|
generatedPath: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ConfigInterfaceDataFragment = {
|
||||||
|
__typename?: "ConfigInterfaceResult";
|
||||||
|
|
||||||
|
css: Maybe<string>;
|
||||||
|
|
||||||
|
cssEnabled: Maybe<boolean>;
|
||||||
|
};
|
||||||
|
|
||||||
export type ConfigDataFragment = {
|
export type ConfigDataFragment = {
|
||||||
__typename?: "ConfigResult";
|
__typename?: "ConfigResult";
|
||||||
|
|
||||||
general: ConfigDataGeneral;
|
general: ConfigDataGeneral;
|
||||||
|
|
||||||
|
interface: ConfigDataInterface;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ConfigDataGeneral = ConfigGeneralDataFragment;
|
export type ConfigDataGeneral = ConfigGeneralDataFragment;
|
||||||
|
|
||||||
|
export type ConfigDataInterface = ConfigInterfaceDataFragment;
|
||||||
|
|
||||||
export type GalleryDataFragment = {
|
export type GalleryDataFragment = {
|
||||||
__typename?: "Gallery";
|
__typename?: "Gallery";
|
||||||
|
|
||||||
@@ -1335,14 +1366,25 @@ export const ConfigGeneralDataFragmentDoc = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const ConfigInterfaceDataFragmentDoc = gql`
|
||||||
|
fragment ConfigInterfaceData on ConfigInterfaceResult {
|
||||||
|
css
|
||||||
|
cssEnabled
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const ConfigDataFragmentDoc = gql`
|
export const ConfigDataFragmentDoc = gql`
|
||||||
fragment ConfigData on ConfigResult {
|
fragment ConfigData on ConfigResult {
|
||||||
general {
|
general {
|
||||||
...ConfigGeneralData
|
...ConfigGeneralData
|
||||||
}
|
}
|
||||||
|
interface {
|
||||||
|
...ConfigInterfaceData
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
${ConfigGeneralDataFragmentDoc}
|
${ConfigGeneralDataFragmentDoc}
|
||||||
|
${ConfigInterfaceDataFragmentDoc}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const SlimPerformerDataFragmentDoc = gql`
|
export const SlimPerformerDataFragmentDoc = gql`
|
||||||
@@ -1574,6 +1616,26 @@ export function useConfigureGeneral(
|
|||||||
ConfigureGeneralVariables
|
ConfigureGeneralVariables
|
||||||
>(ConfigureGeneralDocument, baseOptions);
|
>(ConfigureGeneralDocument, baseOptions);
|
||||||
}
|
}
|
||||||
|
export const ConfigureInterfaceDocument = gql`
|
||||||
|
mutation ConfigureInterface($input: ConfigInterfaceInput!) {
|
||||||
|
configureInterface(input: $input) {
|
||||||
|
...ConfigInterfaceData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
${ConfigInterfaceDataFragmentDoc}
|
||||||
|
`;
|
||||||
|
export function useConfigureInterface(
|
||||||
|
baseOptions?: ReactApolloHooks.MutationHookOptions<
|
||||||
|
ConfigureInterfaceMutation,
|
||||||
|
ConfigureInterfaceVariables
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
return ReactApolloHooks.useMutation<
|
||||||
|
ConfigureInterfaceMutation,
|
||||||
|
ConfigureInterfaceVariables
|
||||||
|
>(ConfigureInterfaceDocument, baseOptions);
|
||||||
|
}
|
||||||
export const PerformerCreateDocument = gql`
|
export const PerformerCreateDocument = gql`
|
||||||
mutation PerformerCreate(
|
mutation PerformerCreate(
|
||||||
$name: String
|
$name: String
|
||||||
|
|||||||
@@ -8,11 +8,14 @@ import "./index.scss";
|
|||||||
import * as serviceWorker from "./serviceWorker";
|
import * as serviceWorker from "./serviceWorker";
|
||||||
|
|
||||||
ReactDOM.render((
|
ReactDOM.render((
|
||||||
|
<>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css"/>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<ApolloProvider client={StashService.initialize()!}>
|
<ApolloProvider client={StashService.initialize()!}>
|
||||||
<App />
|
<App />
|
||||||
</ApolloProvider>
|
</ApolloProvider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
</>
|
||||||
), document.getElementById("root"));
|
), document.getElementById("root"));
|
||||||
|
|
||||||
// If you want your app to work offline and load faster, you can change
|
// If you want your app to work offline and load faster, you can change
|
||||||
|
|||||||
Reference in New Issue
Block a user