とりあえず一旦これで自動修正
This commit is contained in:
@@ -5,23 +5,29 @@
|
||||
<div v-if="state === MetadataLoadState.Loading" class="row no-gutters">
|
||||
<div class="col-12">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title text-center font-weight-bold text-info" style="font-size: small;"><span class="oi oi-loop-circular"></span> オカズの情報を読み込んでいます…</h6>
|
||||
<h6 class="card-title text-center font-weight-bold text-info" style="font-size: small;">
|
||||
<span class="oi oi-loop-circular"></span> オカズの情報を読み込んでいます…
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="state === MetadataLoadState.Success" class="row no-gutters">
|
||||
<div v-if="hasImage" class="col-4 justify-content-center align-items-center">
|
||||
<img :src="metadata.image" alt="Thumbnail" class="w-100 bg-secondary">
|
||||
<img :src="metadata.image" alt="Thumbnail" class="w-100 bg-secondary" />
|
||||
</div>
|
||||
<div :class="descClasses">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title font-weight-bold" style="font-size: small;">{{ metadata.title }}</h6>
|
||||
<template v-if="suggestions.length > 0">
|
||||
<p class="card-text mb-2" style="font-size: small;">タグ候補<br><span class="text-secondary">(クリックするとタグ入力欄にコピーできます)</span></p>
|
||||
<p class="card-text mb-2" style="font-size: small;">
|
||||
タグ候補<br /><span class="text-secondary"
|
||||
>(クリックするとタグ入力欄にコピーできます)</span
|
||||
>
|
||||
</p>
|
||||
<ul class="list-inline d-inline">
|
||||
<li v-for="tag in suggestions"
|
||||
:class="tagClasses(tag)"
|
||||
@click="addTag(tag.name)"><span class="oi oi-tag"></span> {{ tag.name }}</li>
|
||||
<li v-for="tag in suggestions" :class="tagClasses(tag)" @click="addTag(tag.name)">
|
||||
<span class="oi oi-tag"></span> {{ tag.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</div>
|
||||
@@ -30,7 +36,9 @@
|
||||
<div v-else class="row no-gutters">
|
||||
<div class="col-12">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title text-center font-weight-bold text-danger" style="font-size: small;"><span class="oi oi-circle-x"></span> オカズの情報を読み込めませんでした</h6>
|
||||
<h6 class="card-title text-center font-weight-bold text-danger" style="font-size: small;">
|
||||
<span class="oi oi-circle-x"></span> オカズの情報を読み込めませんでした
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,104 +48,104 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {Vue, Component, Prop} from "vue-property-decorator";
|
||||
import {bus, MetadataLoadState} from "../checkin";
|
||||
import { Vue, Component, Prop } from 'vue-property-decorator';
|
||||
import { bus, MetadataLoadState } from '../checkin';
|
||||
|
||||
type Metadata = {
|
||||
url: string,
|
||||
title: string,
|
||||
description: string,
|
||||
image: string,
|
||||
expires_at: string | null,
|
||||
tags: {
|
||||
name: string
|
||||
}[],
|
||||
};
|
||||
type Metadata = {
|
||||
url: string;
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
expires_at: string | null;
|
||||
tags: {
|
||||
name: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
type Suggestion = {
|
||||
name: string,
|
||||
used: boolean,
|
||||
type Suggestion = {
|
||||
name: string;
|
||||
used: boolean;
|
||||
};
|
||||
|
||||
@Component
|
||||
export default class MetadataPreview extends Vue {
|
||||
@Prop() readonly state!: MetadataLoadState;
|
||||
@Prop() readonly metadata!: Metadata | null;
|
||||
|
||||
// for use in v-if
|
||||
private readonly MetadataLoadState = MetadataLoadState;
|
||||
|
||||
tags: string[] = [];
|
||||
|
||||
created() {
|
||||
bus.$on('change-tag', (tags: string[]) => (this.tags = tags));
|
||||
bus.$emit('resend-tag');
|
||||
}
|
||||
|
||||
@Component
|
||||
export default class MetadataPreview extends Vue {
|
||||
@Prop() readonly state!: MetadataLoadState;
|
||||
@Prop() readonly metadata!: Metadata | null;
|
||||
|
||||
// for use in v-if
|
||||
private readonly MetadataLoadState = MetadataLoadState;
|
||||
|
||||
tags: string[] = [];
|
||||
|
||||
created() {
|
||||
bus.$on("change-tag", (tags: string[]) => this.tags = tags);
|
||||
bus.$emit("resend-tag");
|
||||
}
|
||||
|
||||
addTag(tag: string) {
|
||||
bus.$emit("add-tag", tag);
|
||||
}
|
||||
|
||||
tagClasses(s: Suggestion) {
|
||||
return {
|
||||
"list-inline-item": true,
|
||||
"badge": true,
|
||||
"badge-primary": !s.used,
|
||||
"badge-secondary": s.used,
|
||||
"metadata-tag-item": true,
|
||||
};
|
||||
}
|
||||
|
||||
get suggestions(): Suggestion[] {
|
||||
if (this.metadata === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.metadata.tags.map(t => {
|
||||
return {
|
||||
name: t.name,
|
||||
used: this.tags.indexOf(t.name) !== -1
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
get hasImage() {
|
||||
return this.metadata !== null && this.metadata.image !== ''
|
||||
}
|
||||
|
||||
get descClasses() {
|
||||
return {
|
||||
"col-8": this.hasImage,
|
||||
"col-12": !this.hasImage,
|
||||
};
|
||||
}
|
||||
addTag(tag: string) {
|
||||
bus.$emit('add-tag', tag);
|
||||
}
|
||||
|
||||
tagClasses(s: Suggestion) {
|
||||
return {
|
||||
'list-inline-item': true,
|
||||
badge: true,
|
||||
'badge-primary': !s.used,
|
||||
'badge-secondary': s.used,
|
||||
'metadata-tag-item': true,
|
||||
};
|
||||
}
|
||||
|
||||
get suggestions(): Suggestion[] {
|
||||
if (this.metadata === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.metadata.tags.map((t) => {
|
||||
return {
|
||||
name: t.name,
|
||||
used: this.tags.indexOf(t.name) !== -1,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
get hasImage() {
|
||||
return this.metadata !== null && this.metadata.image !== '';
|
||||
}
|
||||
|
||||
get descClasses() {
|
||||
return {
|
||||
'col-8': this.hasImage,
|
||||
'col-12': !this.hasImage,
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.link-card-mini {
|
||||
$height: 150px;
|
||||
overflow: hidden;
|
||||
.link-card-mini {
|
||||
$height: 150px;
|
||||
overflow: hidden;
|
||||
|
||||
.row > div:first-child {
|
||||
display: flex;
|
||||
.row > div:first-child {
|
||||
display: flex;
|
||||
|
||||
&:not([display=none]) {
|
||||
min-height: $height;
|
||||
&:not([display='none']) {
|
||||
min-height: $height;
|
||||
|
||||
img {
|
||||
position: absolute;
|
||||
}
|
||||
img {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.card-text {
|
||||
white-space: pre-line;
|
||||
}
|
||||
}
|
||||
|
||||
.metadata-tag-item {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
.card-text {
|
||||
white-space: pre-line;
|
||||
}
|
||||
}
|
||||
|
||||
.metadata-tag-item {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,96 +1,91 @@
|
||||
<template>
|
||||
<div :class="containerClass" @click="$refs.input.focus()">
|
||||
<input :name="name" type="hidden" :value="tagValue">
|
||||
<input :name="name" type="hidden" :value="tagValue" />
|
||||
<ul class="list-inline d-inline">
|
||||
<li v-for="(tag, i) in tags"
|
||||
class="list-inline-item badge badge-primary tag-item"
|
||||
@click="removeTag(i)"><span class="oi oi-tag"></span> {{ tag }} | x</li>
|
||||
<li v-for="(tag, i) in tags" class="list-inline-item badge badge-primary tag-item" @click="removeTag(i)">
|
||||
<span class="oi oi-tag"></span> {{ tag }} | x
|
||||
</li>
|
||||
</ul>
|
||||
<input :id="id"
|
||||
ref="input"
|
||||
type="text"
|
||||
class="tag-input"
|
||||
v-model="buffer"
|
||||
@keydown="onKeyDown">
|
||||
<input :id="id" ref="input" type="text" class="tag-input" v-model="buffer" @keydown="onKeyDown" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {Vue, Component, Prop, Watch} from "vue-property-decorator";
|
||||
import {bus} from "../checkin";
|
||||
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
|
||||
import { bus } from '../checkin';
|
||||
|
||||
@Component
|
||||
export default class TagInput extends Vue {
|
||||
@Prop(String) readonly id!: string;
|
||||
@Prop(String) readonly name!: string;
|
||||
@Prop(String) readonly value!: string;
|
||||
@Prop(Boolean) readonly isInvalid!: boolean;
|
||||
@Component
|
||||
export default class TagInput extends Vue {
|
||||
@Prop(String) readonly id!: string;
|
||||
@Prop(String) readonly name!: string;
|
||||
@Prop(String) readonly value!: string;
|
||||
@Prop(Boolean) readonly isInvalid!: boolean;
|
||||
|
||||
tags: string[] = this.value.trim() !== "" ? this.value.trim().split(" ") : [];
|
||||
buffer: string = "";
|
||||
tags: string[] = this.value.trim() !== '' ? this.value.trim().split(' ') : [];
|
||||
buffer = '';
|
||||
|
||||
created() {
|
||||
bus.$on("add-tag", (tag: string) => this.tags.indexOf(tag) === -1 && this.tags.push(tag));
|
||||
bus.$on("resend-tag", () => bus.$emit("change-tag", this.tags));
|
||||
}
|
||||
created() {
|
||||
bus.$on('add-tag', (tag: string) => this.tags.indexOf(tag) === -1 && this.tags.push(tag));
|
||||
bus.$on('resend-tag', () => bus.$emit('change-tag', this.tags));
|
||||
}
|
||||
|
||||
onKeyDown(event: KeyboardEvent) {
|
||||
if (this.buffer.trim() !== "") {
|
||||
switch (event.key) {
|
||||
case 'Tab':
|
||||
case 'Enter':
|
||||
case ' ':
|
||||
if ((event as any).isComposing !== true) {
|
||||
this.tags.push(this.buffer.trim());
|
||||
this.buffer = "";
|
||||
}
|
||||
onKeyDown(event: KeyboardEvent) {
|
||||
if (this.buffer.trim() !== '') {
|
||||
switch (event.key) {
|
||||
case 'Tab':
|
||||
case 'Enter':
|
||||
case ' ':
|
||||
if ((event as any).isComposing !== true) {
|
||||
this.tags.push(this.buffer.trim());
|
||||
this.buffer = '';
|
||||
}
|
||||
event.preventDefault();
|
||||
break;
|
||||
case 'Unidentified':
|
||||
// 実際にテキストボックスに入力されている文字を見に行く (フォールバック処理)
|
||||
if (event.srcElement && (event.srcElement as HTMLInputElement).value.slice(-1) == ' ') {
|
||||
this.tags.push(this.buffer.trim());
|
||||
this.buffer = '';
|
||||
event.preventDefault();
|
||||
break;
|
||||
case 'Unidentified':
|
||||
// 実際にテキストボックスに入力されている文字を見に行く (フォールバック処理)
|
||||
if (event.srcElement && (event.srcElement as HTMLInputElement).value.slice(-1) == ' ') {
|
||||
this.tags.push(this.buffer.trim());
|
||||
this.buffer = "";
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (event.key === "Enter") {
|
||||
// 誤爆防止
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
removeTag(index: number) {
|
||||
this.tags.splice(index, 1);
|
||||
}
|
||||
|
||||
@Watch("tags")
|
||||
onTagsChanged() {
|
||||
bus.$emit("change-tag", this.tags);
|
||||
}
|
||||
|
||||
get containerClass(): object {
|
||||
return {
|
||||
"form-control": true,
|
||||
"h-auto": true,
|
||||
"is-invalid": this.isInvalid
|
||||
};
|
||||
}
|
||||
|
||||
get tagValue(): string {
|
||||
return this.tags.join(" ");
|
||||
} else if (event.key === 'Enter') {
|
||||
// 誤爆防止
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
removeTag(index: number) {
|
||||
this.tags.splice(index, 1);
|
||||
}
|
||||
|
||||
@Watch('tags')
|
||||
onTagsChanged() {
|
||||
bus.$emit('change-tag', this.tags);
|
||||
}
|
||||
|
||||
get containerClass(): object {
|
||||
return {
|
||||
'form-control': true,
|
||||
'h-auto': true,
|
||||
'is-invalid': this.isInvalid,
|
||||
};
|
||||
}
|
||||
|
||||
get tagValue(): string {
|
||||
return this.tags.join(' ');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tag-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
.tag-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tag-input {
|
||||
border: 0;
|
||||
outline: 0;
|
||||
}
|
||||
.tag-input {
|
||||
border: 0;
|
||||
outline: 0;
|
||||
}
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user