215 lines
8.6 KiB
Vue
215 lines
8.6 KiB
Vue
<template>
|
|
<div class="character-kinks-block" @contextmenu="contextMenu" @touchstart="contextMenu" @touchend="contextMenu">
|
|
<div class="compare-highlight-block d-flex justify-content-between">
|
|
<div v-if="shared.authenticated" class="quick-compare-block form-inline">
|
|
<character-select v-model="characterToCompare"></character-select>
|
|
<button class="btn btn-primary" @click="compareKinks" :disabled="loading || !characterToCompare">
|
|
{{ compareButtonText }}
|
|
</button>
|
|
</div>
|
|
<div class="form-inline">
|
|
<select v-model="highlightGroup" class="form-control">
|
|
<option :value="undefined">None</option>
|
|
<option v-for="group in kinkGroups" v-if="group" :value="group.id" :key="group.id">{{group.name}}</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="form-row mt-3">
|
|
<div class="col-sm-6 col-lg-3">
|
|
<div class="card bg-light">
|
|
<div class="card-header">
|
|
<h4>Favorites</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<kink v-for="kink in groupedKinks['favorite']" :kink="kink" :key="kink.key" :highlights="highlighting"
|
|
:comparisons="comparison"></kink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-lg-3">
|
|
<div class="card bg-light">
|
|
<div class="card-header">
|
|
<h4>Yes</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<kink v-for="kink in groupedKinks['yes']" :kink="kink" :key="kink.key" :highlights="highlighting"
|
|
:comparisons="comparison"></kink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-lg-3">
|
|
<div class="card bg-light">
|
|
<div class="card-header">
|
|
<h4>Maybe</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<kink v-for="kink in groupedKinks['maybe']" :kink="kink" :key="kink.key" :highlights="highlighting"
|
|
:comparisons="comparison"></kink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-lg-3">
|
|
<div class="card bg-light">
|
|
<div class="card-header">
|
|
<h4>No</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<kink v-for="kink in groupedKinks['no']" :kink="kink" :key="kink.key" :highlights="highlighting"
|
|
:comparisons="comparison"></kink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<context-menu v-if="shared.authenticated && !oldApi" prop-name="custom" ref="context-menu"></context-menu>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import {Component, Prop, Watch} from '@f-list/vue-ts';
|
|
import Vue from 'vue';
|
|
import {Kink, KinkChoice, KinkGroup} from '../../interfaces';
|
|
import * as Utils from '../utils';
|
|
import CopyCustomMenu from './copy_custom_menu.vue';
|
|
import {methods, Store} from './data_store';
|
|
import {Character, DisplayKink} from './interfaces';
|
|
import KinkView from './kink.vue';
|
|
|
|
@Component({
|
|
components: {'context-menu': CopyCustomMenu, kink: KinkView}
|
|
})
|
|
export default class CharacterKinksView extends Vue {
|
|
@Prop({required: true})
|
|
readonly character!: Character;
|
|
@Prop
|
|
readonly oldApi?: true;
|
|
shared = Store;
|
|
characterToCompare = Utils.settings.defaultCharacter;
|
|
highlightGroup: number | undefined;
|
|
|
|
loading = false;
|
|
comparing = false;
|
|
highlighting: {[key: string]: boolean} = {};
|
|
comparison: {[key: string]: KinkChoice} = {};
|
|
|
|
async compareKinks(): Promise<void> {
|
|
if(this.comparing) {
|
|
this.comparison = {};
|
|
this.comparing = false;
|
|
this.loading = false;
|
|
return;
|
|
}
|
|
|
|
try {
|
|
this.loading = true;
|
|
this.comparing = true;
|
|
const kinks = await methods.kinksGet(this.characterToCompare);
|
|
const toAssign: {[key: number]: KinkChoice} = {};
|
|
for(const kink of kinks)
|
|
toAssign[kink.id] = kink.choice;
|
|
this.comparison = toAssign;
|
|
} catch(e) {
|
|
this.comparing = false;
|
|
this.comparison = {};
|
|
Utils.ajaxError(e, 'Unable to get kinks for comparison.');
|
|
}
|
|
this.loading = false;
|
|
}
|
|
|
|
@Watch('highlightGroup')
|
|
highlightKinks(group: number | null): void {
|
|
this.highlighting = {};
|
|
if(group === null) return;
|
|
const toAssign: {[key: string]: boolean} = {};
|
|
for(const kinkId in Store.shared.kinks) {
|
|
const kink = Store.shared.kinks[kinkId];
|
|
if(kink.kink_group === group)
|
|
toAssign[kinkId] = true;
|
|
}
|
|
this.highlighting = toAssign;
|
|
}
|
|
|
|
get kinkGroups(): {[key: string]: KinkGroup | undefined} {
|
|
return Store.shared.kinkGroups;
|
|
}
|
|
|
|
get compareButtonText(): string {
|
|
if(this.loading)
|
|
return 'Loading...';
|
|
return this.comparing ? 'Clear' : 'Compare';
|
|
}
|
|
|
|
get groupedKinks(): {[key in KinkChoice]: DisplayKink[]} {
|
|
const kinks = Store.shared.kinks;
|
|
const characterKinks = this.character.character.kinks;
|
|
const characterCustoms = this.character.character.customs;
|
|
const displayCustoms: {[key: string]: DisplayKink | undefined} = {};
|
|
const outputKinks: {[key: string]: DisplayKink[]} = {favorite: [], yes: [], maybe: [], no: []};
|
|
const makeKink = (kink: Kink): DisplayKink => ({
|
|
id: kink.id,
|
|
name: kink.name,
|
|
description: kink.description,
|
|
group: kink.kink_group,
|
|
isCustom: false,
|
|
hasSubkinks: false,
|
|
ignore: false,
|
|
subkinks: [],
|
|
key: kink.id.toString()
|
|
});
|
|
const kinkSorter = (a: DisplayKink, b: DisplayKink) => {
|
|
if(this.character.settings.customs_first && a.isCustom !== b.isCustom)
|
|
return a.isCustom < b.isCustom ? 1 : -1;
|
|
|
|
if(a.name === b.name)
|
|
return 0;
|
|
return a.name < b.name ? -1 : 1;
|
|
};
|
|
|
|
for(const id in characterCustoms) {
|
|
const custom = characterCustoms[id]!;
|
|
displayCustoms[id] = {
|
|
id: custom.id,
|
|
name: custom.name,
|
|
description: custom.description,
|
|
choice: custom.choice,
|
|
group: -1,
|
|
isCustom: true,
|
|
hasSubkinks: false,
|
|
ignore: false,
|
|
subkinks: [],
|
|
key: `c${custom.id}`
|
|
};
|
|
}
|
|
|
|
for(const kinkId in characterKinks) {
|
|
const kinkChoice = characterKinks[kinkId]!;
|
|
const kink = <Kink | undefined>kinks[kinkId];
|
|
if(kink === undefined) continue;
|
|
const newKink = makeKink(kink);
|
|
if(typeof kinkChoice === 'number' && typeof displayCustoms[kinkChoice] !== 'undefined') {
|
|
const custom = displayCustoms[kinkChoice]!;
|
|
newKink.ignore = true;
|
|
custom.hasSubkinks = true;
|
|
custom.subkinks.push(newKink);
|
|
}
|
|
if(!newKink.ignore)
|
|
outputKinks[kinkChoice].push(newKink);
|
|
}
|
|
|
|
for(const customId in displayCustoms) {
|
|
const custom = displayCustoms[customId]!;
|
|
if(custom.hasSubkinks)
|
|
custom.subkinks.sort(kinkSorter);
|
|
outputKinks[<string>custom.choice].push(custom);
|
|
}
|
|
|
|
for(const choice in outputKinks)
|
|
outputKinks[choice].sort(kinkSorter);
|
|
|
|
return <{[key in KinkChoice]: DisplayKink[]}>outputKinks;
|
|
}
|
|
|
|
contextMenu(event: TouchEvent): void {
|
|
if(this.shared.authenticated && !this.oldApi) (<CopyCustomMenu>this.$refs['context-menu']).outerClick(event);
|
|
}
|
|
}
|
|
</script> |