feat(share): symbol page share button + distinguish note delete vs failure
- New ShareButton in the page header tries navigator.share() first
(native sheet on mobile), then falls back to navigator.clipboard, then
to a hidden textarea + execCommand("copy") for non-secure-context LAN.
Shows a brief "링크 복사됨" / "복사 안됨" toast; native share success
shows none (the OS sheet is the feedback).
- Mounted between ⇄ 비교 and the Star button.
Fixes reviewer concern on 442cc38: writeNote() used to return null for
both "user emptied the textarea (intentional delete)" and "localStorage
quota failure," so clearing a note showed "저장 안됨." It now returns a
discriminated { status: "saved" | "deleted" | "failed" } and the panel
shows "저장됨" / "삭제됨" / "저장 안됨" accordingly. Failure keeps the
user's text so they can retry or shorten it.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,12 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { NOTE_MAX_LEN, readNote, writeNote, type Note } from "../lib/notes";
|
||||
|
||||
const FEEDBACK_TEXT: Record<"saved" | "deleted" | "failed", string> = {
|
||||
saved: "저장됨",
|
||||
deleted: "삭제됨",
|
||||
failed: "저장 안됨",
|
||||
};
|
||||
|
||||
type Props = {
|
||||
code: string;
|
||||
};
|
||||
@@ -60,10 +66,16 @@ export function InvestmentNote({ code }: Props) {
|
||||
const remaining = useMemo(() => NOTE_MAX_LEN - text.length, [text]);
|
||||
|
||||
const save = () => {
|
||||
const next = writeNote(code, text);
|
||||
setSaved(next);
|
||||
setText(next?.text ?? "");
|
||||
setFeedback(next ? "저장됨" : "저장 안됨");
|
||||
const res = writeNote(code, text);
|
||||
if (res.status === "saved") {
|
||||
setSaved(res.note);
|
||||
setText(res.note.text);
|
||||
} else if (res.status === "deleted") {
|
||||
setSaved(null);
|
||||
setText("");
|
||||
}
|
||||
// failed: 입력값 유지 — 사용자가 재시도하거나 일부를 줄일 수 있도록.
|
||||
setFeedback(FEEDBACK_TEXT[res.status]);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user