Skip to content
Draft
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f1e8566
fix: sends a trimmed Pokemon payload to Poracle instead
Mygod Apr 3, 2026
21d7229
fix: review findings
Mygod Apr 3, 2026
14f5755
fix: avoid treating add-new Pokémon filters as updates
Mygod Apr 3, 2026
28ef291
fix: preserve no-iv Pokemon filter ranges
Mygod Apr 3, 2026
a2cd348
fix: preserve Pokemon webhook edit state
Mygod Apr 3, 2026
0526ea6
fix: keep Pokemon webhook UI flags local
Mygod Apr 3, 2026
2211aab
fix: preserve Pokemon create payload modes
Mygod Apr 3, 2026
5df4ff9
fix: preserve all-forms Pokemon mode state
Mygod Apr 3, 2026
701a88c
fix: separate Pokemon update serialization
Mygod Apr 3, 2026
677892a
fix: normalize Pokemon update payloads
Mygod Apr 3, 2026
75826c8
fix: preserve Pokemon create payload defaults
Mygod Apr 3, 2026
8020854
fix: copilot comments
Mygod Apr 3, 2026
0edb729
fix: fix Incl. No IV
Mygod Apr 3, 2026
dc9ff59
fix(webhooks): preserve no-iv pokemon ranges
Mygod Apr 3, 2026
e7cab4c
fix(webhooks): preserve pokemon weight defaults
Mygod Apr 3, 2026
8f85977
fix(webhooks): preserve omitted pokemon iv state
Mygod Apr 3, 2026
4c5abf9
fix(webhooks): handle nullable omitted iv bounds
Mygod Apr 3, 2026
a4b8e6b
fix(webhooks): preserve omitted pokemon defaults
Mygod Apr 3, 2026
6d93ac9
fix(webhooks): preserve pvp edit fields
Mygod Apr 4, 2026
194696f
fix(webhooks): clear disabled pokemon pvp filters
Mygod Apr 4, 2026
33a1f44
fix(webhooks): preserve omitted pokemon bounds
Mygod Apr 4, 2026
14dbebd
fix(webhooks): align pokemon webhook state
Mygod Apr 4, 2026
835983c
fix(webhooks): preserve no-iv mode until pvp
Mygod Apr 4, 2026
3596ece
fix(webhooks): exit pvp mode on range edits
Mygod Apr 4, 2026
12aca35
fix(webhooks): keep pvp size filters active
Mygod Apr 4, 2026
6ff4252
fix(webhooks): keep pvp size mode explicit
Mygod Apr 4, 2026
fb882d0
fix(webhooks): isolate pvp pokemon payloads
Mygod Apr 4, 2026
ef7c566
fix(webhooks): seed pvp fields in pokemon edits
Mygod Apr 4, 2026
5456fc8
fix(webhooks): reset pokemon pvp fields on disable
Mygod Apr 4, 2026
be5fe39
fix(webhooks): clear pokemon pvp exit paths
Mygod Apr 4, 2026
8b34f48
fix(webhooks): clear inactive pokemon pvp payloads
Mygod Apr 4, 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
9 changes: 7 additions & 2 deletions src/features/webhooks/Manage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,12 @@ export function Manage() {
React.useEffect(() => {
if (!addNew.open && addNew.save && category !== 'human') {
const { tempFilters } = useWebhookStore.getState()
const values = Poracle.processor(
const values = Poracle.toLocalState(
category,
Object.values(tempFilters || {}).filter((x) => x && x.enabled),
useWebhookStore.getState().context.ui[category].defaults,
)
const payload = Poracle.toApiPayload(
category,
Object.values(tempFilters || {}).filter((x) => x && x.enabled),
Comment thread
Mygod marked this conversation as resolved.
Outdated
useWebhookStore.getState().context.ui[category].defaults,
Expand All @@ -102,7 +107,7 @@ export function Manage() {
mutation: Query.webhook(category.toUpperCase()),
variables: {
category,
data: values,
data: payload,
status: 'POST',
},
refetchQueries: [ALL_PROFILES],
Expand Down
204 changes: 161 additions & 43 deletions src/features/webhooks/services/Poracle.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export class Poracle {
return reactMapFriendly
}

static processor(category, entries, defaults) {
static processPokemon(entries, defaults, includeUiState = false) {
const pvpFields = [
'pvp_ranking_league',
'pvp_ranking_best',
Expand All @@ -194,6 +194,70 @@ export class Poracle {
'pvpEntry',
]
const dupes = {}

return entries
.map((pokemon) => {
const normalized = pokemon.allForms
? { ...pokemon, form: defaults.form }
: pokemon
const fields = [
'uid',
'pokemon_id',
'form',
'clean',
'distance',
'min_time',
'template',
'profile_no',
'ping',
'gender',
'rarity',
'max_rarity',
'size',
'max_size',
]
const newPokemon = {}

if (pokemon.allForms) {
if (dupes[pokemon.pokemon_id]) {
return null
}
dupes[pokemon.pokemon_id] = true
}

if (pokemon.pvpEntry) {
fields.push(...pvpFields)
} else {
fields.push(
...Object.keys(normalized).filter(
(key) => !pvpFields.includes(key) && !ignoredFields.includes(key),
),
)
}

new Set(fields).forEach((field) => {
newPokemon[field] =
normalized[field] === undefined
? defaults[field]
: normalized[field]
})

if (includeUiState) {
newPokemon.allForms = !!pokemon.allForms
newPokemon.byDistance = !!pokemon.byDistance
newPokemon.noIv = !!pokemon.noIv
newPokemon.pvpEntry = !!pokemon.pvpEntry
newPokemon.xs = !!pokemon.xs
newPokemon.xl = !!pokemon.xl
}

return newPokemon
})
.filter((pokemon) => pokemon)
}

static processor(category, entries, defaults) {
const dupes = {}
switch (category) {
case 'egg':
return entries.map((egg) => ({
Expand Down Expand Up @@ -255,49 +319,103 @@ export class Poracle {
})
.filter((quest) => quest)
default:
return entries
.map((pkmn) => {
const fields = [
'pokemon_id',
'form',
'clean',
'distance',
'min_time',
'template',
'profile_no',
'gender',
'rarity',
'max_rarity',
'size',
'max_size',
]
const newPokemon = {}
if (pkmn.allForms) {
pkmn.form = 0
if (dupes[pkmn.pokemon_id]) {
return null
}
dupes[pkmn.pokemon_id] = true
}
if (pkmn.pvpEntry) {
fields.push(...pvpFields)
} else {
fields.push(
...Object.keys(pkmn).filter(
(key) =>
!pvpFields.includes(key) && !ignoredFields.includes(key),
),
)
}
new Set(fields).forEach(
(field) =>
(newPokemon[field] =
pkmn[field] === undefined ? defaults[field] : pkmn[field]),
)
return newPokemon
})
.filter((pokemon) => pokemon)
return Poracle.processPokemon(entries, defaults)
}
}

static toLocalState(category, entries, defaults) {
if (category !== 'pokemon') {
return Poracle.processor(category, entries, defaults)
}

return Poracle.processPokemon(entries, defaults, true)
}

static toUpdatePayload(category, entries, defaults) {
const processed = Poracle.toLocalState(category, entries, defaults)
if (category !== 'pokemon') {
return processed
}

const requiredFields = [
'uid',
'pokemon_id',
'form',
'profile_no',
'template',
]
const scalarFields = ['clean', 'distance', 'gender', 'min_time']
const rangeGroups = [
['min_cp', 'max_cp'],
['min_level', 'max_level'],
['atk', 'max_atk'],
['def', 'max_def'],
['sta', 'max_sta'],
['rarity', 'max_rarity'],
['size', 'max_size'],
['min_weight', 'max_weight'],
]
const pvpFields = [
'pvp_ranking_league',
'pvp_ranking_best',
'pvp_ranking_worst',
'pvp_ranking_min_cp',
'pvp_ranking_cap',
]
Comment thread
Mygod marked this conversation as resolved.
Outdated

return processed.map((pokemon) => {
const payload = {}

requiredFields.forEach((field) => {
if (pokemon[field] !== undefined) {
payload[field] = pokemon[field]
}
})

if (pokemon.ping !== undefined) {
payload.ping = pokemon.ping
}

scalarFields.forEach((field) => {
payload[field] =
pokemon[field] === undefined ? defaults[field] : pokemon[field]
})

payload.min_iv =
pokemon.min_iv === undefined ? defaults.min_iv : pokemon.min_iv
payload.max_iv =
pokemon.max_iv === undefined ? defaults.max_iv : pokemon.max_iv

rangeGroups.forEach(([low, high]) => {
payload[low] = pokemon[low] === undefined ? defaults[low] : pokemon[low]
payload[high] =
pokemon[high] === undefined ? defaults[high] : pokemon[high]
})

pvpFields.forEach((field) => {
payload[field] =
pokemon.pvpEntry && pokemon.pvp_ranking_league
? pokemon[field] === undefined
? defaults[field]
: pokemon[field]
: defaults[field]
})

return payload
})
}

static toApiPayload(category, entries, defaults) {
const processed = Poracle.toUpdatePayload(category, entries, defaults)
if (category !== 'pokemon') {
return processed
}

return processed.map((pokemon) => {
const payload = { ...pokemon }
delete payload.uid
return payload
})
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/features/webhooks/tiles/TrackedTile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,19 @@ export function TrackedTile({ index }) {
useWebhookStore.setState((prev) => ({
tempFilters: {
...prev.tempFilters,
[id]: { ...item, byDistance: !!item.distance },
[id]: { ...defaults, ...item, byDistance: !!item.distance },
},
}))
}
}, [advOpen, id, item])
}, [advOpen, defaults, id, item])

const onClose = React.useCallback(
(newFilter, save) => {
if (save) {
apolloClient.mutate({
mutation: webhookNodes[category.toUpperCase()],
variables: {
data: Poracle.processor(category, [newFilter], defaults),
data: Poracle.toUpdatePayload(category, [newFilter], defaults),
status: 'POST',
category,
},
Expand Down
Loading