diff --git a/resources/assets/js/checkin.ts b/resources/assets/js/checkin.tsx
similarity index 89%
rename from resources/assets/js/checkin.ts
rename to resources/assets/js/checkin.tsx
index 45bbd2a..5cbe176 100644
--- a/resources/assets/js/checkin.ts
+++ b/resources/assets/js/checkin.tsx
@@ -15,6 +15,17 @@ export enum MetadataLoadState {
Failed,
}
+export type Metadata = {
+ url: string;
+ title: string;
+ description: string;
+ image: string;
+ expires_at: string | null;
+ tags: {
+ name: string;
+ }[];
+};
+
new Vue({
el: '#app',
data: {
@@ -71,6 +82,6 @@ new Vue({
});
ReactDOM.render(
- React.createElement(TagInput2, { id: 'tagInput2', name: 'tags2', value: '', isInvalid: false }),
+ ,
document.querySelector('#tagInput2')
);
diff --git a/resources/assets/js/components/MetadataPreview2.tsx b/resources/assets/js/components/MetadataPreview2.tsx
new file mode 100644
index 0000000..e2dcdac
--- /dev/null
+++ b/resources/assets/js/components/MetadataPreview2.tsx
@@ -0,0 +1,110 @@
+import * as React from 'react';
+import { Metadata, MetadataLoadState } from '../checkin';
+import * as classNames from 'classnames';
+
+type Suggestion = {
+ name: string;
+ used: boolean;
+};
+
+type MetadataPreviewProps = {
+ state: MetadataLoadState;
+ metadata: Metadata | null;
+ tags: string[];
+ handleAddTag: (tag: string) => void;
+};
+
+const MetadataLoading = () => (
+
+
+
+
+ オカズの情報を読み込んでいます…
+
+
+
+
+);
+
+const MetadataLoadFailed = () => (
+
+
+
+
+ オカズの情報を読み込めませんでした
+
+
+
+
+);
+
+export const MetadataPreview: React.FC = ({ state, metadata, tags, handleAddTag }) => {
+ if (state === MetadataLoadState.Inactive) {
+ return null;
+ }
+ const hasImage = metadata !== null && metadata.image !== '';
+ const descClasses = classNames({
+ 'col-8': hasImage,
+ 'col-12': !hasImage,
+ });
+ const tagClasses = (s: Suggestion) =>
+ classNames({
+ 'list-inline-item': true,
+ badge: true,
+ 'badge-primary': !s.used,
+ 'badge-secondary': s.used,
+ 'metadata-tag-item': true,
+ });
+ const suggestions =
+ metadata?.tags.map((t) => ({
+ name: t.name,
+ used: tags.indexOf(t.name) !== -1,
+ })) ?? [];
+
+ return (
+
+
+
+ {state === MetadataLoadState.Loading ? (
+
+ ) : state === MetadataLoadState.Success ? (
+
+
+
+
+
+
+
{metadata?.title}
+ {suggestions.length > 0 && (
+ <>
+
+ タグ候補
+
+
+ (クリックするとタグ入力欄にコピーできます)
+
+
+
+ {suggestions.map((tag) => (
+ - handleAddTag(tag.name)}
+ >
+ {tag.name}
+
+ ))}
+
+ >
+ )}
+
+
+
+ ) : (
+
+ )}
+
+
+
+ );
+};
diff --git a/resources/assets/sass/components/_metadata-preview.scss b/resources/assets/sass/components/_metadata-preview.scss
new file mode 100644
index 0000000..4ce8e79
--- /dev/null
+++ b/resources/assets/sass/components/_metadata-preview.scss
@@ -0,0 +1,28 @@
+.tis-metadata-preview {
+ &-link-card {
+ $height: 150px;
+ overflow: hidden;
+ font-size: small;
+
+ .row > div:first-child {
+ display: flex;
+
+ &:not([display='none']) {
+ min-height: $height;
+
+ img {
+ position: absolute;
+ }
+ }
+ }
+
+ .card-text {
+ white-space: pre-line;
+ }
+ }
+
+ &-tag-item {
+ cursor: pointer;
+ user-select: none;
+ }
+}
diff --git a/resources/views/ejaculation/checkin.blade.php b/resources/views/ejaculation/checkin.blade.php
index 1ae063f..9ffb8ca 100644
--- a/resources/views/ejaculation/checkin.blade.php
+++ b/resources/views/ejaculation/checkin.blade.php
@@ -65,6 +65,7 @@
+