メタデータプレビューとタグ候補選択のコンポーネント
This commit is contained in:
parent
a1cb313d4f
commit
b8482e0e3c
@ -1,9 +1,45 @@
|
||||
import Vue from 'vue';
|
||||
import TagInput from "./components/TagInput.vue";
|
||||
import MetadataPreview from './components/MetadataPreview.vue';
|
||||
|
||||
export const bus = new Vue({name: "EventBus"});
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
metadata: null
|
||||
},
|
||||
components: {
|
||||
TagInput
|
||||
TagInput,
|
||||
MetadataPreview
|
||||
},
|
||||
mounted() {
|
||||
// TODO: 編集モード時はすぐにメタデータを取得する
|
||||
},
|
||||
methods: {
|
||||
// オカズリンクの変更時
|
||||
onChangeLink(event: Event) {
|
||||
if (event.target instanceof HTMLInputElement) {
|
||||
const url = event.target.value;
|
||||
|
||||
if (url.trim() === '' || !/^https?:\/\//.test(url)) {
|
||||
this.metadata = null;
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '/api/checkin/card',
|
||||
method: 'get',
|
||||
type: 'json',
|
||||
data: {
|
||||
url
|
||||
}
|
||||
}).then(data => {
|
||||
this.metadata = data;
|
||||
}).catch(e => {
|
||||
this.metadata = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
66
resources/assets/js/components/MetadataPreview.vue
Normal file
66
resources/assets/js/components/MetadataPreview.vue
Normal file
@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<div class="form-row" v-if="metadata !== null">
|
||||
<div class="form-group col-sm-12">
|
||||
<div class="card link-card-mini mb-2 px-0">
|
||||
<div class="row no-gutters">
|
||||
<div class="col-4 justify-content-center align-items-center">
|
||||
<img :src="metadata.image" alt="Thumbnail" class="card-img-top-to-left bg-secondary">
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<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>
|
||||
<ul class="list-inline d-inline">
|
||||
<li v-for="tag in suggestions"
|
||||
class="list-inline-item badge badge-primary metadata-tag-item"
|
||||
@click="addTag(tag)"><span class="oi oi-tag"></span> {{ tag }}</li>
|
||||
</ul>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {Vue, Component, Prop} from "vue-property-decorator";
|
||||
import {bus} from "../checkin";
|
||||
|
||||
type Metadata = {
|
||||
url: string,
|
||||
title: string | null,
|
||||
description: string | null,
|
||||
image: string | null,
|
||||
expires_at: string | null,
|
||||
tags: {
|
||||
name: string
|
||||
}[],
|
||||
};
|
||||
|
||||
@Component
|
||||
export default class MetadataPreview extends Vue {
|
||||
@Prop() readonly metadata!: Metadata | null;
|
||||
|
||||
addTag(tag: string) {
|
||||
bus.$emit("add-tag", tag);
|
||||
}
|
||||
|
||||
get suggestions() {
|
||||
if (this.metadata === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.metadata.tags.map(t => t.name);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.metadata-tag-item {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
@ -17,6 +17,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import {Vue, Component, Prop} from "vue-property-decorator";
|
||||
import {bus} from "../checkin";
|
||||
|
||||
@Component
|
||||
export default class TagInput extends Vue {
|
||||
@ -28,6 +29,10 @@
|
||||
tags: string[] = this.value.trim() !== "" ? this.value.trim().split(" ") : [];
|
||||
buffer: string = "";
|
||||
|
||||
created() {
|
||||
bus.$on("add-tag", (tag: string) => this.tags.push(tag));
|
||||
}
|
||||
|
||||
onKeyDown(event: KeyboardEvent) {
|
||||
if (this.buffer.trim() !== "") {
|
||||
switch (event.key) {
|
||||
|
23
resources/assets/sass/components/_link-card.scss
vendored
23
resources/assets/sass/components/_link-card.scss
vendored
@ -28,4 +28,25 @@
|
||||
.card-text {
|
||||
white-space: pre-line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// チェックイン画面用
|
||||
.link-card-mini {
|
||||
$height: 150px;
|
||||
|
||||
.row > div {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.row > div:first-child {
|
||||
display: flex;
|
||||
|
||||
&:not([display=none]) {
|
||||
height: $height;
|
||||
}
|
||||
}
|
||||
|
||||
.card-text {
|
||||
white-space: pre-line;
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,9 @@
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label for="link"><span class="oi oi-link-intact"></span> オカズリンク</label>
|
||||
<input id="link" name="link" type="text" autocomplete="off" class="form-control {{ $errors->has('link') ? ' is-invalid' : '' }}" placeholder="http://..." value="{{ old('link') ?? $defaults['link'] }}">
|
||||
<input id="link" name="link" type="text" autocomplete="off" class="form-control {{ $errors->has('link') ? ' is-invalid' : '' }}"
|
||||
placeholder="http://..." value="{{ old('link') ?? $defaults['link'] }}"
|
||||
@change="onChangeLink">
|
||||
<small class="form-text text-muted">
|
||||
オカズのURLを貼り付けて登録することができます。
|
||||
</small>
|
||||
@ -61,6 +63,7 @@
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<metadata-preview :metadata="metadata"></metadata-preview>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>
|
||||
@ -96,4 +99,4 @@
|
||||
|
||||
@push('script')
|
||||
<script src="{{ mix('js/checkin.js') }}"></script>
|
||||
@endpush
|
||||
@endpush
|
||||
|
@ -53,7 +53,9 @@
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label for="link"><span class="oi oi-link-intact"></span> オカズリンク</label>
|
||||
<input id="link" name="link" type="text" autocomplete="off" class="form-control {{ $errors->has('link') ? ' is-invalid' : '' }}" placeholder="http://..." value="{{ old('link') ?? $ejaculation->link }}">
|
||||
<input id="link" name="link" type="text" autocomplete="off" class="form-control {{ $errors->has('link') ? ' is-invalid' : '' }}"
|
||||
placeholder="http://..." value="{{ old('link') ?? $ejaculation->link }}"
|
||||
@change="onChangeLink">
|
||||
<small class="form-text text-muted">
|
||||
オカズのURLを貼り付けて登録することができます。
|
||||
</small>
|
||||
@ -62,6 +64,7 @@
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<metadata-preview :metadata="metadata"></metadata-preview>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>
|
||||
@ -97,4 +100,4 @@
|
||||
|
||||
@push('script')
|
||||
<script src="{{ mix('js/checkin.js') }}"></script>
|
||||
@endpush
|
||||
@endpush
|
||||
|
Loading…
Reference in New Issue
Block a user