Skip to content

Commit 6d5e7ff

Browse files
authored
Merge branch 'main' into feature/95-enhance-offline-experience-with-fallback-page-and-service-worker-pre-caching
2 parents 5272ec8 + 40241c1 commit 6d5e7ff

20 files changed

Lines changed: 1470 additions & 1246 deletions

File tree

src/partials/40x.ejs

Lines changed: 7 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -4,98 +4,16 @@
44
<head>
55
<%- include("../partials/head.ejs") %>
66
<title>Tridecco | <%= status %></title>
7-
<style>
8-
@keyframes pulse {
9-
0% {
10-
transform: scale(1);
11-
opacity: 0.8;
12-
}
13-
14-
50% {
15-
transform: scale(1.1);
16-
opacity: 1;
17-
}
18-
19-
100% {
20-
transform: scale(1);
21-
opacity: 0.8;
22-
}
23-
}
24-
25-
@keyframes float {
26-
0% {
27-
transform: translateY(0);
28-
}
29-
30-
50% {
31-
transform: translateY(-10px);
32-
}
33-
34-
100% {
35-
transform: translateY(0);
36-
}
37-
}
38-
</style>
39-
<%- include("../partials/libs/tridecco-board.ejs") %>
407
</head>
418

42-
<body class="h-screen flex items-center justify-center overflow-hidden" style="background: url('<%= env.CDN_URL %>/img/backgrounds/tridecco.jpg') center center / cover no-repeat;">
43-
<div class="relative">
44-
45-
<div id="board-container" class="w-96 h-96 md:w-[32rem] md:h-[32rem] rounded-2xl shadow-2xl overflow-hidden transform transition-transform hover:scale-105 duration-300">
46-
</div>
47-
48-
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-center">
49-
<h1 class="font-display text-6xl md:text-8xl font-bold text-black drop-shadow-[2px_2px_0px_white] animate-pulse"><%= status %></h1>
50-
<p class="text-lg md:text-xl text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.8)] mt-4 animate-float"><%= message %></p>
51-
<a href="/" class="inline-block mt-8 py-2 px-4 bg-blue-500 hover:bg-blue-700 text-white font-bold rounded-md shadow-md transition-colors duration-300">Back to the Lobby</a>
52-
</div>
9+
<body class="min-h-screen flex items-center justify-center bg-cover bg-center" style="background-image: url('<%= env.CDN_URL %>/img/backgrounds/tridecco.jpg');">
10+
<div class="bg-white/80 backdrop-blur-md rounded-2xl shadow-2xl px-8 py-12 max-w-md w-full text-center border border-amber-700/30">
11+
<h1 class="font-display text-7xl md:text-8xl font-extrabold text-amber-600 drop-shadow mb-4 tracking-tight"><%= status %></h1>
12+
<p class="text-xl md:text-2xl text-gray-700 font-medium mb-8"><%= message %></p>
13+
<a href="/" class="inline-block px-6 py-3 bg-amber-500 hover:bg-amber-600 text-white font-semibold rounded-lg shadow transition-colors duration-200">
14+
Back to the Lobby
15+
</a>
5316
</div>
54-
<script>
55-
window.addEventListener('load', () => {
56-
const {
57-
Board,
58-
Piece,
59-
Renderer
60-
} = Tridecco;
61-
62-
const board = new Board();
63-
const renderer = new Renderer({
64-
board: board,
65-
container: document.getElementById('board-container'),
66-
texturesUrl: `${TRIDECCO_BOARD_ASSETS_URL}/textures/classic/normal`,
67-
backgroundUrl: `${TRIDECCO_BOARD_ASSETS_URL}/backgrounds/wooden-board.jpg`,
68-
gridUrl: `${TRIDECCO_BOARD_ASSETS_URL}/grids/black.png`,
69-
}, () => {
70-
const pieceColorList = [
71-
['blue', 'white'],
72-
['red', 'blue'],
73-
['red', 'yellow'],
74-
['white', 'red'],
75-
['yellow', 'blue']
76-
];
77-
78-
// Randomly fill the board on initialization
79-
for (let i = 0; i < 63; i++) {
80-
const colorPair = pieceColorList[Math.floor(Math.random() * pieceColorList.length)];
81-
const piece = new Piece(colorPair);
82-
board.place(i, piece);
83-
}
84-
85-
// Randomly change the colors of pieces
86-
setInterval(() => {
87-
const randomIndex = Math.floor(Math.random() * 63);
88-
const colorPair = pieceColorList[Math.floor(Math.random() * pieceColorList.length)];
89-
const piece = new Piece(colorPair);
90-
91-
if (board.get(randomIndex)) {
92-
board.remove(randomIndex); // Remove the old piece
93-
}
94-
board.place(randomIndex, piece); // Place the new piece
95-
}, 500); // Execute every 0.5 seconds
96-
});
97-
});
98-
</script>
9917
<script>
10018
history.pushState(null, null, app.location.params.path || app.location.path);
10119
</script>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<div id="load-error-content" class="hidden flex flex-col items-center justify-center py-20">
2+
<svg class="w-14 h-14 text-amber-600 mb-4" fill="none" viewBox="0 0 48 48" stroke="currentColor">
3+
<circle cx="24" cy="24" r="22" stroke-width="3" class="text-amber-200" fill="currentColor" fill-opacity="0.1" />
4+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M24 16v10m0 6h.01" />
5+
</svg>
6+
<h3 class="text-xl font-bold text-amber-800 mb-3">Failed to Load</h3>
7+
<p class="text-gray-700 mb-5 text-center max-w-xs">Sorry, something went wrong while loading the content. Please check your network connection and try again.</p>
8+
<button id="retry-load-button" class="bg-amber-600 hover:bg-amber-700 text-white font-semibold px-6 py-2 rounded-lg shadow-md transition duration-200">
9+
Retry
10+
</button>
11+
</div>

src/partials/navigation-bar-mobile.ejs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,13 @@ function classNames(active) {
2525
</svg>
2626
<span class="text-xs">Ranks</span>
2727
</a>
28-
<a href="/offline" class="<%= classNames(page === 'offline') %>">
28+
<a href="/more" class="<%= classNames(page === 'more') %>">
2929
<svg class="w-6 h-6 mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
30-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 18h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path>
30+
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" />
31+
<circle cx="8" cy="12" r="1" fill="currentColor" />
32+
<circle cx="12" cy="12" r="1" fill="currentColor" />
33+
<circle cx="16" cy="12" r="1" fill="currentColor" />
3134
</svg>
32-
<span class="text-xs">Offline</span>
33-
</a>
34-
<a href="/user/settings" class="<%= classNames(page === 'settings') %>">
35-
<svg class="w-6 h-6 mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
36-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path>
37-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
38-
</svg>
39-
<span class="text-xs">Settings</span>
35+
<span class="text-xs">More</span>
4036
</a>
4137
</nav>

src/partials/navigation-bar.ejs

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ function classNames(active) {
66
}
77
%>
88

9+
<style>
10+
.nav-active {
11+
background-color: rgba(217, 119, 6, 0.1);
12+
border-left-color: #D97706;
13+
color: #92400E;
14+
font-weight: 600;
15+
}
16+
17+
.nav-item:hover {
18+
background-color: rgba(0, 0, 0, 0.05);
19+
}
20+
</style>
21+
922
<aside class="hidden lg:flex flex-col w-20 hover:w-56 transition-all duration-300 ease-in-out bg-white/80 backdrop-blur-sm rounded-xl shadow-lg border border-amber-700/30 overflow-hidden group">
1023
<!-- Logo/Game Title Area -->
1124
<div class="w-full p-4 flex items-center group-hover:justify-start space-x-3 border-b border-amber-700/20 h-[72px] flex-shrink-0">
@@ -14,43 +27,64 @@ function classNames(active) {
1427
<span class="text-xl font-bold text-amber-900 opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">Tridecco</span>
1528
</div>
1629
<!-- Navigation Links -->
17-
<nav class="flex-1 py-4 space-y-1 custom-scrollbar overflow-y-auto">
30+
<nav class="flex-1 py-4 space-y-1 custom-scrollbar overflow-y-auto overflow-x-hidden">
1831
<!-- Home -->
1932
<a href="/" class="<%= classNames(page === 'home') %>">
20-
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === "home" ? 'text-amber-800' : "" %>" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
33+
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === 'home' ? 'text-amber-800' : '' %>" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2134
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>
2235
</svg>
2336
<span class="opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">Home</span>
2437
</a>
2538
<!-- Profile -->
2639
<a href="/user" class="<%= classNames(page === 'profile') %>">
27-
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === "profile" ? 'text-amber-800' : "" %>" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
40+
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === 'profile' ? 'text-amber-800' : '' %>" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2841
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
2942
</svg>
3043
<span class="opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">Profile</span>
3144
</a>
32-
<!-- Leaderboards -->
33-
<a href="/leaderboards" class="<%= classNames(page === 'leaderboards') %>">
34-
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === "leaderboards" ? 'text-amber-800' : "" %>" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
35-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
45+
<!-- Account -->
46+
<a href="/user/account" class="<%= classNames(page === 'account') %>">
47+
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === 'account' ? 'text-amber-800' : '' %>" fill="none" stroke="currentColor" viewBox="0 0 24 24">
48+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5.121 17.804A13.937 13.937 0 0112 16c2.5 0 4.847.655 6.879 1.804M15 10a3 3 0 11-6 0 3 3 0 016 0zm6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
49+
</svg>
50+
<span class="opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">Account</span>
51+
</a>
52+
<!-- Game History -->
53+
<a href="/user/game-history" class="<%= classNames(page === 'game-history') %>">
54+
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === 'game-history' ? 'text-amber-800' : '' %>" fill="none" stroke="currentColor" viewBox="0 0 24 24">
55+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
3656
</svg>
37-
<span class="opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">Leaderboards</span>
57+
<span class="opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">Game History</span>
3858
</a>
39-
<!-- Offline Game -->
40-
<a href="/offline" class="<%= classNames(page === 'offline') %>">
41-
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === "offline" ? 'text-amber-800' : "" %>" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
42-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 18h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path>
59+
<!-- Elo History -->
60+
<a href="/user/elo-history" class="<%= classNames(page === 'elo-history') %>">
61+
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === 'elo-history' ? 'text-amber-800' : '' %>" fill="none" stroke="currentColor" viewBox="0 0 24 24">
62+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 8v8m-4-5v5m-4-2v2m-2 4h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
4363
</svg>
44-
<span class="opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">Offline Game</span>
64+
<span class="opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">Elo History</span>
65+
</a>
66+
<!-- Experience History -->
67+
<a href="/user/experience-history" class="<%= classNames(page === 'experience-history') %>">
68+
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === 'experience-history' ? 'text-amber-800' : '' %>" fill="none" stroke="currentColor" viewBox="0 0 24 24">
69+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"></path>
70+
</svg>
71+
<span class="opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">Experience History</span>
4572
</a>
4673
<!-- Settings -->
4774
<a href="/user/settings" class="<%= classNames(page === 'settings') %>">
48-
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === "settings" ? 'text-amber-800' : "" %>" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
75+
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === 'settings' ? 'text-amber-800' : '' %>" fill="none" stroke="currentColor" viewBox="0 0 24 24">
4976
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path>
5077
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
5178
</svg>
5279
<span class="opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">Settings</span>
5380
</a>
81+
<!-- Security -->
82+
<a href="/user/security" class="<%= classNames(page === 'security') %>">
83+
<svg class="w-5 h-5 mr-4 flex-shrink-0 <%= page === 'security' ? 'text-amber-800' : '' %>" fill="none" stroke="currentColor" viewBox="0 0 24 24">
84+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path>
85+
</svg>
86+
<span class="opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">Security</span>
87+
</a>
5488
</nav>
5589
<!-- Logout Button Area -->
5690
<div class="p-3 border-t border-amber-700/20 mt-auto flex-shrink-0">

src/partials/tridecco-board-animator.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
board: board,
1515
container: document.getElementById('board-container'),
1616
texturesUrl: `${TRIDECCO_BOARD_ASSETS_URL}/textures/classic/normal`,
17-
backgroundUrl: `${TRIDECCO_BOARD_ASSETS_URL}/backgrounds/wooden-board.jpg`,
17+
backgroundUrl: EMPTY_PICTURE,
1818
gridUrl: `${TRIDECCO_BOARD_ASSETS_URL}/grids/black.png`,
1919
}, () => {
2020
const pieceColorList = [

0 commit comments

Comments
 (0)