diff --git a/package.json b/package.json index ada1684..a0b2306 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "femto-webapp", "private": true, - "version": "1.26.6", + "version": "1.26.4", "type": "module", "scripts": { "dev": "vite --host 0.0.0.0", diff --git a/src/app/api/schema.ts b/src/app/api/schema.ts index 6af29b3..f03c6b0 100644 --- a/src/app/api/schema.ts +++ b/src/app/api/schema.ts @@ -9,7 +9,7 @@ export interface paths { get: { parameters: { query?: { - After?: string + From?: string Amount?: number AuthorId?: string Author?: string @@ -192,47 +192,6 @@ export interface paths { patch?: never trace?: never } - '/posts/{postId}/comments': { - parameters: { - query?: never - header?: never - path?: never - cookie?: never - } - get?: never - put?: never - post: { - parameters: { - query?: never - header?: never - path: { - postId: string - } - cookie?: never - } - requestBody: { - content: { - 'application/json': components['schemas']['AddPostCommentRequest'] - 'text/json': components['schemas']['AddPostCommentRequest'] - 'application/*+json': components['schemas']['AddPostCommentRequest'] - } - } - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown - } - content?: never - } - } - } - delete?: never - options?: never - head?: never - patch?: never - trace?: never - } '/media': { parameters: { query?: never @@ -682,11 +641,6 @@ export interface paths { export type webhooks = Record export interface components { schemas: { - AddPostCommentRequest: { - /** Format: uuid */ - authorId: string - content: string - } AddPostReactionRequest: { emoji: string } @@ -755,12 +709,6 @@ export interface components { authorId: string username: string } - PostCommentDto: { - author: string - content: string - /** Format: date-time */ - postedOn: string - } PostDto: { author: components['schemas']['PostAuthorDto'] /** Format: uuid */ @@ -771,7 +719,6 @@ export interface components { /** Format: date-time */ createdAt: string possibleReactions: string[] - comments: components['schemas']['PostCommentDto'][] } PostMediaDto: { /** Format: uri */ diff --git a/src/app/feed/components/NewCommentWidget.tsx b/src/app/feed/components/NewCommentWidget.tsx deleted file mode 100644 index 3d2e4ea..0000000 --- a/src/app/feed/components/NewCommentWidget.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { useState } from 'react' -import FancyTextEditor, { - TextInputKeyDownEvent, -} from '../../../components/inputs/FancyTextEditor.tsx' -import Button from '../../../components/buttons/Button.tsx' -import { useTranslations } from '../../i18n/translations.ts' - -interface NewCommentWidgetProps { - onSubmit: (content: string) => void - isSubmitting?: boolean -} - -export default function NewCommentWidget({ - onSubmit, - isSubmitting = false, -}: NewCommentWidgetProps) { - const { t } = useTranslations() - const [content, setContent] = useState('') - - const onContentInput = (value: string) => { - setContent(value) - } - - const handleSubmit = () => { - if (!content.trim()) { - return - } - - onSubmit(content) - - setContent('') - } - - const onInputKeyDown = (e: TextInputKeyDownEvent) => { - if (e.key === 'Enter' && e.ctrlKey) { - e.preventDefault() - handleSubmit() - } - } - - return ( -
- - -
- -
-
- ) -} diff --git a/src/app/feed/components/PostTimeline.tsx b/src/app/feed/components/PostTimeline.tsx index c9653f1..9fe6ddc 100644 --- a/src/app/feed/components/PostTimeline.tsx +++ b/src/app/feed/components/PostTimeline.tsx @@ -1,67 +1,31 @@ -import { PostComment, PostReaction } from '../posts/posts.ts' +import { PostReaction } from '../posts/posts.ts' import { Temporal } from '@js-temporal/polyfill' interface PostTimelineProps { reactions: PostReaction[] - comments: PostComment[] } -export function PostTimeline({ reactions, comments }: PostTimelineProps) { - const items = [ - ...reactions.map((reaction) => ({ - timestamp: reaction.reactedOn, - component: ( - - ), - })), - ...comments.map((comment) => ({ - timestamp: comment.postedOn, - component: ( - - ), - })), - ].toSorted((a, b) => Temporal.Instant.compare(a.timestamp, b.timestamp)) - +export function PostTimeline({ reactions }: PostTimelineProps) { return ( -
{items.map((item) => item.component)}
- ) -} - -function ReactionItem({ reaction }: { reaction: PostReaction }) { - return ( -
- {formatItemDate(reaction.reactedOn)} -
- @{reaction.authorName}  - clicked  - {reaction.emoji} -
+
+ {reactions.map((reaction) => ( +
+
+ {Temporal.Now.instant().toLocaleString('en-AU', { + year: 'numeric', + month: 'numeric', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + })} +
+
+ @{reaction.authorName}  + did  + {reaction.emoji} +
+
+ ))}
) } - -function CommentItem({ comment }: { comment: PostComment }) { - return ( -
-
{formatItemDate(comment.postedOn)}
-
- @{comment.author}  -
-
{comment.content}
-
- ) -} - -function formatItemDate(date: Temporal.Instant) { - return date.toLocaleString('en-AU', { - year: 'numeric', - month: 'numeric', - day: 'numeric', - }) -} diff --git a/src/app/feed/pages/HomePage.tsx b/src/app/feed/pages/HomePage.tsx index b505d83..edef521 100644 --- a/src/app/feed/pages/HomePage.tsx +++ b/src/app/feed/pages/HomePage.tsx @@ -2,7 +2,7 @@ import { useRef, useState } from 'react' import { PostsService } from '../posts/postsService.ts' import { useUserStore } from '../../user/user.ts' import { MediaService } from '../../media/mediaService.ts' -import NewPostWidget from '../components/NewPostWidget.tsx' +import NewPostWidget from '../../../components/NewPostWidget.tsx' import SingleColumnLayout from '../../../layouts/SingleColumnLayout.tsx' import NavBar from '../../../components/NavBar.tsx' import AuthNavButtons from '../../auth/components/AuthNavButtons.tsx' diff --git a/src/app/feed/pages/PostPage.tsx b/src/app/feed/pages/PostPage.tsx index b275b68..d8929d3 100644 --- a/src/app/feed/pages/PostPage.tsx +++ b/src/app/feed/pages/PostPage.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from 'react' +import { useEffect } from 'react' import { useParams } from 'react-router-dom' import { PostsService } from '../posts/postsService.ts' import SingleColumnLayout from '../../../layouts/SingleColumnLayout.tsx' @@ -11,7 +11,6 @@ import { usePostViewModel } from '../posts/usePostViewModel.ts' import { Temporal } from '@js-temporal/polyfill' import { useUserStore } from '../../user/user.ts' import { PostTimeline } from '../components/PostTimeline.tsx' -import NewCommentWidget from '../components/NewCommentWidget.tsx' interface PostPageProps { postsService: PostsService @@ -25,15 +24,11 @@ export default function PostPage({ postsService }: PostPageProps) { const post = posts.at(0) const reactions = (post?.postId ? _reactions[post.postId] : []) ?? [] - const loadPost = useCallback(() => { + useEffect(() => { if (!postId) return postsService.load(postId).then((post) => setPosts(post ? [post] : [])) }, [postId, postsService, setPosts]) - useEffect(() => { - loadPost() - }, [loadPost]) - const onAddReaction = async (emoji: string) => { if (!username) return if (!post) return @@ -51,22 +46,6 @@ export default function PostPage({ postsService }: PostPageProps) { removeReaction(post.postId, emoji, username) } - async function onSubmitComment(content: string) { - if (!postId) return - if (!content.trim()) return - - try { - setIsSubmittingComment(true) - await postsService.addComment(postId, content) - } finally { - setIsSubmittingComment(false) - } - - loadPost() - } - - const [isSubmittingComment, setIsSubmittingComment] = useState(false) - return ( - - +
)} diff --git a/src/app/feed/posts/posts.ts b/src/app/feed/posts/posts.ts index 837e2b8..7fe2547 100644 --- a/src/app/feed/posts/posts.ts +++ b/src/app/feed/posts/posts.ts @@ -8,12 +8,6 @@ export interface PostReaction { reactedOn: Temporal.Instant } -export interface PostComment { - author: string - content: string - postedOn: Temporal.Instant -} - export class Post { [immerable] = true @@ -24,7 +18,6 @@ export class Post { public readonly authorName: string public readonly reactions: PostReaction[] public readonly possibleReactions: string[] - public readonly comments: PostComment[] constructor( postId: string, @@ -32,9 +25,8 @@ export class Post { media: PostMedia[], createdAt: string | Temporal.Instant, authorName: string, - reactions: PostReaction[], - possibleReactions: string[], - comments: PostComment[], + reactions: PostReaction[] = [], + possibleReactions: string[] = [], ) { this.postId = postId this.content = content @@ -43,7 +35,6 @@ export class Post { this.authorName = authorName this.reactions = reactions this.possibleReactions = possibleReactions - this.comments = comments } public static fromDto(dto: components['schemas']['PostDto']): Post { @@ -55,7 +46,6 @@ export class Post { dto.author.username, dto.reactions.map((r) => ({ ...r, reactedOn: Temporal.Instant.from(r.reactedOn) })), dto.possibleReactions, - dto.comments.map((c) => ({ ...c, postedOn: Temporal.Instant.from(c.postedOn) })), ) } } diff --git a/src/app/feed/posts/postsService.ts b/src/app/feed/posts/postsService.ts index 72e55f7..11272e9 100644 --- a/src/app/feed/posts/postsService.ts +++ b/src/app/feed/posts/postsService.ts @@ -1,6 +1,5 @@ import { Post } from './posts.ts' import { ApiClient } from '../../api/client.ts' -import { useUserStore } from '../../user/user.ts' export class PostsService { constructor(private readonly client: ApiClient) {} @@ -79,17 +78,6 @@ export class PostsService { credentials: 'include', }) } - - async addComment(postId: string, content: string): Promise { - const authorId = useUserStore.getState().user?.id - if (!authorId) return - - await this.client.POST('/posts/{postId}/comments', { - params: { path: { postId } }, - body: { content, authorId }, - credentials: 'include', - }) - } } interface CreatePostMedia { diff --git a/src/app/feed/posts/usePostViewModel.ts b/src/app/feed/posts/usePostViewModel.ts index 2fb06bd..74004ef 100644 --- a/src/app/feed/posts/usePostViewModel.ts +++ b/src/app/feed/posts/usePostViewModel.ts @@ -1,5 +1,5 @@ import { useCallback, useState } from 'react' -import { Post, PostComment, PostMedia, PostReaction } from './posts.ts' +import { Post, PostMedia, PostReaction } from './posts.ts' import { Temporal } from '@js-temporal/polyfill' import { produce } from 'immer' @@ -10,7 +10,6 @@ export interface PostInfo { createdAt: Temporal.Instant media: PostMedia[] possibleReactions: string[] - comments: PostComment[] } type ReactionMap = Record diff --git a/src/app/feed/components/NewPostWidget.tsx b/src/components/NewPostWidget.tsx similarity index 95% rename from src/app/feed/components/NewPostWidget.tsx rename to src/components/NewPostWidget.tsx index e0bd87a..c943577 100644 --- a/src/app/feed/components/NewPostWidget.tsx +++ b/src/components/NewPostWidget.tsx @@ -1,9 +1,9 @@ import { useState } from 'react' -import FancyTextEditor, { TextInputKeyDownEvent } from '../../../components/inputs/FancyTextEditor.tsx' -import Button from '../../../components/buttons/Button.tsx' -import { openFileDialog } from '../../../utils/openFileDialog.ts' +import FancyTextEditor, { TextInputKeyDownEvent } from './inputs/FancyTextEditor.tsx' +import Button from './buttons/Button.tsx' +import { openFileDialog } from '../utils/openFileDialog.ts' import makePica from 'pica' -import { useTranslations } from '../../i18n/translations.ts' +import { useTranslations } from '../app/i18n/translations.ts' interface NewPostWidgetProps { onSubmit: (