Skip to content

Commit f99606c

Browse files
committed
웹소켓3
1 parent 25fa02d commit f99606c

1 file changed

Lines changed: 58 additions & 7 deletions

File tree

src/components/codecast/codecastlive/CodecastLive.jsx

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export default function CodecastLive({ isDark }) {
106106

107107
const [participants, setParticipants] = useState([initialMe]);
108108
const [currentUser, setCurrentUser] = useState(initialMe);
109+
const [activeParticipantId, setActiveParticipantId] = useState(initialMe.id);
109110

110111
// 채팅
111112
const [isChatOpen, setIsChatOpen] = useState(false);
@@ -144,6 +145,21 @@ export default function CodecastLive({ isDark }) {
144145

145146
const { connect, disconnect, subscribeSystem, subscribeCode, sendCodeUpdate, publish } = useCollabSocket();
146147

148+
useEffect(() => {
149+
const exists = participants.some((p) => p.id === activeParticipantId);
150+
if (!exists) {
151+
const hostParticipant = participants.find((p) => p.role === 'host');
152+
setActiveParticipantId(hostParticipant?.id || userId);
153+
}
154+
}, [participants, activeParticipantId, userId]);
155+
156+
const activeParticipant = useMemo(() => {
157+
const target = participants.find((p) => p.id === activeParticipantId);
158+
if (target) return target;
159+
const selfParticipant = participants.find((p) => p.id === userId);
160+
return selfParticipant || participants[0] || null;
161+
}, [participants, activeParticipantId, userId]);
162+
147163
const applyRoomStateUpdate = useCallback(
148164
(msg) => {
149165
if (!msg) return;
@@ -440,6 +456,7 @@ export default function CodecastLive({ isDark }) {
440456

441457
// 에디터 변경 → 서버 publish
442458
const handleEditorChange = (nextText) => {
459+
if (activeParticipantId !== currentUser.id) return;
443460
// 서버에 보내는 것은 동일
444461
// 로컬 상태 업데이트
445462
setCurrentUser((prev) => ({
@@ -533,6 +550,8 @@ export default function CodecastLive({ isDark }) {
533550
stage: 'ready',
534551
}));
535552

553+
setActiveParticipantId(userId);
554+
536555
broadcastSystemEvent('SESSION_READY', {
537556
sessionId: newSessionId,
538557
ownerId: currentUser.id,
@@ -586,6 +605,8 @@ export default function CodecastLive({ isDark }) {
586605
return;
587606
}
588607

608+
setActiveParticipantId(userId);
609+
589610
const nextStage = currentUser.stage === 'editing' ? 'ready' : 'editing';
590611
const prevStage = currentUser.stage;
591612
const nextStatus = nextStage === 'editing' ? 'ACTIVE' : 'INACTIVE';
@@ -772,9 +793,38 @@ export default function CodecastLive({ isDark }) {
772793
const findByName = (name) => participants.find((p) => p.name === name);
773794
const findById = (id) => participants.find((p) => p.id === id);
774795

796+
const isViewingSelf = activeParticipant?.id === currentUser.id;
797+
const editorReadOnly = !(isViewingSelf && currentUser.stage === 'editing' && canEdit);
798+
799+
const previewParticipants = useMemo(() => {
800+
const editingList = participants.filter((p) => p.stage === 'editing' && p.file !== null);
801+
const selfParticipant = participants.find((p) => p.id === userId);
802+
if (selfParticipant && !editingList.some((p) => p.id === selfParticipant.id)) {
803+
editingList.push(selfParticipant);
804+
}
805+
return editingList;
806+
}, [participants, userId]);
807+
775808
// 참가자가 'editing' 상태일 때만 프리뷰에 표시
776809
// 이제 기본 파일도 공유 가능하므로 defaultFile.id 조건은 제거합니다.
777-
const isAnyParticipantSharing = participants.some(p => p.stage === 'editing' && p.file !== null);
810+
const isAnyParticipantSharing = previewParticipants.some(p => p.stage === 'editing' && p.file !== null);
811+
812+
useEffect(() => {
813+
if (!isAnyParticipantSharing && activeParticipantId !== userId) {
814+
setActiveParticipantId(userId);
815+
}
816+
}, [isAnyParticipantSharing, activeParticipantId, userId]);
817+
818+
useEffect(() => {
819+
if (!isViewingSelf) return;
820+
if (currentUser.stage === 'editing') return;
821+
const editingParticipant = participants.find(
822+
(p) => p.stage === 'editing' && p.file !== null && p.id !== userId
823+
);
824+
if (editingParticipant && editingParticipant.id !== activeParticipantId) {
825+
setActiveParticipantId(editingParticipant.id);
826+
}
827+
}, [isViewingSelf, currentUser.stage, participants, activeParticipantId, userId]);
778828

779829

780830
return (
@@ -876,11 +926,12 @@ export default function CodecastLive({ isDark }) {
876926

877927
<div className="editor-area">
878928
<CodeEditor
879-
file={currentUser.file}
929+
file={activeParticipant?.file}
880930
onChange={handleEditorChange}
881-
currentUser={currentUser}
931+
currentUser={activeParticipant || currentUser}
932+
readOnly={editorReadOnly}
882933
isDark={isDark}
883-
selectFileAction={FileSelectButton}
934+
selectFileAction={isViewingSelf ? FileSelectButton : null}
884935
/>
885936
</div>
886937

@@ -923,11 +974,11 @@ export default function CodecastLive({ isDark }) {
923974
<div className="preview-strip nochrome" aria-label="participants preview strip">
924975
<div className="preview-strip-scroller">
925976
<CodePreviewList
926-
participants={participants.filter(p => p.stage === 'editing')}
927-
activeName={currentUser.name}
977+
participants={previewParticipants}
978+
activeName={activeParticipant?.name || currentUser.name}
928979
onSelect={(userName) => {
929980
const pickedUser = participants.find((p) => p.name === userName);
930-
if (pickedUser) setCurrentUser(pickedUser);
981+
if (pickedUser) setActiveParticipantId(pickedUser.id);
931982
}}
932983
/>
933984
</div>

0 commit comments

Comments
 (0)