"Track 3 가 clip 을 썼고. Track 4 가 clip 을 읽어. Side panel 이 진짜 library 로 끝남 — searchable, copy-to-clipboard, source 로 다시 link. CRUD 두 글자가 이제 board 에."
여기서 'R' 의 의미
CRUD 의 R 은 그냥 "display" 아냐. 진짜 read view 는 scannable, searchable, actionable 함으로써 자기 surface 를 정당화. ClipDeck 에 구체적으로:
- 최신 clip 이 맨 위 (
savedAt내림차순 정렬). - 각 row 가 source title (clickable link), 상대 시간 ("5m ago"), clip text (긴 clip 엔 read-more affordance 가진 truncate) 표시.
- User 가 타이핑하는 동안 filter 하는 search box (clip text 와 title 의 substring match).
- Row 당 system clipboard 에 write 하는 "copy text" 버튼.
- 뭘 해야 할지 설명하는 empty state: "No clips yet. Select text on any page and press Ctrl+Shift+K."
Render loop
Track 2 의 패턴이 곧장 carry:
- Panel mount.
chrome.storage.local에서 clip 한 번 read. - Search input 의 현재 filter 포함해서 render.
chrome.storage.onChanged구독.clips바뀌면 re-render.- Search input 의
inputevent 구독. 매 keystroke 마다 새 filter 와 re-render.
State-management library 필요 없음. Storage 가 source of truth; panel 은 derived view. Panel 에 parallel in-memory clip array 유지 발견되면 state 중복 — 매 render 마다 storage 에서 read, 또는 array cache 하되 매 onChanged fire 마다 rebuild.
상대 시간
현대 browser (Chrome 71+) 가 human-friendly 시간 문자열에 Intl.RelativeTimeFormat 포함. 제대로 쓰면 localization 자동 처리 — 한국어로 "5분 전", 영어로 "5 minutes ago", 추가 코드 없음.
Bucket logic 은 직설적: 초 단위 차이 계산, bucket 통과 (초 → 분 → 시간 → 일), 적절한 unit 으로 format. setInterval 통해 렌더된 시간 매 분 refresh, 또는 user interact 까지 stale 되는 거 받아들이기.
Clipboard 에 copy
현대 clipboard API (navigator.clipboard.writeText) 가 extra permission 없이 extension page 에서 동작, 단 user gesture 필요 — 버튼 click handler 카운트. Legacy document.execCommand('copy') 경로도 옛 Chrome 의 fallback 으로 동작, 대부분 install 은 그거 건너뛸 만큼 최근.
패턴: copy 버튼 click, navigator.clipboard.writeText(clip.text) await, 1.5 초 후 auto-fade 하는 짧은 확인 toast ("Copied!") 표시. alert 사용 충동 저항 — alert 가 user 가 읽는 page 에서 focus 훔치고 persistent-panel UX 깸.
Filter
몇 백 clip 엔 render 마다 단순 substring matching 이 충분히 빠름 — index 필요 없음. 양쪽 lowercase, inclusion 확인, 끝. 몇 천 넘어가면 lazy-loaded list 나 fuzzy-search index 만들 가치 있을 수도, 그건 v1 scope 한참 넘음.
Source URL 열기
Clip 의 title 이 원본 URL 로 link. 클릭이 새 tab 열기 (anchor 의 target="_blank", 또는 programmatic chrome.tabs.create({ url, active: false })). active: false 변형이 tab 을 background 로 열어 user 가 side panel 자리 안 잃음 — 보통 library view 의 맞는 default.
escapeHtml helper (또는 풍부한 HTML 엔 DOMPurify) 가 최소 baseline; v1 엔 text 만 렌더, 그래서 escape helper 충분.