From 4f376f4777a55ca84052f01aa7943ed9e4ca542e Mon Sep 17 00:00:00 2001 From: bbdoc Date: Mon, 6 Jun 2022 14:00:48 +0200 Subject: [PATCH 01/63] Update index.jsx --- src/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.jsx b/src/index.jsx index abf3a41c0..b903e21a6 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -1,6 +1,6 @@ import React from 'react' import { render } from 'react-dom' -import ReactGA from 'react-ga' +import ReactGA from 'react-ga4' import * as Sentry from '@sentry/react' import { Integrations } from '@sentry/tracing' From 89767b50feeccdd7d75e1e262d6ca6a9f05743c8 Mon Sep 17 00:00:00 2001 From: bbdoc Date: Mon, 6 Jun 2022 14:02:30 +0200 Subject: [PATCH 02/63] Update Utility.js --- src/services/Utility.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/Utility.js b/src/services/Utility.js index 614b62cbc..26b76f93c 100644 --- a/src/services/Utility.js +++ b/src/services/Utility.js @@ -1,5 +1,5 @@ /* eslint-disable no-nested-ternary */ -import ReactGA from 'react-ga' +import ReactGA from 'react-ga4' import SunCalc from 'suncalc' import formatInterval from './functions/formatInterval' From 1fc2c075a70f6e066028d8a1e784b71e16f590d7 Mon Sep 17 00:00:00 2001 From: bbdoc Date: Mon, 6 Jun 2022 14:03:07 +0200 Subject: [PATCH 03/63] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8a9a275ab..9eac6501d 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "prop-types": "^15.7.2", "react": "17.0.2", "react-dom": "17.0.2", - "react-ga": "^3.3.0", + "react-ga4": "^1.4.1", "react-i18next": "^11.16.7", "react-leaflet": "3.2.2", "react-leaflet-markercluster": "3.0.0-rc1", From fc813333864ce58fec0fd0355a5e19a569e5df80 Mon Sep 17 00:00:00 2001 From: bbdoc Date: Wed, 8 Jun 2022 10:37:01 +0200 Subject: [PATCH 04/63] Update yarn.lock --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 922310473..1f22f47b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3889,10 +3889,10 @@ react-dom@17.0.2: object-assign "^4.1.1" scheduler "^0.20.2" -react-ga@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/react-ga/-/react-ga-3.3.0.tgz#c91f407198adcb3b49e2bc5c12b3fe460039b3ca" - integrity sha512-o8RScHj6Lb8cwy3GMrVH6NJvL+y0zpJvKtc0+wmH7Bt23rszJmnqEQxRbyrqUzk9DTJIHoP42bfO5rswC9SWBQ== +react-ga4@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/react-ga4/-/react-ga4-1.4.1.tgz" + integrity sha512-ioBMEIxd4ePw4YtaloTUgqhQGqz5ebDdC4slEpLgy2sLx1LuZBC9iYCwDymTXzcntw6K1dHX183ulP32nNdG7w== react-i18next@^11.16.7: version "11.16.7" From 63b31252ea1bb1e659bc4159c41336f0d36e94cc Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Wed, 8 Jun 2022 18:50:42 -0400 Subject: [PATCH 05/63] Fix nest searching eMbArrAssiNg --- server/src/models/Nest.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/server/src/models/Nest.js b/server/src/models/Nest.js index 1b56c9a93..bea564007 100644 --- a/server/src/models/Nest.js +++ b/server/src/models/Nest.js @@ -60,12 +60,12 @@ module.exports = class Nest extends Model { .groupBy('pokemon_id', 'pokemon_form') .orderBy('pokemon_id', 'asc') - return results.map(pokemon => { + return results.length ? results.map(pokemon => { if (pokemon.pokemon_form == 0 || pokemon.pokemon_form === null) { return `${pokemon.pokemon_id}-${Event.masterfile.pokemon[pokemon.pokemon_id].defaultFormId || 0}` } return `${pokemon.pokemon_id}-${pokemon.pokemon_form || 0}` - }) + }) : fetchNests() } static async search(perms, args, { isMad }, distance) { @@ -89,9 +89,7 @@ module.exports = class Nest extends Model { if (perms.areaRestrictions?.length) { getAreaSql(query, perms.areaRestrictions, isMad) } - const results = await query - - return results.length ? results : fetchNests() + return query } static getOne(id) { From 8e7f609f0d8d430222c3841e3f8067622e7094fd Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Thu, 9 Jun 2022 01:03:45 -0400 Subject: [PATCH 06/63] Filter by Quest Conditions - Filter quests by their conditions now if a reward has multiple conditions - Rework available, returns an object instead now for future expandability - questConditions gql api update - version bump - Make better use of promise.all in getAvailable pokestops method to reduce query times --- package.json | 2 +- server/src/graphql/mapTypes.js | 1 + server/src/graphql/resolvers.js | 3 +- server/src/models/Filters.js | 2 +- server/src/models/Gym.js | 16 +- server/src/models/Nest.js | 14 +- server/src/models/Pokemon.js | 2 +- server/src/models/Pokestop.js | 210 +++++++++--------- server/src/routes/rootRouter.js | 1 + server/src/services/DbCheck.js | 15 +- .../layout/dialogs/filters/Advanced.jsx | 29 ++- src/services/queries/available.js | 1 + 12 files changed, 168 insertions(+), 128 deletions(-) diff --git a/package.json b/package.json index 3e9ee6cb1..c5f400436 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "reactmap", - "version": "1.2.7", + "version": "1.2.8", "description": "React based frontend map.", "main": "ReactMap.mjs", "author": "TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com>", diff --git a/server/src/graphql/mapTypes.js b/server/src/graphql/mapTypes.js index c60ba1f94..f8683a45b 100644 --- a/server/src/graphql/mapTypes.js +++ b/server/src/graphql/mapTypes.js @@ -8,6 +8,7 @@ module.exports = gql` pokemon: [String] nests: [String] filters: JSON + questConditions: JSON } type Badge { diff --git a/server/src/graphql/resolvers.js b/server/src/graphql/resolvers.js index ba24a8d04..829907447 100644 --- a/server/src/graphql/resolvers.js +++ b/server/src/graphql/resolvers.js @@ -10,7 +10,7 @@ const Fetch = require('../services/Fetch') module.exports = { JSON: GraphQLJSON, Query: { - available: (_, args, { Event, perms, version }) => { + available: (_, args, { Event, Db, perms, version }) => { if (args.version && args.version !== version) throw new UserInputError('old_client') if (!perms) throw new AuthenticationError('session_expired') const available = { @@ -18,6 +18,7 @@ module.exports = { gyms: perms.gyms ? Event.available.gyms : [], nests: perms.nests ? Event.available.nests : [], pokestops: perms.pokestops ? Event.available.pokestops : [], + questConditions: perms.quests ? Db.questConditions : {}, } return { ...available, diff --git a/server/src/models/Filters.js b/server/src/models/Filters.js index b330a6842..ad4c4c280 100644 --- a/server/src/models/Filters.js +++ b/server/src/models/Filters.js @@ -5,6 +5,7 @@ class GenericFilter { constructor(enabled, size) { this.enabled = enabled || false this.size = size || 'md' + this.adv = '' } } @@ -16,7 +17,6 @@ class PokemonFilter extends GenericFilter { this.def_iv = def || [0, 15] this.sta_iv = sta || [0, 15] this.level = level || [1, 35] - this.adv = '' leagues.forEach(league => this[league.name] = pvp || [(league.minRank || 1), (league.maxRank || 100)]) } } diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index 615e32a41..888c8666e 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -290,14 +290,16 @@ module.exports = class Gym extends Model { return [...unique] }) if (!results.length) { - return [...teamResults, ...await fetchRaids()] + return { available: [...teamResults, ...await fetchRaids()] } + } + return { + available: [...teamResults, ...results.flatMap(result => { + if (result.raid_pokemon_id) { + return `${result.raid_pokemon_id}-${result.raid_pokemon_form}` + } + return [`e${result.raid_level}`, `r${result.raid_level}`] + })], } - return [...teamResults, ...results.flatMap(result => { - if (result.raid_pokemon_id) { - return `${result.raid_pokemon_id}-${result.raid_pokemon_form}` - } - return [`e${result.raid_level}`, `r${result.raid_level}`] - })] } static async search(perms, args, { isMad }, distance) { diff --git a/server/src/models/Nest.js b/server/src/models/Nest.js index bea564007..ce61f6dde 100644 --- a/server/src/models/Nest.js +++ b/server/src/models/Nest.js @@ -60,12 +60,14 @@ module.exports = class Nest extends Model { .groupBy('pokemon_id', 'pokemon_form') .orderBy('pokemon_id', 'asc') - return results.length ? results.map(pokemon => { - if (pokemon.pokemon_form == 0 || pokemon.pokemon_form === null) { - return `${pokemon.pokemon_id}-${Event.masterfile.pokemon[pokemon.pokemon_id].defaultFormId || 0}` - } - return `${pokemon.pokemon_id}-${pokemon.pokemon_form || 0}` - }) : fetchNests() + return { + available: results.length ? results.map(pokemon => { + if (pokemon.pokemon_form == 0 || pokemon.pokemon_form === null) { + return `${pokemon.pokemon_id}-${Event.masterfile.pokemon[pokemon.pokemon_id].defaultFormId || 0}` + } + return `${pokemon.pokemon_id}-${pokemon.pokemon_form || 0}` + }) : fetchNests(), + } } static async search(perms, args, { isMad }, distance) { diff --git a/server/src/models/Pokemon.js b/server/src/models/Pokemon.js index dcdb1d93d..76d387098 100644 --- a/server/src/models/Pokemon.js +++ b/server/src/models/Pokemon.js @@ -342,7 +342,7 @@ module.exports = class Pokemon extends Model { .where(isMad ? 'disappear_time' : 'expire_timestamp', '>=', isMad ? this.knex().fn.now() : ts) .groupBy('pokemon_id', 'form') .orderBy('pokemon_id', 'form') - return results.map(pkmn => `${pkmn.pokemon_id}-${pkmn.form}`) + return { available: results.map(pkmn => `${pkmn.pokemon_id}-${pkmn.form}`) } } static getOne(id, { isMad }) { diff --git a/server/src/models/Pokestop.js b/server/src/models/Pokestop.js index e071ef8db..a49724579 100644 --- a/server/src/models/Pokestop.js +++ b/server/src/models/Pokestop.js @@ -371,8 +371,10 @@ module.exports = class Pokestop extends Model { } if (quest.quest_timestamp >= midnight && (filters.onlyAllPokestops || filters[newQuest.key] || (filters[`u${quest.quest_reward_type}`] && map.enableQuestRewardTypeFilters))) { - this.fieldAssigner(newQuest, quest, fields) - filtered.quests.push(newQuest) + if (filters[newQuest.key].adv ? quest.quest_title === filters[newQuest.key].adv : true) { + this.fieldAssigner(newQuest, quest, fields) + filtered.quests.push(newQuest) + } } } }) @@ -462,194 +464,187 @@ module.exports = class Pokestop extends Model { static async getAvailable({ isMad, hasAltQuests, hasMultiInvasions, multiInvasionMs, hasRewardAmount }) { const ts = Math.floor((new Date()).getTime() / 1000) const finalList = new Set() - const quests = {} - const stops = {} + const conditions = {} + const queries = {} + + const process = (key, title, target) => { + if (title) { + if (key in conditions) { + conditions[key][`${title}-${target}`] = { title, target } + } else { + conditions[key] = { [`${title}-${target}`]: { title, target } } + } + } + finalList.add(key) + } - quests.items = await this.query() - .select('quest_item_id') + queries.items = this.query() + .select('quest_item_id', 'quest_title', 'quest_target') .from(isMad ? 'trs_quest' : 'pokestop') .where('quest_reward_type', 2) - .groupBy('quest_item_id') + .groupBy('quest_item_id', 'quest_title', 'quest_target') if (hasAltQuests) { - quests.items = [ - ...quests.items, - ...await this.query() - .select('alternative_quest_item_id AS quest_item_id') - .where('alternative_quest_reward_type', 2) - .groupBy('alternative_quest_item_id'), - ] + queries.itemsAlt = this.query() + .select('alternative_quest_item_id AS quest_item_id', 'alternative_quest_title AS quest_title', 'alternative_quest_target AS quest_target') + .where('alternative_quest_reward_type', 2) + .groupBy('alternative_quest_item_id', 'alternative_quest_title', 'alternative_quest_target') } if (isMad) { - quests.stardust = await this.query() - .select('quest_stardust AS amount') + queries.stardust = this.query() + .select('quest_stardust AS amount', 'quest_title', 'quest_target') .from('trs_quest') .where('quest_stardust', '>', 0) - .groupBy('amount') + .groupBy('amount', 'quest_title', 'quest_target') } else { - const dustQuery = this.query() + queries.stardust = this.query() .where('quest_reward_type', 3) if (hasRewardAmount) { - dustQuery - .select('quest_reward_amount AS amount') + queries.stardust + .select('quest_reward_amount AS amount', 'quest_title', 'quest_target') .where('quest_reward_amount', '>', 0) - .groupBy('amount') + .groupBy('amount', 'quest_title', 'quest_target') } else { - dustQuery + queries.stardust + .select('quest_title', 'quest_target') .distinct(raw('json_extract(quest_rewards, "$[0].info.amount")') .as('amount')) } - quests.stardust = await dustQuery if (hasAltQuests) { - const altDustQuery = this.query() + queries.stardustAlt = this.query() .where('alternative_quest_reward_type', 3) if (hasRewardAmount) { - altDustQuery - .select('alternative_quest_reward_amount AS amount') + queries.stardustAlt + .select('alternative_quest_reward_amount AS amount', 'alternative_quest_title AS quest_title', 'alternative_quest_target AS quest_target') .where('alternative_quest_reward_amount', '>', 0) - .groupBy('amount') + .groupBy('amount', 'alternative_quest_title', 'alternative_quest_target') } else { - altDustQuery + queries.stardustAlt + .select('alternative_quest_title AS quest_title', 'alternative_quest_target AS quest_target') .distinct(raw('json_extract(alternative_quest_rewards, "$[0].info.amount")') .as('amount')) } - quests.stardust = [ - ...quests.stardust, - ...await altDustQuery, - ] } } - const megaQuery = this.query() + queries.mega = this.query() .from(isMad ? 'trs_quest' : 'pokestop') .where('quest_reward_type', 12) if (hasRewardAmount) { - megaQuery + queries.mega + .select('quest_title', 'quest_target') .distinct(`${isMad ? 'quest_item_amount' : 'quest_reward_amount'} AS amount`) .distinct('quest_pokemon_id AS id') } else { - megaQuery + queries.mega + .select('quest_title', 'quest_target') .distinct(raw(`json_extract(${isMad ? 'quest_reward' : 'quest_rewards'}, "$[0].${isMad ? 'mega_resource' : 'info'}.pokemon_id")`) .as('id')) .distinct(raw(`json_extract(${isMad ? 'quest_reward' : 'quest_rewards'}, "$[0].${isMad ? 'mega_resource' : 'info'}.amount")`) .as('amount')) } - quests.mega = await megaQuery if (hasAltQuests) { - const altMegaQuery = this.query() + queries.megaAlt = this.query() .where('alternative_quest_reward_type', 12) if (hasRewardAmount) { - altMegaQuery + queries.megaAlt + .select('alternative_quest_title AS quest_title', 'alternative_quest_target AS quest_target') .distinct('alternative_quest_reward_amount AS amount') .distinct('alternative_quest_pokemon_id AS id') } else { - altMegaQuery + queries.megaAlt + .select('alternative_quest_title AS quest_title', 'alternative_quest_target AS quest_target') .distinct(raw('json_extract(alternative_quest_rewards, "$[0].info.pokemon_id")') .as('id')) .distinct(raw('json_extract(alternative_quest_rewards, "$[0].info.amount")') .as('amount')) } - quests.mega = [ - ...quests.mega, - ...await altMegaQuery, - ] } - quests.candy = await this.query() + queries.candy = this.query() + .select('quest_title', 'quest_target') .distinct('quest_pokemon_id') .from(isMad ? 'trs_quest' : 'pokestop') .where('quest_reward_type', 4) if (hasAltQuests) { - quests.candy = [ - ...quests.candy, - ...await this.query() - .distinct('alternative_quest_pokemon_id AS quest_pokemon_id') - .where('alternative_quest_reward_type', 4), - ] + queries.candyAlt = this.query() + .select('alternative_quest_title AS quest_title', 'alternative_quest_target AS quest_target') + .distinct('alternative_quest_pokemon_id AS quest_pokemon_id') + .where('alternative_quest_reward_type', 4) } - quests.xlCandy = await this.query() + queries.xlCandy = this.query() + .select('quest_title', 'quest_target') .distinct('quest_pokemon_id') .from(isMad ? 'trs_quest' : 'pokestop') .where('quest_reward_type', 9) if (hasAltQuests) { - quests.xlCandy = [ - ...quests.xlCandy, - ...await this.query() - .distinct('alternative_quest_pokemon_id AS quest_pokemon_id') - .where('alternative_quest_reward_type', 9), - ] + queries.xlCandyAlt = this.query() + .select('alternative_quest_title AS quest_title', 'alternative_quest_target AS quest_target') + .distinct('alternative_quest_pokemon_id AS quest_pokemon_id') + .where('alternative_quest_reward_type', 9) } if (isMad) { - quests.pokemon = await this.query() - .select('quest_pokemon_id', 'quest_pokemon_form_id AS form') + queries.pokemon = this.query() + .select('quest_pokemon_id', 'quest_pokemon_form_id AS form', 'quest_title', 'quest_target') .from('trs_quest') .where('quest_reward_type', 7) - .groupBy('quest_pokemon_id', 'quest_pokemon_form_id') + .groupBy('quest_pokemon_id', 'quest_pokemon_form_id', 'quest_title', 'quest_target') } else { - quests.pokemon = await this.query() + queries.pokemon = this.query() .distinct('quest_pokemon_id') .select(raw('json_extract(quest_rewards, "$[0].info.form_id")') - .as('form')) + .as('form'), 'quest_title', 'quest_target') .where('quest_reward_type', 7) if (hasAltQuests) { - quests.pokemon = [ - ...quests.pokemon, - ...await this.query() - .distinct('alternative_quest_pokemon_id AS quest_pokemon_id') - .select(raw('json_extract(alternative_quest_rewards, "$[0].info.form_id")') - .as('form')) - .where('alternative_quest_reward_type', 7), - ] + queries.pokemonAlt = this.query() + .distinct('alternative_quest_pokemon_id AS quest_pokemon_id') + .select(raw('json_extract(alternative_quest_rewards, "$[0].info.form_id")') + .as('form'), 'alternative_quest_title AS quest_title', 'alternative_quest_target AS quest_target') + .where('alternative_quest_reward_type', 7) } } - Object.entries(quests).forEach(([questType, rewards]) => { - switch (questType) { - case 'items': rewards.forEach(reward => finalList.add(`q${reward.quest_item_id}`)); break - case 'mega': rewards.forEach(reward => finalList.add(`m${reward.id}-${reward.amount}`)); break - case 'invasions': rewards.forEach(reward => finalList.add(`i${reward.grunt_type}`)); break - case 'stardust': rewards.forEach(reward => finalList.add(`d${reward.amount}`)); break - case 'candy': rewards.forEach(reward => finalList.add(`c${reward.id}`)); break - case 'xlCandy': rewards.forEach(reward => finalList.add(`x${reward.id}`)); break - default: rewards.forEach(reward => finalList.add(`${reward.quest_pokemon_id}-${reward.form ?? 0}`)); break - } - }) - if (hasMultiInvasions) { - stops.invasions = await this.query() + queries.invasions = this.query() .leftJoin('incident', 'pokestop.id', 'incident.pokestop_id') - .select([ - '*', - 'pokestop.id AS id', - 'incident.id AS incidentId', - raw(multiInvasionMs - ? 'FLOOR(incident.expiration_ms / 1000) AS incident_expire_timestamp' - : 'incident.expiration AS incident_expire_timestamp'), - 'incident.character AS grunt_type', - ]) + .distinct('incident.character AS grunt_type') .where(multiInvasionMs ? 'expiration_ms' : 'incident.expiration', '>=', ts * (multiInvasionMs ? 1000 : 1)) .orderBy('grunt_type') - } else if (hasMultiInvasions === false) { - stops.invasions = await this.query() - .select(isMad ? 'incident_grunt_type AS grunt_type' : 'grunt_type') + } else { + queries.invasions = this.query() + .distinct(isMad ? 'incident_grunt_type AS grunt_type' : 'grunt_type') .where(isMad ? 'incident_expiration' : 'incident_expire_timestamp', '>=', isMad ? this.knex().fn.now() : ts) - .groupBy('grunt_type') .orderBy('grunt_type') - } else { - stops.invasions = Object.keys(Event.masterfile.invasions) - .filter(grunt => +grunt < 100) - .map(i => ({ grunt_type: i })) } - stops.lures = await this.query() + queries.lures = this.query() .select(isMad ? 'active_fort_modifier AS lure_id' : 'lure_id') .andWhere(isMad ? 'lure_expiration' : 'lure_expire_timestamp', '>=', isMad ? this.knex().fn.now() : ts) .groupBy(isMad ? 'active_fort_modifier' : 'lure_id') .orderBy(isMad ? 'active_fort_modifier' : 'lure_id') - Object.entries(stops).forEach(stopType => { - const [sType, rewards] = stopType - switch (sType) { + const resolved = Object.fromEntries( + await Promise.all( + Object.entries(queries).map(async ([key, query]) => ([key, await query])), + ), + ) + Object.entries(resolved).forEach(([questType, rewards]) => { + switch (questType) { + case 'itemsAlt': + case 'items': rewards.forEach(reward => process(`q${reward.quest_item_id}`, reward.quest_title, reward.quest_target)); break + case 'megaAlt': + case 'mega': rewards.forEach(reward => process(`m${reward.id}-${reward.amount}`, reward.quest_title, reward.quest_target)); break + case 'stardustAlt': + case 'stardust': rewards.forEach(reward => process(`d${reward.amount}`, reward.quest_title, reward.quest_target)); break + case 'candyAlt': + case 'candy': rewards.forEach(reward => process(`c${reward.id}`, reward.quest_title, reward.quest_target)); break + case 'xlCandyAlt': + case 'xlCandy': rewards.forEach(reward => process(`x${reward.id}`, reward.quest_title, reward.quest_target)); break case 'lures': rewards.forEach(reward => finalList.add(`l${reward.lure_id}`)); break - default: rewards.forEach(reward => finalList.add(`i${reward.grunt_type}`)); break + case 'invasions': rewards.forEach(reward => finalList.add(`i${reward.grunt_type}`)); break + default: rewards.forEach(reward => process(`${reward.quest_pokemon_id}-${reward.form ?? 0}`, reward.quest_title, reward.quest_target)); break } }) - return finalList.size === 0 ? fetchQuests() : [...finalList] + const withConditions = Object.fromEntries( + Object.entries(conditions).map(([key, titles]) => [key, Object.values(titles)]), + ) + + return { available: finalList.size ? [...finalList] : await fetchQuests(), withConditions } } static parseRdmRewards = (quest) => { @@ -774,6 +769,9 @@ module.exports = class Pokestop extends Model { }) .limit(searchResultsLimit) .orderBy('distance') + if (perms.areaRestrictions?.length) { + getAreaSql(altQuestQuery, perms.areaRestrictions, isMad) + } const altQuestResults = await altQuestQuery const remapped = altQuestResults.map(result => ({ ...result, diff --git a/server/src/routes/rootRouter.js b/server/src/routes/rootRouter.js index 21594d229..d13d39c36 100644 --- a/server/src/routes/rootRouter.js +++ b/server/src/routes/rootRouter.js @@ -189,6 +189,7 @@ rootRouter.get('/settings', async (req, res) => { serverSettings.available.pokestops = config.api.queryOnSessionInit.quests ? await Db.getAvailable('Pokestop') : Event.available.pokestops + serverSettings.available.withConditions = Db.questConditions } if (serverSettings.user.perms.nests) { serverSettings.available.nests = config.api.queryOnSessionInit.nests diff --git a/server/src/services/DbCheck.js b/server/src/services/DbCheck.js index ddc46c125..0cd67abda 100644 --- a/server/src/services/DbCheck.js +++ b/server/src/services/DbCheck.js @@ -8,6 +8,7 @@ module.exports = class DbCheck { this.singleModels = ['User', 'Badge', 'Session'] this.searchLimit = apiSettings.searchLimit this.models = {} + this.questConditions = {} this.connections = dbSettings.schemas .filter(s => s.useFor.length) .map((schema, i) => { @@ -164,12 +165,20 @@ module.exports = class DbCheck { source.SubModel.getAvailable(source) ))) console.log(`[DB] Setting available for ${model}`) - if (results.length === 1) return results[0] + results.forEach(result => { + if ('withConditions' in result) { + this.questConditions = { + ...this.questConditions, + ...result.withConditions, + } + } + }) + if (results.length === 1) return results[0].available if (results.length > 1) { const returnSet = new Set() for (let i = 0; i < results.length; i += 1) { - for (let j = 0; j < results[i].length; j += 1) { - returnSet.add(results[i][j]) + for (let j = 0; j < results[i].available.length; j += 1) { + returnSet.add(results[i].available[j]) } } return [...returnSet] diff --git a/src/components/layout/dialogs/filters/Advanced.jsx b/src/components/layout/dialogs/filters/Advanced.jsx index 5e90b36c2..e22c3b664 100644 --- a/src/components/layout/dialogs/filters/Advanced.jsx +++ b/src/components/layout/dialogs/filters/Advanced.jsx @@ -1,5 +1,5 @@ -import React, { useState } from 'react' -import { Grid, DialogContent } from '@material-ui/core' +import React, { useState, useEffect } from 'react' +import { Select, Typography, Grid, DialogContent, MenuItem } from '@material-ui/core' import { useTranslation } from 'react-i18next' import Utility from '@services/Utility' @@ -10,6 +10,7 @@ import Footer from '@components/layout/general/Footer' import StringFilter from './StringFilter' import SliderTile from './SliderTile' import Size from './Size' +import QuestTitle from '../../general/QuestTitle' export default function AdvancedFilter({ toggleAdvMenu, advancedFilter, type, isTutorial, @@ -17,6 +18,7 @@ export default function AdvancedFilter({ Utility.analytics(`/${type}/${advancedFilter.id}`) const ui = useStatic(state => state.ui) + const { questConditions } = useStatic(state => state.available) const [filterValues, setFilterValues] = useState(advancedFilter.tempFilters) const filters = useStore(state => state.filters) const userSettings = useStore(state => state.userSettings) @@ -59,6 +61,19 @@ export default function AdvancedFilter({ ) } + // Provides a reset if that condition is no longer available + useEffect(() => { + if (type === 'pokestops' && ui.pokestops?.quests) { + if (!questConditions && filterValues.adv) { + setFilterValues({ ...filterValues, adv: '' }) + } else if (questConditions + && (!questConditions[advancedFilter.id] + || questConditions[advancedFilter.id].every(cond => cond.title !== filterValues.adv))) { + setFilterValues({ ...filterValues, adv: '' }) + } + } + }, []) + return ( <>
)} + {(type === 'pokestops' && ui.pokestops?.quests && questConditions?.[advancedFilter.id]) && ( + + + + )}