Skip to content

Commit 58d7ee0

Browse files
committed
hot fix
1 parent 5a4b210 commit 58d7ee0

5 files changed

Lines changed: 76 additions & 47 deletions

File tree

src/features/game/multiplayer/chat/components/Lobby/ChatWindow.vue

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@
6262
type="text"
6363
v-model="newMessage"
6464
placeholder="메시지를 입력하세요..."
65-
@keyup.enter="sendMessage"
65+
@keydown.stop
66+
@keydown.enter="sendMessage"
67+
@focus="handleInputFocus"
68+
@blur="handleInputBlur"
69+
ref="chatInput"
6670
/>
6771
<button
6872
class="send-button"
@@ -109,7 +113,8 @@ export default {
109113
return {
110114
newMessage: '',
111115
onlineUsers: 37, // 테스트 데이터, 실제로는 서버에서 받아와야 함
112-
currentMemberId: null
116+
currentMemberId: null,
117+
isInputFocused: false
113118
};
114119
},
115120
@@ -159,6 +164,14 @@ export default {
159164
this.newMessage = '';
160165
},
161166
167+
handleInputFocus() {
168+
this.isInputFocused = true;
169+
},
170+
171+
handleInputBlur() {
172+
this.isInputFocused = false;
173+
},
174+
162175
closeChat() {
163176
this.$emit('close');
164177
},

src/features/game/multiplayer/roadview/components/results/RoundResults.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -508,12 +508,12 @@ export default {
508508
509509
// 거리 포맷팅 메서드 (소수점 3자리에서 반올림)
510510
formatDistance(distance) {
511-
if (distance == null || (distance !== 0 && !distance)) return "0";
511+
if (distance == null || (distance !== 0 && !distance)) return "0.000";
512512
// 소수점 3자리에서 반올림: 소수점 4자리에서 반올림하여 소수점 3자리까지 표시
513513
// 예: 1.23456 -> 1.235, 1.23444 -> 1.234
514514
const rounded = Math.round(Number(distance) * 1000) / 1000;
515-
// 소수점 3자리까지 표시 (불필요한 0은 자동 제거됨)
516-
return parseFloat(rounded.toFixed(3));
515+
// 소수점 3자리까지 항상 표시 (toFixed(3) 사용)
516+
return rounded.toFixed(3);
517517
},
518518
},
519519
};

src/features/game/multiplayer/roadview/composables/useSoloGameFlow.js

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -911,33 +911,37 @@ export function useSoloGameFlow(gameStore, uiCallbacks = {}) {
911911

912912
if (!gameStore) return
913913

914+
// playerResults가 없거나 빈 배열이면 콜백을 호출하지 않음
915+
if (!message.playerResults || !Array.isArray(message.playerResults) || message.playerResults.length === 0) {
916+
console.warn('[Solo Flow] 게임 종료 메시지에 playerResults가 없거나 빈 배열임, 콜백 호출하지 않음')
917+
return
918+
}
919+
914920
// 모든 타이머 정리
915921
clearTimerInterval()
916922
clearTransitionInterval()
917923

918924
// 백엔드에서 받은 최종 결과 데이터 매핑 (gameStore에 저장하지 않고 콜백으로 전달)
919-
let finalGameResult = null
920-
if (message.playerResults && Array.isArray(message.playerResults)) {
921-
// PlayerFinalResult를 게임 결과 형식에 맞게 매핑
922-
const playerResults = message.playerResults.map(player => ({
923-
playerId: player.playerId,
924-
nickname: player.nickname || '알 수 없음',
925-
markerImageUrl: player.markerImageUrl || null,
926-
totalScore: player.totalScore != null ? Number(player.totalScore) : 0,
927-
finalRank: player.finalRank != null ? Number(player.finalRank) : 0,
928-
earnedPoint: player.earnedPoint != null ? Number(player.earnedPoint) : 0
929-
}))
930-
931-
finalGameResult = {
932-
gameId: message.gameId != null ? Number(message.gameId) : null,
933-
message: message.message || '',
934-
timestamp: message.timestamp != null ? Number(message.timestamp) : Date.now(),
935-
playerResults: playerResults
936-
}
925+
// playerResults가 유효한 경우에만 finalGameResult 생성
926+
const playerResults = message.playerResults.map(player => ({
927+
playerId: player.playerId,
928+
nickname: player.nickname || '알 수 없음',
929+
markerImageUrl: player.markerImageUrl || null,
930+
totalScore: player.totalScore != null ? Number(player.totalScore) : 0,
931+
finalRank: player.finalRank != null ? Number(player.finalRank) : 0,
932+
earnedPoint: player.earnedPoint != null ? Number(player.earnedPoint) : 0
933+
}))
934+
935+
const finalGameResult = {
936+
gameId: message.gameId != null ? Number(message.gameId) : null,
937+
message: message.message || '',
938+
timestamp: message.timestamp != null ? Number(message.timestamp) : Date.now(),
939+
playerResults: playerResults
937940
}
938941

939942
// UI 콜백: 게임 종료 화면 표시 (finalGameResult 데이터 전달)
940-
if (callbacks.onGameFinish) {
943+
// finalGameResult가 null이 아니고 playerResults가 있는 경우에만 호출
944+
if (callbacks.onGameFinish && finalGameResult) {
941945
callbacks.onGameFinish(finalGameResult)
942946
}
943947
}

src/features/game/multiplayer/roadview/views/SoloGameView.vue

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -685,15 +685,23 @@ export default {
685685
onGameFinish: (finalGameResult) => {
686686
console.log('[Solo Game] 게임 종료 - WebSocket 메시지 수신:', finalGameResult)
687687
688-
// WebSocket으로 받은 게임 종료 메시지 데이터를 로컬 데이터에 저장
689-
if (finalGameResult) {
690-
this.finalGameResult = finalGameResult
691-
this.showGameResults = true
692-
console.log('[Solo Game] 게임 결과 모달 표시:', finalGameResult)
693-
} else {
688+
// finalGameResult가 null이거나 빈 객체인 경우 무시
689+
if (!finalGameResult || typeof finalGameResult !== 'object') {
694690
console.warn('[Solo Game] 게임 종료 메시지에 finalGameResult 데이터가 없음')
691+
return
692+
}
693+
694+
// playerResults가 없거나 빈 배열이면 무시
695+
if (!finalGameResult.playerResults || !Array.isArray(finalGameResult.playerResults) || finalGameResult.playerResults.length === 0) {
696+
console.warn('[Solo Game] 게임 종료 메시지에 playerResults가 없거나 빈 배열임')
697+
return
695698
}
696699
700+
// WebSocket으로 받은 게임 종료 메시지 데이터를 로컬 데이터에 저장
701+
this.finalGameResult = finalGameResult
702+
this.showGameResults = true
703+
console.log('[Solo Game] 게임 결과 모달 표시:', finalGameResult)
704+
697705
// 총 게임 시간 계산
698706
if (this.gameStartTime) {
699707
this.totalGameTime = Math.floor((Date.now() - this.gameStartTime) / 1000)

src/features/game/multiplayer/room/views/RoomView.vue

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -496,14 +496,20 @@ const isChatVisible = ref(false);
496496
const chatInputFieldRef = ref(null);
497497
498498
// 화면 크기 감지
499-
const checkScreenSize = () => {
499+
const checkScreenSize = (preserveChatState = false) => {
500500
isMobileView.value = window.innerWidth <= 1024;
501-
if (!isMobileView.value) {
502-
isChatVisible.value = true; // 데스크톱에서는 항상 채팅 표시
503-
} else {
504-
// 반응형 전환 시 기본은 플레이어 리스트 화면이 먼저 보이도록 채팅 숨김
505-
isChatVisible.value = false;
501+
502+
// 리사이즈 이벤트로 인한 호출이 아닌 경우에만 채팅창 상태 초기화
503+
if (!preserveChatState) {
504+
if (!isMobileView.value) {
505+
isChatVisible.value = true; // 데스크톱에서는 항상 채팅 표시
506+
} else {
507+
// 반응형 전환 시 기본은 플레이어 리스트 화면이 먼저 보이도록 채팅 숨김
508+
isChatVisible.value = false;
509+
}
506510
}
511+
// preserveChatState가 true인 경우 (리사이즈 이벤트)에는 채팅창 상태를 변경하지 않음
512+
// 이렇게 하면 모바일에서 키보드로 인한 뷰포트 변경 시에도 채팅창이 닫히지 않음
507513
};
508514
509515
// 채팅 토글 래퍼 함수
@@ -520,13 +526,9 @@ const handleChatInputFocus = () => {
520526
}
521527
522528
nextTick(() => {
529+
// 채팅 메시지 영역의 스크롤만 조정 (레이아웃 재계산 방지)
523530
scrollChatToBottom();
524-
if (chatInputFieldRef.value) {
525-
chatInputFieldRef.value.scrollIntoView({
526-
behavior: 'smooth',
527-
block: 'nearest'
528-
});
529-
}
531+
// scrollIntoView 제거: 키보드 포커스 시 모달 위치 변경 방지
530532
});
531533
};
532534
@@ -577,7 +579,7 @@ const handleBeforeUnload = (event) => {
577579
578580
onMounted(async () => {
579581
checkScreenSize();
580-
window.addEventListener('resize', checkScreenSize);
582+
window.addEventListener('resize', () => checkScreenSize(true));
581583
582584
// 강제 종료 감지를 위한 beforeunload 이벤트 리스너 추가
583585
window.addEventListener('beforeunload', handleBeforeUnload);
@@ -1157,6 +1159,7 @@ const formatUpdateTime = (timestamp) => {
11571159
.room-content {
11581160
flex-direction: column;
11591161
gap: 1rem;
1162+
position: relative;
11601163
}
11611164
11621165
.left-panel {
@@ -1182,21 +1185,22 @@ const formatUpdateTime = (timestamp) => {
11821185
11831186
/* 모바일에서 채팅이 표시될 때 전체 화면 */
11841187
.right-panel:not(.hidden-mobile) {
1185-
position: fixed;
1188+
position: absolute;
11861189
top: 0;
11871190
left: 0;
11881191
right: 0;
1189-
bottom: 0;
1192+
height: 100%;
11901193
z-index: 1000;
11911194
background: rgba(0, 0, 0, 0.5);
11921195
padding: 1rem;
1193-
min-height: 100vh;
1196+
transform: translateX(0);
11941197
}
11951198
11961199
.right-panel:not(.hidden-mobile) .chat-panel {
11971200
max-width: 500px;
1198-
margin: 0 auto;
1201+
width: 100%;
11991202
height: 100%;
1203+
margin: 0 auto;
12001204
}
12011205
}
12021206

0 commit comments

Comments
 (0)