Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2a9cbbf
fix: battle/raid filtering race condition
Mygod Dec 9, 2025
cd01a92
fix: ground raid/battle icons
Mygod Dec 9, 2025
3717c2e
chore: centralize overlay logic
Mygod Dec 9, 2025
21b50f5
fix: weather icon in pokemon background popup
Mygod Dec 10, 2025
640c5ad
chore(release): v1.40.2-develop.1 [skip ci]
semantic-release-bot Dec 10, 2025
4f5aace
feat: support stationed pokemon extras
Mygod Dec 10, 2025
907ca33
fix: no scrollbars plz
Mygod Dec 11, 2025
8a0447c
feat: dynamic placed Pokemon dropdown height
Mygod Dec 11, 2025
497f350
fix: battle/raid icon max height
Mygod Dec 11, 2025
b2ea525
chore(release): v1.41.0-develop.1 [skip ci]
semantic-release-bot Dec 11, 2025
0f157ed
fix: remove extra Forms
Mygod Dec 11, 2025
e46ea5b
chore(release): v1.41.0-develop.2 [skip ci]
semantic-release-bot Dec 15, 2025
a2c7f17
fix: logic bug in loading non-clustered elements (#1161)
ComplementaryPogo Dec 15, 2025
bce4be5
chore: sync config [skip ci]
turtlesocks-bot Dec 15, 2025
d3ea283
feat: default clientPrompt to none to skip permission reapproval
Mygod Dec 16, 2025
d7ecbde
chore: sync config [skip ci]
turtlesocks-bot Dec 16, 2025
b579ded
fix: more robust discord handling (#1181)
Mygod Dec 16, 2025
11c75e0
chore(release): v1.41.0-develop.3 [skip ci]
semantic-release-bot Dec 16, 2025
cea3141
fix: area reload
Mygod Dec 31, 2025
5c907c5
chore(release): v1.41.0-develop.4 [skip ci]
semantic-release-bot Dec 31, 2025
7bd5ce1
fix: escape gpx xml (#1186)
josh-vin Jan 8, 2026
5b32067
chore(release): v1.41.0-develop.5 [skip ci]
semantic-release-bot Jan 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,60 @@
# [1.41.0-develop.5](https://github.com/WatWowMap/ReactMap/compare/v1.41.0-develop.4...v1.41.0-develop.5) (2026-01-08)


### Bug Fixes

* escape gpx xml ([#1186](https://github.com/WatWowMap/ReactMap/issues/1186)) ([7bd5ce1](https://github.com/WatWowMap/ReactMap/commit/7bd5ce10d3e8aa6f64faac8d3d9773c589d6a28e))

# [1.41.0-develop.4](https://github.com/WatWowMap/ReactMap/compare/v1.41.0-develop.3...v1.41.0-develop.4) (2025-12-31)


### Bug Fixes

* area reload ([cea3141](https://github.com/WatWowMap/ReactMap/commit/cea3141386d804f502e83e89b9bf92da93102a5d))

# [1.41.0-develop.3](https://github.com/WatWowMap/ReactMap/compare/v1.41.0-develop.2...v1.41.0-develop.3) (2025-12-16)


### Bug Fixes

* logic bug in loading non-clustered elements ([#1161](https://github.com/WatWowMap/ReactMap/issues/1161)) ([a2c7f17](https://github.com/WatWowMap/ReactMap/commit/a2c7f17e02ff7cd5467d4bf5ccd8b13a444ba725))
* more robust discord handling ([#1181](https://github.com/WatWowMap/ReactMap/issues/1181)) ([b579ded](https://github.com/WatWowMap/ReactMap/commit/b579dedeb196fb4d8b1da025e325049bfd7833e8))


### Features

* default clientPrompt to none to skip permission reapproval ([d3ea283](https://github.com/WatWowMap/ReactMap/commit/d3ea283b5eacda18b9f4725e50e5353a955a363d))

# [1.41.0-develop.2](https://github.com/WatWowMap/ReactMap/compare/v1.41.0-develop.1...v1.41.0-develop.2) (2025-12-15)


### Bug Fixes

* remove extra Forms ([0f157ed](https://github.com/WatWowMap/ReactMap/commit/0f157edba37eb727fdb9f4a5b96bdf417298cdfc))

# [1.41.0-develop.1](https://github.com/WatWowMap/ReactMap/compare/v1.40.2-develop.1...v1.41.0-develop.1) (2025-12-11)


### Bug Fixes

* battle/raid icon max height ([497f350](https://github.com/WatWowMap/ReactMap/commit/497f3504a4ea6000184c9df30c5a3c3e76d65d80))
* no scrollbars plz ([907ca33](https://github.com/WatWowMap/ReactMap/commit/907ca331beb1fe81dd671732d5ebe1980d8d6faa))


### Features

* dynamic placed Pokemon dropdown height ([8a0447c](https://github.com/WatWowMap/ReactMap/commit/8a0447c3e9d7df9c4aa9add657a234a1bc59b412))
* support stationed pokemon extras ([4f5aace](https://github.com/WatWowMap/ReactMap/commit/4f5aace285285d55e3a946fb2f465b7609a9caea))

## [1.40.2-develop.1](https://github.com/WatWowMap/ReactMap/compare/v1.40.1...v1.40.2-develop.1) (2025-12-10)


### Bug Fixes

* battle/raid filtering race condition ([2a9cbbf](https://github.com/WatWowMap/ReactMap/commit/2a9cbbf180313064830a524f86eae62f41b6b87b))
* ground raid/battle icons ([cd01a92](https://github.com/WatWowMap/ReactMap/commit/cd01a92bda81f786ca2c14f10df8cc4489163fd6))
* weather icon in pokemon background popup ([21b50f5](https://github.com/WatWowMap/ReactMap/commit/21b50f51b81bf6f7723753a4f77289ead99c51e7))

## [1.40.1](https://github.com/WatWowMap/ReactMap/compare/v1.40.0...v1.40.1) (2025-12-09)


Expand Down
2 changes: 1 addition & 1 deletion config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@
"allowedGuilds": [],
"blockedGuilds": [],
"allowedUsers": [],
"clientPrompt": "consent",
"clientPrompt": "none",
"thumbnailUrl": "https://user-images.githubusercontent.com/58572875/167069223-745a139d-f485-45e3-a25c-93ec4d09779c.png",
"trialPeriod": {
"start": {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "reactmap",
"version": "1.40.1",
"version": "1.41.0-develop.5",
"private": true,
"description": "React based frontend map.",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/config/.configref
Original file line number Diff line number Diff line change
@@ -1 +1 @@
26702
26699
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The config reference is being changed from 26702 to 26699, which appears to be going backwards in version/reference number. This seems unusual for a sync operation and may indicate an unintended downgrade or incorrect merge.

Suggested change
26699
26702

Copilot uses AI. Check for mistakes.
5 changes: 1 addition & 4 deletions packages/types/lib/scanner.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,11 +372,8 @@ export interface Route {

export type FullRoute = FullModel<Route, RouteModel.Route>

export interface StationPokemon {
export interface StationPokemon extends PokemonDisplay {
pokemon_id: number
form: number
costume: number
gender: number
bread_mode: number
}

Expand Down
6 changes: 6 additions & 0 deletions server/src/graphql/typeDefs/scanner.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -323,5 +323,11 @@ type StationPokemon {
form: Int
costume: Int
gender: Int
shiny: Boolean
temp_evolution: Int
temp_evolution_finish_ms: Float
alignment: Int
badge: Int
background: Int
bread_mode: Int
}
31 changes: 22 additions & 9 deletions server/src/services/DiscordClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,36 @@ class DiscordClient extends AuthClient {
this.client.login(this.strategy.botToken)
}

/** @param {string} guildId @param {string} userId */
/**
* @param {string} guildId
* @param {string} userId
* @returns {Promise<string[]>}
*/
async getUserRoles(guildId, userId) {
try {
const members = await this.client.guilds.cache
.get(guildId)
?.members.fetch()
if (members) {
const member = members.get(userId)
return member?.roles.cache.map((role) => role.id) || []
}
return []
const guild =
this.client.guilds.cache.get(guildId) ||
(await this.client.guilds.fetch(guildId))
const member = await guild?.members.fetch(userId)
return member?.roles.cache.map((role) => role.id) || []
} catch (e) {
const code =
e && typeof e === 'object' && 'code' in e ? Number(e.code) : null
if (code === 10007) {
this.log.debug(
'Discord member not found in guild',
guildId,
'for user',
userId,
)
return []
}
this.log.error(
'Failed to get roles in guild',
guildId,
'for user',
userId,
e,
)
}
return []
Expand Down
8 changes: 5 additions & 3 deletions server/src/utils/reloadConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const { log, TAGS } = require('@rm/logger')

const { state } = require('../services/state')
const { bindConnections } = require('../models')
const { loadLatestAreas } = require('../services/areas')
const { loadCachedAreas, loadLatestAreas } = require('../services/areas')
const { loadAuthStrategies } = require('../routes/authRouter')
const { deepCompare } = require('./deepCompare')

Expand Down Expand Up @@ -52,6 +52,10 @@ async function reloadConfig() {
const newConfig = require('@rm/config')

const { areas, ...oldWithoutAreas } = oldConfig
const primedAreas = areas || loadCachedAreas()
// Prime areas early so config.getSafe('areas') never fails during reload.
newConfig.setAreas(primedAreas)
oldWithoutAreas.areas = primedAreas

const { report, areEqual, changed } = deepCompare(
oldWithoutAreas,
Expand All @@ -69,8 +73,6 @@ async function reloadConfig() {
!report.manualAreas.areEqual
) {
newConfig.setAreas(await loadLatestAreas())
} else {
newConfig.setAreas(areas)
}

if (areEqual) {
Expand Down
39 changes: 28 additions & 11 deletions src/assets/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,34 @@ body {
position: absolute;
}

.marker-overlay-icon {
position: absolute;
display: flex;
align-items: flex-end;
justify-content: center;
transform: translateX(-50%);
width: var(--marker-overlay-size, 30px);
height: var(--marker-overlay-size, 30px);
}

.marker-overlay-icon img,
.leaflet-container
.leaflet-marker-pane
.pokestop-marker__stack-item
img:not(.pokestop-marker__decoration) {
width: var(--marker-overlay-size, var(--marker-size, 30px)) !important;
height: auto !important;
max-width: var(--marker-overlay-size, var(--marker-size, 30px)) !important;
max-height: var(--marker-overlay-size, var(--marker-size, 30px)) !important;
object-fit: contain;
}

/* Override Leaflet's marker-pane img reset for overlay icons */
.leaflet-container .leaflet-marker-pane .marker-overlay-icon img {
max-width: var(--marker-overlay-size, var(--marker-size, 30px)) !important;
max-height: var(--marker-overlay-size, var(--marker-size, 30px)) !important;
}

.invasion-reward {
display: inline-block;
width: 30px;
Expand Down Expand Up @@ -356,17 +384,6 @@ img {
transform: translateX(-50%);
}

.leaflet-container
.leaflet-marker-pane
.pokestop-marker__stack-item
img:not(.pokestop-marker__decoration) {
width: var(--marker-size, 30px) !important;
height: auto !important;
max-width: var(--marker-size, 30px) !important;
max-height: var(--marker-size, 30px) !important;
object-fit: contain;
}

.leaflet-container
.leaflet-marker-pane
.pokestop-marker__stack-item[data-reward-type='12']
Expand Down
4 changes: 3 additions & 1 deletion src/components/filters/Advanced.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ export function AdvancedFilter() {
category === 'pokemon' || (!id.startsWith('l') && !id.startsWith('i'))
? t('advanced')
: t('set_size')
} - ${tId(id)}`}
} - ${tId(id, {
omitFormSuffix: true,
})}`}
action={() => toggleClose(false)}
/>
<DialogContent sx={{ mt: 3 }}>
Expand Down
1 change: 1 addition & 0 deletions src/components/virtual/SelectorItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function SelectorItem({
alt: true,
newLine: true,
quest: category === 'pokestops',
omitFormSuffix: true,
})
const title = t(id)
const url = useMemory((s) => s.Icons.getIconById(id))
Expand Down
5 changes: 4 additions & 1 deletion src/components/virtual/VirtualGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ const List = React.forwardRef(({ context, ...props }, ref) => (
* children: import('react-virtuoso').VirtuosoGridProps<T, U & SomeGridProps>['itemContent'],
* Header?: React.ComponentType<U>,
* Footer?: React.ComponentType<U>,
* useWindowScroll?: boolean
* useWindowScroll?: boolean,
* scrollerRef?: import('react-virtuoso').VirtuosoGridProps<T, U & SomeGridProps>['scrollerRef']
* }} props
*/
export function VirtualGrid({
Expand All @@ -55,6 +56,7 @@ export function VirtualGrid({
Header,
Footer,
useWindowScroll,
scrollerRef,
}) {
const fullContext = React.useMemo(
() => ({ ...context, xs, sm, md, lg, xl }),
Expand All @@ -74,6 +76,7 @@ export function VirtualGrid({
components={components}
itemContent={children}
useWindowScroll={useWindowScroll}
scrollerRef={scrollerRef}
/>
)
}
25 changes: 17 additions & 8 deletions src/features/drawer/Stations.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import ListItemText from '@mui/material/ListItemText'
import MenuItem from '@mui/material/MenuItem'
import { useTranslation } from 'react-i18next'

import { useMemory } from '@store/useMemory'
import { useDeepStore, useStorage } from '@store/useStorage'
import { useGetAvailable } from '@hooks/useGetAvailable'
import { FCSelect } from '@components/inputs/FCSelect'

import { CollapsibleItem } from './components/CollapsibleItem'
import { SelectorListMemo } from './components/SelectorList'

function StationLevels() {
const { t } = useTranslation()
const available = useMemory((s) => s.available.stations)
const { available } = useGetAvailable('stations')
const enabled = useStorage(
(s) =>
!!s.filters?.stations?.maxBattles && !s.filters?.stations?.allStations,
Expand All @@ -24,6 +24,20 @@ function StationLevels() {
'filters.stations.battleTier',
'all',
)

const battleTiers = React.useMemo(() => {
const availableTiers = available
.filter((x) => x.startsWith('j'))
.map((y) => +y.slice(1))
if (filters === 'all') return availableTiers

const storedTier = Number(filters)
if (Number.isNaN(storedTier) || availableTiers.includes(storedTier)) {
return availableTiers
}
return [storedTier, ...availableTiers]
}, [available, filters])

return (
<CollapsibleItem open={enabled}>
<ListItem
Expand All @@ -36,12 +50,7 @@ function StationLevels() {
setFilters(e.target.value === 'all' ? 'all' : e.target.value)
}
>
{[
'all',
...available
.filter((x) => x.startsWith('j'))
.map((y) => +y.slice(1)),
].map((tier, i) => (
{['all', ...battleTiers].map((tier, i) => (
<MenuItem key={tier} dense value={tier}>
{t(i ? `max_battle_${tier}_plural` : 'disabled')}
</MenuItem>
Expand Down
5 changes: 4 additions & 1 deletion src/features/drawer/components/SelectorList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ function SelectorList({ category, subCategory, label, height = 400 }) {
subCategory ? capitalize(subCategory) : ''
}QuickSelect`
const { available } = useGetAvailable(category)
const { t: tId } = useTranslateById({ quest: subCategory === 'pokemon' })
const { t: tId } = useTranslateById({
quest: subCategory === 'pokemon',
omitFormSuffix: true,
})
const { t } = useTranslation()
const allFilters = useMemory((s) => s.filters[category]?.filter)

Expand Down
25 changes: 17 additions & 8 deletions src/features/drawer/gyms/Raids.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,32 @@ import ListItemText from '@mui/material/ListItemText'
import MenuItem from '@mui/material/MenuItem'
import { useTranslation } from 'react-i18next'

import { useMemory } from '@store/useMemory'
import { useStorage, useDeepStore } from '@store/useStorage'
import { useGetAvailable } from '@hooks/useGetAvailable'
import { FCSelect } from '@components/inputs/FCSelect'

import { CollapsibleItem } from '../components/CollapsibleItem'
import { MultiSelectorList, SelectorListMemo } from '../components/SelectorList'

const RaidOverride = () => {
const { t } = useTranslation()
const available = useMemory((s) => s.available.gyms)
const { available } = useGetAvailable('gyms')
const enabled = useStorage((s) => !!s.filters?.gyms?.raids)
const [filters, setFilters] = useDeepStore('filters.gyms.raidTier', 'all')

const raidTiers = React.useMemo(() => {
const availableTiers = available
.filter((x) => x.startsWith('r'))
.map((y) => +y.slice(1))
if (filters === 'all') return availableTiers

const storedTier = Number(filters)
if (Number.isNaN(storedTier) || availableTiers.includes(storedTier)) {
return availableTiers
}
return [storedTier, ...availableTiers]
}, [available, filters])

return (
<CollapsibleItem open={enabled}>
<ListItem
Expand All @@ -29,12 +43,7 @@ const RaidOverride = () => {
setFilters(e.target.value === 'all' ? 'all' : e.target.value)
}
>
{[
'all',
...available
.filter((x) => x.startsWith('r'))
.map((y) => +y.slice(1)),
].map((tier, i) => (
{['all', ...raidTiers].map((tier, i) => (
<MenuItem key={tier} dense value={tier}>
{t(i ? `raid_${tier}_plural` : 'disabled')}
</MenuItem>
Expand Down
Loading
Loading