Skip to content

Commit

Permalink
v0.1.4
Browse files Browse the repository at this point in the history
  • Loading branch information
InfiniteStash authored Jan 28, 2022
2 parents 8c5beab + e07cf80 commit d3a657d
Show file tree
Hide file tree
Showing 17 changed files with 141 additions and 56 deletions.
7 changes: 6 additions & 1 deletion frontend/src/components/editCard/EditExpiration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ const ExpirationNotification: FC<Props> = ({ edit }) => {
const { data } = useConfig();
const config = data?.getConfig;

if (!config || edit.status !== VoteStatusEnum.PENDING) return <></>;
if (
!config ||
!config.vote_cron_interval ||
edit.status !== VoteStatusEnum.PENDING
)
return <></>;

// Pending edits that have reached the voting threshold have shorter voting periods.
// This will happen for destructive edits, or when votes are not unanimous.
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/components/editCard/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,16 @@
margin-bottom: 20px;
text-align: right;
}

.ListChangeRow {
&-Tags {
ul {
list-style-type: none;
padding-left: 0;

li {
display: inline-block;
}
}
}
}
2 changes: 1 addition & 1 deletion frontend/src/components/listChangeRow/ListChangeRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const ListChangeRow = <T extends unknown>({
showDiff,
}: PropsWithChildren<ListChangeRowProps<T>>) =>
(added ?? []).length > 0 || (removed ?? []).length > 0 ? (
<Row className={CLASSNAME}>
<Row className={`${CLASSNAME}-${name}`}>
<b className="col-2 text-end">{name}</b>
{showDiff && (
<Col xs={5}>
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/components/searchField/SearchField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ interface SearchResult {

const Option = (props: OptionProps<SearchResult, false>) => {
const {
data: { label, subLabel },
data: { label, subLabel, value },
} = props;
return (
<components.Option {...props}>
<div className="search-value">{label}</div>
<div className="search-value">
{value?.deleted ? <del>{label}</del> : label}
</div>
<div className="search-subvalue">{subLabel}</div>
</components.Option>
);
Expand Down
1 change: 1 addition & 0 deletions frontend/src/graphql/definitions/SearchAll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export interface SearchAll_searchScene {
id: string;
date: any | null;
title: string | null;
deleted: boolean;
duration: number | null;
urls: SearchAll_searchScene_urls[];
images: SearchAll_searchScene_images[];
Expand Down
1 change: 1 addition & 0 deletions frontend/src/graphql/queries/SearchAll.gql
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ query SearchAll($term: String!, $limit: Int = 5) {
id
date
title
deleted
duration
urls {
...URLFragment
Expand Down
23 changes: 18 additions & 5 deletions frontend/src/pages/performers/PerformerMerge.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useState } from "react";
import { FC, useEffect, useState } from "react";
import { useHistory } from "react-router-dom";
import { Button, Col, Form, Row } from "react-bootstrap";
import { flatMap } from "lodash-es";
Expand All @@ -15,6 +15,11 @@ import PerformerSelect from "src/components/performerSelect";
import PerformerCard from "src/components/performerCard";
import { editHref } from "src/utils";
import PerformerForm from "./performerForm";
import { Help } from "src/components/fragments";

const UPDATE_ALIAS_MESSAGE = `Enabling this option sets each merged performer's name as an alias on every scene that performer does not have an alias on.
In most cases, it should be enabled when merging aliases of a performer, and disabled when the performers share the same name.
`;

const CLASSNAME = "PerformerMerge";

Expand All @@ -33,6 +38,15 @@ const PerformerMerge: FC<Props> = ({ performer }) => {
},
});

const toggleMerge = () => {
setMergeActive(true);
const sameName = mergeSources.every(
({ name }) => name.trim() === performer.name.trim()
);
// Don't update aliases by default if the names match
setAliasUpdating(!sameName);
};

const doUpdate = (
insertData: PerformerEditDetailsInput,
editNote: string,
Expand Down Expand Up @@ -77,10 +91,7 @@ const PerformerMerge: FC<Props> = ({ performer }) => {
]}
/>
{mergeSources.length > 0 && (
<Button
onClick={() => setMergeActive(true)}
className="ms-auto"
>
<Button onClick={toggleMerge} className="ms-auto">
Continue
</Button>
)}
Expand Down Expand Up @@ -124,7 +135,9 @@ const PerformerMerge: FC<Props> = ({ performer }) => {
checked={aliasUpdating}
onChange={() => setAliasUpdating(!aliasUpdating)}
label="Update scene performance aliases on merged performers to old performer name."
className="d-inline-block"
/>
<Help message={UPDATE_ALIAS_MESSAGE} />
<h5 className="mt-4">
Update performer metadata for <em>{performer.name}</em>
</h5>
Expand Down
43 changes: 25 additions & 18 deletions frontend/src/pages/performers/performerForm/PerformerForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ const ETHNICITY: OptionEnum[] = [
{ value: "OTHER", label: "Other" },
];

const UPDATE_ALIAS_MESSAGE = `When changing from alias A to B, it may be desirable to enable this so all unset performances will continue to have the old name.
If however a typo in the name is corrected, this should not be used.
const UPDATE_ALIAS_MESSAGE = `Enabling this option sets the current name as an alias on every scene that this performer does not have an alias on.
In most cases, it should be enabled when renaming a performer to a different alias, and disabled when correcting a typo in the name.
`;

const getEnumValue = (enumArray: OptionEnum[], val: string) => {
Expand Down Expand Up @@ -175,6 +175,15 @@ const PerformerForm: FC<PerformerProps> = ({
[fieldData, performer]
);

const changedName =
!!performer.id &&
fieldData.name !== undefined &&
performer.name !== fieldData.name;

useEffect(() => {
setUpdateAliases(changedName);
}, [changedName, setUpdateAliases]);

const showBreastType =
fieldData.gender !== GenderEnum.MALE &&
fieldData.gender !== GenderEnum.TRANSGENDER_MALE;
Expand Down Expand Up @@ -296,22 +305,20 @@ const PerformerForm: FC<PerformerProps> = ({
</Form.Group>
</Row>

{performer.id &&
fieldData.name !== undefined &&
performer.name !== fieldData.name && (
<Row>
<Form.Group className="col mb-3">
<Form.Check
id="update-modify-aliases"
checked={updateAliases}
onChange={() => setUpdateAliases(!updateAliases)}
label="Set unset performance aliases to old name"
className="d-inline-block"
/>
<Help message={UPDATE_ALIAS_MESSAGE} />
</Form.Group>
</Row>
)}
{changedName && (
<Row>
<Form.Group className="col mb-3">
<Form.Check
id="update-modify-aliases"
checked={updateAliases}
onChange={() => setUpdateAliases(!updateAliases)}
label="Set unset performance aliases to old name"
className="d-inline-block"
/>
<Help message={UPDATE_ALIAS_MESSAGE} />
</Form.Group>
</Row>
)}

<Row>
<Form.Group controlId="aliases" className="col mb-3">
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/pages/scenes/sceneForm/SceneForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,11 @@ const SceneForm: FC<SceneProps> = ({ scene, initial, callback, saving }) => {
) : (
<InputGroup.Text className="flex-grow-1 text-start text-truncate">
<GenderIcon gender={p.gender} />
<span className="performer-name text-truncate">
<span
className={cx("performer-name text-truncate", {
"text-decoration-line-through": p.deleted,
})}
>
<b>{p.name}</b>
{p.disambiguation && (
<small className="ms-1">({p.disambiguation})</small>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/scenes/sceneForm/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const selectSceneDetails = (
name: p.name,
gender: genderEnum(p.gender),
disambiguation: p.disambiguation ?? null,
deleted: false,
deleted: p.deleted ?? false,
},
as: p.alias ?? null,
},
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/resolver_model_scene_draft.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (r *sceneDraftResolver) Tags(ctx context.Context, obj *models.SceneDraft) (
for _, t := range obj.Tags {
var st models.SceneDraftTag
if t.ID != nil {
tag, err := qb.Find(*t.ID)
tag, err := qb.FindWithRedirect(*t.ID)
if err != nil {
return nil, err
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/draft/draft.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ func Destroy(fac models.Repo, id uuid.UUID) error {
if err != nil {
return err
}
if draft == nil {
return fmt.Errorf("Draft not found: %v", id)
}

var imageID *uuid.UUID
switch draft.Type {
Expand Down
5 changes: 5 additions & 0 deletions pkg/models/model_edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ func (e *Edit) IsDestructive() bool {
if e.Operation == OperationEnumDestroy.String() || e.Operation == OperationEnumMerge.String() {
return true
}
// When renaming a performer and not updating the performance aliases
if (e.Operation == OperationEnumModify.String() || e.Operation == OperationEnumMerge.String()) && e.TargetType == TargetTypeEnumPerformer.String() {
data, _ := e.GetPerformerData()
return data.New.Name != nil && !data.SetModifyAliases
}
return false
}

Expand Down
1 change: 1 addition & 0 deletions pkg/models/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type TagRepo interface {
FindByNames(names []string) ([]*Tag, error)
FindByName(name string) (*Tag, error)
FindByNameOrAlias(name string) (*Tag, error)
FindWithRedirect(id uuid.UUID) (*Tag, error)
Count() (int, error)
Query(tagFilter *TagFilterType, findFilter *QuerySpec) ([]*Tag, int, error)
GetAliases(id uuid.UUID) ([]string, error)
Expand Down
10 changes: 7 additions & 3 deletions pkg/models/translate.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ type ErrEditPrerequisiteFailed struct {
func (e *ErrEditPrerequisiteFailed) Error() string {
expected := "_blank_"
if e.expected != "" {
expected = fmt.Sprintf("“**%s**”", e.expected)
expected = fmt.Sprintf("“**%v**”", e.expected)
}
actual := "_blank_"
if e.actual != "" {
actual = fmt.Sprintf("“**%s**”", e.actual)
actual = fmt.Sprintf("“**%v**”", e.actual)
}
return fmt.Sprintf("Expected %s to be %s, but was %s.", e.field, expected, actual)
}
Expand Down Expand Up @@ -220,6 +220,10 @@ func (v *editValidator) uuid(field string, old *uuid.UUID, current uuid.NullUUID
}

if old != nil && (!current.Valid || (*old != current.UUID)) {
v.err = v.error(field, *old, current)
currentUUID := ""
if current.Valid {
currentUUID = current.UUID.String()
}
v.err = v.error(field, old.String(), currentUUID)
}
}
26 changes: 23 additions & 3 deletions pkg/sqlx/querybuilder_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,12 @@ func (qb *tagQueryBuilder) Find(id uuid.UUID) (*models.Tag, error) {
}

func (qb *tagQueryBuilder) FindByNameOrAlias(name string) (*models.Tag, error) {
query := `SELECT tags.* FROM tags
left join tag_aliases on tags.id = tag_aliases.tag_id
WHERE LOWER(tag_aliases.alias) = LOWER(?) OR LOWER(tags.name) = LOWER(?)`
query := `
SELECT T.* FROM tags T
LEFT JOIN tag_aliases TA ON T.id = TA.tag_id
WHERE LOWER(TA.alias) = LOWER($1) OR LOWER(T.name) = LOWER($1)
ORDER BY T.deleted ASC
`

args := []interface{}{name, name}
results, err := qb.queryTags(query, args)
Expand Down Expand Up @@ -229,6 +232,23 @@ func (qb *tagQueryBuilder) FindByAlias(name string) ([]*models.Tag, error) {
return qb.queryTags(query, args)
}

func (qb *tagQueryBuilder) FindWithRedirect(id uuid.UUID) (*models.Tag, error) {
query := `
SELECT T.* FROM tags T
WHERE T.id = $1 AND T.deleted = FALSE
UNION
SELECT T2.* FROM tag_redirects R
JOIN tags T2 ON T2.id = R.target_id
WHERE R.source_id = $1 AND T2.deleted = FALSE
`
args := []interface{}{id}
tags, err := qb.queryTags(query, args)
if len(tags) > 0 {
return tags[0], err
}
return nil, err
}

func (qb *tagQueryBuilder) Count() (int, error) {
return runCountQuery(qb.dbi.db(), buildCountQuery("SELECT tags.id FROM tags"), nil)
}
Expand Down
46 changes: 26 additions & 20 deletions pkg/sqlx/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,36 @@ type txnState struct {
dialect Dialect
}

func (m *txnState) WithTxn(fn func() error) (txErr error) {
if !m.InTxn() {
tx, err := m.rootDB.Beginx()
if err != nil {
return err
}
func (m *txnState) WithTxn(fn func() error) (err error) {
if m.InTxn() {
err = fn()
return
}

m.tx = tx
tx, err := m.rootDB.Beginx()
if err != nil {
return
}

var txErr error
defer func() {
m.tx = nil
if txErr != nil {
// ignore rollback errors
_ = tx.Rollback()
} else {
txErr = tx.Commit()
}
}()
m.tx = tx

return fn()
}
defer func() {
m.tx = nil
//nolint:gocritic
if p := recover(); p != nil {
// a panic occurred, rollback and repanic
_ = tx.Rollback()
panic(p)
} else if err != nil {
// something went wrong, rollback
_ = tx.Rollback()
} else {
err = tx.Commit()
}
}()

return fn()
err = fn()
return
}

func (m *txnState) InTxn() bool {
Expand Down

0 comments on commit d3a657d

Please sign in to comment.