fix: unintended changes in the leaderboard JSON model

This commit is contained in:
sBubshait 2025-08-07 11:15:33 +03:00
parent 8541eb4a6e
commit 5e5c6c7346
3 changed files with 148 additions and 143 deletions

View File

@ -70,10 +70,9 @@ public class PuzzleController {
@GetMapping("/leaderboard") @GetMapping("/leaderboard")
@Operation(summary = "Get daily leaderboard", description = "Returns leaderboard with 9am cutoff logic (before 9am shows yesterday, from 9am shows today)") @Operation(summary = "Get daily leaderboard", description = "Returns leaderboard with 9am cutoff logic (before 9am shows yesterday, from 9am shows today)")
public ResponseEntity<ApiResponse<Map<String, Object>>> getLeaderboard() { public ResponseEntity<ApiResponse<List<LeaderboardEntry>>> getLeaderboard() {
try { try {
List<PuzzleAttempt> attempts = puzzleService.getTodaysLeaderboard(); List<PuzzleAttempt> attempts = puzzleService.getTodaysLeaderboard();
String leaderboardInfo = puzzleService.getLeaderboardDateInfo();
List<LeaderboardEntry> leaderboard = attempts.stream() List<LeaderboardEntry> leaderboard = attempts.stream()
.filter(attempt -> attempt.isSolved()) .filter(attempt -> attempt.isSolved())
@ -87,12 +86,7 @@ public class PuzzleController {
)) ))
.collect(Collectors.toList()); .collect(Collectors.toList());
Map<String, Object> response = Map.of( return ResponseEntity.ok(ApiResponse.success(leaderboard));
"leaderboard", leaderboard,
"dateInfo", leaderboardInfo
);
return ResponseEntity.ok(ApiResponse.success(response));
} catch (RuntimeException e) { } catch (RuntimeException e) {
return ResponseEntity.ok(ApiResponse.error(e.getMessage())); return ResponseEntity.ok(ApiResponse.error(e.getMessage()));
} }

View File

@ -172,15 +172,4 @@ public class PuzzleService {
return puzzleAttemptRepository.findByPuzzleOrderBySubmittedAtAsc(puzzleOpt.get()); return puzzleAttemptRepository.findByPuzzleOrderBySubmittedAtAsc(puzzleOpt.get());
} }
public String getLeaderboardDateInfo() {
LocalDateTime riyadhNow = getRiyadhNow();
LocalDate leaderboardDate = getLeaderboardDate();
LocalDate today = riyadhNow.toLocalDate();
if (leaderboardDate.equals(today)) {
return "Today's Leaderboard (from 9:00 AM Riyadh time)";
} else {
return "Yesterday's Leaderboard (before 9:00 AM Riyadh time)";
}
}
} }

View File

@ -383,142 +383,164 @@ class _WordlePageState extends State<WordlePage> with TickerProviderStateMixin {
child: Container(height: 1, color: Colors.grey[200]), child: Container(height: 1, color: Colors.grey[200]),
), ),
), ),
body: Column( body: SafeArea(
children: [ child: LayoutBuilder(
Expanded( builder: (context, constraints) {
child: Center( double screenHeight = constraints.maxHeight;
child: Container( double keyboardHeight = (gameWon || gameLost) ? 200 : 200; // Estimated heights
constraints: BoxConstraints(maxWidth: 350), double availableHeight = screenHeight - keyboardHeight;
child: Column(
mainAxisAlignment: MainAxisAlignment.center, return Column(
children: [ children: [
// Game Grid // Game Grid Section
Container( Expanded(
padding: EdgeInsets.all(16), child: Container(
child: Column( height: availableHeight,
children: List.generate(MAX_ATTEMPTS, (row) { child: Center(
return Padding( child: Container(
padding: EdgeInsets.symmetric(vertical: 2), constraints: BoxConstraints(maxWidth: 350),
child: Row( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(WORD_LENGTH, (col) { children: [
bool shouldAnimate = // Game Grid
row == animatingRow && Container(
gridStates[row][col] != padding: EdgeInsets.all(16),
LetterState.empty; child: Column(
children: List.generate(MAX_ATTEMPTS, (row) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 2),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(WORD_LENGTH, (col) {
bool shouldAnimate =
row == animatingRow &&
gridStates[row][col] !=
LetterState.empty;
return Container( return Container(
margin: EdgeInsets.all(2), margin: EdgeInsets.all(2),
width: 62, width: 62,
height: 62, height: 62,
child: shouldAnimate child: shouldAnimate
? AnimatedBuilder( ? AnimatedBuilder(
animation: _tileAnimations[col], animation: _tileAnimations[col],
builder: (context, child) { builder: (context, child) {
double scale = double scale =
0.8 + 0.8 +
(0.2 * (0.2 *
_tileAnimations[col] _tileAnimations[col]
.value); .value);
return Transform.scale( return Transform.scale(
scale: scale, scale: scale,
child: Container( child: Container(
width: 62, width: 62,
height: 62, height: 62,
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: Border.all(
color: color:
_getBorderColor( _getBorderColor(
row,
col,
),
width: 2,
),
color:
_getAnimatedTileColor(
row,
col,
_tileAnimations[col]
.value,
),
borderRadius:
BorderRadius.circular(
4,
),
),
child: Center(
child: Text(
grid[row][col],
style: TextStyle(
fontSize: 32,
fontWeight:
FontWeight.bold,
color: _getAnimatedTextColor(
row,
col,
_tileAnimations[col]
.value,
),
),
),
),
),
);
},
)
: Container(
width: 62,
height: 62,
decoration: BoxDecoration(
border: Border.all(
color: _getBorderColor(
row,
col,
),
width: 2,
),
color: _getTileColor(
row,
col,
),
borderRadius:
BorderRadius.circular(4),
),
child: Center(
child: Text(
grid[row][col],
style: TextStyle(
fontSize: 32,
fontWeight:
FontWeight.bold,
color: _getTextColor(
row, row,
col, col,
), ),
width: 2,
),
color:
_getAnimatedTileColor(
row,
col,
_tileAnimations[col]
.value,
),
borderRadius:
BorderRadius.circular(
4,
),
),
child: Center(
child: Text(
grid[row][col],
style: TextStyle(
fontSize: 32,
fontWeight:
FontWeight.bold,
color: _getAnimatedTextColor(
row,
col,
_tileAnimations[col]
.value,
), ),
), ),
), ),
), ),
), );
); }),
}, ),
) );
: Container( }),
width: 62, ),
height: 62,
decoration: BoxDecoration(
border: Border.all(
color: _getBorderColor(
row,
col,
),
width: 2,
),
color: _getTileColor(
row,
col,
),
borderRadius:
BorderRadius.circular(4),
),
child: Center(
child: Text(
grid[row][col],
style: TextStyle(
fontSize: 32,
fontWeight:
FontWeight.bold,
color: _getTextColor(
row,
col,
),
),
),
),
),
);
}),
), ),
); ],
}), ),
), ),
), ),
], ),
), ),
), // Spacer between grid and keyboard
), SizedBox(height: 16),
), // Keyboard or completion message section
// Keyboard or completion message Container(
Container( constraints: BoxConstraints(
padding: EdgeInsets.all(8), minHeight: 200,
child: (gameWon || gameLost) maxHeight: 250,
? _buildCompletionMessage() ),
: _buildKeyboard(), padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16),
), child: (gameWon || gameLost)
], ? _buildCompletionMessage()
: _buildKeyboard(),
),
// Bottom padding to ensure keyboard isn't at the very bottom
SizedBox(height: MediaQuery.of(context).padding.bottom + 8),
],
);
},
),
), ),
), ),
), ),