Skip to content

Commit 0a524f9

Browse files
Jinhyen Kimjinhyenkim01
authored andcommitted
fix: 코드 블록 알람 기능 추가
1 parent 7c844c3 commit 0a524f9

2 files changed

Lines changed: 73 additions & 35 deletions

File tree

src/app/components/ChatPanel.tsx

Lines changed: 69 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,44 +1103,46 @@ export function ChatPanel({ channelId = "general", title, messages, reactions, r
11031103
<div className="px-6 py-4" style={{
11041104
borderTop: '1px solid rgba(32, 227, 255, 0.14)'
11051105
}}>
1106-
{activePanel === 'code' && (
1107-
<div className="mb-3 px-4 py-3 rounded-xl" style={{
1108-
background: 'rgba(32, 227, 255, 0.08)',
1109-
border: '1px solid rgba(32, 227, 255, 0.22)'
1110-
}}>
1111-
<p className="m-0 mb-2 tracking-tight" style={{
1112-
fontSize: '12px',
1113-
fontWeight: 900,
1114-
color: 'var(--neon-cyan)'
1115-
}}>
1116-
코드 블록 모드
1117-
</p>
1118-
<textarea
1119-
placeholder="코드를 입력하세요..."
1120-
value={codeBlockText}
1121-
onChange={(event) => setCodeBlockText(event.target.value)}
1122-
className="w-full px-3 py-2 rounded-lg border-0 font-mono tracking-tight resize-none"
1123-
rows={4}
1124-
style={{
1125-
background: 'rgba(5, 11, 20, 0.6)',
1126-
border: '1px solid rgba(32, 227, 255, 0.14)',
1127-
color: 'var(--white)',
1128-
fontSize: '13px',
1129-
fontWeight: 700
1130-
}}
1131-
/>
1132-
</div>
1133-
)}
1134-
1135-
{selectedAttachments.length > 0 && (
1106+
{(codeBlockText.trim() || selectedAttachments.length > 0) && (
11361107
<div className="mb-3 flex flex-wrap items-center gap-2">
11371108
<span className="tracking-tight" style={{
11381109
fontSize: '11px',
11391110
fontWeight: 900,
11401111
color: 'var(--muted)'
11411112
}}>
1142-
첨부 {selectedAttachments.length}
1113+
첨부 {selectedAttachments.length + (codeBlockText.trim() ? 1 : 0)}
11431114
</span>
1115+
{codeBlockText.trim() && (
1116+
<button
1117+
type="button"
1118+
onClick={() => setActivePanel('code')}
1119+
className="flex items-center gap-1.5 rounded-full border-0 px-2.5 py-1 tracking-tight transition-all"
1120+
style={{
1121+
background: 'rgba(32, 227, 255, 0.12)',
1122+
border: '1px solid rgba(32, 227, 255, 0.34)',
1123+
color: 'var(--neon-cyan)',
1124+
cursor: 'pointer',
1125+
fontSize: '12px',
1126+
fontWeight: 900,
1127+
}}
1128+
title="코드 블록 보기"
1129+
>
1130+
<Code size={12} />
1131+
<span>코드 블록</span>
1132+
<span
1133+
role="button"
1134+
aria-label="코드 블록 제거"
1135+
onClick={(e) => {
1136+
e.stopPropagation();
1137+
setCodeBlockText('');
1138+
if (activePanel === 'code') setActivePanel(null);
1139+
}}
1140+
style={{ marginLeft: '2px', opacity: 0.7, cursor: 'pointer' }}
1141+
>
1142+
×
1143+
</span>
1144+
</button>
1145+
)}
11441146
{selectedAttachments.map((attachment) => (
11451147
<button
11461148
key={attachment.id}
@@ -1164,6 +1166,35 @@ export function ChatPanel({ channelId = "general", title, messages, reactions, r
11641166
</div>
11651167
)}
11661168

1169+
{activePanel === 'code' && (
1170+
<div className="mb-3 px-4 py-3 rounded-xl" style={{
1171+
background: 'rgba(32, 227, 255, 0.08)',
1172+
border: '1px solid rgba(32, 227, 255, 0.22)'
1173+
}}>
1174+
<p className="m-0 mb-2 tracking-tight" style={{
1175+
fontSize: '12px',
1176+
fontWeight: 900,
1177+
color: 'var(--neon-cyan)'
1178+
}}>
1179+
코드 블록 모드
1180+
</p>
1181+
<textarea
1182+
placeholder="코드를 입력하세요..."
1183+
value={codeBlockText}
1184+
onChange={(event) => setCodeBlockText(event.target.value)}
1185+
className="w-full px-3 py-2 rounded-lg border-0 font-mono tracking-tight resize-none"
1186+
rows={4}
1187+
style={{
1188+
background: 'rgba(5, 11, 20, 0.6)',
1189+
border: '1px solid rgba(32, 227, 255, 0.14)',
1190+
color: 'var(--white)',
1191+
fontSize: '13px',
1192+
fontWeight: 700
1193+
}}
1194+
/>
1195+
</div>
1196+
)}
1197+
11671198
{activePanel === 'attachment' && (
11681199
<div className="mb-3 rounded-xl px-4 py-3" style={{
11691200
background: 'rgba(5, 11, 20, 0.78)',
@@ -1375,7 +1406,7 @@ export function ChatPanel({ channelId = "general", title, messages, reactions, r
13751406
<div className="flex shrink-0 flex-wrap justify-end gap-1">
13761407
<button
13771408
onClick={() => togglePanel('code')}
1378-
className="w-9 h-9 rounded-lg border-0 flex items-center justify-center"
1409+
className="relative w-9 h-9 rounded-lg border-0 flex items-center justify-center"
13791410
style={{
13801411
background: activePanel === 'code' ? 'rgba(32, 227, 255, 0.15)' : 'rgba(5, 11, 20, 0.6)',
13811412
border: `1px solid ${activePanel === 'code' ? 'rgba(32, 227, 255, 0.3)' : 'rgba(32, 227, 255, 0.14)'}`,
@@ -1386,6 +1417,12 @@ export function ChatPanel({ channelId = "general", title, messages, reactions, r
13861417
aria-label="코드 블록"
13871418
>
13881419
<Code size={18} />
1420+
{codeBlockText.trim() && (
1421+
<span
1422+
className="absolute top-1 right-1 h-2 w-2 rounded-full"
1423+
style={{ background: 'var(--neon-cyan)', boxShadow: '0 0 4px var(--neon-cyan)' }}
1424+
/>
1425+
)}
13891426
</button>
13901427
<button
13911428
onClick={() => togglePanel('attachment')}

src/app/components/MessageReactions.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,10 @@ export function MessageReactions({ reactions = [], onToggle }: MessageReactionsP
5959

6060
if (buttonRef.current) {
6161
const rect = buttonRef.current.getBoundingClientRect();
62-
// Place above the button — natural for reactions at the bottom of messages
63-
// 116px = 2 rows × (36px + 6px gap) + 16px padding + 8px gap
64-
setPickerPos({ top: rect.top - 116, left: rect.left });
62+
// Prefer above the button; fall back to below if too close to the top of the viewport
63+
const spaceAbove = rect.top - 116;
64+
const top = spaceAbove >= 8 ? spaceAbove : rect.bottom + 8;
65+
setPickerPos({ top, left: rect.left });
6566
}
6667

6768
// Lock the nearest scrollable ancestor so the chat doesn't scroll while picker is open

0 commit comments

Comments
 (0)