diff --git a/lib/dialogs/settings_dialog.dart b/lib/dialogs/settings_dialog.dart index 0af2bc7..cd739d0 100644 --- a/lib/dialogs/settings_dialog.dart +++ b/lib/dialogs/settings_dialog.dart @@ -14,7 +14,7 @@ void showSettingsDialog(BuildContext context) { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( - width: MediaQuery.of(context).size.width * 0.2, + width: MediaQuery.of(context).size.width * 0.1, child: const Text( '', // 공백 (디자인용) @@ -26,7 +26,7 @@ void showSettingsDialog(BuildContext context) { ), ), Container( - width: MediaQuery.of(context).size.width * 0.2, + width: MediaQuery.of(context).size.width * 0.3, child: const Text( 'Settings', // '설정' diff --git a/lib/views/room/finish_private_page.dart b/lib/views/room/finish_private_page.dart index 3bd5ddf..c4cec0f 100644 --- a/lib/views/room/finish_private_page.dart +++ b/lib/views/room/finish_private_page.dart @@ -56,10 +56,13 @@ class _FinishPrivatePageState extends State { if (response['result'] == 'OK') { final resp = response['response'] ?? {}; if (resp['result'] == 'OK') { - final data = resp['data'] ?? {}; + final data = resp['data'] ?? {}; + // (1) room_info final rInfo = data['room_info'] ?? {}; - final uInfo = data['user_info'] ?? {}; + + // (2) user_info는 List 형태로 받아오기 + final List uInfoList = data['user_info'] ?? []; final rTitle = (rInfo['room_title'] ?? '') as String; final mSeq = (rInfo['master_user_seq'] ?? 0) as int; @@ -68,9 +71,7 @@ class _FinishPrivatePageState extends State { setState(() { _roomInfo = rInfo; - _userMap = uInfo; _roomTitle = rTitle.isNotEmpty ? rTitle : 'Finished Room (Solo)'; - // '종료된 방(개인전)' _masterUserSeq = mSeq.toString(); if (sdt != null && sdt is String && sdt.contains('T')) { @@ -81,39 +82,35 @@ class _FinishPrivatePageState extends State { } }); - // Convert userInfo → list (userInfo -> List 변환) + // (3) List로 변환 final List> tempList = []; - uInfo.forEach((_, val) { - // val: { user_seq, participant_type, nickname, score, ... } - tempList.add(Map.from(val)); - }); + for (var item in uInfoList) { + tempList.add(Map.from(item)); + } - final playerList = tempList.toList(); - - // Sort by score descending (점수 내림차순 정렬) - playerList.sort((a, b) { + // (4) 점수 내림차순 정렬 + tempList.sort((a, b) { final sa = (a['score'] ?? 0) as int; final sb = (b['score'] ?? 0) as int; return sb.compareTo(sa); }); + // (5) 상태 갱신 setState(() { - _playerList = playerList; - _isLoading = false; + _playerList = tempList; + _isLoading = false; }); + } else { - final msgTitle = resp['response_info']?['msg_title'] ?? 'Error'; // '오류' - final msgContent = resp['response_info']?['msg_content'] ?? 'Failed to fetch data'; - // '데이터 조회 실패' + final msgTitle = resp['response_info']?['msg_title'] ?? 'Error'; + final msgContent = resp['response_info']?['msg_content'] ?? 'Failed to fetch data'; showResponseDialog(context, msgTitle, msgContent); } } else { - showResponseDialog(context, 'Failed', 'Server communication error.'); - // '실패', '서버 통신 오류' + showResponseDialog(context, 'Failed', 'Server communication error.'); } } catch (e) { - showResponseDialog(context, 'Error', '$e'); - // '오류' + showResponseDialog(context, 'Error', '$e'); } finally { setState(() => _isLoading = false); } diff --git a/lib/views/room/finish_team_page.dart b/lib/views/room/finish_team_page.dart index eddfbf1..68cc3a3 100644 --- a/lib/views/room/finish_team_page.dart +++ b/lib/views/room/finish_team_page.dart @@ -58,7 +58,7 @@ class _FinishTeamPageState extends State { if (resp['result'] == 'OK') { final data = resp['data'] ?? {}; final rInfo = data['room_info'] ?? {}; - final uInfo = data['user_info'] ?? {}; + final List uInfoList = data['user_info'] ?? []; final rTitle = (rInfo['room_title'] ?? '') as String; final mSeq = (rInfo['master_user_seq'] ?? 0) as int; @@ -67,9 +67,7 @@ class _FinishTeamPageState extends State { setState(() { _roomInfo = rInfo; - _userMap = uInfo; - _roomTitle = rTitle.isNotEmpty ? rTitle : 'Finished Team Game'; - // '종료된 팀전' + _roomTitle = rTitle.isNotEmpty ? rTitle : 'Finished Team Game'; _masterUserSeq = mSeq.toString(); if (sdt != null && sdt is String && sdt.contains('T')) { @@ -80,12 +78,13 @@ class _FinishTeamPageState extends State { } }); - // userList + // user_info 처리 (List) final List> tempList = []; - uInfo.forEach((_, val) { - tempList.add(Map.from(val)); - }); + for (var u in uInfoList) { + tempList.add(Map.from(u)); + } + // 전체 플레이어 final players = tempList.toList(); // (3) Separate by team + sum scores (팀명별 분류 + 점수 합) @@ -99,10 +98,10 @@ class _FinishTeamPageState extends State { tMap[tName]!.add(user); } - // Calculate team scores (팀별 점수) + // 팀별 점수 계산 tMap.forEach((team, mems) { int sumScore = 0; - // Sort each team's members by descending score (팀 멤버 점수 내림차순) + // 팀 멤버를 점수 내림차순 정렬 mems.sort((a, b) { final sa = (a['score'] ?? 0) as int; final sb = (b['score'] ?? 0) as int; @@ -114,11 +113,10 @@ class _FinishTeamPageState extends State { tScoreMap[team] = sumScore; }); - // (4) Sort teams by score (팀들을 점수순으로 정렬) + // (4) 팀들을 점수 순으로 정렬 final sortedTeams = tScoreMap.keys.toList(); sortedTeams.sort((a, b) => tScoreMap[b]!.compareTo(tScoreMap[a]!)); - // Put sorted results into a new map (정렬된 결과를 새 맵에) final Map>> finalTeamMap = {}; final Map finalScoreMap = {}; @@ -128,24 +126,21 @@ class _FinishTeamPageState extends State { } setState(() { - _userList = tempList; // Keep the entire list if needed + _userList = tempList; // 전체 유저 리스트 _teamMap = finalTeamMap; _teamScoreMap = finalScoreMap; _isLoading = false; }); } else { - final msgTitle = resp['response_info']?['msg_title'] ?? 'Error'; // '오류' - final msgContent = resp['response_info']?['msg_content'] ?? 'Failed to fetch data'; - // '데이터 조회 실패' + final msgTitle = resp['response_info']?['msg_title'] ?? 'Error'; + final msgContent = resp['response_info']?['msg_content'] ?? 'Failed to fetch data'; showResponseDialog(context, msgTitle, msgContent); } } else { - showResponseDialog(context, 'Failed', 'Server communication error.'); - // '실패', '서버 통신 오류' + showResponseDialog(context, 'Failed', 'Server communication error.'); } } catch (e) { - showResponseDialog(context, 'Error', '$e'); - // '오류' + showResponseDialog(context, 'Error', '$e'); } finally { setState(() => _isLoading = false); } diff --git a/lib/views/room/main_page.dart b/lib/views/room/main_page.dart index beca721..1e28cf6 100644 --- a/lib/views/room/main_page.dart +++ b/lib/views/room/main_page.dart @@ -41,6 +41,8 @@ class _MainPageState extends State { // e.g., if a second back press occurs within 2 seconds, exit the app (2초 이내로 두 번 누르면 종료) static const _exitDuration = Duration(seconds: 2); + double scaleFactor = 1.0; + @override void initState() { super.initState(); @@ -60,6 +62,21 @@ class _MainPageState extends State { super.dispose(); } + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _updateScaleFactor(); + } + + // Adjust font size by screen width (화면 크기에 따라 폰트 크기 조절) + void _updateScaleFactor() { + final screenWidth = MediaQuery.of(context).size.width; + const baseWidth = 400.0; + setState(() { + scaleFactor = (screenWidth / baseWidth).clamp(0.8, 1.4); + }); + } + // On back press callback (뒤로가기 콜백) Future _onWillPop() async { final now = DateTime.now(); @@ -247,16 +264,23 @@ class _MainPageState extends State { required String label, required VoidCallback onTap, }) { - return ElevatedButton( - onPressed: onTap, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.white, // 버튼 배경색 - foregroundColor: Colors.black, // 버튼 텍스트 색 - side: const BorderSide(color: Colors.black, width: 1), - padding: const EdgeInsets.symmetric(vertical: 36, horizontal: 32), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + return SizedBox( + width: 100 * scaleFactor, + height: 100 * scaleFactor, + child: ElevatedButton( + onPressed: onTap, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + foregroundColor: Colors.black, + side: const BorderSide(color: Colors.black, width: 1), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + ), + child: Text( + label, + style: const TextStyle(color: Colors.black), + textAlign: TextAlign.center, + ), ), - child: Text(label, style: const TextStyle(color: Colors.black)), ); } } diff --git a/lib/views/room/playing_team_page.dart b/lib/views/room/playing_team_page.dart index 4bf099b..f35a7ab 100644 --- a/lib/views/room/playing_team_page.dart +++ b/lib/views/room/playing_team_page.dart @@ -165,6 +165,7 @@ class _PlayingTeamPageState extends State { 'nickname': uData['nickname'] ?? 'User', // '유저' 'team_name': (uData['team_name'] ?? '').toString().toUpperCase(), 'score': uData['score'] ?? 0, + 'profile_img': uData['profile_img'] ?? '', }); if (uSeq.toString() == mySeq) { myParticipantType = (uData['participant_type'] ?? '').toString().toUpperCase(); @@ -566,6 +567,8 @@ class _PlayingTeamPageState extends State { final tempScore = userData['score'] ?? 0; final score = (scoreOpenRange == 'ALL') ? tempScore : '-'; final nickname = userData['nickname'] ?? 'User'; // '유저' + final profileImg = userData['profile_img'] ?? ''; + print('profileImg: $profileImg'); final bool isActive = _userListMap[userSeq] ?? true; final hasExited = !isActive; @@ -605,7 +608,7 @@ class _PlayingTeamPageState extends State { ) : ClipOval( child: Image.network( - 'https://eldsoft.com:8097/images${userData['profile_img']}', + profileImg.isNotEmpty ? 'https://eldsoft.com:8097/images$profileImg' : '', fit: BoxFit.cover, errorBuilder: (ctx, err, st) => const Center( child: Text(