From 478d4ecdd227145944b9bbfff071ae838e954a21 Mon Sep 17 00:00:00 2001
From: Matt <7128721+TobiTenno@users.noreply.github.com>
Date: Sat, 24 Sep 2022 12:15:24 -0500
Subject: [PATCH] feat: archon hunt panel (#872)
---
.../modalDialogs/Filters/ComponentsFilter.jsx | 25 ++--
.../modalDialogs/Filters/FissureFilters.jsx | 16 ++-
.../Filters/NotificationFilters.jsx | 16 +--
components/panels/SortiePanel.jsx | 115 ++++++++++++++++++
components/panels/SortiePanel.vue | 93 --------------
cypress/.eslintrc.yaml | 16 ++-
cypress/e2e/openworld/load.spec.js | 28 ++---
cypress/e2e/synthesis/load.spec.js | 6 +-
cypress/e2e/timers/load.spec.js | 19 +--
package-lock.json | 11 +-
package.json | 1 +
pages/index.vue | 3 +-
services/Notifier.js | 27 ++--
static/json/components.json | 10 ++
static/json/trackables.json | 5 +
static/lang/en.json | 5 +-
16 files changed, 226 insertions(+), 170 deletions(-)
create mode 100644 components/panels/SortiePanel.jsx
delete mode 100644 components/panels/SortiePanel.vue
diff --git a/components/modalDialogs/Filters/ComponentsFilter.jsx b/components/modalDialogs/Filters/ComponentsFilter.jsx
index d7845192..6fb1bb1f 100644
--- a/components/modalDialogs/Filters/ComponentsFilter.jsx
+++ b/components/modalDialogs/Filters/ComponentsFilter.jsx
@@ -3,13 +3,10 @@ import baseComponents from '@/static/json/components.json';
export default {
computed: {
- ...mapGetters('worldstate', {
- rawCS: 'componentState',
- }),
+ ...mapGetters('worldstate', ['componentState']),
activeComponents: {
get() {
- return Object.keys(this.rawCS)
- .map((component) => this.rawCS[component])
+ return Object.values(this.componentState)
.filter(
(component) =>
component.display && (!baseComponents[component.key] || baseComponents[component.key].displayable)
@@ -17,23 +14,25 @@ export default {
.map((component) => component.key);
},
set(enabledComponents) {
- Object.keys(this.rawCS).forEach((component) => {
- this.$store.commit('worldstate/commitComponentDisplayMode', [
- component,
- enabledComponents.includes(component),
- ]);
+ Object.keys(this.componentState).forEach((component) => {
+ if (this.componentState[component].display !== enabledComponents.includes(component)) {
+ this.$store.commit('worldstate/commitComponentDisplayMode', [
+ component,
+ enabledComponents.includes(component),
+ ]);
+ }
});
},
},
componentStates() {
- return Object.keys(this.rawCS)
+ return Object.keys(this.componentState)
.map((component) => {
if (!baseComponents[component] || !baseComponents[component].displayable) {
return false;
}
return {
- text: this.rawCS[component].displayName,
- value: this.rawCS[component].key,
+ text: this.componentState[component].displayName,
+ value: this.componentState[component].key,
};
})
.filter((c) => c);
diff --git a/components/modalDialogs/Filters/FissureFilters.jsx b/components/modalDialogs/Filters/FissureFilters.jsx
index 4fb55a27..2b3fe485 100644
--- a/components/modalDialogs/Filters/FissureFilters.jsx
+++ b/components/modalDialogs/Filters/FissureFilters.jsx
@@ -15,14 +15,13 @@ export default {
return planets.filter((planet) => planet.state).map((planet) => planet.value);
},
- set() {},
- },
- },
- methods: {
- updateFissureStates(enabledFissures) {
- Object.keys(this.fissureStates).forEach((planet) => {
- this.$store.commit('worldstate/commitFissurePlanetState', [planet, enabledFissures.includes(planet)]);
- });
+ set(enabledFissures) {
+ Object.keys(this.fissureStates).forEach((planet) => {
+ if (this.fissureStates[planet] !== enabledFissures.includes(planet)) {
+ this.$store.commit('worldstate/commitFissurePlanetState', [planet, enabledFissures.includes(planet)]);
+ }
+ });
+ },
},
},
render() {
@@ -40,7 +39,6 @@ export default {
switches
stacked
class="settings-group fissure-setting-group"
- input={(vals) => this.updateFissureStates(vals)}
>
diff --git a/components/modalDialogs/Filters/NotificationFilters.jsx b/components/modalDialogs/Filters/NotificationFilters.jsx
index 8c24f43c..7c6dd21a 100644
--- a/components/modalDialogs/Filters/NotificationFilters.jsx
+++ b/components/modalDialogs/Filters/NotificationFilters.jsx
@@ -97,8 +97,8 @@ export default {
preserve-search={true}
hide-selected={true}
multiple={true}
- select={this.toggleRewardState}
- remove={this.toggleRewardState}
+ onSelect={this.toggleRewardState}
+ onRemove={this.toggleRewardState}
/>
diff --git a/components/panels/SortiePanel.jsx b/components/panels/SortiePanel.jsx
new file mode 100644
index 00000000..73fd88b8
--- /dev/null
+++ b/components/panels/SortiePanel.jsx
@@ -0,0 +1,115 @@
+import dayjs from 'dayjs';
+
+import HubImg from '@/components/HubImg.jsx';
+import TimeBadge from '@/components/TimeBadge.jsx';
+import HubPanelWrap from '@/components/HubPanelWrap.jsx';
+import { cdn } from '@/services/utilities';
+
+const corpus = cdn('svg/factions/corpus.svg');
+const corrupted = cdn('svg/factions/corrupted.svg');
+const grineer = cdn('svg/factions/grineer.svg');
+const infested = cdn('svg/factions/infested.svg');
+const sentient = cdn('svg/factions/sentient.svg');
+const narmer = cdn('svg/factions/narmer2.svg');
+
+const styles = {
+ inline: {
+ display: 'inline',
+ },
+ missionType: {
+ filter: 'invert(100%)',
+ 'margin-top': '-3px',
+ 'margin-right': '5px',
+ width: '25px',
+ height: '25px',
+ },
+};
+const tooltips = {
+ 'v-b-tooltip.top': true,
+};
+
+export default {
+ name: 'SortiePanel',
+ components: {
+ TimeBadge,
+ HubImg,
+ HubPanelWrap,
+ },
+ props: {
+ sortie: {
+ type: Object,
+ default: () => {
+ return {};
+ },
+ },
+ },
+ computed: {
+ headertext() {
+ return this.$props.sortie?.missions?.length ? this.$t('sortie.hunt.header') : this.$t('sortie.header');
+ },
+ factionImg() {
+ const fImg = {
+ corpus,
+ grineer,
+ infested,
+ infestation: infested,
+ corrupted,
+ orokin: corrupted,
+ sentient,
+ narmer,
+ };
+ return fImg[this.$props.sortie?.faction?.toLowerCase()] || corrupted;
+ },
+ missions() {
+ return (this.$props.sortie?.variants?.length ? this.$props.sortie.variants : this.$props.sortie.missions) || [];
+ },
+ },
+ render() {
+ const now = dayjs().toISOString();
+ return (
+
+
+
+
+
+
+ {this.sortie.boss}
+
+
+
+
+ {this.missions.map((mission, index) => {
+ return (
+
+
+
+
+ {mission.missionType || mission.type} - {mission.node}
+
+
+
+ {mission.modifier}
+
+
+
+ );
+ })}
+
+
+ );
+ },
+};
diff --git a/components/panels/SortiePanel.vue b/components/panels/SortiePanel.vue
deleted file mode 100644
index f8e820f7..00000000
--- a/components/panels/SortiePanel.vue
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
-
-
-
- {{ sortie.boss }}
-
-
-
-
-
-
-
- {{ mission.missionType }} - {{ mission.node }}
-
-
- {{ mission.modifier }}
-
-
-
-
-
-
-
-
diff --git a/cypress/.eslintrc.yaml b/cypress/.eslintrc.yaml
index 0b03a94a..e2a61c04 100644
--- a/cypress/.eslintrc.yaml
+++ b/cypress/.eslintrc.yaml
@@ -1,6 +1,14 @@
globals:
cy: readonly
- it: readonly
- describe: readonly
- beforeEach: readonly
- expect: readonly
+env:
+ mocha: true
+ cypress/globals: true
+plugins:
+ - cypress
+rules:
+ cypress/no-assigning-return-values: error
+ cypress/no-unnecessary-waiting: 0
+ cypress/assertion-before-screenshot: warn
+ cypress/no-force: warn
+ cypress/no-async-tests: error
+ cypress/no-pause: error
diff --git a/cypress/e2e/openworld/load.spec.js b/cypress/e2e/openworld/load.spec.js
index 164c651a..d73bafe4 100644
--- a/cypress/e2e/openworld/load.spec.js
+++ b/cypress/e2e/openworld/load.spec.js
@@ -6,8 +6,8 @@ describe('Maps', () => {
});
describe(`${ow} map`, () => {
it('should load', () => {
- const map = cy.get('div.vue2leaflet-map');
- map.should('exist');
+ cy.get('div.vue2leaflet-map').as('map');
+ cy.get('@map').should('exist');
cy.get('div.leaflet-control-zoom').should('exist');
cy.get('div.leaflet-control-layers').should('exist');
cy.get('div.leaflet-pane.leaflet-map-pane').should('exist');
@@ -23,20 +23,20 @@ describe('Fish', () => {
});
describe(`${ow} fish data`, () => {
it('should load', () => {
- const table = cy.get('div.fish-info');
- table.should('exist');
- const rowtypes = table.find('[role=rowgroup]');
- rowtypes.should('have.length', 2);
- const head = rowtypes.get('thead');
- head.should('exist');
+ cy.get('div.fish-info').as('fish');
+ cy.get('@fish').should('exist');
+ cy.get('@fish').find('[role=rowgroup]').as('rowtypes');
+ cy.get('@rowtypes').should('have.length', 2);
+ cy.get('@rowtypes').get('thead').as('head');
+ cy.get('@head').should('exist');
- const rows = rowtypes.get('tbody');
- rows.should('exist');
- rows.children().should('have.length.gt', 10);
+ cy.get('@rowtypes').get('tbody').as('rows');
+ cy.get('@rows').should('exist');
+ cy.get('@rows').children().should('have.length.gt', 10);
- const first = rows.children().get('tr:nth-of-type(1)');
- first.should('exist');
- first.children().should('have.length.gt', 13);
+ cy.get('@rows').children().get('tr:nth-of-type(1)').as('first');
+ cy.get('@first').should('exist');
+ cy.get('@first').children().should('have.length.gt', 13);
});
});
});
diff --git a/cypress/e2e/synthesis/load.spec.js b/cypress/e2e/synthesis/load.spec.js
index 453f51ce..18ed73d0 100644
--- a/cypress/e2e/synthesis/load.spec.js
+++ b/cypress/e2e/synthesis/load.spec.js
@@ -4,8 +4,8 @@ describe('Synthesis', () => {
cy.wait(1000);
});
it('should load', () => {
- const searchBox = cy.get('input#filterInput');
- searchBox.should('exist');
- searchBox.siblings('.input-group-append').find('.btn').should('have.text', 'Clear');
+ cy.get('input#filterInput').as('search');
+ cy.get('@search').should('exist');
+ cy.get('@search').siblings('.input-group-append').find('.btn').should('have.text', 'Clear');
});
});
diff --git a/cypress/e2e/timers/load.spec.js b/cypress/e2e/timers/load.spec.js
index 5e89f7e3..50f9f68c 100644
--- a/cypress/e2e/timers/load.spec.js
+++ b/cypress/e2e/timers/load.spec.js
@@ -1,7 +1,7 @@
describe('Timers', () => {
- beforeEach(() => {
+ before(() => {
cy.visit('http://localhost:3000/');
- cy.wait(1000);
+ cy.wait(5000);
});
describe('Fissures', () => {
let fissures;
@@ -82,21 +82,22 @@ describe('Timers', () => {
});
describe('Nightwave', () => {
it('should load', () => {
- const nightwave = cy.get('div.nightwave');
- nightwave.children().should('have.length', 2);
+ cy.get('div.nightwave').as('nightwave');
+ cy.get('@nightwave').children().should('have.length', 2);
});
});
describe('Sortie', () => {
it('should load', () => {
- const sortie = cy.get('div.sortie');
- sortie.children().should('have.length', 2);
+ cy.get('div.sortie').as('sortie');
+ // 2 for archons, 2 for sortie
+ cy.get('@sortie').children().should('have.length', 4);
});
});
describe('Bounties', () => {
it('should load', () => {
- const bounties = cy.get('div.bounties');
- bounties.should('have.length', 3);
- bounties.each((bountyPanel) => {
+ cy.get('div.bounties').as('bounties');
+ cy.get('@bounties').should('have.length', 3);
+ cy.get('@bounties').each((bountyPanel) => {
expect(bountyPanel.children()).to.have.length(2);
});
});
diff --git a/package-lock.json b/package-lock.json
index 43885394..925465a3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@wfcd/hub",
- "version": "2.1.2",
+ "version": "2.1.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -9507,6 +9507,15 @@
}
}
},
+ "eslint-plugin-cypress": {
+ "version": "2.12.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-2.12.1.tgz",
+ "integrity": "sha512-c2W/uPADl5kospNDihgiLc7n87t5XhUbFDoTl6CfVkmG+kDAb5Ux10V9PoLPu9N+r7znpc+iQlcmAqT1A/89HA==",
+ "dev": true,
+ "requires": {
+ "globals": "^11.12.0"
+ }
+ },
"eslint-plugin-es": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz",
diff --git a/package.json b/package.json
index 5b3448d2..30d9b53b 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,7 @@
"cypress": "^10.8.0",
"eslint": "^8.4.1",
"eslint-config-prettier": "^8.3.0",
+ "eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-nuxt": "^4.0.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vuejs-accessibility": "^1.2.0",
diff --git a/pages/index.vue b/pages/index.vue
index 4c7dc72e..90faa0ad 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -15,6 +15,7 @@
+
@@ -31,7 +32,7 @@ import { mapState, mapGetters } from 'vuex';
import AlertPanel from '@/components/panels/AlertPanel.jsx';
import NewsPanel from '@/components/panels/NewsPanel.vue';
import AggregatedTimePanel from '@/components/panels/AggregatedTimePanel.jsx';
-import SortiePanel from '@/components/panels/SortiePanel.vue';
+import SortiePanel from '@/components/panels/SortiePanel.jsx';
import FissuresPanel from '@/components/panels/FissuresPanel.vue';
import BountyPanel from '@/components/panels/BountyPanel.vue';
import InvasionsPanel from '@/components/panels/InvasionsPanel.jsx';
diff --git a/services/Notifier.js b/services/Notifier.js
index ee7403fc..6cd961f2 100644
--- a/services/Notifier.js
+++ b/services/Notifier.js
@@ -107,6 +107,14 @@ const makeNotification = (type, data) => {
icon: wfcdLogoUrl,
},
};
+ case 'archonHunt':
+ return {
+ head: `Archon Hunt: ${data.boss}`,
+ body: {
+ body: `${data.missions.map((mission) => `${mission.type} • ${mission.node}`).join('\n')}\n${data.eta}`,
+ icon: wfcdLogoUrl,
+ },
+ };
case 'fissure':
return {
head: 'New Fissure Detected',
@@ -250,7 +258,6 @@ export default class Notifier {
}
}
});
-
safeCall(() => {
for (const event of ws.events) {
if (this.isNotifiable(event.id, 'operation')) {
@@ -258,7 +265,6 @@ export default class Notifier {
}
}
});
-
safeCall(() => {
if (ws.cetusCycle.shortString) {
if (ws.cetusCycle.isDay) {
@@ -270,20 +276,17 @@ export default class Notifier {
}
}
});
-
safeCall(() => {
const cetus = ws.syndicateMissions.filter((synd) => synd.syndicate === 'Ostrons')[0];
if (cetus && this.isNotifiable(cetus.id, 'syndicate.ostrons')) {
toNotify.push(makeNotification('syndicate.ostrons', cetus));
}
});
-
safeCall(() => {
if (ws.voidTrader.active && this.isNotifiable(ws.voidTrader.id, 'baro')) {
toNotify.push(makeNotification('baro', ws.voidTrader));
}
});
-
safeCall(() => {
for (const currentItem of ws.dailyDeals) {
if (this.isNotifiable(currentItem.id, 'darvo')) {
@@ -291,7 +294,6 @@ export default class Notifier {
}
}
});
-
safeCall(() => {
for (const acolyte of ws.persistentEnemies) {
if (this.isNotifiable(acolyte.pid, 'enemies')) {
@@ -299,13 +301,16 @@ export default class Notifier {
}
}
});
-
safeCall(() => {
if (ws.sortie && this.isNotifiable(ws.sortie.id)) {
toNotify.push(makeNotification('sortie', ws.sortie));
}
});
-
+ safeCall(() => {
+ if (ws.archonHunt && this.isNotifiable(ws.archonHunt.id)) {
+ toNotify.push(makeNotification('archonHunt', ws.archonHunt));
+ }
+ });
safeCall(() => {
for (const fissure of ws.fissures) {
const notifIdentifier = `fissures.t${fissure.tierNum}.${fissure.missionType.toLowerCase().replace(/\s/gi, '')}`;
@@ -314,7 +319,6 @@ export default class Notifier {
}
}
});
-
safeCall(() => {
for (const article of ws.news) {
let type;
@@ -335,7 +339,6 @@ export default class Notifier {
}
}
});
-
safeCall(() => {
for (const invasion of ws.invasions) {
if (this.isNotifiable(invasion.id, 'invasions', invasion.rewardTypes)) {
@@ -343,7 +346,6 @@ export default class Notifier {
}
}
});
-
safeCall(() => {
if (ws.vallisCycle.shortString) {
if (ws.vallisCycle.isWarm) {
@@ -355,7 +357,6 @@ export default class Notifier {
}
}
});
-
safeCall(() => {
if (ws.nightwave && ws.nightwave.activeChallenges.length) {
for (const challenge of ws.nightwave.activeChallenges) {
@@ -365,7 +366,6 @@ export default class Notifier {
}
}
});
-
safeCall(() => {
if (ws.sentientOutposts.id && ws.sentientOutposts.active) {
if (this.isNotifiable(ws.sentientOutposts.id, 'outposts')) {
@@ -373,7 +373,6 @@ export default class Notifier {
}
}
});
-
safeCall(() => {
if (ws.arbitration) {
const id = `arbitration:${new Date(ws.arbitration.expiry).getTime()}`;
diff --git a/static/json/components.json b/static/json/components.json
index 01025581..274725b0 100644
--- a/static/json/components.json
+++ b/static/json/components.json
@@ -153,6 +153,16 @@
"sortie": "@worldstate.sortie"
}
},
+ "archonHunt": {
+ "display": true,
+ "displayable": true,
+ "displayName": "Archon Hunt",
+ "key": "archonHunt",
+ "component": "SortiePanel",
+ "props": {
+ "sortie": "@worldstate.archonHunt"
+ }
+ },
"arbitration": {
"display": true,
"displayable": true,
diff --git a/static/json/trackables.json b/static/json/trackables.json
index 58244ee2..338b956a 100644
--- a/static/json/trackables.json
+++ b/static/json/trackables.json
@@ -122,6 +122,11 @@
"value": "sorties",
"text": "Sorties"
},
+ "archonHunt": {
+ "state": false,
+ "value": "archonHunt",
+ "text": "Archon Hunt"
+ },
"baro": {
"state": false,
"value": "baro",
diff --git a/static/lang/en.json b/static/lang/en.json
index 1ead7b7d..02c7023f 100644
--- a/static/lang/en.json
+++ b/static/lang/en.json
@@ -154,7 +154,10 @@
"prediction": "Prediction"
},
"sortie": {
- "header": "Sortie"
+ "header": "Sortie",
+ "hunt": {
+ "header": "Archon Hunt"
+ }
},
"steelPath": {
"header": "Steel Path"