Skip to content

Commit 620e386

Browse files
author
web3blind
committed
Fix quest and chronicle display regressions
1 parent 485b4a9 commit 620e386

9 files changed

Lines changed: 107 additions & 15 deletions

File tree

app/index.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@
141141
<script src="js/data/spells.js"></script>
142142
<script src="js/data/recipes.js"></script>
143143
<script src="js/data/regions.js"></script>
144-
<script src="js/data/quests.js"></script>
144+
<script src="js/data/quests.js?v=20260621e"></script>
145145

146146
<!-- Game engine -->
147147
<script src="js/engine/types.js"></script>
@@ -161,10 +161,10 @@
161161
<script src="js/engine/block-processor.js"></script>
162162
<script src="js/engine/world-events.js"></script>
163163
<script src="js/engine/world-boss.js"></script>
164-
<script src="js/engine/quest-system.js"></script>
164+
<script src="js/engine/quest-system.js?v=20260621e"></script>
165165
<script src="js/engine/loci.js"></script>
166166
<script src="js/engine/npc-framework.js"></script>
167-
<script src="js/engine/state-engine.js"></script>
167+
<script src="js/engine/state-engine.js?v=20260621e"></script>
168168
<script src="js/engine/daily-leaderboard-storage.js"></script>
169169
<script src="js/engine/daily-leaderboard.js"></script>
170170

@@ -184,14 +184,14 @@
184184
<script src="js/ui/screens/character.js"></script>
185185
<script src="js/ui/screens/hunt.js"></script>
186186
<script src="js/ui/screens/inventory.js"></script>
187-
<script src="js/ui/screens/chronicle.js"></script>
187+
<script src="js/ui/screens/chronicle.js?v=20260621f"></script>
188188
<script src="js/ui/screens/duel.js"></script>
189189
<script src="js/ui/screens/arena.js?v=20260621d"></script>
190190
<script src="js/ui/screens/guild.js?v=20260621d"></script>
191191
<script src="js/ui/screens/map.js"></script>
192192
<script src="js/ui/screens/marketplace.js"></script>
193193
<script src="js/ui/screens/crafting.js"></script>
194-
<script src="js/ui/screens/quests.js"></script>
194+
<script src="js/ui/screens/quests.js?v=20260621e"></script>
195195
<script src="js/ui/screens/world-boss.js"></script>
196196
<script src="js/ui/screens/settings.js"></script>
197197
<script src="js/ui/screens/help.js"></script>

app/js/engine/quest-system.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ var QuestSystem = (function() {
238238
playerQuests.active.splice(questIndex, 1);
239239
playerQuests.completed.push({
240240
id: quest.id,
241+
titleKey: quest.titleKey || (questTemplate && questTemplate.titleKey) || '',
241242
completedBlock: blockNum
242243
});
243244

app/js/engine/state-engine.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ var StateEngine = (function() {
696696
if (!guild) return [];
697697
var ok = GuildSystem.joinGuild(guild, sender, blockNum);
698698
if (!ok) return [];
699-
return [{ type: 'guild_joined', guildId: data.guild_id, account: sender }];
699+
return [{ type: 'guild_joined', guildId: data.guild_id, guildName: guild.name || data.guild_id, account: sender }];
700700
}
701701

702702
function _handleGuildLeave(sender, data, blockNum) {

app/js/i18n/en.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ var LangEN = {
772772
quest_completed: 'Quest completed!',
773773
quest_abandon: 'Abandon',
774774
quest_abandoned: 'Quest abandoned.',
775+
chronicle_unknown_guild: 'an unknown guild',
775776
quest_type_hunt: 'Hunt',
776777
quest_type_craft: 'Craft',
777778
quest_type_duel: 'Duel',

app/js/i18n/ru.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ var LangRU = {
772772
quest_completed: 'Задание выполнено!',
773773
quest_abandon: 'Отказаться',
774774
quest_abandoned: 'Задание отменено.',
775+
chronicle_unknown_guild: 'неизвестная гильдия',
775776
quest_type_hunt: 'Охота',
776777
quest_type_craft: 'Ковка',
777778
quest_type_duel: 'Дуэль',

app/js/ui/screens/chronicle.js

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,10 +456,10 @@ var ChronicleScreen = (function() {
456456
var itemName = (ev0 && ev0.itemName) ? ev0.itemName : '';
457457
return t('chronicle_narrative_craft', { name: name, item: itemName });
458458
case 'guild.create':
459-
var guildName = (ev0 && ev0.guildName) ? ev0.guildName : '';
459+
var guildName = _guildNameForCreateAction(action, ev0);
460460
return t('chronicle_narrative_guild_created', { name: name, guild: guildName });
461461
case 'guild.accept':
462-
var gJoin = (ev0 && ev0.guildName) ? ev0.guildName : '';
462+
var gJoin = _guildDisplayName(ev0 && ev0.guildId, ev0 && ev0.guildName);
463463
return t('chronicle_narrative_guild_join', { name: name, guild: gJoin });
464464
case 'boss.attack':
465465
return name + ' ' + (t('boss_attack') || 'attacks the boss') + '!';
@@ -477,6 +477,38 @@ var ChronicleScreen = (function() {
477477
return (charInfo && charInfo.name) ? charInfo.name : account;
478478
}
479479

480+
function _guildNameForCreateAction(action, ev0) {
481+
if (ev0 && (ev0.guildName || ev0.guildId)) {
482+
return _guildDisplayName(ev0.guildId, ev0.guildName);
483+
}
484+
485+
var state = StateEngine.getState();
486+
if (state && state.guilds) {
487+
for (var guildId in state.guilds) {
488+
if (!state.guilds.hasOwnProperty(guildId)) continue;
489+
var guild = state.guilds[guildId];
490+
if (!guild) continue;
491+
if (action && guild.createdBlock && action.blockNum && guild.createdBlock === action.blockNum) {
492+
return guild.name || guildId;
493+
}
494+
if (action && action.sender && guild.founder === action.sender) {
495+
return guild.name || guildId;
496+
}
497+
}
498+
}
499+
500+
return Helpers.t('chronicle_unknown_guild');
501+
}
502+
503+
function _guildDisplayName(guildId, eventName) {
504+
if (eventName) return eventName;
505+
var state = StateEngine.getState();
506+
if (guildId && state && state.guilds && state.guilds[guildId]) {
507+
return state.guilds[guildId].name || guildId;
508+
}
509+
return guildId || Helpers.t('chronicle_unknown_guild');
510+
}
511+
480512
function _filterByTab(entries, state) {
481513
if (currentTab === 'all') return entries;
482514

app/js/ui/screens/quests.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,27 @@ var QuestsScreen = (function() {
177177
var html = '<ul class="quest-list completed" role="list">';
178178
for (var i = completed.length - 1; i >= Math.max(0, completed.length - 20); i--) {
179179
var q = completed[i];
180+
var title = _completedQuestTitle(q, t);
180181
html += '<li class="quest-card quest-completed-card">' +
181182
'<span class="quest-icon" aria-hidden="true">\u2714</span>' +
182-
'<span class="quest-name">' + Helpers.t(q.id) + '</span>' +
183+
'<span class="quest-name">' + Helpers.escapeHtml(title) + '</span>' +
183184
'</li>';
184185
}
185186
html += '</ul>';
186187
return html;
187188
}
188189

190+
function _completedQuestTitle(q, t) {
191+
if (!q) return '';
192+
if (q.titleKey) return t(q.titleKey);
193+
if (typeof GameQuests !== 'undefined' && GameQuests.getQuest) {
194+
var quest = GameQuests.getQuest(q.id);
195+
if (quest && quest.titleKey) return t(quest.titleKey);
196+
}
197+
if (/^daily_[0-9]+_[0-9]+$/.test(q.id || '')) return t('quest_daily_hunt');
198+
return String(q.id || '').replace(/^q_/, '').replace(/_/g, ' ');
199+
}
200+
189201
function _renderQuestCard(quest, t, showActions) {
190202
var html = '<li class="quest-card' + (quest.completed ? ' quest-ready' : '') + '" role="listitem">';
191203
html += '<div class="quest-card-header">';

app/sw.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Viz Magic — Service Worker
2-
var CACHE_NAME = 'viz-magic-v16';
2+
var CACHE_NAME = 'viz-magic-v19';
33
var ASSETS = [
44
'/',
55
'/index.html',
@@ -65,6 +65,8 @@ self.addEventListener('install', function(event) {
6565
event.waitUntil(
6666
caches.open(CACHE_NAME).then(function(cache) {
6767
return cache.addAll(ASSETS);
68+
}).then(function() {
69+
return self.skipWaiting();
6870
})
6971
);
7072
});
@@ -76,11 +78,32 @@ self.addEventListener('activate', function(event) {
7678
names.filter(function(n) { return n !== CACHE_NAME; })
7779
.map(function(n) { return caches.delete(n); })
7880
);
81+
}).then(function() {
82+
return self.clients.claim();
7983
})
8084
);
8185
});
8286

8387
self.addEventListener('fetch', function(event) {
88+
if (event.request.mode === 'navigate') {
89+
event.respondWith(
90+
fetch(event.request).then(function(response) {
91+
if (response && response.status === 200 && response.type === 'basic') {
92+
var clone = response.clone();
93+
caches.open(CACHE_NAME).then(function(cache) {
94+
cache.put(event.request, clone);
95+
});
96+
}
97+
return response;
98+
}).catch(function() {
99+
return caches.match(event.request).then(function(cached) {
100+
return cached || caches.match('/index.html');
101+
});
102+
})
103+
);
104+
return;
105+
}
106+
84107
event.respondWith(
85108
caches.match(event.request).then(function(cached) {
86109
return cached || fetch(event.request).then(function(response) {
@@ -91,11 +114,6 @@ self.addEventListener('fetch', function(event) {
91114
});
92115
}
93116
return response;
94-
}).catch(function() {
95-
// Offline fallback
96-
if (event.request.mode === 'navigate') {
97-
return caches.match('/index.html');
98-
}
99117
});
100118
})
101119
);

tests/player-bug-regressions.test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const inventoryJs = read('app/js/ui/screens/inventory.js');
3434
const huntJs = read('app/js/ui/screens/hunt.js');
3535
const mapJs = read('app/js/ui/screens/map.js');
3636
const chronicleJs = read('app/js/ui/screens/chronicle.js');
37+
const questScreenJs = read('app/js/ui/screens/quests.js');
3738
const guildJs = read('app/js/ui/screens/guild.js');
3839
const leaderboardJs = read('app/js/ui/screens/leaderboard.js');
3940
const characterJs = read('app/js/ui/screens/character.js');
@@ -123,6 +124,22 @@ test('chronicle keeps loaded tabs visible and shows sent blessings immediately',
123124
assert.ok(/_injectLocalBlessing\(account, energy\)/.test(chronicleJs), 'blessing success path should inject visible local action');
124125
});
125126

127+
128+
129+
test('completed quest list resolves quest titles instead of raw ids', function () {
130+
assert.ok(/titleKey: quest\.titleKey/.test(read('app/js/engine/quest-system.js')), 'completed quest records should preserve titleKey for future claims');
131+
assert.ok(/function _completedQuestTitle/.test(questScreenJs), 'quest screen should resolve completed quest titles');
132+
assert.ok(/GameQuests\.getQuest\(q\.id\)/.test(questScreenJs), 'completed quest title should fall back to quest template');
133+
assert.ok(!/Helpers\.t\(q\.id\)/.test(questScreenJs), 'completed quest list must not translate raw quest ids');
134+
});
135+
136+
test('chronicle guild narratives have a guild-name fallback', function () {
137+
assert.ok(/function _guildDisplayName/.test(chronicleJs), 'chronicle should resolve guild display names');
138+
assert.ok(/function _guildNameForCreateAction/.test(chronicleJs), 'chronicle should recover guild names for old create entries');
139+
assert.ok(/guildName: guild\.name/.test(stateEngineJs), 'guild join events should carry guildName');
140+
assert.ok(/chronicle_unknown_guild/.test(chronicleJs + ruJs + enJs), 'unknown guild fallback copy should exist');
141+
});
142+
126143
test('stale checkpoint catch-up keeps using scaled batches after first batch', function () {
127144
assert.ok(/function _nextCatchupBatchEnd/.test(appJs), 'app should centralize catch-up batch sizing');
128145
assert.ok(/var remaining = Math\.max\(0, chainHead - startBlock \+ 1\)/.test(appJs), 'batch sizing should use remaining gap');
@@ -164,6 +181,16 @@ test('high-traffic UI narration and inventory stat labels are translated', funct
164181
});
165182
});
166183

184+
185+
186+
test('service worker updates quickly and keeps navigations network-first', function () {
187+
const swJs = read('app/sw.js');
188+
assert.ok(/viz-magic-v19/.test(swJs), 'service worker cache version should be bumped');
189+
assert.ok(/self\.skipWaiting\(\)/.test(swJs), 'service worker should activate new cache without waiting for all tabs to close');
190+
assert.ok(/self\.clients\.claim\(\)/.test(swJs), 'service worker should claim clients after activation');
191+
assert.ok(/event\.request\.mode === 'navigate'[\s\S]*fetch\(event\.request\)/.test(swJs), 'navigation requests should prefer network to avoid stale cached index');
192+
});
193+
167194
test('leaderboard has local character fallback while 24h scan is empty or slow', function () {
168195
assert.ok(/function _fallbackRowsFromState/.test(leaderboardJs), 'leaderboard should expose local fallback rows');
169196
assert.ok(/rows = _fallbackRowsFromState\(\)/.test(leaderboardJs), 'leaderboard should use fallback when snapshot rows are empty');

0 commit comments

Comments
 (0)