@@ -59,6 +59,62 @@ async function joinRoomApi(roomId, token) {
5959 throw new Error ( text || `HTTP ${ res . status } ` ) ;
6060}
6161
62+ const pickFirstNonEmptyString = ( ...values ) => {
63+ for ( const value of values ) {
64+ if ( typeof value === 'string' ) {
65+ const trimmed = value . trim ( ) ;
66+ if ( trimmed ) return trimmed ;
67+ }
68+ }
69+ return '' ;
70+ } ;
71+
72+ const resolveParticipantName = ( primary , fallbackEntry , fallbackId ) => {
73+ const name = pickFirstNonEmptyString (
74+ primary ?. displayName ,
75+ primary ?. nickName ,
76+ primary ?. nickname ,
77+ primary ?. profile ?. nickname ,
78+ primary ?. profile ?. name ,
79+ primary ?. userName ,
80+ primary ?. username ,
81+ primary ?. email ,
82+ primary ?. userEmail ,
83+ primary ?. ownerName ,
84+ primary ?. name ,
85+ typeof primary ?. userId === 'string' ? primary . userId : null ,
86+ fallbackEntry ?. displayName ,
87+ fallbackEntry ?. nickName ,
88+ fallbackEntry ?. nickname ,
89+ fallbackEntry ?. profile ?. nickname ,
90+ fallbackEntry ?. profile ?. name ,
91+ fallbackEntry ?. userName ,
92+ fallbackEntry ?. username ,
93+ fallbackEntry ?. email ,
94+ fallbackEntry ?. userEmail ,
95+ fallbackEntry ?. ownerName ,
96+ fallbackEntry ?. name ,
97+ typeof fallbackEntry ?. userId === 'string' ? fallbackEntry . userId : null ,
98+ fallbackId != null ? String ( fallbackId ) : null
99+ ) ;
100+
101+ return name || ( fallbackId != null ? String ( fallbackId ) : '익명 사용자' ) ;
102+ } ;
103+
104+ const resolveParticipantEmail = ( primary , fallbackEntry ) => {
105+ return pickFirstNonEmptyString (
106+ primary ?. email ,
107+ primary ?. userEmail ,
108+ primary ?. contactEmail ,
109+ primary ?. ownerEmail ,
110+ fallbackEntry ?. email ,
111+ fallbackEntry ?. userEmail ,
112+ fallbackEntry ?. contactEmail ,
113+ fallbackEntry ?. ownerEmail
114+ ) ;
115+ } ;
116+
117+
62118export default function CodecastLive ( { isDark } ) {
63119 const navigate = useNavigate ( ) ;
64120 const location = useLocation ( ) ;
@@ -69,6 +125,7 @@ export default function CodecastLive({ isDark }) {
69125 // 로그인 유저
70126 const storedUserId = localStorage . getItem ( 'userId' ) || '' ;
71127 const username = localStorage . getItem ( 'username' ) || storedUserId || 'anonymous' ;
128+ const storedEmail = localStorage . getItem ( 'email' ) || localStorage . getItem ( 'userEmail' ) || '' ;
72129 const token = localStorage . getItem ( 'token' ) || '' ;
73130 useEffect ( ( ) => {
74131 if ( ! token ) {
@@ -114,12 +171,14 @@ export default function CodecastLive({ isDark }) {
114171 ( ) => ( {
115172 id : userId ,
116173 name : username ,
174+ displayName : username ,
175+ email : storedEmail ,
117176 role : defaultRole ,
118177 code : defaultFile . content ,
119178 file : defaultFile ,
120179 stage : 'ready' ,
121180 } ) ,
122- [ userId , username , defaultRole , defaultFile ]
181+ [ userId , username , defaultRole , defaultFile , storedEmail ]
123182 ) ;
124183
125184 const [ participants , setParticipants ] = useState ( [ initialMe ] ) ;
@@ -267,7 +326,10 @@ export default function CodecastLive({ isDark }) {
267326
268327 if ( ownerIdFromSession ) {
269328 sessionOwnerPatch = {
270- name : sessionLike . ownerName || sessionLike . owner ?. userName || sessionLike . owner ?. name ,
329+ ownerName : sessionLike . ownerName ,
330+ name : resolveParticipantName ( sessionLike . owner , null , ownerIdFromSession ) ,
331+ displayName : resolveParticipantName ( sessionLike . owner , null , ownerIdFromSession ) ,
332+ email : resolveParticipantEmail ( sessionLike . owner , null ) ,
271333 stage : normalizedStage ,
272334 sessionId : sId , // ✅ 세션 ID 저장
273335 file : sessionFile
@@ -353,9 +415,14 @@ export default function CodecastLive({ isDark }) {
353415 const prevEntry = prevMap . get ( id ) ;
354416 const normalizedId = String ( id ) ;
355417 const isHost = draft . role === 'host' || prevEntry ?. role === 'host' ;
418+ const resolvedName = resolveParticipantName ( draft , prevEntry , id ) ;
419+ const resolvedEmail = resolveParticipantEmail ( draft , prevEntry ) || prevEntry ?. email || '' ;
420+
356421 nextMap . set ( id , {
357422 id,
358- name : draft . name || prevEntry ?. name || id ,
423+ name : resolvedName ,
424+ displayName : resolvedName ,
425+ email : resolvedEmail ,
359426 role : isHost
360427 ? 'host'
361428 : editIds . has ( normalizedId )
@@ -376,7 +443,10 @@ export default function CodecastLive({ isDark }) {
376443 const ownerParticipantId = msg . owner . userId || msg . owner . id ;
377444 if ( ownerParticipantId ) {
378445 upsert ( ownerParticipantId , {
379- name : msg . owner . userName || msg . owner . userId || msg . owner . name || ownerParticipantId ,
446+ ownerName : msg . owner . displayName || msg . owner . userName ,
447+ name : resolveParticipantName ( msg . owner , null , ownerParticipantId ) ,
448+ displayName : resolveParticipantName ( msg . owner , null , ownerParticipantId ) ,
449+ email : resolveParticipantEmail ( msg . owner , null ) ,
380450 role : 'host' ,
381451 } ) ;
382452 }
@@ -386,7 +456,10 @@ export default function CodecastLive({ isDark }) {
386456 const participantId = participant ?. userId || participant ?. id ;
387457 if ( ! participantId ) return ;
388458 upsert ( participantId , {
389- name : participant . userName || participant . userId || participant . name || participantId ,
459+ displayName : participant . displayName || participant . ownerName ,
460+ ownerName : participant . ownerName ,
461+ name : resolveParticipantName ( participant , null , participantId ) ,
462+ email : resolveParticipantEmail ( participant , null ) ,
390463 stage : participant . stage ,
391464 code : typeof participant . code === 'string' ? participant . code : undefined ,
392465 file : participant . file ,
@@ -410,7 +483,7 @@ export default function CodecastLive({ isDark }) {
410483 return ordered ;
411484 } ) ;
412485 } ,
413- [ initialMe , sessionId , setSessionOwnerId , updateParticipants , userId ]
486+ [ initialMe , setSessionOwnerId , updateParticipants , userId ]
414487 ) ;
415488
416489 const handleSystemEvent = useCallback (
@@ -430,12 +503,19 @@ export default function CodecastLive({ isDark }) {
430503 }
431504
432505 if ( ownerId ) {
506+ const nameDraft = {
507+ ownerName,
508+ displayName : ownerName ,
509+ name : ownerName ,
510+ } ;
511+
433512 updateParticipants ( ( prev ) =>
434513 prev . map ( ( p ) =>
435514 p . id === ownerId
436515 ? {
437516 ...p ,
438- name : ownerName || p . name ,
517+ name : resolveParticipantName ( nameDraft , p , ownerId ) ,
518+ displayName : resolveParticipantName ( nameDraft , p , ownerId ) ,
439519 sessionId : nextSessionId || p . sessionId , // ✅
440520 file : file
441521 ? { ...p . file , ...file , ...( typeof code === 'string' ? { content : code } : { } ) }
@@ -460,11 +540,19 @@ export default function CodecastLive({ isDark }) {
460540 }
461541
462542 if ( ownerId && stage ) {
543+ const nameDraft = {
544+ ownerName : payload . ownerName ,
545+ displayName : payload . ownerName ,
546+ name : payload . ownerName ,
547+ } ;
548+
463549 updateParticipants ( ( prev ) =>
464550 prev . map ( ( p ) =>
465551 p . id === ownerId
466552 ? {
467553 ...p ,
554+ name : resolveParticipantName ( nameDraft , p , ownerId ) ,
555+ displayName : resolveParticipantName ( nameDraft , p , ownerId ) ,
468556 sessionId : nextSessionId || p . sessionId , // ✅
469557 stage,
470558 file : file
@@ -809,11 +897,14 @@ export default function CodecastLive({ isDark }) {
809897 const isSessionOwner = ! ! ownerId && p . id === ownerId ;
810898 const hasEditPermission = perms [ p . id ] === 'edit' || perms [ idKey ] === 'edit' ;
811899 const sessionRole = isSessionOwner ? 'owner' : hasEditPermission ? 'edit' : 'view' ;
900+ const displayName = resolveParticipantName ( p , null , p . id ) ;
812901
813902 return {
814903 ...p ,
815904 sessionRole,
816905 isRoomOwner : p . id === roomOwnerId ,
906+ displayName,
907+ name : displayName ,
817908 } ;
818909 } ) ;
819910 } , [ participants , activeSessionPermissions , activeSessionMeta ?. ownerId , roomOwnerId ] ) ;
0 commit comments