diff --git a/src/App.tsx b/src/App.tsx index 1f4a7b3..fa7b957 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -529,34 +529,6 @@ const TimelineSection = ({ } }; - const handleToggleBookmark = async (status: Status) => { - if (!account) { - onError("계정을 선택해주세요."); - return; - } - onError(null); - const isBookmarking = !status.bookmarked; - const optimistic = { - ...status, - bookmarked: isBookmarking - }; - timeline.updateItem(optimistic); - try { - const updated = status.bookmarked - ? await services.api.unbookmark(account, status.id) - : await services.api.bookmark(account, status.id); - timeline.updateItem(updated); - if (isBookmarking) { - showToast("북마크했습니다."); - } else { - showToast("북마크를 취소했습니다."); - } - } catch (err) { - onError(err instanceof Error ? err.message : "북마크 처리에 실패했습니다."); - timeline.updateItem(status); - } - }; - const handleReact = useCallback( (status: Status, reaction: ReactionInput) => { onReact(account, status, reaction); @@ -706,9 +678,8 @@ const TimelineSection = ({ onReply={(item) => onReply(item, account)} onStatusClick={(status) => onStatusClick(status, account)} onToggleFavourite={handleToggleFavourite} - onToggleReblog={handleToggleReblog} - onToggleBookmark={handleToggleBookmark} - onDelete={handleDeleteStatus} + onToggleReblog={handleToggleReblog} + onDelete={handleDeleteStatus} onReact={handleReact} onProfileClick={(item) => onProfileClick(item, account)} activeHandle={ @@ -839,9 +810,8 @@ const TimelineSection = ({ onReply={(item) => onReply(item, account)} onStatusClick={(status) => onStatusClick(status, account)} onToggleFavourite={handleToggleFavourite} - onToggleReblog={handleToggleReblog} - onToggleBookmark={handleToggleBookmark} - onDelete={handleDeleteStatus} + onToggleReblog={handleToggleReblog} + onDelete={handleDeleteStatus} onReact={handleReact} onProfileClick={(item) => onProfileClick(item, account)} activeHandle={ @@ -2097,27 +2067,6 @@ onAccountChange={setSectionAccount} setActionError(err instanceof Error ? err.message : "부스트 처리에 실패했습니다."); } }} - onToggleBookmark={async (status) => { - if (!composeAccount) { - setActionError("계정을 선택해주세요."); - return; - } - setActionError(null); - const isBookmarking = !status.bookmarked; - try { - const updated = status.bookmarked - ? await services.api.unbookmark(composeAccount, status.id) - : await services.api.bookmark(composeAccount, status.id); - setSelectedStatus(updated); - if (isBookmarking) { - showToast("북마크했습니다."); - } else { - showToast("북마크를 취소했습니다."); - } - } catch (err) { - setActionError(err instanceof Error ? err.message : "북마크 처리에 실패했습니다."); - } - }} onDelete={async (status) => { if (!composeAccount) { return; diff --git a/src/domain/types.ts b/src/domain/types.ts index c36276f..6eee19a 100644 --- a/src/domain/types.ts +++ b/src/domain/types.ts @@ -94,7 +94,6 @@ export type Status = { reactions: Reaction[]; reblogged: boolean; favourited: boolean; - bookmarked: boolean; inReplyToId: string | null; mentions: Mention[]; mediaAttachments: MediaAttachment[]; diff --git a/src/infra/MastodonHttpClient.ts b/src/infra/MastodonHttpClient.ts index 807f329..bb141e0 100644 --- a/src/infra/MastodonHttpClient.ts +++ b/src/infra/MastodonHttpClient.ts @@ -283,10 +283,6 @@ export class MastodonHttpClient implements MastodonApi { return mapAccountRelationship(data); } - async fetchThreadContext(account: Account, statusId: string): Promise { - return this.fetchContext(account, statusId); - } - async fetchAccountStatuses( account: Account, accountId: string, @@ -390,14 +386,6 @@ export class MastodonHttpClient implements MastodonApi { return this.postAction(account, statusId, "unfavourite"); } - async bookmark(account: Account, statusId: string): Promise { - return this.postAction(account, statusId, "bookmark"); - } - - async unbookmark(account: Account, statusId: string): Promise { - return this.postAction(account, statusId, "unbookmark"); - } - async createReaction(_account: Account, _statusId: string, _reaction: string): Promise { throw new Error("리액션은 미스키 계정에서만 사용할 수 있습니다."); } diff --git a/src/infra/UnifiedApiClient.ts b/src/infra/UnifiedApiClient.ts index c6139df..df9d50e 100644 --- a/src/infra/UnifiedApiClient.ts +++ b/src/infra/UnifiedApiClient.ts @@ -95,14 +95,6 @@ export class UnifiedApiClient implements MastodonApi { return this.getClient(account).unfavourite(account, statusId); } - bookmark(account: Account, statusId: string) { - return this.getClient(account).bookmark(account, statusId); - } - - unbookmark(account: Account, statusId: string) { - return this.getClient(account).unbookmark(account, statusId); - } - createReaction(account: Account, statusId: string, reaction: string) { return this.getClient(account).createReaction(account, statusId, reaction); } diff --git a/src/infra/mastodonMapper.ts b/src/infra/mastodonMapper.ts index ba315be..19168f6 100644 --- a/src/infra/mastodonMapper.ts +++ b/src/infra/mastodonMapper.ts @@ -259,7 +259,6 @@ export const mapStatus = (raw: unknown): Status => { reactions, reblogged: Boolean(value.reblogged ?? false), favourited: Boolean(value.favourited ?? false), - bookmarked: Boolean(value.bookmarked ?? false), inReplyToId: value.in_reply_to_id ? String(value.in_reply_to_id) : null, mentions: mapMentions(value.mentions), mediaAttachments: mapMediaAttachments(value.media_attachments), @@ -328,8 +327,6 @@ export const mapNotificationToStatus = (raw: unknown): Status | null => { accountUrl, accountAvatarUrl, content, - htmlContent: "", - hasRichContent: false, url: target?.url ?? null, visibility: target?.visibility ?? "public", spoilerText: "", @@ -341,7 +338,6 @@ export const mapNotificationToStatus = (raw: unknown): Status | null => { reactions: [], reblogged: false, favourited: false, - bookmarked: false, inReplyToId: target?.inReplyToId ?? null, mentions: [], mediaAttachments: target?.mediaAttachments ?? [], diff --git a/src/services/MastodonApi.ts b/src/services/MastodonApi.ts index ccb56a3..c181188 100644 --- a/src/services/MastodonApi.ts +++ b/src/services/MastodonApi.ts @@ -1,4 +1,4 @@ -import type { Account, AccountRelationship, Status, TimelineType, Visibility, InstanceInfo, UserProfile, ThreadContext } from "../domain/types"; +import type { Account, AccountRelationship, Status, TimelineType, Visibility, InstanceInfo, UserProfile } from "../domain/types"; import type { CustomEmoji } from "../domain/types"; export type CreateStatusInput = { @@ -21,8 +21,6 @@ export interface MastodonApi { deleteStatus(account: Account, statusId: string): Promise; favourite(account: Account, statusId: string): Promise; unfavourite(account: Account, statusId: string): Promise; - bookmark(account: Account, statusId: string): Promise; - unbookmark(account: Account, statusId: string): Promise; createReaction(account: Account, statusId: string, reaction: string): Promise; deleteReaction(account: Account, statusId: string): Promise; reblog(account: Account, statusId: string): Promise; @@ -38,5 +36,4 @@ export interface MastodonApi { blockAccount(account: Account, accountId: string): Promise; unblockAccount(account: Account, accountId: string): Promise; fetchAccountStatuses(account: Account, accountId: string, limit: number, maxId?: string): Promise; - fetchThreadContext(account: Account, statusId: string): Promise; } diff --git a/src/ui/components/ProfileModal.tsx b/src/ui/components/ProfileModal.tsx index f65c606..d77a481 100644 --- a/src/ui/components/ProfileModal.tsx +++ b/src/ui/components/ProfileModal.tsx @@ -365,27 +365,6 @@ export const ProfileModal = ({ [account, api, updateItem] ); - const handleToggleBookmark = useCallback( - async (target: Status) => { - if (!account) { - setItemsError("계정을 선택해 주세요."); - return; - } - setItemsError(null); - const isBookmarking = !target.bookmarked; - try { - const updated = target.bookmarked - ? await api.unbookmark(account, target.id) - : await api.bookmark(account, target.id); - updateItem(updated); - showToast(isBookmarking ? "북마크했습니다." : "북마크를 취소했습니다."); - } catch (error) { - setItemsError(error instanceof Error ? error.message : "북마크 처리에 실패했습니다."); - } - }, - [account, api, updateItem, showToast] - ); - const handleDeleteStatus = useCallback( async (target: Status) => { if (!account) { @@ -980,10 +959,9 @@ export const ProfileModal = ({ key={item.id} status={item} onReply={(target) => onReply(target, account)} - onToggleFavourite={handleToggleFavourite} - onToggleReblog={handleToggleReblog} - onToggleBookmark={handleToggleBookmark} - onDelete={handleDeleteStatus} + onToggleFavourite={handleToggleFavourite} + onToggleReblog={handleToggleReblog} + onDelete={handleDeleteStatus} onReact={handleReact} onStatusClick={onStatusClick} onProfileClick={(target) => onProfileClick(target, account)} diff --git a/src/ui/components/StatusModal.tsx b/src/ui/components/StatusModal.tsx index 3c28f00..d65a77f 100644 --- a/src/ui/components/StatusModal.tsx +++ b/src/ui/components/StatusModal.tsx @@ -15,7 +15,6 @@ export const StatusModal = ({ onReply, onToggleFavourite, onToggleReblog, - onToggleBookmark, onDelete, onProfileClick, activeHandle, @@ -34,7 +33,6 @@ export const StatusModal = ({ onReply: (status: Status) => void; onToggleFavourite: (status: Status) => void; onToggleReblog: (status: Status) => void; - onToggleBookmark: (status: Status) => void; onDelete?: (status: Status) => void; onProfileClick?: (status: Status, account: Account | null) => void; activeHandle: string; @@ -196,13 +194,12 @@ export const StatusModal = ({
{threadContext.ancestors.map((ancestorStatus) => (
- {})} + {})} onProfileClick={handleProfileClick} activeHandle={activeHandle} activeAccountHandle={activeAccountHandle} @@ -232,7 +229,6 @@ export const StatusModal = ({ onReply={onReply} onToggleFavourite={onToggleFavourite} onToggleReblog={onToggleReblog} - onToggleBookmark={onToggleBookmark} onDelete={onDelete || (() => {})} onProfileClick={handleProfileClick} activeHandle={activeHandle} @@ -262,7 +258,6 @@ export const StatusModal = ({ onReply={onReply} onToggleFavourite={onToggleFavourite} onToggleReblog={onToggleReblog} - onToggleBookmark={onToggleBookmark} onDelete={onDelete || (() => {})} onProfileClick={handleProfileClick} activeHandle={activeHandle} diff --git a/src/ui/components/TimelineItem.tsx b/src/ui/components/TimelineItem.tsx index 773de1d..f21915f 100644 --- a/src/ui/components/TimelineItem.tsx +++ b/src/ui/components/TimelineItem.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react" import type { Account, CustomEmoji, Mention, ReactionInput, Status } from "../../domain/types"; import type { MastodonApi } from "../../services/MastodonApi"; import { sanitizeHtml } from "../utils/htmlSanitizer"; -import { renderTextWithLinks, type MentionLink } from "../utils/linkify"; +import { renderTextWithLinks } from "../utils/linkify"; import BoostIcon from "../assets/boost-icon.svg?react"; import ReplyIcon from "../assets/reply-icon.svg?react"; import TrashIcon from "../assets/trash-icon.svg?react"; @@ -30,7 +30,6 @@ export const TimelineItem = ({ onToggleFavourite, onToggleReblog, onDelete, - onToggleBookmark, onReact, onProfileClick, onStatusClick, @@ -50,7 +49,6 @@ export const TimelineItem = ({ onToggleFavourite: (status: Status) => void; onToggleReblog: (status: Status) => void; onDelete: (status: Status) => void; - onToggleBookmark: (status: Status) => void; onReact?: (status: Status, reaction: ReactionInput) => void; onProfileClick?: (status: Status) => void; onStatusClick?: (status: Status) => void; @@ -475,7 +473,6 @@ export const TimelineItem = ({ reactions: [], reblogged: false, favourited: false, - bookmarked: false, inReplyToId: null, mentions: [], mediaAttachments: [], @@ -489,11 +486,11 @@ export const TimelineItem = ({ [displayStatus.createdAt, displayStatus.id] ); const handleMentionClick = useCallback( - (mention: MentionLink) => { + (mention: Mention) => { if (!onProfileClick || !mention.id) { return; } - onProfileClick(buildMentionStatus(mention as Mention)); + onProfileClick(buildMentionStatus(mention)); }, [buildMentionStatus, onProfileClick] ); @@ -864,15 +861,6 @@ export const TimelineItem = ({ <>