feat(falukant): enhance notification handling and localization updates
All checks were successful
Deploy to production / deploy (push) Successful in 2m52s
All checks were successful
Deploy to production / deploy (push) Successful in 2m52s
- Updated the `enrichNotificationsWithCharacterNames` method in FalukantService to include region name enrichment and handle additional character IDs. - Introduced a new `serializeNotificationForClient` function to format notifications for the client, ensuring all relevant data is included. - Enhanced the MessagesDialog component to merge notification payloads and extract parameters more effectively, improving the clarity of displayed messages. - Added new localization entries for director resignation risk and regional festival effects in multiple languages, ensuring comprehensive user notifications.
This commit is contained in:
@@ -138,6 +138,9 @@ export default {
|
||||
if (!n || typeof n !== 'object') return n || {};
|
||||
let merged = { ...n };
|
||||
const raw = n.tr;
|
||||
if (raw && typeof raw === 'object') {
|
||||
merged = { ...merged, ...raw };
|
||||
}
|
||||
if (typeof raw === 'string') {
|
||||
const trimmed = raw.trim();
|
||||
if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
|
||||
@@ -151,6 +154,9 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (merged.character_name && merged.characterName == null) {
|
||||
merged.characterName = merged.character_name;
|
||||
}
|
||||
return merged;
|
||||
},
|
||||
|
||||
@@ -228,10 +234,8 @@ export default {
|
||||
try {
|
||||
const titleKey = `${eventKey}.title`;
|
||||
const descKey = `${eventKey}.description`;
|
||||
// If no params were parsed from JSON, try to extract them from the notification (effects, character_id, etc.)
|
||||
if ((!params || Object.keys(params).length === 0) && payload) {
|
||||
params = this.extractParams(payload) || {};
|
||||
}
|
||||
const extracted = this.extractParams(payload) || {};
|
||||
params = { ...extracted, ...params };
|
||||
|
||||
if (this.$te(titleKey) && this.$te(descKey)) {
|
||||
const title = this.$t(titleKey, params);
|
||||
@@ -243,6 +247,10 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
// Immer Parameter aus dem vollständigen Payload (nach merge), z. B. director.resignation_risk_high
|
||||
const extractedAll = this.extractParams(payload) || {};
|
||||
params = { ...extractedAll, ...params };
|
||||
|
||||
// Fallback: Alte Methode für andere Notification-Typen
|
||||
return this.$t(key, params);
|
||||
},
|
||||
@@ -312,6 +320,14 @@ export default {
|
||||
extractParams(n) {
|
||||
const base = this.mergeNotificationPayload(n);
|
||||
const params = {};
|
||||
const locale = this.$i18n?.locale || 'de';
|
||||
const isGerman = String(locale).startsWith('de');
|
||||
|
||||
if (base.characterName) {
|
||||
params.characterName = base.characterName;
|
||||
} else if (base.character_name) {
|
||||
params.characterName = base.character_name;
|
||||
}
|
||||
|
||||
// Parameter aus effects extrahieren (Daemon: effects oft nur im JSON in tr)
|
||||
if (base.effects && Array.isArray(base.effects)) {
|
||||
@@ -326,11 +342,27 @@ export default {
|
||||
} else if (effect.percent !== undefined) {
|
||||
params.percent = effect.percent;
|
||||
}
|
||||
} else if (effect.type === 'price_change') {
|
||||
if (effect.percent !== undefined && effect.percent !== null) {
|
||||
const p = Number(effect.percent);
|
||||
if (Number.isFinite(p)) {
|
||||
params.priceChangePercent = `${p > 0 ? '+' : ''}${p.toFixed(1)}`;
|
||||
}
|
||||
}
|
||||
} else if (effect.type === 'production_quality_change') {
|
||||
if (effect.change !== undefined && effect.change !== null) {
|
||||
const v = Number(effect.change);
|
||||
if (Number.isFinite(v)) {
|
||||
params.productionQualityChange = (v > 0 ? '+' : '') + (Number.isInteger(v) ? String(v) : v.toFixed(1));
|
||||
}
|
||||
}
|
||||
} else if (effect.type === 'weather_change') {
|
||||
params.hasWeatherChange = true;
|
||||
} else if (effect.type === 'character_health_change') {
|
||||
if (effect.character_id) {
|
||||
// Prefer explicit characterName from notification, otherwise fall back to provided name or use id placeholder
|
||||
params.character_id = effect.character_id;
|
||||
params.characterName = params.characterName || base.characterName || `#${effect.character_id}`;
|
||||
params.characterName = params.characterName || base.characterName || base.character_name || `#${effect.character_id}`;
|
||||
}
|
||||
if (effect.change !== undefined) {
|
||||
params.change = effect.change;
|
||||
@@ -352,9 +384,33 @@ export default {
|
||||
}
|
||||
|
||||
// Weitere Parameter aus der Notification selbst
|
||||
if (base.region_id && base.regionName) {
|
||||
params.regionName = base.regionName;
|
||||
if (base.region_id != null) {
|
||||
if (base.regionName) {
|
||||
params.regionName = base.regionName;
|
||||
} else if (base.region_name) {
|
||||
params.regionName = base.region_name;
|
||||
}
|
||||
}
|
||||
|
||||
// Daemon: Meta-Objekte (auch wenn effects[] schon Werte liefert — fehlende Werte ergänzen)
|
||||
if (params.priceChangePercent == null && base.price_change && typeof base.price_change === 'object') {
|
||||
const applied = base.price_change.applied !== false;
|
||||
const pct = base.price_change.percent;
|
||||
if (applied && pct != null && Number.isFinite(Number(pct))) {
|
||||
const p = Number(pct);
|
||||
params.priceChangePercent = `${p > 0 ? '+' : ''}${p.toFixed(1)}`;
|
||||
}
|
||||
}
|
||||
if (params.productionQualityChange == null && base.production_quality && typeof base.production_quality === 'object') {
|
||||
const applied = base.production_quality.applied !== false;
|
||||
const ch = base.production_quality.change;
|
||||
if (applied && ch != null && Number.isFinite(Number(ch))) {
|
||||
const v = Number(ch);
|
||||
params.productionQualityChange = (v > 0 ? '+' : '') + (Number.isInteger(v) ? String(v) : v.toFixed(1));
|
||||
}
|
||||
}
|
||||
|
||||
params.priceEffectLine = this.buildRegionalFestivalEffectsLine(params, isGerman);
|
||||
if (base.character_id && base.characterName) {
|
||||
params.characterName = base.characterName;
|
||||
}
|
||||
@@ -370,6 +426,13 @@ export default {
|
||||
if (base.threshold_percent !== undefined) {
|
||||
params.threshold_percent = base.threshold_percent;
|
||||
}
|
||||
const isDirectorResign = base.event === 'director_resignation_risk_high'
|
||||
|| (typeof base.tr === 'string' && base.tr.includes('director.resignation'));
|
||||
if (isDirectorResign) {
|
||||
params.directorName = params.characterName
|
||||
|| base.character_name
|
||||
|| (base.director_character_id != null ? `#${base.director_character_id}` : '');
|
||||
}
|
||||
if (base.director_id !== undefined) {
|
||||
params.director_id = base.director_id;
|
||||
}
|
||||
@@ -440,7 +503,48 @@ export default {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2
|
||||
}).format(amount);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Zeilen für regionale Events (Fest o. ä.): Wetter, Preis, Produktionsqualität — aus effects[] und/oder price_change / production_quality.
|
||||
*/
|
||||
buildRegionalFestivalEffectsLine(params, isGerman) {
|
||||
const parts = [];
|
||||
const kw = 'falukant.notifications.random_event.effects.festival_weather_line';
|
||||
const kp = 'falukant.notifications.random_event.effects.festival_price_line';
|
||||
const kq = 'falukant.notifications.random_event.effects.festival_quality_line';
|
||||
if (params.hasWeatherChange) {
|
||||
if (this.$te(kw)) parts.push(String(this.$t(kw)));
|
||||
else parts.push(isGerman ? 'Wetter in der Region schlägt um.' : 'The regional weather shifts.');
|
||||
}
|
||||
if (params.priceChangePercent != null) {
|
||||
if (this.$te(kp)) {
|
||||
parts.push(String(this.$t(kp, { percent: params.priceChangePercent })));
|
||||
} else {
|
||||
const legacy = 'falukant.notifications.random_event.effects.price_effect_suffix';
|
||||
parts.push(
|
||||
this.$te(legacy)
|
||||
? String(this.$t(legacy, { percent: params.priceChangePercent }))
|
||||
: (isGerman
|
||||
? `Warenpreise etwa ${params.priceChangePercent} %.`
|
||||
: `Goods prices about ${params.priceChangePercent}%.`)
|
||||
);
|
||||
}
|
||||
}
|
||||
if (params.productionQualityChange != null) {
|
||||
if (this.$te(kq)) {
|
||||
parts.push(String(this.$t(kq, { change: params.productionQualityChange })));
|
||||
} else {
|
||||
parts.push(
|
||||
isGerman
|
||||
? `Produktionsqualität etwa ${params.productionQualityChange}.`
|
||||
: `Production quality about ${params.productionQualityChange}.`
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!parts.length) return '';
|
||||
return ` ${parts.join(' ')}`;
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
totalPages() {
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"notify_election_created": "Giskedyul ang usa ka bag-ong eleksiyon.",
|
||||
"notify_office_filled": "Na puno ang usa ka politikal nga opisina.",
|
||||
"director": {
|
||||
"resignation_risk_high": "Taas ang risgo nga mubiyaa ang direktor: risgo {risk_percent}% (threshold {threshold_percent}%). Karon nga satisfaction {satisfaction}."
|
||||
"resignation_risk_high": "Taas ang risgo nga mobiya ang direktor nga si {directorName}: risgo {risk_percent}% (threshold {threshold_percent}%). Karon nga satisfaction {satisfaction}."
|
||||
},
|
||||
"director_death": "Namatay si {characterName} sa edad nga {ageYears}. Isip amo, kinahanglan kang magtudlo og bag-ong direktor.{regionLabel}{spouses}{children}{lovers}",
|
||||
"relationship_death": "Namatay si {characterName} sa edad nga {ageYears}.{regionLabel}{spouses}{children}{lovers}",
|
||||
@@ -93,7 +93,13 @@
|
||||
},
|
||||
"regional_festival": {
|
||||
"title": "Pista sa rehiyon",
|
||||
"description": "Adunay dakong pista sa rehiyon nga {regionName}."
|
||||
"description": "Adunay dakong pista sa rehiyon nga {regionName}.{priceEffectLine}"
|
||||
},
|
||||
"effects": {
|
||||
"price_effect_suffix": " Epekto: gipaabot nga pagbag-o sa presyo sa mga paliton nga ~{percent}%.",
|
||||
"festival_weather_line": "Ang panahon sa rehiyon nagbag-o.",
|
||||
"festival_price_line": "Presyo sa mga paliton ~{percent}%.",
|
||||
"festival_quality_line": "Kalidad sa produksyon ~{change}."
|
||||
},
|
||||
"regional_epidemic": {
|
||||
"title": "Epidemya",
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"notify_election_created": "Es wurde eine neue Wahl ausgeschrieben.",
|
||||
"notify_office_filled": "Ein politisches Amt wurde neu besetzt.",
|
||||
"director": {
|
||||
"resignation_risk_high": "Hohe Kündigungsgefahr bei einem Direktor: Risiko {risk_percent}% (Schwelle {threshold_percent}%). Zufriedenheit aktuell {satisfaction}."
|
||||
"resignation_risk_high": "Hohe Kündigungsgefahr für den Direktor {directorName}: Risiko {risk_percent} % (Schwelle {threshold_percent} %). Zufriedenheit aktuell {satisfaction}."
|
||||
},
|
||||
"director_death": "{characterName} ist im Alter von {ageYears} Jahren verstorben. Als Arbeitgeber musst du die Direktion neu besetzen.{regionLabel}{spouses}{children}{lovers}",
|
||||
"relationship_death": "{characterName} ist im Alter von {ageYears} Jahren verstorben.{regionLabel}{spouses}{children}{lovers}",
|
||||
@@ -95,7 +95,13 @@
|
||||
},
|
||||
"regional_festival": {
|
||||
"title": "Regionales Fest",
|
||||
"description": "Ein großes Fest findet in der Region {regionName} statt."
|
||||
"description": "Ein großes Fest findet in der Region {regionName} statt.{priceEffectLine}"
|
||||
},
|
||||
"effects": {
|
||||
"price_effect_suffix": " Auswirkung: erwartete Warenpreisänderung ca. {percent} %.",
|
||||
"festival_weather_line": "Wetter in der Region schlägt um.",
|
||||
"festival_price_line": "Warenpreise etwa {percent} %.",
|
||||
"festival_quality_line": "Produktionsqualität etwa {change}."
|
||||
},
|
||||
"regional_epidemic": {
|
||||
"title": "Epidemie",
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"notify_election_created": "A new election has been scheduled.",
|
||||
"notify_office_filled": "A political office has been filled.",
|
||||
"director": {
|
||||
"resignation_risk_high": "High resignation risk for a director: risk {risk_percent}% (threshold {threshold_percent}%). Current satisfaction {satisfaction}."
|
||||
"resignation_risk_high": "High resignation risk for director {directorName}: risk {risk_percent}% (threshold {threshold_percent}%). Current satisfaction {satisfaction}."
|
||||
},
|
||||
"director_death": "{characterName} died at the age of {ageYears}. As employer you need to appoint a new director.{regionLabel}{spouses}{children}{lovers}",
|
||||
"relationship_death": "{characterName} died at the age of {ageYears}.{regionLabel}{spouses}{children}{lovers}",
|
||||
@@ -93,7 +93,13 @@
|
||||
},
|
||||
"regional_festival": {
|
||||
"title": "Regional Festival",
|
||||
"description": "A large festival is taking place in the region {regionName}."
|
||||
"description": "A large festival is taking place in the region {regionName}.{priceEffectLine}"
|
||||
},
|
||||
"effects": {
|
||||
"price_effect_suffix": " Effect: expected goods price change ~{percent}%.",
|
||||
"festival_weather_line": "The regional weather shifts.",
|
||||
"festival_price_line": "Goods prices about {percent}%.",
|
||||
"festival_quality_line": "Production quality about {change}."
|
||||
},
|
||||
"regional_epidemic": {
|
||||
"title": "Epidemic",
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"notify_election_created": "Se ha convocado una nueva elección.",
|
||||
"notify_office_filled": "Se ha cubierto un cargo político.",
|
||||
"director": {
|
||||
"resignation_risk_high": "Alto riesgo de renuncia de un director: riesgo {risk_percent}% (umbral {threshold_percent}%). Satisfacción actual {satisfaction}."
|
||||
"resignation_risk_high": "Alto riesgo de renuncia del director {directorName}: riesgo {risk_percent}% (umbral {threshold_percent}%). Satisfacción actual {satisfaction}."
|
||||
},
|
||||
"director_death": "{characterName} ha fallecido a la edad de {ageYears} años. Como empleador debes nombrar un nuevo director.{regionLabel}{spouses}{children}{lovers}",
|
||||
"relationship_death": "{characterName} ha fallecido a la edad de {ageYears} años.{regionLabel}{spouses}{children}{lovers}",
|
||||
@@ -95,7 +95,13 @@
|
||||
},
|
||||
"regional_festival": {
|
||||
"title": "Fiesta regional",
|
||||
"description": "Se celebra una gran fiesta en la región {regionName}."
|
||||
"description": "Se celebra una gran fiesta en la región {regionName}.{priceEffectLine}"
|
||||
},
|
||||
"effects": {
|
||||
"price_effect_suffix": " Efecto: variación esperada del precio de las mercancías ~{percent}%.",
|
||||
"festival_weather_line": "El tiempo en la región cambia.",
|
||||
"festival_price_line": "Precios de mercancías ~{percent} %.",
|
||||
"festival_quality_line": "Calidad de producción ~{change}."
|
||||
},
|
||||
"regional_epidemic": {
|
||||
"title": "Epidemia",
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"notify_election_created": "Une nouvelle élection a été déclenchée.",
|
||||
"notify_office_filled": "Une fonction politique a été pourvue.",
|
||||
"director": {
|
||||
"resignation_risk_high": "Risque élevé de démission d’un directeur : risque {risk_percent}% (seuil {threshold_percent}%). Satisfaction actuelle {satisfaction}."
|
||||
"resignation_risk_high": "Risque élevé de démission du directeur {directorName} : risque {risk_percent}% (seuil {threshold_percent}%). Satisfaction actuelle {satisfaction}."
|
||||
},
|
||||
"director_death": "{characterName} est décédé à l'âge de {ageYears}. En tant qu'employeur, vous devez remplir le conseil d'administration.{regionLabel}{spouses}{children}{lovers}",
|
||||
"relationship_death": "{characterName} est décédé à l'âge de {ageYears}.{regionLabel}{spouses}{children}{lovers}",
|
||||
@@ -95,7 +95,13 @@
|
||||
},
|
||||
"regional_festival": {
|
||||
"title": "Fête régionale",
|
||||
"description": "Un grand festival a lieu dans la région {regionName}."
|
||||
"description": "Un grand festival a lieu dans la région {regionName}.{priceEffectLine}"
|
||||
},
|
||||
"effects": {
|
||||
"price_effect_suffix": " Effet : variation attendue des prix des marchandises ~{percent} %.",
|
||||
"festival_weather_line": "Le temps dans la région change.",
|
||||
"festival_price_line": "Prix des marchandises ~{percent} %.",
|
||||
"festival_quality_line": "Qualité de production ~{change}."
|
||||
},
|
||||
"regional_epidemic": {
|
||||
"title": "Épidémie",
|
||||
|
||||
Reference in New Issue
Block a user