Skip to content

Commit 6b02c3e

Browse files
committed
feat: finish the core reaction system
1 parent dca0299 commit 6b02c3e

5 files changed

Lines changed: 96 additions & 101 deletions

File tree

src/components/ImageCard.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Fieldset } from 'primereact/fieldset';
44
import { Tag } from 'primereact/tag';
55
import { createPortal } from 'react-dom';
66
import { Preview } from './Preview';
7+
import { PhotoReaction } from '../types/PhotoReaction';
78

89
export interface ImageElement {
910
id: number;
@@ -12,6 +13,7 @@ export interface ImageElement {
1213
info?: string;
1314
categories?: string[];
1415
author?: string;
16+
reaction?: PhotoReaction;
1517
}
1618

1719
export interface ImageCardProps {

src/components/Preview.tsx

Lines changed: 66 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import { InputText } from 'primereact/inputtext';
1+
import { SelectButton } from 'primereact/selectbutton';
22
import { Button } from 'primereact/button';
3-
import { SplitButton } from 'primereact/splitbutton';
3+
import { AutoComplete } from 'primereact/autocomplete';
44
import React, { useState } from 'react';
55
import { TransformWrapper, TransformComponent, MiniMap } from "react-zoom-pan-pinch";
66
import { ImageElement } from './ImageCard';
77
import { DomHandler } from 'primereact/utils';
88
import { gql, useMutation } from '@apollo/client';
9-
import { format } from 'date-fns';
109

1110
const CREATE_COMMENT = gql`
1211
mutation CreateOneComment($data: PhotoReactionInsertInput!) {
@@ -17,10 +16,11 @@ mutation CreateOneComment($data: PhotoReactionInsertInput!) {
1716
}
1817
`;
1918

20-
const CREATE_TAG = gql`
21-
mutation CreateOneTAG($data: TagInsertInput!) {
22-
tagCreateOne(data: $data) {
23-
id
19+
const UPDATE_COMMENT = gql`
20+
mutation UpdateOneComment($data: PhotoReactionUpdateInput!, $filter: PhotoReactionFilterInput!) {
21+
photoReactionUpdate(data: $data, filter: $filter) {
22+
comment,
23+
isRecommended
2424
}
2525
}
2626
`;
@@ -32,90 +32,54 @@ interface PreviewProps {
3232
onClose: () => void;
3333
}
3434

35-
function generateRandomString(): string {
36-
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
37-
let result = '';
38-
for (let i = 0; i < 3; i++) {
39-
const randomIndex = Math.floor(Math.random() * letters.length);
40-
result += letters[randomIndex];
41-
}
42-
return result;
43-
}
44-
4535
export const Preview: React.FC<PreviewProps> = (props) => {
4636
const { height } = DomHandler.getViewport();
4737
const [index, setIndex] = useState<number>(props.index);
4838
const image = props.images[index];
49-
const [value, setValue] = useState<string>('');
39+
const [isRecommended, setIsRecommended] = useState<string | null>(
40+
image.reaction ? (image.reaction.isRecommended ? '正向' : '負向') : null
41+
);
42+
const [value, setValue] = useState<string>(image.reaction?.comment ?? '');
43+
const [searchItems, setSearchItems] = useState<string[]>([]);
5044
const [createComment] = useMutation(CREATE_COMMENT);
51-
const [createTag] = useMutation(CREATE_TAG);
52-
const goods = [
53-
{
54-
label: '構圖不錯',
55-
command: async () => {
56-
await createComment({
57-
variables: {
58-
data: {
59-
userId: props.userId,
60-
photoId: image.id,
61-
comment: '構圖不錯',
62-
isRecommended: 1
63-
}
64-
}
65-
});
66-
}
67-
},
68-
{
69-
label: '攝影技巧不錯',
70-
command: async () => {
71-
await createTag({
72-
variables: {
73-
data: {
74-
name: generateRandomString(),
75-
description: '測試',
76-
note: '測試',
77-
tagType: 'photographer'
78-
}
79-
}
80-
})
81-
}
82-
},
83-
{
84-
label: '主題選擇不錯',
85-
command: () => {
86-
45+
const [updateComment] = useMutation(UPDATE_COMMENT);
46+
const handleCreateComment = async (comment: string, isRecommended: number) => {
47+
if (image.reaction) {
48+
await updateComment({
49+
variables: {
50+
data: {
51+
comment,
52+
isRecommended
53+
},
54+
filter: {
55+
userId: { eq: props.userId },
56+
photoId: { eq: image.id }
57+
}
8758
}
88-
},
89-
{
90-
label: '內容充實',
91-
command: () => {
92-
93-
}
94-
}
95-
];
96-
const bads = [
97-
{
98-
label: '構圖不好',
99-
command: () => {
100-
}
101-
},
102-
{
103-
label: '過曝',
104-
command: () => {
105-
}
106-
},
107-
{
108-
label: '失焦',
109-
command: () => {
110-
111-
}
112-
},
113-
{
114-
label: '光線不足',
115-
command: () => {
116-
59+
});
60+
} else {
61+
await createComment({
62+
variables: {
63+
data: {
64+
userId: props.userId,
65+
photoId: image.id,
66+
comment,
67+
isRecommended
68+
}
11769
}
70+
});
11871
}
72+
setValue('');
73+
};
74+
const suggestions = [
75+
'構圖不錯',
76+
'攝影技巧不錯',
77+
'主題選擇不錯',
78+
'內容充實',
79+
'構圖不好',
80+
'過曝',
81+
'失焦',
82+
'光線不足',
11983
];
12084
return (
12185
<>
@@ -127,22 +91,26 @@ export const Preview: React.FC<PreviewProps> = (props) => {
12791
>
12892
<div className='flex h-full ml-2 min-w-[700px]'>
12993
<div className='flex h-full items-center gap-2'>
130-
<SplitButton label="我喜歡" icon="pi pi-plus" model={goods} size="small" />
131-
<SplitButton label="影象模糊" icon="pi pi-plus" model={bads} size="small" />
132-
<InputText value={value} onChange={(e) => setValue(e.target.value)} placeholder='其他想法' className='z-1002' />
94+
<AutoComplete
95+
suggestions={searchItems}
96+
value={value}
97+
onChange={(e) => setValue(e.value)}
98+
completeMethod={(e) => {
99+
setSearchItems(suggestions.filter(item => item.includes(e.query)));
100+
}}
101+
dropdown
102+
placeholder='建議'
103+
className='z-1002'
104+
/>
133105
<span className='!text-white'></span>
134-
<Button
135-
size='small'
136-
className='!text-white'
137-
>
138-
正向
139-
</Button>
140-
<Button
141-
size='small'
142-
className='!text-white'
143-
>
144-
負向
145-
</Button>
106+
<SelectButton
107+
value={isRecommended}
108+
onChange={(e) => {
109+
setIsRecommended(e.value);
110+
handleCreateComment(value, e.value === '正向' ? 1 : 0);
111+
}}
112+
options={['正向', '負向']}
113+
/>
146114
<span className='!text-white'>的評價送出</span>
147115
</div>
148116
<div className='flex flex-grow'></div>

src/pages/Gallery.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ query GetFlickrPhotoSizes ($userId: Int) {
4242
}
4343
`;
4444

45+
const GET_SECHEMA = gql`
46+
query GetSchema {
47+
__schema {
48+
types {
49+
name
50+
kind
51+
description
52+
}
53+
}
54+
}
55+
`;
56+
4557
const Gallery: React.FC = () => {
4658
const { keycloak } = useKeycloak();
4759
const { data: me, loading: meLoading, error: meError } = useQuery(GET_ME, {
@@ -52,17 +64,20 @@ const Gallery: React.FC = () => {
5264
variables: { userId: me?.user?.nodes[0]?.id },
5365
skip: !me,
5466
});
67+
const { data: schemaData, loading: schemaLoading, error: schemaError } = useQuery(GET_SECHEMA);
5568

56-
if (loading || meLoading) return <p>Loading...</p>;
57-
if (error || meError) return <p>Error: {[error?.message, meError?.message].join('.')}</p>;
69+
if (loading || meLoading || schemaLoading) return <p>Loading...</p>;
70+
if (error || meError || schemaError) return <p>Error: {[error?.message, meError?.message, schemaError?.message].join('.')}</p>;
5871

5972
console.log(data);
73+
console.log(schemaData);
6074

6175
const arr: ImageElement[] = data.flickrPhotoSize.nodes.map((item: FlickrPhotoSize) => ({
6276
id: item.flickrPhoto.photoId,
6377
src: `https://live.staticflickr.com/${item.serverId}/${item.flickrPhotoId}_${item.secret}_${item.suffix}.jpg`,
6478
fileName: `${item.flickrPhotoId}_${item.secret}_${item.suffix}.jpg`,
6579
categories: ['Nature', 'Animals'],
80+
reaction: item.flickrPhoto.photo.photoReaction.nodes[0]
6681
}));
6782

6883
return (

src/types/FlickrPhoto.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1+
import { PhotoReaction } from "./PhotoReaction";
2+
13
export interface FlickrPhoto {
2-
flickrId: number;
4+
photo: {
5+
photoReaction: {
6+
nodes: PhotoReaction[];
7+
};
8+
};
39
photoId: number;
410
}

src/types/PhotoReaction.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface PhotoReaction {
2+
isRecommended: number;
3+
comment: string;
4+
}

0 commit comments

Comments
 (0)