diff --git a/packages/types/lib/server.d.ts b/packages/types/lib/server.d.ts
index ede9dc9d6..382ad0110 100644
--- a/packages/types/lib/server.d.ts
+++ b/packages/types/lib/server.d.ts
@@ -106,6 +106,7 @@ export interface DbCheckClass {
reactMapDb: null | number
filterContext: {
Route: { maxDistance: number; maxDuration: number }
+ Pokestop: { hasConfirmedInvasions: boolean }
}
}
diff --git a/server/src/configs/default.json b/server/src/configs/default.json
index bb2393501..54a733e39 100644
--- a/server/src/configs/default.json
+++ b/server/src/configs/default.json
@@ -234,8 +234,6 @@
"forceTutorial": true,
"enableTutorial": true,
"enableUserProfile": true,
- "enableQuestSetSelector": true,
- "enableConfirmedInvasions": false,
"noScanAreaOverlay": false,
"scanAreaMenuHeight": 400,
"permImageDir": "images/perms",
diff --git a/server/src/configs/local.example.json b/server/src/configs/local.example.json
index 3b311c82f..dec49e922 100644
--- a/server/src/configs/local.example.json
+++ b/server/src/configs/local.example.json
@@ -18,9 +18,6 @@
"startZoom": 12,
"minZoom": 10,
"maxZoom": 18
- },
- "misc": {
- "enableQuestSetSelector": true
}
},
"database": {
@@ -323,4 +320,4 @@
"domain": "map_2.your_map.com"
}
]
-}
+}
\ No newline at end of file
diff --git a/server/src/graphql/resolvers.js b/server/src/graphql/resolvers.js
index d92705346..b8c40e586 100644
--- a/server/src/graphql/resolvers.js
+++ b/server/src/graphql/resolvers.js
@@ -23,7 +23,7 @@ const resolvers = {
const data = {
questConditions: perms.quests ? Db.questConditions : {},
masterfile: { ...Event.masterfile, invasions: Event.invasions },
- filters: buildDefaultFilters(perms, Db),
+ filters: buildDefaultFilters(perms),
audio: {
...config.getSafe('audio'),
styles: Event.uaudio,
diff --git a/server/src/models/Pokestop.js b/server/src/models/Pokestop.js
index 79fca9101..f94b6be5e 100644
--- a/server/src/models/Pokestop.js
+++ b/server/src/models/Pokestop.js
@@ -13,7 +13,6 @@ const {
stopValidDataLimit,
hideOldPokestops,
} = config.getSafe('api')
-const map = config.getSafe('map')
const questProps = {
quest_type: true,
@@ -812,8 +811,7 @@ class Pokestop extends Model {
pokestop.quests.forEach((quest) => {
if (
quest.quest_reward_type &&
- (!map.misc.enableQuestSetSelector ||
- filters.onlyShowQuestSet === 'both' ||
+ (filters.onlyShowQuestSet === 'both' ||
(filters.onlyShowQuestSet === 'with_ar' && quest.with_ar) ||
(filters.onlyShowQuestSet === 'without_ar' && !quest.with_ar))
) {
@@ -1322,6 +1320,7 @@ class Pokestop extends Model {
'>=',
ts * (multiInvasionMs ? 1000 : 1),
)
+ .andWhereNot('incident.display_type', 9)
.groupBy('incident.character', 'incident.display_type')
.orderBy('incident.character', 'incident.display_type')
}
@@ -1336,6 +1335,7 @@ class Pokestop extends Model {
.distinct(isMad ? 'incident_grunt_type AS grunt_type' : 'grunt_type')
.where(isMad ? 'incident_grunt_type' : 'grunt_type', '>', 0)
.andWhere('incident_expire_timestamp', '>=', ts)
+ .andWhereNot('incident.display_type', 9)
.orderBy('grunt_type')
}
if (isMad && !hasMultiInvasions) {
@@ -1968,6 +1968,21 @@ class Pokestop extends Model {
return results.filter((x) => x.enabled && !x.deleted)
}
+
+ /**
+ * returns pokestop context
+ * @param {import('@rm/types').DbContext} ctx
+ * @returns {Promise<{ hasConfirmedInvasions: boolean }>}
+ */
+ static async getFilterContext({ isMad, hasConfirmed }) {
+ if (isMad || !hasConfirmed) return { hasConfirmedInvasions: false }
+ const result = await this.query()
+ .from('incident')
+ .count('id', { as: 'total' })
+ .where('confirmed', 1)
+ .first()
+ return { hasConfirmedInvasions: result.total > 0 }
+ }
}
module.exports = Pokestop
diff --git a/server/src/services/DbCheck.js b/server/src/services/DbCheck.js
index b88098f66..598c0bdd8 100644
--- a/server/src/services/DbCheck.js
+++ b/server/src/services/DbCheck.js
@@ -44,6 +44,7 @@ module.exports = class DbCheck {
this.historical = getCache('historical.json', {})
this.filterContext = getCache('filterContext.json', {
Route: { maxDistance: 0, maxDuration: 0 },
+ Pokestop: { hasConfirmedInvasions: false },
})
this.reactMapDb = null
this.connections = config
@@ -627,8 +628,8 @@ module.exports = class DbCheck {
* Builds filter context for all models
*/
async getFilterContext() {
- try {
- if (this.models.Route) {
+ if (this.models.Route) {
+ try {
const results = await Promise.all(
this.models.Route.map(({ SubModel, ...source }) =>
SubModel.getFilterContext(source),
@@ -642,12 +643,22 @@ module.exports = class DbCheck {
)
log.info(HELPERS.db, 'Updating filter context for routes')
await setCache('filterContext.json', this.filterContext)
+ } catch (e) {
+ log.error(
+ HELPERS.db,
+ 'If you are using RDM, you likely do not have a routes table. Remove `route` from the `useFor` array in your config',
+ e,
+ )
}
- } catch (e) {
- log.error(
- HELPERS.db,
- 'If you are using RDM, you likely do not have a routes table. Remove `route` from the `useFor` array in your config',
- e,
+ }
+ if (this.models.Pokestop) {
+ const results = await Promise.all(
+ this.models.Pokestop.map(({ SubModel, ...source }) =>
+ SubModel.getFilterContext(source),
+ ),
+ )
+ this.filterContext.Pokestop.hasConfirmedInvasions = results.some(
+ (result) => result.hasConfirmedInvasions,
)
}
}
diff --git a/server/src/services/api/scannerApi.js b/server/src/services/api/scannerApi.js
index e83e86173..85d443ff8 100644
--- a/server/src/services/api/scannerApi.js
+++ b/server/src/services/api/scannerApi.js
@@ -216,7 +216,7 @@ async function scannerApi(
}
const scannerResponse = await fetch(
`${payloadObj.url}${payloadObj.url.includes('?') ? '&' : '?'}username=${
- user.username
+ user.username || user.id || 'a visitor'
}`,
{
...payloadObj.options,
diff --git a/server/src/services/cache.js b/server/src/services/cache.js
index 4a1f43401..e8b1e6d1b 100644
--- a/server/src/services/cache.js
+++ b/server/src/services/cache.js
@@ -17,6 +17,11 @@ const getCache = (fileName, fallback = null) => {
const data = JSON.parse(
fs.readFileSync(path.resolve(CACHE_DIR, fileName), 'utf-8'),
)
+ if (fallback) {
+ Object.entries(fallback).forEach(([key, value]) => {
+ if (!(key in data)) data[key] = value
+ })
+ }
log.info(HELPERS.cache, 'Loaded', fileName)
return data
} catch (e) {
diff --git a/server/src/services/filters/builder/base.js b/server/src/services/filters/builder/base.js
index 6b523afd0..1475f494f 100644
--- a/server/src/services/filters/builder/base.js
+++ b/server/src/services/filters/builder/base.js
@@ -1,6 +1,7 @@
// @ts-check
const config = require('@rm/config')
+const { Db } = require('../../initialization')
const buildPokemon = require('./pokemon')
const buildPokestops = require('./pokestop')
const buildGyms = require('./gym')
@@ -26,12 +27,10 @@ const custom = new PokemonFilter(
)
/**
- *
* @param {import("@rm/types").Permissions} perms
- * @param {import("@rm/types").DbCheckClass} database
* @returns
*/
-function buildDefaultFilters(perms, database) {
+function buildDefaultFilters(perms) {
const stopReducer =
perms.pokestops || perms.lures || perms.quests || perms.invasions
const gymReducer = perms.gyms || perms.raids
@@ -40,7 +39,7 @@ function buildDefaultFilters(perms, database) {
return {
gyms:
- gymReducer && database.models.Gym
+ gymReducer && Db.models.Gym
? {
enabled: defaultFilters.gyms.enabled,
allGyms: perms.gyms ? defaultFilters.gyms.enabled : undefined,
@@ -62,7 +61,7 @@ function buildDefaultFilters(perms, database) {
}
: undefined,
nests:
- perms.nests && database.models.Nest
+ perms.nests && Db.models.Nest
? {
enabled: defaultFilters.nests.enabled,
pokemon: defaultFilters.nests.pokemon,
@@ -73,7 +72,7 @@ function buildDefaultFilters(perms, database) {
}
: undefined,
pokestops:
- stopReducer && database.models.Pokestop
+ stopReducer && Db.models.Pokestop
? {
enabled: defaultFilters.pokestops.enabled,
allPokestops: perms.pokestops
@@ -104,7 +103,7 @@ function buildDefaultFilters(perms, database) {
}
: undefined,
pokemon:
- perms.pokemon && database.models.Pokemon
+ perms.pokemon && Db.models.Pokemon
? {
enabled: defaultFilters.pokemon.enabled,
easyMode: defaultFilters.pokemon.easyMode,
@@ -126,12 +125,12 @@ function buildDefaultFilters(perms, database) {
}
: undefined,
routes:
- perms.routes && database.models.Route
+ perms.routes && Db.models.Route
? {
enabled: defaultFilters.routes.enabled,
distance: [
0,
- Math.ceil(database.filterContext.Route.maxDistance / 1000) + 1,
+ Math.ceil(Db.filterContext.Route.maxDistance / 1000) + 1,
],
standard: new BaseFilter(),
filter: {
@@ -140,7 +139,7 @@ function buildDefaultFilters(perms, database) {
}
: undefined,
portals:
- perms.portals && database.models.Portal
+ perms.portals && Db.models.Portal
? {
enabled: defaultFilters.portals.enabled,
standard: new BaseFilter(),
@@ -160,7 +159,7 @@ function buildDefaultFilters(perms, database) {
}
: undefined,
submissionCells:
- perms.submissionCells && database.models.Pokestop && database.models.Gym
+ perms.submissionCells && Db.models.Pokestop && Db.models.Gym
? {
enabled: defaultFilters.submissionCells.enabled,
rings: defaultFilters.submissionCells.rings,
@@ -180,7 +179,7 @@ function buildDefaultFilters(perms, database) {
}
: undefined,
weather:
- perms.weather && database.models.Weather
+ perms.weather && Db.models.Weather
? {
enabled: defaultFilters.weather.enabled,
standard: new BaseFilter(),
@@ -188,7 +187,7 @@ function buildDefaultFilters(perms, database) {
}
: undefined,
spawnpoints:
- perms.spawnpoints && database.models.Spawnpoint
+ perms.spawnpoints && Db.models.Spawnpoint
? {
enabled: defaultFilters.spawnpoints.enabled,
standard: new BaseFilter(),
@@ -201,7 +200,7 @@ function buildDefaultFilters(perms, database) {
}
: undefined,
scanCells:
- perms.scanCells && database.models.ScanCell
+ perms.scanCells && Db.models.ScanCell
? {
enabled: defaultFilters.scanCells.enabled,
standard: new BaseFilter(),
@@ -209,7 +208,7 @@ function buildDefaultFilters(perms, database) {
}
: undefined,
devices:
- perms.devices && database.models.Device
+ perms.devices && Db.models.Device
? {
enabled: defaultFilters.devices.enabled,
standard: new BaseFilter(),
diff --git a/server/src/services/filters/builder/pokemon.js b/server/src/services/filters/builder/pokemon.js
index 38dd7dc42..d58933421 100644
--- a/server/src/services/filters/builder/pokemon.js
+++ b/server/src/services/filters/builder/pokemon.js
@@ -1,8 +1,5 @@
// @ts-check
-/* eslint-disable no-restricted-syntax */
-const config = require('@rm/config')
-
-const { Event } = require('../../initialization')
+const { Event, Db } = require('../../initialization')
const BaseFilter = require('../Base')
/**
@@ -33,20 +30,22 @@ function buildPokemon(defaults, base, custom) {
.map((e) => e.split('-')[1]),
])
- for (const [i, pkmn] of Object.entries(Event.masterfile.pokemon)) {
- for (const j of Object.keys(pkmn.forms)) {
- pokemon.full[`${i}-${j}`] = base
- pokemon.raids[`${i}-${j}`] = new BaseFilter(defaults.gyms.pokemon)
- pokemon.quests[`${i}-${j}`] = new BaseFilter(defaults.pokestops.pokemon)
- if (config.getSafe('map.misc.enableConfirmedInvasions')) {
- pokemon.rocket[`a${i}-${j}`] = new BaseFilter(
+ Object.entries(Event.masterfile.pokemon).forEach(([id, pkmn]) => {
+ Object.keys(pkmn.forms).forEach((form) => {
+ pokemon.full[`${id}-${form}`] = base
+ pokemon.raids[`${id}-${form}`] = new BaseFilter(defaults.gyms.pokemon)
+ pokemon.quests[`${id}-${form}`] = new BaseFilter(
+ defaults.pokestops.pokemon,
+ )
+ if (Db.filterContext.Pokestop.hasConfirmedInvasions) {
+ pokemon.rocket[`a${id}-${form}`] = new BaseFilter(
defaults.pokestops.invasionPokemon,
)
}
- pokemon.nests[`${i}-${j}`] = new BaseFilter(defaults.nests.allPokemon)
- }
+ pokemon.nests[`${id}-${form}`] = new BaseFilter(defaults.nests.allPokemon)
+ })
if ('family' in pkmn) {
- if (pkmn.family === +i) {
+ if (pkmn.family === +id) {
pokemon.quests[`c${pkmn.family}`] = new BaseFilter(
defaults.pokestops.candy,
)
@@ -57,12 +56,12 @@ function buildPokemon(defaults, base, custom) {
}
if ('tempEvolutions' in pkmn) {
energyAmounts.forEach((a) => {
- pokemon.quests[`m${i}-${a}`] = new BaseFilter(
+ pokemon.quests[`m${id}-${a}`] = new BaseFilter(
defaults.pokestops.megaEnergy,
)
})
}
- }
+ })
return pokemon
}
diff --git a/server/src/services/filters/builder/pokestop.js b/server/src/services/filters/builder/pokestop.js
index 928a839f2..d9837fff4 100644
--- a/server/src/services/filters/builder/pokestop.js
+++ b/server/src/services/filters/builder/pokestop.js
@@ -1,8 +1,6 @@
// @ts-check
-const config = require('@rm/config')
-
const BaseFilter = require('../Base')
-const { Event } = require('../../initialization')
+const { Event, Db } = require('../../initialization')
/**
*
@@ -72,7 +70,7 @@ function buildPokestops(perms, defaults) {
}
if (
avail.startsWith('a') &&
- config.getSafe('map.misc.enableConfirmedInvasions')
+ Db.filterContext.Pokestop.hasConfirmedInvasions
) {
quests[avail] = new BaseFilter(defaults.invasionPokemon)
}
diff --git a/src/components/layout/dialogs/filters/OptionsContainer.jsx b/src/components/layout/dialogs/filters/OptionsContainer.jsx
index 088d5018b..dc101bd60 100644
--- a/src/components/layout/dialogs/filters/OptionsContainer.jsx
+++ b/src/components/layout/dialogs/filters/OptionsContainer.jsx
@@ -1,13 +1,15 @@
import * as React from 'react'
-import Typography from '@mui/material/Typography'
-import Grid from '@mui/material/Grid'
-import Button from '@mui/material/Button'
import Chip from '@mui/material/Chip'
+import List from '@mui/material/List'
+import ListItem from '@mui/material/ListItem'
+import ListItemText from '@mui/material/ListItemText'
import { useTranslation } from 'react-i18next'
+import ReplayIcon from '@mui/icons-material/Replay'
import { useMemory } from '@hooks/useMemory'
import { useStorage } from '@hooks/useStorage'
import Utility from '@services/Utility'
+import { BasicListButton } from '@components/layout/general/BasicListButton'
import Options from './Options'
@@ -97,27 +99,20 @@ export default function OptionsContainer({
return null
},
)}
-
-
-
-
-
-
- {t('showing')}: {countShow}/{countTotal}
-
-
-
+
+
+
+
+
-
-
+
+
+
+
+
>
)
}
diff --git a/src/components/layout/drawer/Actions.jsx b/src/components/layout/drawer/Actions.jsx
index f35eca7fc..3bc8bf95f 100644
--- a/src/components/layout/drawer/Actions.jsx
+++ b/src/components/layout/drawer/Actions.jsx
@@ -7,7 +7,7 @@ import { Link } from 'react-router-dom'
import AccountBoxIcon from '@mui/icons-material/AccountBox'
import ExitToAppIcon from '@mui/icons-material/ExitToApp'
import HelpOutlineIcon from '@mui/icons-material/HelpOutline'
-import RotateLeftIcon from '@mui/icons-material/RotateLeft'
+import ReplayIcon from '@mui/icons-material/Replay'
import ImportExportIcon from '@mui/icons-material/ImportExport'
import TrendingUpIcon from '@mui/icons-material/TrendingUp'
import FeedbackIcon from '@mui/icons-material/Feedback'
@@ -84,14 +84,14 @@ export default function DrawerActions() {
onClick={exportSettings}
label="import"
>
-
+
useLayoutStore.setState({ resetFilters: true })}
label="reset_filters"
>
-
+
{!!methods.length && (
@@ -101,7 +101,7 @@ export default function DrawerActions() {
href={loggedIn ? '/auth/logout' : undefined}
label={loggedIn ? 'logout' : 'login'}
>
-
+
)}
@@ -113,7 +113,7 @@ export default function DrawerActions() {
rel="noreferrer"
label="contribute"
>
-
+
)}
{config.links.statsLink && (
diff --git a/src/components/layout/drawer/Extras.jsx b/src/components/layout/drawer/Extras.jsx
index 16846be46..1553c65cb 100644
--- a/src/components/layout/drawer/Extras.jsx
+++ b/src/components/layout/drawer/Extras.jsx
@@ -5,7 +5,6 @@ import * as React from 'react'
import Box from '@mui/material/Box'
import ListItem from '@mui/material/ListItem'
import ListItemText from '@mui/material/ListItemText'
-import ListItemIcon from '@mui/material/ListItemIcon'
import Select from '@mui/material/Select'
import MenuItem from '@mui/material/MenuItem'
import { useTranslation } from 'react-i18next'
@@ -26,7 +25,6 @@ import SliderTile from '../dialogs/filters/SliderTile'
import { CollapsibleItem } from './CollapsibleItem'
import { MultiSelectorList, SelectorListMemo } from './SelectorList'
import { BoolToggle } from './BoolToggle'
-import { Img } from '../general/Img'
const BaseNestSlider = () => {
const slider = useMemory((s) => s.ui.nests?.sliders?.secondary?.[0])
@@ -230,7 +228,9 @@ const QuestSet = React.memo(BaseQuestSet)
const BaseInvasion = () => {
const enabled = useStorage((s) => !!s.filters?.pokestops?.invasions)
- const hasConfirmed = useMemory((s) => s.config.misc.enableConfirmedInvasions)
+ const hasConfirmed = useMemory((s) =>
+ s.available.pokestops.some((x) => x.startsWith('a')),
+ )
return (
{hasConfirmed && (
@@ -273,21 +273,8 @@ const BaseInvasion = () => {
}
const Invasion = React.memo(BaseInvasion)
-/** @param {{ id: string }} props */
-const IndividualEvent = ({ id }) => {
- const { t } = useTranslation()
- const src = useMemory((s) => s.Icons.getIconById(id))
- const label = t(`display_type_${id.slice(1)}`)
- return (
-
-
-
-
-
- )
-}
-const ShowcaseQuickSelect = () => {
- const enabled = useStorage((s) => !!s.filters?.pokestops?.filter?.b9?.enabled)
+const BaseEventStops = () => {
+ const enabled = useStorage((s) => !!s.filters?.pokestops?.eventStops)
return (
@@ -300,20 +287,6 @@ const ShowcaseQuickSelect = () => {
)
}
-const BaseEventStops = () => {
- const available = useMemory((s) => s.available.pokestops)
- const enabled = useStorage((s) => !!s.filters?.pokestops?.eventStops)
- return (
-
- {available
- ?.filter((event) => event.startsWith('b'))
- .map((event) => (
-
- ))}
-
-
- )
-}
const EventStops = React.memo(BaseEventStops)
/** @param {{ item: (typeof WAYFARER_OPTIONS)[number], index: number, disabled: boolean }} props */
@@ -426,8 +399,6 @@ const BaseLureQuickSelector = () => {
const LureQuickSelector = React.memo(BaseLureQuickSelector)
function Extras({ category, subItem }) {
- const { enableQuestSetSelector } = useMemory.getState().config.misc
-
switch (category) {
case 'nests':
return subItem === 'sliders' ? (
@@ -442,7 +413,7 @@ function Extras({ category, subItem }) {
case 'allPokestops':
return
case 'quests':
- return enableQuestSetSelector ? : null
+ return
case 'invasions':
return
case 'eventStops':
diff --git a/src/components/layout/drawer/SelectorList.jsx b/src/components/layout/drawer/SelectorList.jsx
index fe1b15a39..61245f559 100644
--- a/src/components/layout/drawer/SelectorList.jsx
+++ b/src/components/layout/drawer/SelectorList.jsx
@@ -79,7 +79,11 @@ function SelectorList({ category, subCategory, label, height = 400 }) {
key.startsWith('p')
)
case 'showcase':
- return key.startsWith('f') || key.startsWith('h')
+ return (
+ key.startsWith('f') ||
+ key.startsWith('h') ||
+ key.startsWith('b')
+ )
case 'rocketPokemon':
return key.startsWith('a')
case 'pokemon':
diff --git a/src/services/functions/hasAll.js b/src/services/functions/hasAll.js
index eaf76510f..931e7e805 100644
--- a/src/services/functions/hasAll.js
+++ b/src/services/functions/hasAll.js
@@ -14,7 +14,8 @@ export function checkIfHasAll(category, id) {
id.startsWith('i') ||
id.startsWith('f') ||
id.startsWith('a') ||
- id.startsWith('h')
+ id.startsWith('h') ||
+ id.startsWith('b')
)) ||
(id.startsWith('t') && id !== 't0-0')
)