Merge pull request #112 from WithoutPants/custom_css

Customisable css
This commit is contained in:
StashAppDev 2019-08-24 09:59:11 -07:00 committed by GitHub
commit f321363312
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 531 additions and 14 deletions

View file

@ -4,8 +4,16 @@ fragment ConfigGeneralData on ConfigGeneralResult {
generatedPath
}
fragment ConfigInterfaceData on ConfigInterfaceResult {
css
cssEnabled
}
fragment ConfigData on ConfigResult {
general {
...ConfigGeneralData
}
interface {
...ConfigInterfaceData
}
}

View file

@ -2,4 +2,10 @@ mutation ConfigureGeneral($input: ConfigGeneralInput!) {
configureGeneral(input: $input) {
...ConfigGeneralData
}
}
mutation ConfigureInterface($input: ConfigInterfaceInput!) {
configureInterface(input: $input) {
...ConfigInterfaceData
}
}

View file

@ -91,6 +91,7 @@ type Mutation {
"""Change general configuration options"""
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
configureInterface(input: ConfigInterfaceInput!): ConfigInterfaceResult!
}
type Subscription {

View file

@ -16,7 +16,20 @@ type ConfigGeneralResult {
generatedPath: String!
}
input ConfigInterfaceInput {
"""Custom CSS"""
css: String
cssEnabled: Boolean
}
type ConfigInterfaceResult {
"""Custom CSS"""
css: String
cssEnabled: Boolean
}
"""All configuration settings"""
type ConfigResult {
general: ConfigGeneralResult!
interface: ConfigInterfaceResult!
}

View file

@ -3,10 +3,11 @@ package api
import (
"context"
"fmt"
"path/filepath"
"github.com/stashapp/stash/pkg/manager/config"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/utils"
"path/filepath"
)
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
}
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
}

View file

@ -2,6 +2,7 @@ package api
import (
"context"
"github.com/stashapp/stash/pkg/manager/config"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/utils"
@ -21,7 +22,8 @@ func (r *queryResolver) Directories(ctx context.Context, path *string) ([]string
func makeConfigResult() *models.ConfigResult {
return &models.ConfigResult{
General: makeConfigGeneralResult(),
General: makeConfigGeneralResult(),
Interface: makeConfigInterfaceResult(),
}
}
@ -32,3 +34,12 @@ func makeConfigGeneralResult() *models.ConfigGeneralResult {
GeneratedPath: config.GetGeneratedPath(),
}
}
func makeConfigInterfaceResult() *models.ConfigInterfaceResult {
css := config.GetCSS()
cssEnabled := config.GetCSSEnabled()
return &models.ConfigInterfaceResult{
CSS: &css,
CSSEnabled: &cssEnabled,
}
}

View file

@ -5,6 +5,15 @@ import (
"crypto/tls"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"path"
"path/filepath"
"runtime/debug"
"strconv"
"strings"
"github.com/99designs/gqlgen/handler"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
@ -16,14 +25,6 @@ import (
"github.com/stashapp/stash/pkg/manager/paths"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/utils"
"io/ioutil"
"net/http"
"os"
"path"
"path/filepath"
"runtime/debug"
"strconv"
"strings"
)
var uiBox *packr.Box
@ -72,6 +73,21 @@ func Start() {
r.Mount("/scene", sceneRoutes{}.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
r.HandleFunc("/setup*", func(w http.ResponseWriter, r *http.Request) {
ext := path.Ext(r.URL.Path)

View file

@ -1,7 +1,10 @@
package config
import (
"io/ioutil"
"github.com/spf13/viper"
"github.com/stashapp/stash/pkg/utils"
)
const Stash = "stash"
@ -15,6 +18,8 @@ const Database = "database"
const Host = "host"
const Port = "port"
const CSSEnabled = "cssEnabled"
func Set(key string, value interface{}) {
viper.Set(key, value)
}
@ -51,6 +56,46 @@ func GetPort() int {
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 {
setPaths := viper.IsSet(Stash) && viper.IsSet(Cache) && viper.IsSet(Generated) && viper.IsSet(Metadata)
// TODO: check valid paths

View file

@ -56,8 +56,14 @@ type ComplexityRoot struct {
Stashes func(childComplexity int) int
}
ConfigInterfaceResult struct {
CSS func(childComplexity int) int
CSSEnabled func(childComplexity int) int
}
ConfigResult struct {
General func(childComplexity int) int
General func(childComplexity int) int
Interface func(childComplexity int) int
}
FindGalleriesResultType struct {
@ -107,6 +113,7 @@ type ComplexityRoot struct {
Mutation struct {
ConfigureGeneral func(childComplexity int, input ConfigGeneralInput) int
ConfigureInterface func(childComplexity int, input ConfigInterfaceInput) int
PerformerCreate func(childComplexity int, input PerformerCreateInput) int
PerformerDestroy func(childComplexity int, input PerformerDestroyInput) int
PerformerUpdate func(childComplexity int, input PerformerUpdateInput) int
@ -298,6 +305,7 @@ type MutationResolver interface {
TagUpdate(ctx context.Context, input TagUpdateInput) (*Tag, error)
TagDestroy(ctx context.Context, input TagDestroyInput) (bool, error)
ConfigureGeneral(ctx context.Context, input ConfigGeneralInput) (*ConfigGeneralResult, error)
ConfigureInterface(ctx context.Context, input ConfigInterfaceInput) (*ConfigInterfaceResult, error)
}
type PerformerResolver interface {
Name(ctx context.Context, obj *Performer) (*string, error)
@ -424,6 +432,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
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":
if e.complexity.ConfigResult.General == nil {
break
@ -431,6 +453,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
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":
if e.complexity.FindGalleriesResultType.Count == nil {
break
@ -590,6 +619,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
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":
if e.complexity.Mutation.PerformerCreate == nil {
break
@ -1880,6 +1921,7 @@ type Mutation {
"""Change general configuration options"""
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
configureInterface(input: ConfigInterfaceInput!): ConfigInterfaceResult!
}
type Subscription {
@ -1910,9 +1952,22 @@ type ConfigGeneralResult {
generatedPath: String!
}
input ConfigInterfaceInput {
"""Custom CSS"""
css: String
cssEnabled: Boolean
}
type ConfigInterfaceResult {
"""Custom CSS"""
css: String
cssEnabled: Boolean
}
"""All configuration settings"""
type ConfigResult {
general: ConfigGeneralResult!
interface: ConfigInterfaceResult!
}`},
&ast.Source{Name: "graphql/schema/types/filters.graphql", Input: `enum SortDirectionEnum {
ASC
@ -2294,6 +2349,20 @@ func (ec *executionContext) field_Mutation_configureGeneral_args(ctx context.Con
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) {
var err error
args := map[string]interface{}{}
@ -2917,6 +2986,54 @@ func (ec *executionContext) _ConfigGeneralResult_generatedPath(ctx context.Conte
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 {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
@ -2944,6 +3061,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)
}
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 {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
@ -3951,6 +4095,40 @@ func (ec *executionContext) _Mutation_configureGeneral(ctx context.Context, fiel
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 {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
@ -8049,6 +8227,30 @@ func (ec *executionContext) unmarshalInputConfigGeneralInput(ctx context.Context
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) {
var it FindFilterType
var asMap = v.(map[string]interface{})
@ -8868,6 +9070,32 @@ func (ec *executionContext) _ConfigGeneralResult(ctx context.Context, sel ast.Se
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"}
func (ec *executionContext) _ConfigResult(ctx context.Context, sel ast.SelectionSet, obj *ConfigResult) graphql.Marshaler {
@ -8884,6 +9112,11 @@ func (ec *executionContext) _ConfigResult(ctx context.Context, sel ast.Selection
if out.Values[i] == graphql.Null {
invalids++
}
case "interface":
out.Values[i] = ec._ConfigResult_interface(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@ -9243,6 +9476,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
if out.Values[i] == graphql.Null {
invalids++
}
case "configureInterface":
out.Values[i] = ec._Mutation_configureInterface(ctx, field)
if out.Values[i] == graphql.Null {
invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@ -10843,6 +11081,24 @@ func (ec *executionContext) marshalNConfigGeneralResult2ᚖgithubᚗcomᚋstasha
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 {
return ec._ConfigResult(ctx, sel, &v)
}

View file

@ -26,9 +26,22 @@ type ConfigGeneralResult struct {
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
type ConfigResult struct {
General *ConfigGeneralResult `json:"general"`
General *ConfigGeneralResult `json:"general"`
Interface *ConfigInterfaceResult `json:"interface"`
}
type FindFilterType struct {

View file

@ -1,19 +1,54 @@
import {
Button,
Checkbox,
Divider,
FormGroup,
H4,
Spinner,
TextArea
} from "@blueprintjs/core";
import _ from "lodash";
import React, { FunctionComponent } from "react";
import React, { FunctionComponent, useEffect, useState } from "react";
import { useInterfaceLocalForage } from "../../hooks/LocalForage";
import { StashService } from "../../core/StashService";
import { ErrorUtils } from "../../utils/errors";
import { ToastUtils } from "../../utils/toasts";
interface IProps {}
export const SettingsInterfacePanel: FunctionComponent<IProps> = () => {
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 (
<>
{!!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>
<FormGroup
label="Scene / Marker Wall"
@ -40,6 +75,29 @@ export const SettingsInterfacePanel: FunctionComponent<IProps> = () => {
}}
/>
</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>
</>
);
};

View file

@ -162,6 +162,10 @@ export class StashService {
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) {
return StashService.client.query<GQL.ScrapeFreeonesQuery>({
query: GQL.ScrapeFreeonesDocument,

View file

@ -1,6 +1,6 @@
/* tslint:disable */
/* eslint-disable */
// Generated in 2019-08-14T07:29:27+10:00
// Generated in 2019-08-23T07:28:41+10:00
export type Maybe<T> = T | undefined;
export interface SceneFilterType {
@ -237,6 +237,13 @@ export interface ConfigGeneralInput {
generatedPath?: Maybe<string>;
}
export interface ConfigInterfaceInput {
/** Custom CSS */
css?: Maybe<string>;
cssEnabled?: Maybe<boolean>;
}
export enum CriterionModifier {
Equals = "EQUALS",
NotEquals = "NOT_EQUALS",
@ -277,6 +284,18 @@ export type ConfigureGeneralMutation = {
export type ConfigureGeneralConfigureGeneral = ConfigGeneralDataFragment;
export type ConfigureInterfaceVariables = {
input: ConfigInterfaceInput;
};
export type ConfigureInterfaceMutation = {
__typename?: "Mutation";
configureInterface: ConfigureInterfaceConfigureInterface;
};
export type ConfigureInterfaceConfigureInterface = ConfigInterfaceDataFragment;
export type PerformerCreateVariables = {
name?: Maybe<string>;
url?: Maybe<string>;
@ -932,14 +951,26 @@ export type ConfigGeneralDataFragment = {
generatedPath: string;
};
export type ConfigInterfaceDataFragment = {
__typename?: "ConfigInterfaceResult";
css: Maybe<string>;
cssEnabled: Maybe<boolean>;
};
export type ConfigDataFragment = {
__typename?: "ConfigResult";
general: ConfigDataGeneral;
interface: ConfigDataInterface;
};
export type ConfigDataGeneral = ConfigGeneralDataFragment;
export type ConfigDataInterface = ConfigInterfaceDataFragment;
export type GalleryDataFragment = {
__typename?: "Gallery";
@ -1315,14 +1346,25 @@ export const ConfigGeneralDataFragmentDoc = gql`
}
`;
export const ConfigInterfaceDataFragmentDoc = gql`
fragment ConfigInterfaceData on ConfigInterfaceResult {
css
cssEnabled
}
`;
export const ConfigDataFragmentDoc = gql`
fragment ConfigData on ConfigResult {
general {
...ConfigGeneralData
}
interface {
...ConfigInterfaceData
}
}
${ConfigGeneralDataFragmentDoc}
${ConfigInterfaceDataFragmentDoc}
`;
export const SlimPerformerDataFragmentDoc = gql`
@ -1554,6 +1596,26 @@ export function useConfigureGeneral(
ConfigureGeneralVariables
>(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`
mutation PerformerCreate(
$name: String

View file

@ -8,11 +8,14 @@ import "./index.scss";
import * as serviceWorker from "./serviceWorker";
ReactDOM.render((
<>
<link rel="stylesheet" type="text/css" href="/css"/>
<BrowserRouter>
<ApolloProvider client={StashService.initialize()!}>
<App />
</ApolloProvider>
</BrowserRouter>
</>
), document.getElementById("root"));
// If you want your app to work offline and load faster, you can change