Added favorite stash heart to scene tiles.

This commit is contained in:
DebaucheryLibrarian 2021-03-19 03:27:48 +01:00
parent f3d55806d1
commit 731a2792c5
15 changed files with 146 additions and 28 deletions

View File

@ -365,7 +365,11 @@
:available-actors="actor.actors" :available-actors="actor.actors"
/> />
<Releases :releases="releases" /> <Releases
:releases="releases"
@stash="fetchActor(false)"
@unstash="fetchActor(false)"
/>
<Pagination <Pagination
:items-total="totalCount" :items-total="totalCount"

View File

@ -99,7 +99,11 @@
/> />
<div class="releases"> <div class="releases">
<Releases :releases="entity.releases" /> <Releases
:releases="entity.releases"
@stash="fetchEntity(false)"
@unstash="fetchEntity(false)"
/>
<Pagination <Pagination
:items-total="totalCount" :items-total="totalCount"
@ -120,7 +124,7 @@ import Releases from '../releases/releases.vue';
import Children from './children.vue'; import Children from './children.vue';
import Scroll from '../scroll/scroll.vue'; import Scroll from '../scroll/scroll.vue';
async function fetchEntity() { async function fetchEntity(scroll = true) {
const { entity, totalCount } = await this.$store.dispatch('fetchEntityBySlugAndType', { const { entity, totalCount } = await this.$store.dispatch('fetchEntityBySlugAndType', {
entitySlug: this.$route.params.entitySlug, entitySlug: this.$route.params.entitySlug,
entityType: this.$route.name, entityType: this.$route.name,
@ -134,7 +138,9 @@ async function fetchEntity() {
this.pageTitle = entity.name; this.pageTitle = entity.name;
this.$refs.filter.$el.scrollIntoView(); if (scroll) {
this.$refs.filter.$el.scrollIntoView();
}
} }
async function mounted() { async function mounted() {

View File

@ -10,7 +10,11 @@
:content="$refs.content" :content="$refs.content"
/> />
<Releases :releases="releases" /> <Releases
:releases="releases"
@stash="fetchReleases(false)"
@unstash="fetchReleases(false)"
/>
<Pagination <Pagination
v-if="totalCount > 0" v-if="totalCount > 0"
@ -29,7 +33,7 @@ import FilterBar from '../filters/filter-bar.vue';
import Releases from '../releases/releases.vue'; import Releases from '../releases/releases.vue';
import Pagination from '../pagination/pagination.vue'; import Pagination from '../pagination/pagination.vue';
async function fetchReleases() { async function fetchReleases(scroll = true) {
const { releases, totalCount } = await this.$store.dispatch('fetchReleases', { const { releases, totalCount } = await this.$store.dispatch('fetchReleases', {
limit: this.limit, limit: this.limit,
range: this.$route.params.range, range: this.$route.params.range,
@ -39,7 +43,9 @@ async function fetchReleases() {
this.totalCount = totalCount; this.totalCount = totalCount;
this.releases = releases; this.releases = releases;
this.$refs.filter?.$el.scrollIntoView(); if (scroll) {
this.$refs.filter?.$el.scrollIntoView();
}
} }
async function mounted() { async function mounted() {

View File

@ -52,14 +52,14 @@
</h2> </h2>
<Icon <Icon
v-show="me && isStashed" v-show="me && release.isStashed"
icon="heart7" icon="heart7"
class="stash stashed noselect" class="stash stashed noselect"
@click="unstashScene" @click="unstashScene"
/> />
<Icon <Icon
v-show="me && !isStashed" v-show="me && !release.isStashed"
icon="heart8" icon="heart8"
class="stash unstashed noselect" class="stash unstashed noselect"
@click="stashScene" @click="stashScene"
@ -275,10 +275,6 @@ function me() {
return this.$store.state.auth.user; return this.$store.state.auth.user;
} }
function isStashed() {
return this.release.stashes?.length > 0;
}
function bannerBackground() { function bannerBackground() {
return (this.release.poster && this.getBgPath(this.release.poster, 'thumbnail')) return (this.release.poster && this.getBgPath(this.release.poster, 'thumbnail'))
|| (this.release.covers.length > 0 && this.getBgPath(this.release.covers[0], 'thumbnail')); || (this.release.covers.length > 0 && this.getBgPath(this.release.covers[0], 'thumbnail'));
@ -313,7 +309,6 @@ export default {
computed: { computed: {
pageTitle, pageTitle,
bannerBackground, bannerBackground,
isStashed,
me, me,
showAlbum, showAlbum,
}, },

View File

@ -18,6 +18,8 @@
:release="release" :release="release"
:referer="referer" :referer="referer"
:index="index" :index="index"
@stash="$emit('stash')"
@unstash="$emit('unstash')"
/> />
</li> </li>
</ul> </ul>
@ -63,6 +65,7 @@ export default {
default: null, default: null,
}, },
}, },
emits: ['stash', 'unstash'],
computed: { computed: {
range, range,
sfw, sfw,

View File

@ -40,6 +40,20 @@
:title="release.title" :title="release.title"
class="thumbnail unavailable" class="thumbnail unavailable"
><Icon icon="blocked" />No thumbnail available</div> ><Icon icon="blocked" />No thumbnail available</div>
<Icon
v-show="release.isStashed"
icon="heart7"
class="stash stashed"
@click.prevent.native="unstashScene"
/>
<Icon
v-show="release.isStashed === false"
icon="heart8"
class="stash unstashed"
@click.prevent.native="stashScene"
/>
</a> </a>
</span> </span>
@ -133,6 +147,24 @@
<script> <script>
import Details from './tile-details.vue'; import Details from './tile-details.vue';
async function stashScene() {
this.$store.dispatch('stashScene', {
sceneId: this.release.id,
stashId: this.$store.getters.favorites.id,
});
this.$emit('stash');
}
async function unstashScene() {
this.$store.dispatch('unstashScene', {
sceneId: this.release.id,
stashId: this.$store.getters.favorites.id,
});
this.$emit('unstash');
}
export default { export default {
components: { components: {
Details, Details,
@ -143,6 +175,11 @@ export default {
default: null, default: null,
}, },
}, },
emits: ['stash', 'unstash'],
methods: {
stashScene,
unstashScene,
},
}; };
</script> </script>
@ -167,13 +204,17 @@ export default {
width: 1rem; width: 1rem;
height: 1rem; height: 1rem;
box-sizing: border-box; box-sizing: border-box;
padding: .1rem; padding: .375rem .25rem;
border-radius: 0 0 .5rem 0; border-radius: 0 0 .5rem 0;
color: var(--text-light); color: var(--primary);
background: var(--primary); font-size: 1rem;
font-size: .8rem;
font-weight: bold; font-weight: bold;
line-height: 1; line-height: 1;
text-shadow: 0 0 2px var(--darken-weak);
}
&:hover .unstashed {
fill: var(--lighten);
} }
} }
@ -216,6 +257,22 @@ export default {
} }
} }
.stash {
width: 1.25rem;
height: 1.25rem;
position: absolute;
top: 0;
right: 0;
padding: .25rem .25rem .5rem .5rem;
filter: drop-shadow(0 0 2px var(--darken-weak));
fill: var(--lighten-weak);
&:hover.unstashed,
&.stashed {
fill: var(--primary);
}
}
.row { .row {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@ -49,7 +49,11 @@
:fetch-releases="fetchReleases" :fetch-releases="fetchReleases"
/> />
<Releases :releases="releases" /> <Releases
:releases="releases"
@stash="fetchReleases(false)"
@unstash="fetchReleases(false)"
/>
<Pagination <Pagination
:items-total="totalCount" :items-total="totalCount"
@ -76,7 +80,7 @@ import Scroll from '../scroll/scroll.vue';
const converter = new Converter(); const converter = new Converter();
async function fetchReleases() { async function fetchReleases(scroll = true) {
const { tag, releases, totalCount } = await this.$store.dispatch('fetchTagBySlug', { const { tag, releases, totalCount } = await this.$store.dispatch('fetchTagBySlug', {
tagSlug: this.$route.params.tagSlug, tagSlug: this.$route.params.tagSlug,
pageNumber: Number(this.$route.params.pageNumber), pageNumber: Number(this.$route.params.pageNumber),
@ -91,7 +95,7 @@ async function fetchReleases() {
this.hasMedia = this.tag.poster || this.tag.photos.length > 0; this.hasMedia = this.tag.poster || this.tag.photos.length > 0;
this.description = this.tag.description && converter.makeHtml(escapeHtml(this.tag.description)); this.description = this.tag.description && converter.makeHtml(escapeHtml(this.tag.description));
if (this.$refs.filter) { if (scroll && this.$refs.filter) {
this.$refs.filter.$el.scrollIntoView(); this.$refs.filter.$el.scrollIntoView();
} }
} }

View File

@ -26,6 +26,8 @@ function initEntitiesActions(store, router) {
$beforeTime: Datetime = "2100-01-01", $beforeTime: Datetime = "2100-01-01",
$orderBy: [ReleasesOrderBy!] $orderBy: [ReleasesOrderBy!]
$exclude: [String!] $exclude: [String!]
$hasAuth: Boolean!
$userId: Int
) { ) {
entity: entityBySlugAndType(slug: $entitySlug, type: $entityType) { entity: entityBySlugAndType(slug: $entitySlug, type: $entityType) {
id id
@ -160,6 +162,8 @@ function initEntitiesActions(store, router) {
afterTime: store.getters.after, afterTime: store.getters.after,
beforeTime: store.getters.before, beforeTime: store.getters.before,
exclude: store.state.ui.tagFilter, exclude: store.state.ui.tagFilter,
hasAuth: !!store.state.auth.user,
userId: store.state.auth.user?.id,
}); });
if (!entity) { if (!entity) {

View File

@ -228,6 +228,22 @@ const releaseFields = `
url url
} }
isNew isNew
isStashed
stashes: stashesScenesBySceneId(
filter: {
stash: {
userId: {
equalTo: $userId
}
}
}
) @include(if: $hasAuth) {
stash {
id
name
slug
}
}
`; `;
const releasesFragment = ` const releasesFragment = `
@ -352,6 +368,7 @@ const releaseFragment = `
} }
} }
} }
isStashed
stashes: stashesScenesBySceneId( stashes: stashesScenesBySceneId(
filter: { filter: {
stash: { stash: {

View File

@ -9,6 +9,8 @@ function initReleasesActions(store, router) {
const { connection: { releases, totalCount } } = await graphql(` const { connection: { releases, totalCount } } = await graphql(`
query Releases( query Releases(
$hasAuth: Boolean!
$userId: Int
$limit:Int = 1000, $limit:Int = 1000,
$offset:Int = 0, $offset:Int = 0,
$after:Datetime = "1900-01-01 00:00:00", $after:Datetime = "1900-01-01 00:00:00",
@ -19,6 +21,8 @@ function initReleasesActions(store, router) {
${releasesFragment} ${releasesFragment}
} }
`, { `, {
hasAuth: !!store.state.auth.user,
userId: store.state.auth.user?.id,
limit, limit,
offset: Math.max(0, (pageNumber - 1)) * limit, offset: Math.max(0, (pageNumber - 1)) * limit,
after, after,

View File

@ -2,11 +2,13 @@ import { graphql, post, del } from '../api';
import { releaseFields } from '../fragments'; import { releaseFields } from '../fragments';
import { curateStash } from '../curate'; import { curateStash } from '../curate';
function initStashesActions(_store, _router) { function initStashesActions(store, _router) {
async function fetchStash(context, stashId) { async function fetchStash(context, stashId) {
const { stash } = await graphql(` const { stash } = await graphql(`
query Stash( query Stash(
$stashId: Int! $stashId: Int!
$hasAuth: Boolean!
$userId: Int
) { ) {
stash(id: $stashId) { stash(id: $stashId) {
id id
@ -52,6 +54,8 @@ function initStashesActions(_store, _router) {
} }
`, { `, {
stashId: Number(stashId), stashId: Number(stashId),
hasAuth: !!store.state.auth.user,
userId: store.state.auth.user?.id,
}); });
return curateStash(stash); return curateStash(stash);

View File

@ -23,6 +23,8 @@ function initTagsActions(store, _router) {
$before:Datetime = "2100-01-01", $before:Datetime = "2100-01-01",
$orderBy: [ReleasesOrderBy!], $orderBy: [ReleasesOrderBy!],
$exclude: [String!] $exclude: [String!]
$hasAuth: Boolean!
$userId: Int
) { ) {
tagBySlug(slug:$tagSlug) { tagBySlug(slug:$tagSlug) {
id id
@ -136,6 +138,8 @@ function initTagsActions(store, _router) {
orderBy, orderBy,
offset: Math.max(0, (pageNumber - 1)) * limit, offset: Math.max(0, (pageNumber - 1)) * limit,
exclude: store.state.ui.tagFilter.filter(tagFilter => tagFilter !== tagSlug), exclude: store.state.ui.tagFilter.filter(tagFilter => tagFilter !== tagSlug),
hasAuth: !!store.state.auth.user,
userId: store.state.auth.user?.id,
}); });
return { return {

View File

@ -2,10 +2,12 @@ import { graphql } from '../api';
import { releaseFields } from '../fragments'; import { releaseFields } from '../fragments';
import { curateUser } from '../curate'; import { curateUser } from '../curate';
function initUsersActions(_store, _router) { function initUsersActions(store, _router) {
async function fetchUser(context, username) { async function fetchUser(context, username) {
const { user } = await graphql(` const { user } = await graphql(`
query User( query User(
$hasAuth: Boolean!
$userId: Int
$username: String! $username: String!
) { ) {
user: userByUsername(username: $username) { user: userByUsername(username: $username) {
@ -52,6 +54,8 @@ function initUsersActions(_store, _router) {
} }
} }
`, { `, {
hasAuth: !!store.state.auth.user,
userId: store.state.auth.user?.id,
username, username,
}); });

View File

@ -2,12 +2,12 @@
const ActorPlugins = require('./actors'); const ActorPlugins = require('./actors');
const SitePlugins = require('./sites'); const SitePlugins = require('./sites');
// const ReleasePlugins = require('./releases'); const ReleasePlugins = require('./releases');
const MediaPlugins = require('./media'); const MediaPlugins = require('./media');
module.exports = { module.exports = {
ActorPlugins, ActorPlugins,
SitePlugins, SitePlugins,
ReleasePlugins: [], ReleasePlugins,
MediaPlugins, MediaPlugins,
}; };

View File

@ -4,12 +4,18 @@ const { makeExtendSchemaPlugin, gql } = require('graphile-utils');
const schemaExtender = makeExtendSchemaPlugin(_build => ({ const schemaExtender = makeExtendSchemaPlugin(_build => ({
typeDefs: gql` typeDefs: gql`
extend type Release {} extend type Release {
isStashed: Boolean @requires(columns: ["stashesScenesBySceneId"])
}
`, `,
resolvers: { resolvers: {
Release: { Release: {
async foo(_parent, _args, _context, _info) { isStashed(parent) {
// template if (!parent['@stashes']) {
return null;
}
return parent['@stashes'].length > 0;
}, },
}, },
}, },