From d5a9f38e4f3aab2caa9faf16881062e276402096 Mon Sep 17 00:00:00 2001 From: pjorritsma Date: Sat, 15 Jan 2022 23:14:40 +0100 Subject: [PATCH 01/77] Generate Area.json on startup --- package.json | 2 + public/geofence/geofence.json | 181 ++++++++++++++++++++++++++++ server/scripts/geofenceToGeoJSON.js | 70 +++++++++++ server/scripts/poracleToGeoJSON.js | 68 +++++++++++ 4 files changed, 321 insertions(+) create mode 100644 public/geofence/geofence.json create mode 100644 server/scripts/geofenceToGeoJSON.js create mode 100644 server/scripts/poracleToGeoJSON.js diff --git a/package.json b/package.json index d3ce6b704..ca55d2734 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,8 @@ "create-locales": "node server/scripts/createLocales.js", "missing-locales": "node server/scripts/createLocales.js --missing", "config-migrate": "node server/scripts/configMigration.js", + "create-area": "node server/scripts/geofenceToGeoJSON.js", + "create-area-poracle": "node server/scripts/poracleToGeoJSON.js", "console": "node --experimental-repl-await ./server/src/console.js", "migrate:make": "knex --knexfile server/knexfile.cjs migrate:make", "migrate:latest": "knex --knexfile server/knexfile.cjs migrate:latest", diff --git a/public/geofence/geofence.json b/public/geofence/geofence.json new file mode 100644 index 000000000..be7ac713c --- /dev/null +++ b/public/geofence/geofence.json @@ -0,0 +1,181 @@ +[ + { + "name": "New York", + "color": "#6CB1E1", + "id": 0, + "path": [ + [ + 40.6758460704592, + -74.0183327629713 + ], + [ + 40.6673832118379, + -74.0032265617995 + ], + [ + 40.6667321782243, + -73.9930985405592 + ], + [ + 40.6638675548225, + -73.9817688896803 + ], + [ + 40.6698570816073, + -73.971984191194 + ], + [ + 40.6612632449602, + -73.9785073235182 + ], + [ + 40.6604819321731, + -73.960997863069 + ], + [ + 40.6595703890216, + -73.9359353020338 + ], + [ + 40.6737630049163, + -73.9182541802077 + ], + [ + 40.6939399635959, + -73.9143059685378 + ], + [ + 40.730963376432, + -73.9388086668346 + ], + [ + 40.7539462208294, + -73.9434547762474 + ], + [ + 40.7677776617157, + -73.9427697204215 + ], + [ + 40.7763577594269, + -73.9439713500602 + ], + [ + 40.7818172447128, + -73.944486334191 + ], + [ + 40.7923449848895, + -73.9341866515738 + ], + [ + 40.8044303320442, + -73.9297234557731 + ], + [ + 40.8090857578706, + -73.9352091337489 + ], + [ + 40.819219447895, + -73.9352091337489 + ], + [ + 40.8288320306508, + -73.9352091337489 + ], + [ + 40.8351963525041, + -73.935037472372 + ], + [ + 40.8420795230808, + -73.9305742765712 + ], + [ + 40.8458454836873, + -73.9431055570888 + ], + [ + 40.8244156115839, + -73.9554651762294 + ], + [ + 40.7959616287814, + -73.9772661711024 + ], + [ + 40.7834848035422, + -73.9848192716884 + ], + [ + 40.7729556587662, + -73.9932306791591 + ], + [ + 40.7673654346462, + -73.9968355680751 + ], + [ + 40.7622948246655, + -73.9999254728602 + ], + [ + 40.752022403571, + -74.0078218962001 + ], + [ + 40.7257160733875, + -74.0104929617871 + ], + [ + 40.7125754713621, + -74.0158144644726 + ], + [ + 40.7041172764294, + -74.017874400996 + ], + [ + 40.7008638384784, + -74.0139261893261 + ], + [ + 40.7050282105779, + -74.0046564749707 + ], + [ + 40.7086718225791, + -73.9972750357617 + ], + [ + 40.7104284928515, + -73.9852587393749 + ], + [ + 40.7142669814306, + -73.9765040091503 + ], + [ + 40.7123152352296, + -73.9689079932202 + ], + [ + 40.7076308109205, + -73.9694015196789 + ], + [ + 40.7017748171234, + -73.9751414469708 + ], + [ + 40.7054186071131, + -73.979508083247 + ], + [ + 40.7033364658143, + -73.9939276389111 + ] + ] + } +] \ No newline at end of file diff --git a/server/scripts/geofenceToGeoJSON.js b/server/scripts/geofenceToGeoJSON.js new file mode 100644 index 000000000..8dedd61cf --- /dev/null +++ b/server/scripts/geofenceToGeoJSON.js @@ -0,0 +1,70 @@ +/** +* Credits: https://gist.github.com/moriakaice +* Editor: PJ0tterr +* Date: 15-01-2022 +*/ + +const fs = require('fs'); +const path = require('path'); + +// Set Path where for area.json +const configFolder = path.resolve(__dirname, '../../src/configs') +const geofencesFolder = path.resolve(__dirname, '../../public/geofence/geofence.json') + +if (!fs.existsSync(geofencesFolder)) { + // eslint-disable-next-line no-console + console.error('Error: Geofence directory does not exist:', geofencesFolder); + return; +} + +const geoJSON = { + type: 'FeatureCollection', + features: [], +}; + +fs.readdir(geofencesFolder, (err, files) => { + if (err) { + // eslint-disable-next-line no-console + console.error(err); + return; + } + // eslint-disable-next-line no-plusplus + for (let i = 0; i < files.length; i++) { + const file = path.resolve(geofencesFolder, files[i]); + // eslint-disable-next-line no-shadow + fs.readFile(file, 'utf8', (err, data) => { + if (err) { + // eslint-disable-next-line no-console + console.error(err); + return; + } + // eslint-disable-next-line no-console + console.log('Converting ini geofence file to geoJSON format', file); + const fences = data.match(/\[([^\]]+)\]([^[]*)/g); + fences.forEach(fence => { + const geofence = { type: 'Feature', + properties: { + name: '', + }, + geometry: { + type: 'Polygon', + coordinates: [[]], + } }; + // eslint-disable-next-line prefer-destructuring + geofence.properties.name = fence.match(/\[([^\]]+)\]/)[1]; + geofence.geometry.coordinates[0] = fence.match(/[0-9\-.]+,\s*[0-9\-.]+/g).map(point => [parseFloat(point.split(',')[1]), parseFloat(point.split(',')[0])]); + geofence.geometry.coordinates[0].push(geofence.geometry.coordinates[0][0]); + + geoJSON.features.push(geofence); + }); + fs.writeFile( + path.resolve(configFolder, 'areas.json'), + JSON.stringify(geoJSON, null, 2), + 'utf8', + () => { }, + ); + // eslint-disable-next-line no-console + console.log('areas.json file saved'); + }); + } +}); diff --git a/server/scripts/poracleToGeoJSON.js b/server/scripts/poracleToGeoJSON.js new file mode 100644 index 000000000..af35acf24 --- /dev/null +++ b/server/scripts/poracleToGeoJSON.js @@ -0,0 +1,68 @@ +/** +* Credits: https://gist.github.com/moriakaice +* Editor: PJ0tterr +* Date: 15-01-2022 +*/ + +const fs = require('fs'); +const path = require('path'); + +// Set Path where for area.json +const configFolder = path.resolve(__dirname, '../../src/configs') +const geofencesFolder = path.resolve(__dirname, '../../public/geofence/geofence.json') + +if (!fs.existsSync(geofencesFolder)) { + // eslint-disable-next-line no-console + console.error('Error: Geofence directory does not exist:', geofencesFolder); + return; +} + +const outGeoJSON = { + type: 'FeatureCollection', + features: [], +}; + +fs.readFile(geofencesFolder, 'utf8', (err, data) => { + if (err) { + // eslint-disable-next-line no-console + console.error(err); + return; + } + const inGeoJSON = JSON.parse(data); + if (inGeoJSON.length === 0) { + // eslint-disable-next-line no-console + console.error('Failed to parse poracle geofence file'); + return; + } + // eslint-disable-next-line no-plusplus + for (let i = 0; i < inGeoJSON.length; i++) { + const inGeofence = inGeoJSON[i]; + // eslint-disable-next-line no-console + console.log('Converting', inGeofence.name); + const outGeofence = { + type: 'Feature', + properties: { + name: inGeofence.name || '', + color: inGeofence.color || '#000000', + id: inGeofence.id || 0, + + }, + geometry: { + type: 'Polygon', + coordinates: [[]], + }, + }; + // eslint-disable-next-line no-plusplus + for (let j = 0; j < inGeofence.path.length; j++) { + const coord = inGeofence.path[j]; + inGeofence.path[j] = [coord[1], coord[0]]; + } + outGeofence.geometry.coordinates[0] = inGeofence.path; + outGeoJSON.features.push(outGeofence); + } + const outFilePath = path.resolve(path.dirname(configFolder), 'areas.json'); + fs.writeFile(outFilePath, JSON.stringify(outGeoJSON, null, 2), 'utf8', () => { + // eslint-disable-next-line no-console + console.log(`${outFilePath} file saved.`); + }); +}); From 10f932354bf1564484e984a6ce1347e1e8c8b632 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 16 Jan 2022 11:46:48 -0500 Subject: [PATCH 02/77] Add Gym Badge Support - Db migrations adds gym_badge table - Manually set gym badges from new menu in the popup - Gym badge specific permission - Sub menu for filtering by gym badges on the map - Version bump --- package.json | 4 +- public/base-locales/en.json | 9 +- server/src/configs/default.json | 10 +- server/src/configs/local.example.json | 4 + server/src/db/initialization.js | 3 + .../20220116023217_gym_tracking.cjs | 26 ++++ server/src/graphql/resolvers.js | 21 ++- server/src/graphql/scannerTypes.js | 1 + server/src/graphql/typeDefs.js | 1 + server/src/models/Badge.js | 23 +++ server/src/models/Gym.js | 34 ++++- server/src/models/User.js | 15 ++ server/src/models/index.js | 2 + .../defaultFilters/buildDefaultFilters.js | 2 + server/src/services/ui/clientOptions.js | 1 + server/src/services/ui/primary.js | 2 +- src/components/Map.jsx | 6 +- .../layout/drawer/MultiSelector.jsx | 29 ++++ src/components/layout/drawer/WithSubItems.jsx | 43 +++--- src/components/markers/gym.jsx | 133 ++++++++++++------ src/components/popups/Gym.jsx | 70 ++++++++- src/components/tiles/Gym.jsx | 23 ++- src/services/Query.js | 2 +- src/services/queries/gym.js | 1 + src/services/queries/user.js | 6 + 25 files changed, 374 insertions(+), 97 deletions(-) create mode 100644 server/src/db/migrations/20220116023217_gym_tracking.cjs create mode 100644 server/src/models/Badge.js create mode 100644 src/components/layout/drawer/MultiSelector.jsx diff --git a/package.json b/package.json index d3ce6b704..f540270d6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "reactmap", - "version": "1.0.14", + "version": "1.0.15", "description": "React based frontend map.", "main": "index.js", "author": "TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com>", @@ -16,7 +16,7 @@ "create-locales": "node server/scripts/createLocales.js", "missing-locales": "node server/scripts/createLocales.js --missing", "config-migrate": "node server/scripts/configMigration.js", - "console": "node --experimental-repl-await ./server/src/console.js", + "console": "node --experimental-repl-await ./server/scripts/console.js", "migrate:make": "knex --knexfile server/knexfile.cjs migrate:make", "migrate:latest": "knex --knexfile server/knexfile.cjs migrate:latest", "migrate:rollback": "knex --knexfile server/knexfile.cjs migrate:rollback" diff --git a/public/base-locales/en.json b/public/base-locales/en.json index 7589a1509..d002dc6ca 100644 --- a/public/base-locales/en.json +++ b/public/base-locales/en.json @@ -475,5 +475,12 @@ "pokemon_cell": "Pokemon's Location Could Vary", "timer_verified": "This Timer is Verified", "timer_unverified": "This Timer is Unverified", - "all": "All" + "all": "All", + "badge_0": "None", + "badge_1": "Bronze", + "badge_2": "Silver", + "badge_3": "Gold", + "gym_badge_menu": "Edit Gym Badge", + "gym_badges": "Gym Badges", + "gymBadgeDiamonds": "Show Gym Badges" } diff --git a/server/src/configs/default.json b/server/src/configs/default.json index c23425511..df354c755 100644 --- a/server/src/configs/default.json +++ b/server/src/configs/default.json @@ -178,7 +178,8 @@ "showExBadge": false, "showArBadge": false, "raidLevelBadges": false, - "raidsOr": true + "raidsOr": true, + "gymBadgeDiamonds": true }, "pokestops": { "clustering": true, @@ -239,7 +240,8 @@ "inBattle": false, "raids": true, "eggs": true, - "pokemon": true + "pokemon": true, + "gymBadges": false }, "nests": { "enabled": false, @@ -450,6 +452,10 @@ "donor": { "enabled": true, "roles": [] + }, + "gymBadges": { + "enabled": true, + "roles": [] } } }, diff --git a/server/src/configs/local.example.json b/server/src/configs/local.example.json index fc96e2d65..6a815db54 100644 --- a/server/src/configs/local.example.json +++ b/server/src/configs/local.example.json @@ -218,6 +218,10 @@ }, "donor": { "roles": [] + }, + "gymBadges": { + "enabled": true, + "roles": [] } } }, diff --git a/server/src/db/initialization.js b/server/src/db/initialization.js index 0ed865181..0c2c3ceb0 100644 --- a/server/src/db/initialization.js +++ b/server/src/db/initialization.js @@ -27,6 +27,9 @@ const connections = schemas.map(schema => Knex({ schemas.forEach((schema, index) => { try { schema.useFor.forEach(category => { + if (category === 'user') { + models.Badge.knex(connections[index]) + } const capital = `${category.charAt(0).toUpperCase()}${category.slice(1)}` models[capital].knex(connections[index]) }) diff --git a/server/src/db/migrations/20220116023217_gym_tracking.cjs b/server/src/db/migrations/20220116023217_gym_tracking.cjs new file mode 100644 index 000000000..2038d3296 --- /dev/null +++ b/server/src/db/migrations/20220116023217_gym_tracking.cjs @@ -0,0 +1,26 @@ +const { database: { settings: { userTableName } } } = require('../../services/config') +/** + * @typedef {import("knex")} Knex + */ + +/** + * @param {Knex} knex + */ +exports.up = async (knex) => knex.schema.createTable('gym_badges', table => { + table.bigIncrements('id') + table.bigInteger('user_id') + .references(`${userTableName}.id`) + .notNullable() + .index() + .unsigned() + table.string('gym_id') + table.integer('badge') + .unsigned() + .notNullable() + .defaultTo(0) +}) + +/** + * @param {Knex} knex + */ +exports.down = (knex) => knex.schema.dropTableIfExists('gym_badges') diff --git a/server/src/graphql/resolvers.js b/server/src/graphql/resolvers.js index 7d7f352cc..8e38463fb 100644 --- a/server/src/graphql/resolvers.js +++ b/server/src/graphql/resolvers.js @@ -4,7 +4,7 @@ const { raw } = require('objection') const config = require('../services/config') const { - Device, Gym, Pokemon, Pokestop, Portal, ScanCell, Spawnpoint, Weather, Nest, User, + Device, Gym, Pokemon, Pokestop, Portal, ScanCell, Spawnpoint, Weather, Nest, User, Badge, } = require('../models/index') const Utility = require('../services/Utility') const Fetch = require('../services/Fetch') @@ -32,7 +32,7 @@ module.exports = { gyms: (parent, args, { req }) => { const perms = req.user ? req.user.perms : req.session.perms if (perms?.gyms || perms?.raids) { - return Gym.getAllGyms(args, perms, Utility.dbSelection('gym').type === 'mad') + return Gym.getAllGyms(args, perms, Utility.dbSelection('gym').type === 'mad', req?.user?.id) } return [] }, @@ -311,5 +311,22 @@ module.exports = { .where('username', args.username) return Boolean(results.length) }, + setGymBadge: async (parent, args, { req }) => { + const perms = req.user ? req.user.perms : false + if (perms?.gymBadges) { + if (await Badge.query().where('gym_id', args.gymId).andWhere('user_id', req.user.id).first()) { + await Badge.query().where('gym_id', args.gymId).andWhere('user_id', req.user.id) + .update({ badge: args.badge }) + } else { + await Badge.query().insert({ + badge: args.badge, + gym_id: args.gymId, + user_id: req.user.id, + }) + } + return true + } + return false + }, }, } diff --git a/server/src/graphql/scannerTypes.js b/server/src/graphql/scannerTypes.js index 5663a5882..0313e70ff 100644 --- a/server/src/graphql/scannerTypes.js +++ b/server/src/graphql/scannerTypes.js @@ -42,6 +42,7 @@ module.exports = gql` raid_pokemon_gender: Int raid_pokemon_evolution: Int ar_scan_eligible: Boolean + badge: Int } type Nest { diff --git a/server/src/graphql/typeDefs.js b/server/src/graphql/typeDefs.js index eb68e7248..549479068 100644 --- a/server/src/graphql/typeDefs.js +++ b/server/src/graphql/typeDefs.js @@ -38,5 +38,6 @@ module.exports = gql` tutorial(tutorial: Boolean): Boolean strategy(strategy: String): Boolean checkUsername(username: String): Boolean + setGymBadge(gymId: String, badge: Int): Boolean } ` diff --git a/server/src/models/Badge.js b/server/src/models/Badge.js new file mode 100644 index 000000000..2550b8c52 --- /dev/null +++ b/server/src/models/Badge.js @@ -0,0 +1,23 @@ +const { Model } = require('objection') +const { database: { settings: { userTableName } } } = require('../services/config') + +module.exports = class Badge extends Model { + static get tableName() { + return 'gym_badges' + } + + static get relationMappings() { + // eslint-disable-next-line global-require + const User = require('./User') + return { + user: { + relation: Model.BelongsToOneRelation, + modelClass: User, + join: { + from: 'gym_badges.user_id', + to: `${userTableName}.id`, + }, + }, + } + } +} diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index 385eeb1a7..54959ff98 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -6,6 +6,7 @@ const { pokemon: masterfile } = require('../data/masterfile.json') const dbSelection = require('../services/functions/dbSelection') const getAreaSql = require('../services/functions/getAreaSql') const { api: { searchResultsLimit } } = require('../services/config') +const Badge = require('./Badge') module.exports = class Gym extends Model { static get tableName() { @@ -17,10 +18,10 @@ module.exports = class Gym extends Model { ? 'gym_id' : 'id' } - static async getAllGyms(args, perms, isMad) { - const { gyms: gymPerms, raids: raidPerms, areaRestrictions } = perms + static async getAllGyms(args, perms, isMad, userId) { + const { gyms: gymPerms, raids: raidPerms, areaRestrictions, gymBadges } = perms const { - onlyAllGyms, onlyRaids, onlyExEligible, onlyInBattle, onlyArEligible, onlyOrRaids, ts, + onlyAllGyms, onlyRaids, onlyExEligible, onlyInBattle, onlyArEligible, onlyOrRaids, onlyGymBadges, onlyBadge, ts, } = args.filters const safeTs = ts || Math.floor((new Date()).getTime() / 1000) const query = this.query() @@ -68,6 +69,13 @@ module.exports = class Gym extends Model { const teams = [] const eggs = [] const slots = [] + const actualBadge = onlyBadge === 'all' ? 'all' : onlyBadge && +onlyBadge.replace('badge_', '') + + const userBadges = onlyGymBadges && gymBadges && userId + ? await Badge.query() + .where('user_id', userId) + .andWhere('badge', ...(actualBadge === 'all' ? ['>', 0] : [actualBadge])) + : [] Object.keys(args.filters).forEach(gym => { switch (gym.charAt(0)) { @@ -82,6 +90,7 @@ module.exports = class Gym extends Model { default: raidBosses.add(gym.split('-')[0]); break } }) + if (!onlyOrRaids) raidBosses.add(0) const finalTeams = [] const finalSlots = { @@ -141,6 +150,9 @@ module.exports = class Gym extends Model { }) } } + if (userBadges.length) { + gym.orWhereIn(isMad ? 'gym_id' : 'id', userBadges.map(badge => badge.gym_id)) + } if (onlyRaids && raidPerms) { if (raidBosses.size) { gym.orWhere(raid => { @@ -170,22 +182,30 @@ module.exports = class Gym extends Model { const secondaryFilter = queryResults => { const filteredResults = [] + const userBadgeObj = Object.fromEntries(userBadges.map(b => [b.gym_id, b.badge])) for (let i = 0; i < queryResults.length; i += 1) { const gym = queryResults[i] - if (gym.availble_slots !== undefined) { gym.available_slots = gym.availble_slots } + if (userBadgeObj[gym.id]) { + gym.badge = userBadgeObj[gym.id] + } if (!gymPerms) { gym.team_id = 0 gym.available_slots = 6 } - if (!gym.raid_pokemon_id && (args.filters[`e${gym.raid_level}`] || args.filters[`r${gym.raid_level}`])) { + if (onlyRaids && !gym.raid_pokemon_id && (args.filters[`e${gym.raid_level}`] || args.filters[`r${gym.raid_level}`])) { filteredResults.push(gym) - } else if (args.filters[`${gym.raid_pokemon_id}-${gym.raid_pokemon_form}`] || args.filters[`r${gym.raid_level}`]) { + } else if (onlyRaids && (args.filters[`${gym.raid_pokemon_id}-${gym.raid_pokemon_form}`] || args.filters[`r${gym.raid_level}`])) { filteredResults.push(gym) - } else if (gymPerms && (onlyAllGyms || onlyArEligible || onlyExEligible || onlyInBattle)) { + } else if (gymPerms + && (onlyAllGyms + || (onlyArEligible && gym.ar_scan_eligible) + || (onlyExEligible && gym.ex_raid_eligible) + || (onlyInBattle && gym.in_battle) + || (userBadges.length && (actualBadge === 'all' || userBadgeObj[gym.id] === actualBadge)))) { if (args.filters[`t${gym.team_id}-0`]) { gym.raid_end_timestamp = null gym.raid_battle_timestamp = null diff --git a/server/src/models/User.js b/server/src/models/User.js index 5efb81d89..3ff63719e 100644 --- a/server/src/models/User.js +++ b/server/src/models/User.js @@ -13,4 +13,19 @@ module.exports = class User extends Model { .where({ [`${strategy}Id`]: userId }) .then(() => console.log(`[${botName}] Cleared ${strategy} perms for user ${userId}`)) } + + static get relationMappings() { + // eslint-disable-next-line global-require + const Badge = require('./Badge') + return { + badges: { + relation: Model.HasManyRelation, + modelClass: Badge, + join: { + from: `${userTableName}.id`, + to: 'gym_badges.user_id', + }, + }, + } + } } diff --git a/server/src/models/index.js b/server/src/models/index.js index 4e59eb07f..42727ab8a 100644 --- a/server/src/models/index.js +++ b/server/src/models/index.js @@ -1,3 +1,4 @@ +const Badge = require('./Badge') const Device = require('./Device') const Gym = require('./Gym') const Nest = require('./Nest') @@ -13,6 +14,7 @@ const Weather = require('./Weather') const { PokemonFilter, GenericFilter } = require('./Filters') module.exports = { + Badge, Device, Gym, Nest, diff --git a/server/src/services/defaultFilters/buildDefaultFilters.js b/server/src/services/defaultFilters/buildDefaultFilters.js index 35d7af63a..3febc32c3 100644 --- a/server/src/services/defaultFilters/buildDefaultFilters.js +++ b/server/src/services/defaultFilters/buildDefaultFilters.js @@ -24,6 +24,8 @@ module.exports = function buildDefault(perms) { exEligible: perms.gyms ? defaultFilters.gyms.exEligible : undefined, inBattle: perms.gyms ? defaultFilters.gyms.exEligible : undefined, arEligible: perms.gyms ? false : undefined, + gymBadges: perms.gymBadges ? defaultFilters.gyms.gymBadges : undefined, + badge: perms.gymBadges ? 'all' : undefined, filter: { ...buildGyms(perms, defaultFilters.gyms), ...pokemon.raids, diff --git a/server/src/services/ui/clientOptions.js b/server/src/services/ui/clientOptions.js index 713a0f5a7..72e6305a6 100644 --- a/server/src/services/ui/clientOptions.js +++ b/server/src/services/ui/clientOptions.js @@ -19,6 +19,7 @@ module.exports = function clientOptions(perms) { showArBadge: { type: 'bool', perm: ['gyms'] }, raidLevelBadges: { type: 'bool', perm: ['raids'] }, raidsOr: { type: 'bool', perm: ['raids'] }, + gymBadgeDiamonds: { type: 'bool', perm: ['gymBadges'] }, }, pokestops: { clustering: { type: 'bool', perm: ['pokestops', 'quests', 'invasions'] }, diff --git a/server/src/services/ui/primary.js b/server/src/services/ui/primary.js index 553f8a9d7..b0482424f 100644 --- a/server/src/services/ui/primary.js +++ b/server/src/services/ui/primary.js @@ -3,7 +3,7 @@ const { api: { pvp: { leagues } } } = require('../config') module.exports = function generateUi(filters, perms) { const ui = {} - const ignoredKeys = ['enabled', 'filter', 'showQuestSet'] + const ignoredKeys = ['enabled', 'filter', 'showQuestSet', 'badge'] // builds the initial categories for (const [key, value] of Object.entries(filters)) { diff --git a/src/components/Map.jsx b/src/components/Map.jsx index 83b5b61f5..0379fe2d0 100644 --- a/src/components/Map.jsx +++ b/src/components/Map.jsx @@ -95,8 +95,7 @@ export default function Map({ serverSettings: { config: { map: config, tileServe Icons={Icons} /> ) : ( - Object.entries({ ...ui, ...ui.wayfarer, ...ui.admin }).map(each => { - const [category, value] = each + Object.entries({ ...ui, ...ui.wayfarer, ...ui.admin }).map(([category, value]) => { let enabled = false switch (category) { @@ -110,7 +109,8 @@ export default function Map({ serverSettings: { config: { map: config, tileServe || (filters[category].raids && value.raids) || (filters[category].exEligible && value.exEligible) || (filters[category].inBattle && value.inBattle) - || (filters[category].arEligible && value.arEligible)) + || (filters[category].arEligible && value.arEligible) + || (filters[category].gymBadges && value.gymBadges)) && !webhookMode) { enabled = true } break diff --git a/src/components/layout/drawer/MultiSelector.jsx b/src/components/layout/drawer/MultiSelector.jsx new file mode 100644 index 000000000..792bc21fd --- /dev/null +++ b/src/components/layout/drawer/MultiSelector.jsx @@ -0,0 +1,29 @@ +import React from 'react' +import { ButtonGroup, Button } from '@material-ui/core' +import { useTranslation } from 'react-i18next' + +export default function MultiSelector({ filters, setFilters, category, filterKey, items }) { + const { t } = useTranslation() + return ( + + {items.map(item => ( + + ))} + + ) +} diff --git a/src/components/layout/drawer/WithSubItems.jsx b/src/components/layout/drawer/WithSubItems.jsx index 2a4f2c32f..3f3d4f061 100644 --- a/src/components/layout/drawer/WithSubItems.jsx +++ b/src/components/layout/drawer/WithSubItems.jsx @@ -1,10 +1,11 @@ import React from 'react' import { - Grid, Typography, Switch, ButtonGroup, Button, + Grid, Typography, Switch, } from '@material-ui/core' import { useTranslation } from 'react-i18next' import Utility from '@services/Utility' +import MultiSelector from './MultiSelector' export default function WithSubItems({ category, filters, setFilters, subItem, noScanAreaOverlay, enableQuestSetSelector, @@ -56,28 +57,26 @@ export default function WithSubItems({ {filterCategory} - {enableQuestSetSelector === true && category === 'pokestops' && subItem === 'quests' && filters.pokestops.quests === true && ( + {enableQuestSetSelector === true && category === 'pokestops' && subItem === 'quests' && filters[category].quests === true && ( - - {['with_ar', 'both', 'without_ar'].map(questSet => ( - - ))} - + + + )} + {category === 'gyms' && subItem === 'gymBadges' && filters[category].gymBadges === true && ( + + )} diff --git a/src/components/markers/gym.jsx b/src/components/markers/gym.jsx index 24d45e777..0e0f4fe8d 100644 --- a/src/components/markers/gym.jsx +++ b/src/components/markers/gym.jsx @@ -15,7 +15,7 @@ const getBadgeColor = (raidLevel) => { } } -export default function GymMarker(gym, hasHatched, hasRaid, filters, Icons, userSettings) { +export default function GymMarker(gym, hasHatched, hasRaid, filters, Icons, userSettings, badge) { const { in_battle, team_id, available_slots, raid_level, ex_raid_eligible, ar_scan_eligible, } = gym @@ -58,51 +58,92 @@ export default function GymMarker(gym, hasHatched, hasRaid, filters, Icons, user const ReactIcon = (
- - {Boolean(userSettings.showExBadge && ex_raid_eligible && !gymIcon.includes('_ex')) && ( - - )} - {Boolean(userSettings.showArBadge && ar_scan_eligible && !gymIcon.includes('_ar')) && ( - - )} - {Boolean(in_battle && !gymIcon.includes('_b')) && ( - + {(filters.gymBadges && userSettings.gymBadgeDiamonds && badge) ? ( + <> +
+ + + ) : ( + <> + + {Boolean(userSettings.showExBadge && ex_raid_eligible && !gymIcon.includes('_ex')) && ( + + )} + {Boolean(userSettings.showArBadge && ar_scan_eligible && !gymIcon.includes('_ar')) && ( + + )} + {Boolean(in_battle && !gymIcon.includes('_b')) && ( + + )} + {Boolean(filters.gymBadges && badge) && ( + { switch (badge) { case 1: return 'third'; case 2: return 'second'; default: return 'first' } })())} + style={{ + width: gymSize / 2, + height: 'auto', + bottom: 15 + gymMod.offsetY, + left: `${gymMod.offsetX * 10}%`, + transform: 'translateX(50%)', + }} + /> + )} + )} {raidIcon && ( state.auth) @@ -49,6 +54,8 @@ export default function GymPopup({ perms={perms} hasRaid={hasRaid} t={t} + badge={badge} + setBadge={setBadge} /> {perms.gyms && ( @@ -97,7 +104,7 @@ export default function GymPopup({ )} -
{ const hideList = useStatic(state => state.hideList) const setHideList = useStatic(state => state.setHideList) @@ -131,6 +138,7 @@ const MenuActions = ({ const setFilters = useStore(state => state.setFilters) const [anchorEl, setAnchorEl] = useState(false) + const [badgeMenu, setBadgeMenu] = useState(false) const addWebhook = useWebhook({ category: 'quickGym', selectedWebhook }) const { @@ -150,6 +158,11 @@ const MenuActions = ({ setHideList([...hideList, id]) } + const handleCloseBadge = (open) => { + setAnchorEl(null) + setBadgeMenu(open) + } + const excludeTeam = () => { setAnchorEl(null) const key = `t${team_id}-0` @@ -206,6 +219,9 @@ const MenuActions = ({ if (perms.gyms) { options.push({ name: 'exclude_team', action: excludeTeam }) + if (perms.gymBadges) { + options.push({ name: 'gym_badge_menu', action: () => handleCloseBadge(true) }) + } } if (perms.raids && hasRaid) { options.push( @@ -238,6 +254,15 @@ const MenuActions = ({ handleClose={handleClose} options={options} /> + + + ) } @@ -507,7 +532,7 @@ const Timer = ({ ) : null } -const Footer = ({ +const GymFooter = ({ gym, popups, setPopups, hasRaid, perms, Icons, }) => { const classes = useStyles() @@ -614,3 +639,38 @@ const ExtraInfo = ({ gym, t, ts }) => { ) } + +const BadgeSelection = ({ + gym, setBadgeMenu, t, badge, setBadge, +}) => { + const [setBadgeInDb] = useMutation(Query.user('setGymBadge')) + + return ( + <> +
+ + + {[0, 1, 2, 3].map(i => ( + + ))} + + +
setBadgeMenu(false), color: 'primary', align: 'right' }]} role="webhook_footer" /> + + ) +} diff --git a/src/components/tiles/Gym.jsx b/src/components/tiles/Gym.jsx index 98f545f76..3e5441ebb 100644 --- a/src/components/tiles/Gym.jsx +++ b/src/components/tiles/Gym.jsx @@ -1,5 +1,5 @@ /* eslint-disable camelcase */ -import React, { memo, useState, useRef } from 'react' +import React, { memo, useState, useRef, useEffect } from 'react' import { Marker, Popup, Circle } from 'react-leaflet' import useMarkerTimer from '@hooks/useMarkerTimer' @@ -25,6 +25,7 @@ const GymTile = ({ const markerRef = useRef({}) const [done, setDone] = useState(false) const [stateChange, setStateChange] = useState(false) + const [badge, setBadge] = useState(item.badge || 0) const { raid_battle_timestamp, raid_end_timestamp, raid_level, raid_pokemon_id, raid_pokemon_form, team_id, @@ -43,6 +44,14 @@ const GymTile = ({ useMarkerTimer(timerToDisplay, item.id, markerRef, '', ts, () => setStateChange(!stateChange)) useForcePopup(item.id, markerRef, params, setParams, done) + useEffect(() => { + if (filters.gymBadges) { + setBadge(item.badge || 0) + } else { + setBadge(0) + } + }, [filters.gymBadges, item.badge]) + return !excludeList.includes(`t${team_id}-0`) && ( { @@ -52,7 +61,7 @@ const GymTile = ({ } }} position={[item.lat, item.lon]} - icon={gymMarker(item, hasHatched, hasRaid, filters, Icons, userSettings)} + icon={gymMarker(item, hasHatched, hasRaid, filters, Icons, userSettings, badge)} > {((showTimer || userSettings.raidTimers) && hasRaid) && ( @@ -97,16 +108,18 @@ const areEqual = (prev, next) => { && prev.item.raid_pokemon_id === next.item.raid_pokemon_id && prev.item.raid_level === next.item.raid_level && prev.item.in_battle === next.item.in_battle - && raidLogic() - && prev.showTimer === next.showTimer + && prev.item.badge === next.item.badge + && (`badge_${prev.item.badge}` === next.filters.badge || next.filters.badge === 'all') && prev.item.team_id === next.item.team_id && prev.item.available_slots === next.item.available_slots + && raidLogic() + && prev.showTimer === next.showTimer + && prev.showCircles === next.showCircles && !next.excludeList.includes(`${prev.item.raid_pokemon_id}-${prev.item.raid_pokemon_form}`) && !next.excludeList.includes(`t${prev.item.team_id}-0`) && !next.excludeList.includes(`e${prev.item.raid_level}`) && Object.keys(prev.userIcons).every(key => prev.userIcons[key] === next.userIcons[key]) && Object.keys(prev.userSettings).every(key => prev.userSettings[key] === next.userSettings[key]) - && prev.showCircles === next.showCircles } export default memo(GymTile, areEqual) diff --git a/src/services/Query.js b/src/services/Query.js index b339a3643..d92d6ae0f 100644 --- a/src/services/Query.js +++ b/src/services/Query.js @@ -32,7 +32,7 @@ export default class Query { if (permObj[keyPerm]) query += keyPerm }) if (query === 'get' - && (filters.exEligible || filters.inBattle || filters.arEligible)) { + && (filters.exEligible || filters.inBattle || filters.arEligible || filters.gymBadges)) { query += 'Gyms' } diff --git a/src/services/queries/gym.js b/src/services/queries/gym.js index 8c3a78130..f82842e1a 100644 --- a/src/services/queries/gym.js +++ b/src/services/queries/gym.js @@ -21,6 +21,7 @@ const gym = gql` in_battle guarding_pokemon_id total_cp + badge } ` diff --git a/src/services/queries/user.js b/src/services/queries/user.js index cbcb750fe..ee0d58d29 100644 --- a/src/services/queries/user.js +++ b/src/services/queries/user.js @@ -17,3 +17,9 @@ mutation SetUsername($username: String!) { checkUsername(username: $username) } ` + +export const setGymBadge = gql` +mutation SetGymBadge($gymId: String!, $badge: Int!) { + setGymBadge(gymId: $gymId, badge: $badge) + } +` From d8febe9bbdf77fc9b342f6e9075860edc8187346 Mon Sep 17 00:00:00 2001 From: ReuschelCGN <82573872+ReuschelCGN@users.noreply.github.com> Date: Tue, 18 Jan 2022 12:15:48 +0100 Subject: [PATCH 03/77] Update de.json --- public/base-locales/de.json | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/public/base-locales/de.json b/public/base-locales/de.json index 441df0bd6..0a216a8ea 100644 --- a/public/base-locales/de.json +++ b/public/base-locales/de.json @@ -277,7 +277,7 @@ "weather_subtitle": "Zeigt Wetterinformationen im Spiel für jede Zelle an", "user_profile": "Benutzer-Profil", "candy": "Bonbon", - "show_ex_badge": "Zeige EX Abzeichen", + "show_ex_badge": "EX Abzeichen anzeigen", "search": "Suche", "global_search_quests": "Füge den Name der Belohnung ein...", "global_search_pokestops": "Füge den Name des Pokestop ein...", @@ -328,7 +328,7 @@ "popup_pokemon_data_width": 11, "login_button": 10, "join_button": 10, - "show_dex_num_in_popup": "Zeige Pokedex # in Popup", + "show_dex_num_in_popup": "Pokedex # in Popup anzeigen", "popup": "Popup", "pvp_level": "Level {{level}} PVP Stats", "pvp_mega": "Mega PVP Stats", @@ -390,7 +390,7 @@ "webhook_selection": "{{name}} Auswahl", "message_of_the_day": "Nachricht des Tages", "has_quest_indicator": "Alternative Farbe für Stops mit Quests", - "show_ar_badge": "Zeige AR Symbol", + "show_ar_badge": "AR Symbol anzeigen", "raids_or": "Raidbosse separat filtern", "general": "Allgemeines", "link_global_and_advanced": "Verknüpfe Global und Erweitert", @@ -474,5 +474,12 @@ "all": "Alle", "with_ar": "Mit AR", "without_ar": "Ohne AR", - "both": "Beide" + "both": "Beide", + "badge_0": "keiner", + "badge_1": "Bronze", + "badge_2": "Silber", + "badge_3": "Gold", + "gym_badge_menu": "bearbeite Arenaorden", + "gym_badges": "Arenaorden", + "gymBadgeDiamonds": "Arenaorden anzeigen" } From a180c755cfc47c53e7eb6342bf63fe7426ba4007 Mon Sep 17 00:00:00 2001 From: ReuschelCGN <82573872+ReuschelCGN@users.noreply.github.com> Date: Tue, 18 Jan 2022 12:44:35 +0100 Subject: [PATCH 04/77] Update de.json --- public/base-locales/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/base-locales/de.json b/public/base-locales/de.json index 0a216a8ea..3d0d24ce4 100644 --- a/public/base-locales/de.json +++ b/public/base-locales/de.json @@ -479,7 +479,7 @@ "badge_1": "Bronze", "badge_2": "Silber", "badge_3": "Gold", - "gym_badge_menu": "bearbeite Arenaorden", + "gym_badge_menu": "Arenaorden bearbeiten", "gym_badges": "Arenaorden", "gymBadgeDiamonds": "Arenaorden anzeigen" } From 9c0c4c3720a46a800fd60f3589c46cd9f9624e93 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Tue, 18 Jan 2022 23:14:02 -0500 Subject: [PATCH 05/77] Part 2 - Fix Migration - camelCase instead of snake, - Add createdAt, updatedAt - New badge types - Get all badges resolver - Massive overhaul to user profile page - List all gym badges - Bronze/Silver/Gold count - Fly to gym location upon image click - Edit from user profile page as well --- .../20220116023217_gym_tracking.cjs | 20 +- server/src/graphql/mapTypes.js | 11 + server/src/graphql/resolvers.js | 19 +- server/src/graphql/typeDefs.js | 1 + server/src/models/Badge.js | 13 +- server/src/models/Gym.js | 42 ++- server/src/models/User.js | 2 +- src/assets/scss/main.scss | 12 + src/components/layout/Nav.jsx | 6 +- src/components/layout/dialogs/UserProfile.jsx | 333 ++++++++++++------ src/components/popups/Gym.jsx | 8 +- src/services/Query.js | 3 + src/services/queries/gym.js | 14 + 13 files changed, 359 insertions(+), 125 deletions(-) diff --git a/server/src/db/migrations/20220116023217_gym_tracking.cjs b/server/src/db/migrations/20220116023217_gym_tracking.cjs index 2038d3296..367def008 100644 --- a/server/src/db/migrations/20220116023217_gym_tracking.cjs +++ b/server/src/db/migrations/20220116023217_gym_tracking.cjs @@ -6,21 +6,31 @@ const { database: { settings: { userTableName } } } = require('../../services/co /** * @param {Knex} knex */ -exports.up = async (knex) => knex.schema.createTable('gym_badges', table => { +exports.up = async (knex) => knex.schema.createTable('gymBadges', table => { table.bigIncrements('id') - table.bigInteger('user_id') + .primary() + table.bigInteger('userId') .references(`${userTableName}.id`) + .unsigned() .notNullable() .index() - .unsigned() - table.string('gym_id') + table.string('gymId') + .notNullable() table.integer('badge') .unsigned() .notNullable() .defaultTo(0) + table.bigInteger('createdAt') + .unsigned() + .notNullable() + .defaultTo(0) + table.bigInteger('updatedAt') + .unsigned() + .notNullable() + .defaultTo(0) }) /** * @param {Knex} knex */ -exports.down = (knex) => knex.schema.dropTableIfExists('gym_badges') +exports.down = (knex) => knex.schema.dropTableIfExists('gymBadges') diff --git a/server/src/graphql/mapTypes.js b/server/src/graphql/mapTypes.js index 58a3f7b0b..8a84f4b76 100644 --- a/server/src/graphql/mapTypes.js +++ b/server/src/graphql/mapTypes.js @@ -1,6 +1,17 @@ const { gql } = require('apollo-server-express') module.exports = gql` + + type Badge { + id: String + name: String + url: String + lat: Float + lon: Float + badge: Int + deleted: Boolean + } + type Geocoder { latitude: Float longitude: Float diff --git a/server/src/graphql/resolvers.js b/server/src/graphql/resolvers.js index 8e38463fb..799e75463 100644 --- a/server/src/graphql/resolvers.js +++ b/server/src/graphql/resolvers.js @@ -12,10 +12,17 @@ const Fetch = require('../services/Fetch') module.exports = { JSON: GraphQLJSON, Query: { + badges: (parent, args, { req }) => { + const perms = req.user ? req.user.perms : req.session.perms + if (perms?.gymBadges) { + return Gym.getGymBadges(Utility.dbSelection('gym').type === 'mad', req?.user?.id) + } + return [] + }, devices: (parent, args, { req }) => { const perms = req.user ? req.user.perms : req.session.perms if (perms?.devices) { - return Device.getAllDevices({ areaRestrictions: [] }, Utility.dbSelection('device').type === 'mad') + return Device.getAllDevices(perms, Utility.dbSelection('device').type === 'mad') } return [] }, @@ -313,15 +320,15 @@ module.exports = { }, setGymBadge: async (parent, args, { req }) => { const perms = req.user ? req.user.perms : false - if (perms?.gymBadges) { - if (await Badge.query().where('gym_id', args.gymId).andWhere('user_id', req.user.id).first()) { - await Badge.query().where('gym_id', args.gymId).andWhere('user_id', req.user.id) + if (perms?.gymBadges && req?.user?.id) { + if (await Badge.query().where('gymId', args.gymId).andWhere('userId', req.user.id).first()) { + await Badge.query().where('gymId', args.gymId).andWhere('userId', req.user.id) .update({ badge: args.badge }) } else { await Badge.query().insert({ badge: args.badge, - gym_id: args.gymId, - user_id: req.user.id, + gymId: args.gymId, + userId: req.user.id, }) } return true diff --git a/server/src/graphql/typeDefs.js b/server/src/graphql/typeDefs.js index 549479068..b2651340a 100644 --- a/server/src/graphql/typeDefs.js +++ b/server/src/graphql/typeDefs.js @@ -11,6 +11,7 @@ module.exports = gql` scalar JSON type Query { + badges: [Badge] devices: [Device] geocoder(search: String, name: String): [Geocoder] gyms(minLat: Float, maxLat: Float, minLon: Float, maxLon: Float, ts: Int, filters: JSON): [Gym] diff --git a/server/src/models/Badge.js b/server/src/models/Badge.js index 2550b8c52..4a71a9a64 100644 --- a/server/src/models/Badge.js +++ b/server/src/models/Badge.js @@ -3,7 +3,16 @@ const { database: { settings: { userTableName } } } = require('../services/confi module.exports = class Badge extends Model { static get tableName() { - return 'gym_badges' + return 'gymBadges' + } + + $beforeInsert() { + this.createdAt = Math.floor(Date.now() / 1000) + this.updatedAt = Math.floor(Date.now() / 1000) + } + + $beforeUpdate() { + this.updatedAt = Math.floor(Date.now() / 1000) } static get relationMappings() { @@ -14,7 +23,7 @@ module.exports = class Badge extends Model { relation: Model.BelongsToOneRelation, modelClass: User, join: { - from: 'gym_badges.user_id', + from: 'gymBadges.userId', to: `${userTableName}.id`, }, }, diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index 54959ff98..3c2e6a416 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -73,7 +73,7 @@ module.exports = class Gym extends Model { const userBadges = onlyGymBadges && gymBadges && userId ? await Badge.query() - .where('user_id', userId) + .where('userId', userId) .andWhere('badge', ...(actualBadge === 'all' ? ['>', 0] : [actualBadge])) : [] @@ -151,7 +151,7 @@ module.exports = class Gym extends Model { } } if (userBadges.length) { - gym.orWhereIn(isMad ? 'gym_id' : 'id', userBadges.map(badge => badge.gym_id)) + gym.orWhereIn(isMad ? 'gym.gym_id' : 'id', userBadges.map(badge => badge.gymId)) } if (onlyRaids && raidPerms) { if (raidBosses.size) { @@ -182,7 +182,7 @@ module.exports = class Gym extends Model { const secondaryFilter = queryResults => { const filteredResults = [] - const userBadgeObj = Object.fromEntries(userBadges.map(b => [b.gym_id, b.badge])) + const userBadgeObj = Object.fromEntries(userBadges.map(b => [b.gymId, b.badge])) for (let i = 0; i < queryResults.length; i += 1) { const gym = queryResults[i] @@ -305,4 +305,40 @@ module.exports = class Gym extends Model { } return query } + + static async getGymBadges(isMad, userId) { + const userGyms = await Badge.query() + .select(['gymId', 'badge']) + .where('userId', userId) + .andWhere('badge', '>', 0) + + const query = this.query() + .select([ + 'name', + 'url', + isMad ? 'gym.gym_id AS id' : 'id', + isMad ? 'latitude AS lat' : 'lat', + isMad ? 'longitude AS lon' : 'lon', + isMad ? 'enabled' : 'deleted', + ]) + + if (isMad) { + query.leftJoin('gymdetails', 'gym.gym_id', 'gymdetails.gym_id') + } + + const results = await query + .whereIn(isMad ? 'gym_id' : 'id', userGyms.map(gym => gym.gymId)) + + return results.map(gym => { + if (typeof gym.enabled === 'boolean') { + gym.deleted = !gym.enabled + } + const gymBadge = userGyms.find(userGym => userGym.gymId === gym.id) + + if (gymBadge) { + gym.badge = gymBadge.badge + } + return gym + }) + } } diff --git a/server/src/models/User.js b/server/src/models/User.js index 3ff63719e..d2269323a 100644 --- a/server/src/models/User.js +++ b/server/src/models/User.js @@ -23,7 +23,7 @@ module.exports = class User extends Model { modelClass: Badge, join: { from: `${userTableName}.id`, - to: 'gym_badges.user_id', + to: 'gymBadges.userId', }, }, } diff --git a/src/assets/scss/main.scss b/src/assets/scss/main.scss index 1a37bad25..49fdb0075 100644 --- a/src/assets/scss/main.scss +++ b/src/assets/scss/main.scss @@ -370,3 +370,15 @@ img { input[type="time"]::-webkit-calendar-picker-indicator { filter: invert(100%); } + +.badge_3 { + color: #ffd700; +} + +.badge_2 { + color: #c0c0c0; +} + +.badge_1 { + color: #cd7f32; +} diff --git a/src/components/layout/Nav.jsx b/src/components/layout/Nav.jsx index ba3132053..4acd1c026 100644 --- a/src/components/layout/Nav.jsx +++ b/src/components/layout/Nav.jsx @@ -129,7 +129,11 @@ export default function Nav({ fullScreen={isMobile} fullWidth={!isMobile} > - + ) : ( state.auth) const { map: { excludeList, rolesLinkName, rolesLink } } = useStatic(state => state.config) - const PermPage = ( - - ) + const [tab, setTab] = useState(0) + + const handleTabChange = (event, newValue) => { + setTab(newValue) + } return ( <>
setUserProfile(false)} /> - {auth?.strategy?.includes('local') ? ( - - ) : PermPage} + + + {['profile', 'access'].map(each => ( + + ))} + + + +
+ + +
+
+ + +
{ +const LinkProfiles = ({ auth, t }) => { const setAuth = useStatic(state => state.setAuth) const { map: { discordAuthUrl, telegramAuthUrl, telegramBotEnvRef } } = useStatic(state => state.config) - const [tab, setTab] = useState(0) const [refreshing, setRefreshing] = useState(false) const [setWebhookStrategy] = useMutation(Query.user('setWebhookStrategy')) - const handleTabChange = (event, newValue) => { - setTab(newValue) - } - if (refreshing) { setTimeout(() => window.location.reload(), 2000) } return ( <> - - - {['profile', 'access'].map(each => ( - - ))} - - - - - {auth.methods.includes('discord') && ( - - {auth.discordId - ? {t('discord_linked')} - : } - - )} - {auth.methods.includes('telegram') && ( - - {auth.telegramId - ? {t('telegram_linked')} - : } + + {['discord', 'telegram'].map((method, i) => { + const Component = i + ? + : + return ( + + {auth[`${method}Id`] + ? {t(`${method}_linked`)}! + : Component} - )} + ) + })} + {(auth.discordId && auth.telegramId) && ( - + {t('select_webhook_strategy')} - + - - - - {PermPage} - + )} + {refreshing && } ) @@ -172,46 +179,164 @@ const ProfilePermissions = ({ perms, excludeList, t }) => ( } return ( - - {!perms[perm] &&
} - {perm !== 'areaRestrictions' && perm !== 'webhooks' ? ( - - ) : ( - - {perms[perm].map(area => ( - - - {Utility.getProperName(area)} - - - ))} - - )} - - - {t(Utility.camelToSnake(perm))} - - - {t(`${Utility.camelToSnake(perm)}_subtitle`)} - - - + ) })} ) + +const PermCard = ({ perms, perm, t }) => ( + + {!perms[perm] &&
} + {perm !== 'areaRestrictions' && perm !== 'webhooks' ? ( + + ) : ( + + {perms[perm].map(area => ( + + + {Utility.getProperName(area)} + + + ))} + + )} + + + {t(Utility.camelToSnake(perm))} + + + {t(`${Utility.camelToSnake(perm)}_subtitle`)} + + + +) + +const GymBadges = ({ isMobile, t }) => { + const { data } = useQuery(Query.gyms('badges')) + const Icons = useStatic(s => s.Icons) + const map = useMap() + + let gold = 0 + let silver = 0 + let bronze = 0 + + if (data?.badges) { + data.badges.forEach(gym => { + switch (gym.badge) { + case 3: gold += 1; break + case 2: silver += 1; break + case 1: bronze += 1; break + default: + } + }) + } + + return data ? ( + + + + {t('gym_badges')} + + + {[bronze, silver, gold].map((count, i) => ( + + + {t(`badge_${i + 1}`)}: {count} + + + ))} + + + + + ) : null +} + +const BadgeTile = ({ data, rowIndex, columnIndex, style }) => { + const { badges, columnCount, Icons, t, map } = data + const item = badges[rowIndex * columnCount + columnIndex] + const [badge, setBadge] = useState(item.badge) + const [badgeMenu, setBadgeMenu] = useState(false) + + return item ? ( + + {item.deleted &&
} + setBadgeMenu(true)} + > + + + map.flyTo([item.lat, item.lon], 16)}> + + {badge && ( + + )} + + + + {item.name || t('unknown_gym')} + + + + + + + ) : null +} diff --git a/src/components/popups/Gym.jsx b/src/components/popups/Gym.jsx index 93f63eef0..a19939248 100644 --- a/src/components/popups/Gym.jsx +++ b/src/components/popups/Gym.jsx @@ -640,11 +640,12 @@ const ExtraInfo = ({ gym, t, ts }) => { ) } -const BadgeSelection = ({ +export const BadgeSelection = ({ gym, setBadgeMenu, t, badge, setBadge, }) => { - const [setBadgeInDb] = useMutation(Query.user('setGymBadge')) - + const [setBadgeInDb] = useMutation(Query.user('setGymBadge'), { + refetchQueries: ['GetBadgeInfo'], + }) return ( <>
@@ -653,6 +654,7 @@ const BadgeSelection = ({ {[0, 1, 2, 3].map(i => (
+ + + setWebhookAlert({ open: false, severity: 'info', message: '' })} From 12f9f3dfe8bac9a54385a4094b4f76045f77312d Mon Sep 17 00:00:00 2001 From: kamieniarz Date: Fri, 21 Jan 2022 01:55:20 +0100 Subject: [PATCH 21/77] Create ResetFilters.jsx --- .../layout/dialogs/ResetFilters.jsx | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/components/layout/dialogs/ResetFilters.jsx diff --git a/src/components/layout/dialogs/ResetFilters.jsx b/src/components/layout/dialogs/ResetFilters.jsx new file mode 100644 index 000000000..defa4d75c --- /dev/null +++ b/src/components/layout/dialogs/ResetFilters.jsx @@ -0,0 +1,42 @@ +import React, { useState } from 'react' +import { + Button, Typography, Divider, DialogContent, +} from '@material-ui/core' +import { useTranslation } from 'react-i18next' +import Header from '../general/Header' +import Footer from '../general/Footer' +import { Link, Redirect } from 'react-router-dom' + +export default function ResetFilters({ setResetFilters }) { + const { t } = useTranslation() + const [redirect, setRedirect] = useState(false) + if (redirect) { + return + } + return ( + <> +
+ + + {t('filters_reset_text')} + +
+ +
+ + + +
+
+
setResetFilters(false), color: 'primary', align: 'right' }]} role="webhook_footer" /> + + ) +} From 5b92a3826282c2bf08447b7b6bbe12ef3c781d6e Mon Sep 17 00:00:00 2001 From: kamieniarz Date: Fri, 21 Jan 2022 01:55:39 +0100 Subject: [PATCH 22/77] Update Settings.jsx --- src/components/layout/drawer/Settings.jsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/components/layout/drawer/Settings.jsx b/src/components/layout/drawer/Settings.jsx index 02a11f931..eb775dc36 100644 --- a/src/components/layout/drawer/Settings.jsx +++ b/src/components/layout/drawer/Settings.jsx @@ -2,7 +2,7 @@ import React, { useState } from 'react' import { FormControl, Grid, InputLabel, MenuItem, Select, Button, } from '@material-ui/core' -import { Link, Redirect } from 'react-router-dom' +import { Link } from 'react-router-dom' import { useTranslation } from 'react-i18next' import { useStore, useStatic } from '@hooks/useStore' @@ -16,6 +16,7 @@ export default function Settings({ Icons }) { const setStaticIcons = useStatic(state => state.setIcons) const setUserProfile = useStatic(state => state.setUserProfile) const setFeedback = useStatic(state => state.setFeedback) + const setResetFilters = useStatic(state => state.setResetFilters) const setTutorial = useStore(state => state.setTutorial) const settings = useStore(state => state.settings) @@ -23,8 +24,6 @@ export default function Settings({ Icons }) { const icons = useStore(state => state.icons) const setIcons = useStore(state => state.setIcons) - const [redirect, setRedirect] = useState(false) - const handleChange = event => { setSettings({ ...settings, @@ -68,9 +67,6 @@ export default function Settings({ Icons }) { setTimeout(() => window.location.reload(), 1500) } - if (redirect) { - return - } return ( setRedirect(true)} + onClick={() => setResetFilters(true)} > {t('reset_filters')} From f45d0318f0deed7bf19c9d68422d05cd0d65d3a4 Mon Sep 17 00:00:00 2001 From: kamieniarz Date: Fri, 21 Jan 2022 01:55:58 +0100 Subject: [PATCH 23/77] Update useStore.js --- src/hooks/useStore.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hooks/useStore.js b/src/hooks/useStore.js index 82b4f0b79..3aeb02208 100644 --- a/src/hooks/useStore.js +++ b/src/hooks/useStore.js @@ -92,6 +92,8 @@ const useStatic = create(set => ({ setUserProfile: (userProfile) => set({ userProfile }), feedback: false, setFeedback: (feedback) => set({ feedback }), + resetfilters: false, + setResetFilters: (resetfilters) => set({ resetfilters }), })) export { useStore, useStatic } From 7ca64ac6f1c0aa986efe0bed7d87e697127961c7 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Fri, 21 Jan 2022 00:48:31 -0500 Subject: [PATCH 24/77] Update Caching and Join Tables - Join tables on the backend for slight performance increase when querying all badges from user profile page - Extract BadgeSelection to its own file, better practice etc - Update fetch policy for badges in the user profile --- server/src/models/Gym.js | 31 +++++------- .../layout/dialogs/BadgeSelection.jsx | 47 +++++++++++++++++++ src/components/layout/dialogs/UserProfile.jsx | 7 +-- src/components/popups/Gym.jsx | 47 +------------------ 4 files changed, 65 insertions(+), 67 deletions(-) create mode 100644 src/components/layout/dialogs/BadgeSelection.jsx diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index b80636475..1e094a633 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -5,9 +5,11 @@ const fetchRaids = require('../services/api/fetchRaids') const { pokemon: masterfile } = require('../data/masterfile.json') const dbSelection = require('../services/functions/dbSelection') const getAreaSql = require('../services/functions/getAreaSql') -const { api: { searchResultsLimit } } = require('../services/config') +const { api: { searchResultsLimit }, database: { schemas } } = require('../services/config') const Badge = require('./Badge') +const gymBadgeDb = schemas.find(x => x.useFor.includes('user'))?.database + module.exports = class Gym extends Model { static get tableName() { return 'gym' @@ -307,38 +309,29 @@ module.exports = class Gym extends Model { } static async getGymBadges(isMad, userId) { - const userGyms = await Badge.query() - .select(['gymId', 'badge']) - .where('userId', userId) - .andWhere('badge', '>', 0) - const query = this.query() .select([ 'name', 'url', - isMad ? 'gym.gym_id AS id' : 'id', + isMad ? 'gym.gym_id AS id' : 'gym.id', isMad ? 'latitude AS lat' : 'lat', isMad ? 'longitude AS lon' : 'lon', isMad ? 'enabled' : 'deleted', + 'badge', + 'createdAt', + 'updatedAt', ]) + .leftJoin(`${gymBadgeDb}.gymBadges`, isMad ? 'gym.gym_id' : 'gym.id', 'gymBadges.gymId') + .orderBy('updatedAt') + .where('userId', userId) + .andWhere('badge', '>', 0) if (isMad) { query.leftJoin('gymdetails', 'gym.gym_id', 'gymdetails.gym_id') } const results = await query - .whereIn(isMad ? 'gym.gym_id' : 'id', userGyms.map(gym => gym.gymId)) - - return results.map(gym => { - if (typeof gym.enabled === 'boolean') { - gym.deleted = !gym.enabled - } - const gymBadge = userGyms.find(userGym => userGym.gymId === gym.id) - if (gymBadge) { - gym.badge = gymBadge.badge - } - return gym - }) + return isMad ? results.map(gym => gym.deleted = !gym.enabled) : results } } diff --git a/src/components/layout/dialogs/BadgeSelection.jsx b/src/components/layout/dialogs/BadgeSelection.jsx new file mode 100644 index 000000000..8d227850f --- /dev/null +++ b/src/components/layout/dialogs/BadgeSelection.jsx @@ -0,0 +1,47 @@ +import React from 'react' +import { DialogContent, ButtonGroup, Button } from '@material-ui/core' +import { useTranslation } from 'react-i18next' +import { useMutation } from '@apollo/client' + +import Query from '@services/Query' + +import Header from '../general/Header' +import Footer from '../general/Footer' + +export default function BadgeSelection({ gym, setBadgeMenu, badge, setBadge }) { + const { t } = useTranslation() + + const [setBadgeInDb] = useMutation(Query.user('setGymBadge'), { + refetchQueries: ['GetBadgeInfo'], + }) + return ( + <> +
setBadgeMenu(false)} /> + + + {[0, 1, 2, 3].map(i => ( + + ))} + + +
setBadgeMenu(false), color: 'primary', align: 'right' }]} role="webhook_footer" /> + + ) +} diff --git a/src/components/layout/dialogs/UserProfile.jsx b/src/components/layout/dialogs/UserProfile.jsx index b2b9e9314..572067c09 100644 --- a/src/components/layout/dialogs/UserProfile.jsx +++ b/src/components/layout/dialogs/UserProfile.jsx @@ -25,7 +25,7 @@ import { useStatic } from '@hooks/useStore' import Utility from '@services/Utility' import Query from '@services/Query' -import { BadgeSelection } from '@components/popups/Gym' +import BadgeSelection from './BadgeSelection' import Header from '../general/Header' import Footer from '../general/Footer' import TabPanel from '../general/TabPanel' @@ -229,7 +229,9 @@ const PermCard = ({ perms, perm, t }) => ( ) const GymBadges = ({ isMobile, t }) => { - const { data } = useQuery(Query.gyms('badges')) + const { data } = useQuery(Query.gyms('badges'), { + fetchPolicy: 'network-only', + }) const Icons = useStatic(s => s.Icons) const map = useMap() @@ -333,7 +335,6 @@ const BadgeTile = ({ data, rowIndex, columnIndex, style }) => { @@ -639,41 +634,3 @@ const ExtraInfo = ({ gym, t, ts }) => { ) } - -export const BadgeSelection = ({ - gym, setBadgeMenu, t, badge, setBadge, -}) => { - const [setBadgeInDb] = useMutation(Query.user('setGymBadge'), { - refetchQueries: ['GetBadgeInfo'], - }) - return ( - <> -
- - - {[0, 1, 2, 3].map(i => ( - - ))} - - -
setBadgeMenu(false), color: 'primary', align: 'right' }]} role="webhook_footer" /> - - ) -} From a4e3e3eeae6c2bbfd9501a645575aa983416e07d Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Fri, 21 Jan 2022 01:06:05 -0500 Subject: [PATCH 25/77] Custom Table Name --- server/src/configs/default.json | 1 + server/src/db/migrations/20220116023217_gym_tracking.cjs | 8 +++++--- server/src/models/Badge.js | 8 +++++--- server/src/models/Gym.js | 7 +++++-- server/src/models/User.js | 6 ++++-- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/server/src/configs/default.json b/server/src/configs/default.json index df354c755..37a1b317a 100644 --- a/server/src/configs/default.json +++ b/server/src/configs/default.json @@ -313,6 +313,7 @@ "database": { "settings": { "userTableName": "users", + "gymBadgeTableName": "gymBadges", "sessionTableName": "session", "migrationTableName": "knex_migrations", "hideOldQuests": false, diff --git a/server/src/db/migrations/20220116023217_gym_tracking.cjs b/server/src/db/migrations/20220116023217_gym_tracking.cjs index 367def008..77cc95eaa 100644 --- a/server/src/db/migrations/20220116023217_gym_tracking.cjs +++ b/server/src/db/migrations/20220116023217_gym_tracking.cjs @@ -1,4 +1,6 @@ -const { database: { settings: { userTableName } } } = require('../../services/config') +const { + database: { settings: { userTableName, gymBadgeTableName } }, +} = require('../../services/config') /** * @typedef {import("knex")} Knex */ @@ -6,7 +8,7 @@ const { database: { settings: { userTableName } } } = require('../../services/co /** * @param {Knex} knex */ -exports.up = async (knex) => knex.schema.createTable('gymBadges', table => { +exports.up = async (knex) => knex.schema.createTable(gymBadgeTableName, table => { table.bigIncrements('id') .primary() table.bigInteger('userId') @@ -33,4 +35,4 @@ exports.up = async (knex) => knex.schema.createTable('gymBadges', table => { /** * @param {Knex} knex */ -exports.down = (knex) => knex.schema.dropTableIfExists('gymBadges') +exports.down = (knex) => knex.schema.dropTableIfExists(gymBadgeTableName) diff --git a/server/src/models/Badge.js b/server/src/models/Badge.js index 4a71a9a64..b532ef254 100644 --- a/server/src/models/Badge.js +++ b/server/src/models/Badge.js @@ -1,9 +1,11 @@ const { Model } = require('objection') -const { database: { settings: { userTableName } } } = require('../services/config') +const { + database: { settings: { userTableName, gymBadgeTableName } }, +} = require('../services/config') module.exports = class Badge extends Model { static get tableName() { - return 'gymBadges' + return gymBadgeTableName } $beforeInsert() { @@ -23,7 +25,7 @@ module.exports = class Badge extends Model { relation: Model.BelongsToOneRelation, modelClass: User, join: { - from: 'gymBadges.userId', + from: `${gymBadgeTableName}.userId`, to: `${userTableName}.id`, }, }, diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index 1e094a633..dd4d65f8a 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -5,7 +5,10 @@ const fetchRaids = require('../services/api/fetchRaids') const { pokemon: masterfile } = require('../data/masterfile.json') const dbSelection = require('../services/functions/dbSelection') const getAreaSql = require('../services/functions/getAreaSql') -const { api: { searchResultsLimit }, database: { schemas } } = require('../services/config') +const { + api: { searchResultsLimit }, + database: { schemas, settings: { gymBadgeTableName } }, +} = require('../services/config') const Badge = require('./Badge') const gymBadgeDb = schemas.find(x => x.useFor.includes('user'))?.database @@ -321,7 +324,7 @@ module.exports = class Gym extends Model { 'createdAt', 'updatedAt', ]) - .leftJoin(`${gymBadgeDb}.gymBadges`, isMad ? 'gym.gym_id' : 'gym.id', 'gymBadges.gymId') + .leftJoin(`${gymBadgeDb}.${gymBadgeTableName}`, isMad ? 'gym.gym_id' : 'gym.id', `${gymBadgeTableName}.gymId`) .orderBy('updatedAt') .where('userId', userId) .andWhere('badge', '>', 0) diff --git a/server/src/models/User.js b/server/src/models/User.js index d2269323a..c14889c7d 100644 --- a/server/src/models/User.js +++ b/server/src/models/User.js @@ -1,6 +1,8 @@ /* eslint-disable no-console */ const { Model } = require('objection') -const { database: { settings: { userTableName } } } = require('../services/config') +const { + database: { settings: { userTableName, gymBadgeTableName } }, +} = require('../services/config') module.exports = class User extends Model { static get tableName() { @@ -23,7 +25,7 @@ module.exports = class User extends Model { modelClass: Badge, join: { from: `${userTableName}.id`, - to: 'gymBadges.userId', + to: `${gymBadgeTableName}.userId`, }, }, } From e85ef345936b9e7c69f198c82e99bbdd74155cdf Mon Sep 17 00:00:00 2001 From: kamieniarz Date: Fri, 21 Jan 2022 12:05:55 +0100 Subject: [PATCH 26/77] Update ResetFilters.jsx --- src/components/layout/dialogs/ResetFilters.jsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/layout/dialogs/ResetFilters.jsx b/src/components/layout/dialogs/ResetFilters.jsx index defa4d75c..55dfd84ef 100644 --- a/src/components/layout/dialogs/ResetFilters.jsx +++ b/src/components/layout/dialogs/ResetFilters.jsx @@ -5,11 +5,12 @@ import { import { useTranslation } from 'react-i18next' import Header from '../general/Header' import Footer from '../general/Footer' -import { Link, Redirect } from 'react-router-dom' +import { Redirect } from 'react-router-dom' export default function ResetFilters({ setResetFilters }) { const { t } = useTranslation() const [redirect, setRedirect] = useState(false) + if (redirect) { return } @@ -29,7 +30,12 @@ export default function ResetFilters({ setResetFilters }) { variant="contained" color="primary" size="small" - onClick={() => { setRedirect(true); setResetFilters(false) }} + onClick={() => + { + setRedirect(true) + setResetFilters(false) + } + } > {t('confirm_filters_reset')} From 509e655618c2b01768566b554d72a5bdf092edcf Mon Sep 17 00:00:00 2001 From: kamieniarz Date: Fri, 21 Jan 2022 12:06:15 +0100 Subject: [PATCH 27/77] Update Nav.jsx --- src/components/layout/Nav.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/layout/Nav.jsx b/src/components/layout/Nav.jsx index 0745a3d29..b9b6065fa 100644 --- a/src/components/layout/Nav.jsx +++ b/src/components/layout/Nav.jsx @@ -214,7 +214,7 @@ export default function Nav({ open={resetfilters} maxWidth={isMobile ? 'sm' : 'xs'} > - +
Date: Sat, 22 Jan 2022 03:03:39 +0000 Subject: [PATCH 28/77] Bump node-fetch from 2.6.1 to 3.1.1 Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 3.1.1. - [Release notes](https://github.com/node-fetch/node-fetch/releases) - [Changelog](https://github.com/node-fetch/node-fetch/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v3.1.1) --- updated-dependencies: - dependency-name: node-fetch dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 48 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index d3ce6b704..1b8962187 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "lru-cache": "^6.0.0", "morgan": "^1.10.0", "mysql2": "^2.3.3", - "node-fetch": "^2.6.1", + "node-fetch": "^3.1.1", "node-geocoder": "^3.27.0", "nodes2ts": "^2.0.0", "objection": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index 437025ffb..bb8875395 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3016,6 +3016,11 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +data-uri-to-buffer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b" + integrity sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA== + db-errors@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/db-errors/-/db-errors-0.2.3.tgz#a6a38952e00b20e790f2695a6446b3c65497ffa2" @@ -3752,6 +3757,14 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fetch-blob@^3.1.2, fetch-blob@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.1.4.tgz#e8c6567f80ad7fc22fd302e7dcb72bafde9c1717" + integrity sha512-Eq5Xv5+VlSrYWEqKrusxY1C3Hm/hjeAsCGVG3ft7pZahlUAChpGZT/Ms1WmSLnEAisEXszjzu/s+ce6HZB2VHA== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -3847,6 +3860,13 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -5317,6 +5337,11 @@ node-addon-api@^3.1.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== +node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + node-emoji@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" @@ -5324,23 +5349,27 @@ node-emoji@^1.10.0: dependencies: lodash.toarray "^4.4.0" -node-fetch@2.6.1, node-fetch@^2.6.1: +node-fetch@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== -node-fetch@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.2.tgz#986996818b73785e47b1965cc34eb093a1d464d0" - integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA== - -node-fetch@^2.6.5: +node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.5: version "2.6.6" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== dependencies: whatwg-url "^5.0.0" +node-fetch@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.1.1.tgz#d0d9607e455b3087e3092b821b5b1f1ebf4c2147" + integrity sha512-SMk+vKgU77PYotRdWzqZGTZeuFKlsJ0hu4KPviQKkfY+N3vn2MIzr0rvpnYpR8MtB3IEuhlEcuOLbGvLRlA+yg== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.3" + formdata-polyfill "^4.0.10" + node-geocoder@^3.27.0: version "3.27.0" resolved "https://registry.yarnpkg.com/node-geocoder/-/node-geocoder-3.27.0.tgz#56fe360ab3a8e54050be41dc82a980bf99456a49" @@ -7655,6 +7684,11 @@ watchpack@^2.2.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +web-streams-polyfill@^3.0.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz#a6b74026b38e4885869fb5c589e90b95ccfc7965" + integrity sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" From c705e2747bdd6ae1976704a715ec9616e799f0ff Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Fri, 21 Jan 2022 23:00:07 -0500 Subject: [PATCH 29/77] Fixes - Doesn't left join if the badges db is on a different host than the gym db - Apollo merge fn --- server/src/models/Gym.js | 14 +++++++++++--- src/services/apollo.js | 5 +++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index dd4d65f8a..5557738d8 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -11,8 +11,8 @@ const { } = require('../services/config') const Badge = require('./Badge') -const gymBadgeDb = schemas.find(x => x.useFor.includes('user'))?.database - +const gymBadgeDb = schemas.find(x => x.useFor.includes('user')) +const gymDb = schemas.find(x => x.useFor.includes('gym')) module.exports = class Gym extends Model { static get tableName() { return 'gym' @@ -324,11 +324,19 @@ module.exports = class Gym extends Model { 'createdAt', 'updatedAt', ]) - .leftJoin(`${gymBadgeDb}.${gymBadgeTableName}`, isMad ? 'gym.gym_id' : 'gym.id', `${gymBadgeTableName}.gymId`) .orderBy('updatedAt') .where('userId', userId) .andWhere('badge', '>', 0) + if (gymBadgeDb.host === gymDb.host) { + query.leftJoin(`${gymBadgeDb.database}.${gymBadgeTableName}`, isMad ? 'gym.gym_id' : 'gym.id', `${gymBadgeTableName}.gymId`) + } else { + const userGyms = await Badge.query() + .select(['gymId', 'badge']) + .where('userId', userId) + .andWhere('badge', '>', 0) + query.whereIn(isMad ? 'gym.gym_id' : 'id', userGyms.map(gym => gym.gymId)) + } if (isMad) { query.leftJoin('gymdetails', 'gym.gym_id', 'gymdetails.gym_id') } diff --git a/src/services/apollo.js b/src/services/apollo.js index d280ac2b0..70805307a 100644 --- a/src/services/apollo.js +++ b/src/services/apollo.js @@ -25,6 +25,11 @@ export default new ApolloClient({ return incoming }, }, + badges: { + merge(existing, incoming) { + return incoming + }, + }, }, }, SearchQuest: { From 78dd514224aa77ca5e108dbcf24535f5e4b096d9 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sat, 22 Jan 2022 09:02:18 -0500 Subject: [PATCH 30/77] Node Fetch Issue Fix --- package.json | 2 +- yarn.lock | 46 +++++++--------------------------------------- 2 files changed, 8 insertions(+), 40 deletions(-) diff --git a/package.json b/package.json index 1b8962187..b0790d9a9 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "lru-cache": "^6.0.0", "morgan": "^1.10.0", "mysql2": "^2.3.3", - "node-fetch": "^3.1.1", + "node-fetch": "2", "node-geocoder": "^3.27.0", "nodes2ts": "^2.0.0", "objection": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index bb8875395..536ddebd1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3016,11 +3016,6 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-uri-to-buffer@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b" - integrity sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA== - db-errors@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/db-errors/-/db-errors-0.2.3.tgz#a6a38952e00b20e790f2695a6446b3c65497ffa2" @@ -3757,14 +3752,6 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -fetch-blob@^3.1.2, fetch-blob@^3.1.3: - version "3.1.4" - resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.1.4.tgz#e8c6567f80ad7fc22fd302e7dcb72bafde9c1717" - integrity sha512-Eq5Xv5+VlSrYWEqKrusxY1C3Hm/hjeAsCGVG3ft7pZahlUAChpGZT/Ms1WmSLnEAisEXszjzu/s+ce6HZB2VHA== - dependencies: - node-domexception "^1.0.0" - web-streams-polyfill "^3.0.3" - file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -3860,13 +3847,6 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" -formdata-polyfill@^4.0.10: - version "4.0.10" - resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" - integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== - dependencies: - fetch-blob "^3.1.2" - forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -5337,11 +5317,6 @@ node-addon-api@^3.1.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== -node-domexception@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" - integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== - node-emoji@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" @@ -5349,6 +5324,13 @@ node-emoji@^1.10.0: dependencies: lodash.toarray "^4.4.0" +node-fetch@2: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + node-fetch@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -5361,15 +5343,6 @@ node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.5: dependencies: whatwg-url "^5.0.0" -node-fetch@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.1.1.tgz#d0d9607e455b3087e3092b821b5b1f1ebf4c2147" - integrity sha512-SMk+vKgU77PYotRdWzqZGTZeuFKlsJ0hu4KPviQKkfY+N3vn2MIzr0rvpnYpR8MtB3IEuhlEcuOLbGvLRlA+yg== - dependencies: - data-uri-to-buffer "^4.0.0" - fetch-blob "^3.1.3" - formdata-polyfill "^4.0.10" - node-geocoder@^3.27.0: version "3.27.0" resolved "https://registry.yarnpkg.com/node-geocoder/-/node-geocoder-3.27.0.tgz#56fe360ab3a8e54050be41dc82a980bf99456a49" @@ -7684,11 +7657,6 @@ watchpack@^2.2.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -web-streams-polyfill@^3.0.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz#a6b74026b38e4885869fb5c589e90b95ccfc7965" - integrity sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA== - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" From bd8b870f39fee99a61f12264c2a4c5e8fb2ee16c Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sat, 22 Jan 2022 09:14:27 -0500 Subject: [PATCH 31/77] Update Gym.js --- server/src/models/Gym.js | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index 5557738d8..2b6c6bd99 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -314,35 +314,46 @@ module.exports = class Gym extends Model { static async getGymBadges(isMad, userId) { const query = this.query() .select([ + '*', 'name', 'url', isMad ? 'gym.gym_id AS id' : 'gym.id', isMad ? 'latitude AS lat' : 'lat', isMad ? 'longitude AS lon' : 'lon', isMad ? 'enabled' : 'deleted', - 'badge', - 'createdAt', - 'updatedAt', ]) - .orderBy('updatedAt') - .where('userId', userId) - .andWhere('badge', '>', 0) + + if (isMad) { + query.leftJoin('gymdetails', 'gym.gym_id', 'gymdetails.gym_id') + } if (gymBadgeDb.host === gymDb.host) { query.leftJoin(`${gymBadgeDb.database}.${gymBadgeTableName}`, isMad ? 'gym.gym_id' : 'gym.id', `${gymBadgeTableName}.gymId`) - } else { - const userGyms = await Badge.query() - .select(['gymId', 'badge']) .where('userId', userId) .andWhere('badge', '>', 0) - query.whereIn(isMad ? 'gym.gym_id' : 'id', userGyms.map(gym => gym.gymId)) - } - if (isMad) { - query.leftJoin('gymdetails', 'gym.gym_id', 'gymdetails.gym_id') + .orderBy('updatedAt') + const results = await query + return isMad ? results.map(gym => gym.deleted = !gym.enabled) : results } + const userGyms = await Badge.query() + .select(['gymId', 'badge']) + .where('userId', userId) + .andWhere('badge', '>', 0) + const results = await query + .whereIn(isMad ? 'gym.gym_id' : 'gym.id', userGyms.map(gym => gym.gymId)) - return isMad ? results.map(gym => gym.deleted = !gym.enabled) : results + return results.map(gym => { + if (typeof gym.enabled === 'boolean') { + gym.deleted = !gym.enabled + } + const gymBadge = userGyms.find(userGym => userGym.gymId === gym.id) + + if (gymBadge) { + gym.badge = gymBadge.badge + } + return gym + }) } } From 8f2fffe76979a6c620fd1700f3393ee2524c4f5a Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sat, 22 Jan 2022 11:42:54 -0500 Subject: [PATCH 32/77] Fix Sorting for plebs - Fixes sorting if gym badges aren't joined to gyms - Fixes tutorial flash --- server/src/models/Gym.js | 27 +++++++++++--------- src/components/layout/Nav.jsx | 47 ++++++++++++++++------------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index 2b6c6bd99..4badac899 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -315,8 +315,6 @@ module.exports = class Gym extends Model { const query = this.query() .select([ '*', - 'name', - 'url', isMad ? 'gym.gym_id AS id' : 'gym.id', isMad ? 'latitude AS lat' : 'lat', isMad ? 'longitude AS lon' : 'lon', @@ -344,16 +342,21 @@ module.exports = class Gym extends Model { const results = await query .whereIn(isMad ? 'gym.gym_id' : 'gym.id', userGyms.map(gym => gym.gymId)) - return results.map(gym => { - if (typeof gym.enabled === 'boolean') { - gym.deleted = !gym.enabled - } - const gymBadge = userGyms.find(userGym => userGym.gymId === gym.id) + return results + .map(gym => { + if (typeof gym.enabled === 'boolean') { + gym.deleted = !gym.enabled + } + const gymBadge = userGyms.find(userGym => userGym.gymId === gym.id) - if (gymBadge) { - gym.badge = gymBadge.badge - } - return gym - }) + if (gymBadge) { + gym.badge = gymBadge.badge + gym.updatedAt = gymBadge.updatedAt + gym.createdAt = gymBadge.createdAt + } + return gym + }) + .sort((a, b) => a.updatedAt - b.updatedAt) + .reverse() } } diff --git a/src/components/layout/Nav.jsx b/src/components/layout/Nav.jsx index 4acd1c026..6b81f4c92 100644 --- a/src/components/layout/Nav.jsx +++ b/src/components/layout/Nav.jsx @@ -123,31 +123,28 @@ export default function Nav({ setDonorPage={setDonorPage} /> )} - {userProfile ? ( - - - - ) : ( - - - - )} + + + + + + Date: Sat, 22 Jan 2022 12:16:40 -0500 Subject: [PATCH 33/77] Add Query Limits - Query limits for Gyms, Nests, Pokemon, Pokestops, Portals, ScanCells, and Spawnpoints - checkForUpdates adds instruction updates to console - Re-introduction of noScanAreaOverlay to config - packageSource added to config --- server/scripts/configMigration.js | 1 + server/src/configs/default.json | 13 ++++++++++++- server/src/configs/local.example.json | 1 + server/src/models/Gym.js | 4 ++-- server/src/models/Nest.js | 4 ++-- server/src/models/Pokemon.js | 6 +++--- server/src/models/Pokestop.js | 6 +++--- server/src/models/Portal.js | 4 ++-- server/src/models/ScanCell.js | 3 ++- server/src/models/Spawnpoint.js | 3 ++- server/src/services/checkForUpdates.js | 7 ++++++- server/src/services/config.js | 3 --- 12 files changed, 36 insertions(+), 19 deletions(-) diff --git a/server/scripts/configMigration.js b/server/scripts/configMigration.js index cd11440d5..027b66ca8 100644 --- a/server/scripts/configMigration.js +++ b/server/scripts/configMigration.js @@ -47,6 +47,7 @@ const convertMapObject = (obj) => obj ? ({ enableTutorial: obj?.enableTutorial, enableUserProfile: obj?.enableUserProfile, enableQuestSetSelector: obj?.enableQuestSetSelector, + noScanAreaOverlay: obj?.noScanAreaOverlay, }, theme: obj?.theme, clustering: { diff --git a/server/src/configs/default.json b/server/src/configs/default.json index c23425511..80771d14f 100644 --- a/server/src/configs/default.json +++ b/server/src/configs/default.json @@ -1,6 +1,7 @@ { "interface": "0.0.0.0", "port": 8080, + "packageSource": "git", "devOptions": { "enabled": false, "graphiql": false, @@ -21,6 +22,15 @@ "raids": true, "nests": false }, + "queryLimits": { + "pokemon": 20000, + "pokestops": 5000, + "gyms": 5000, + "portals": 5000, + "spawnpoints": 10000, + "nests": 2500, + "scanCells": 5000 + }, "pvp": { "leagues": [ { @@ -98,7 +108,8 @@ "forceTutorial": true, "enableTutorial": true, "enableUserProfile": true, - "enableQuestSetSelector": false + "enableQuestSetSelector": false, + "noScanAreaOverlay": false }, "theme": { "style": "dark", diff --git a/server/src/configs/local.example.json b/server/src/configs/local.example.json index fc96e2d65..141e356c6 100644 --- a/server/src/configs/local.example.json +++ b/server/src/configs/local.example.json @@ -1,6 +1,7 @@ { "interface": "0.0.0.0", "port": 8080, + "packageSource": "git/docker", "api": { "sessionSecret": "98ki^e72~!@#(85o3kXLI*#c9wu5l!Zx", "reactMapSecret": "You Should Change Me", diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index 385eeb1a7..1f82979be 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -5,7 +5,7 @@ const fetchRaids = require('../services/api/fetchRaids') const { pokemon: masterfile } = require('../data/masterfile.json') const dbSelection = require('../services/functions/dbSelection') const getAreaSql = require('../services/functions/getAreaSql') -const { api: { searchResultsLimit } } = require('../services/config') +const { api: { searchResultsLimit, queryLimits } } = require('../services/config') module.exports = class Gym extends Model { static get tableName() { @@ -197,7 +197,7 @@ module.exports = class Gym extends Model { } return filteredResults } - return secondaryFilter(await query) + return secondaryFilter(await query.limit(queryLimits.gyms)) } static async getAvailableRaidBosses(isMad) { diff --git a/server/src/models/Nest.js b/server/src/models/Nest.js index e9058701e..101899902 100644 --- a/server/src/models/Nest.js +++ b/server/src/models/Nest.js @@ -3,7 +3,7 @@ const i18next = require('i18next') const { pokemon: masterfile } = require('../data/masterfile.json') const getAreaSql = require('../services/functions/getAreaSql') const { pokemon: masterPkmn } = require('../data/masterfile.json') -const { api: { searchResultsLimit } } = require('../services/config') +const { api: { searchResultsLimit, queryLimits } } = require('../services/config') module.exports = class Nest extends Model { static get tableName() { @@ -29,7 +29,7 @@ module.exports = class Nest extends Model { if (areaRestrictions?.length) { getAreaSql(query, areaRestrictions) } - const results = await query + const results = await query.limit(queryLimits.nests) const fixedForms = queryResults => { const returnedResults = [] diff --git a/server/src/models/Pokemon.js b/server/src/models/Pokemon.js index d544b935e..f86e9345a 100644 --- a/server/src/models/Pokemon.js +++ b/server/src/models/Pokemon.js @@ -4,7 +4,7 @@ const Ohbem = require('ohbem') const { pokemon: masterfile } = require('../data/masterfile.json') const legacyFilter = require('../services/legacyFilter') const { - api: { pvp: { minCp: pvpMinCp, leagues, reactMapHandlesPvp, levels } }, + api: { pvp: { minCp: pvpMinCp, leagues, reactMapHandlesPvp, levels }, queryLimits }, } = require('../services/config') const dbSelection = require('../services/functions/dbSelection') const getAreaSql = require('../services/functions/getAreaSql') @@ -258,7 +258,7 @@ module.exports = class Pokemon extends Model { getAreaSql(query, areaRestrictions, isMad, 'pokemon') } - const results = await query + const results = await query.limit(queryLimits.pokemon) const finalResults = [] const pvpResults = [] const listOfIds = [] @@ -319,7 +319,7 @@ module.exports = class Pokemon extends Model { if (areaRestrictions?.length) { getAreaSql(pvpQuery, areaRestrictions, isMad, 'pokemon') } - pvpResults.push(...await pvpQuery) + pvpResults.push(...await pvpQuery.limit(queryLimits.pokemon - results.length)) } // filter pokes with pvp data diff --git a/server/src/models/Pokestop.js b/server/src/models/Pokestop.js index 280197df3..e739de816 100644 --- a/server/src/models/Pokestop.js +++ b/server/src/models/Pokestop.js @@ -6,7 +6,7 @@ const fetchQuests = require('../services/api/fetchQuests') const dbSelection = require('../services/functions/dbSelection') const getAreaSql = require('../services/functions/getAreaSql') const { - api: { searchResultsLimit }, + api: { searchResultsLimit, queryLimits }, database: { settings }, map, } = require('../services/config') @@ -112,7 +112,7 @@ module.exports = class Pokestop extends Model { // returns everything if all pokestops are on if (onlyAllPokestops && pokestopPerms) { - const results = await query + const results = await query.limit(queryLimits.pokestops) const normalized = isMad ? this.mapMAD(results, safeTs) : this.mapRDM(results, safeTs) return this.secondaryFilter(normalized, args.filters, isMad, midnight) } @@ -247,7 +247,7 @@ module.exports = class Pokestop extends Model { }) } }) - const results = await query + const results = await query.limit(queryLimits.pokestops) const normalized = isMad ? this.mapMAD(results, safeTs) : this.mapRDM(results, safeTs) return this.secondaryFilter(normalized, args.filters, isMad, midnight) } diff --git a/server/src/models/Portal.js b/server/src/models/Portal.js index dc7ae8709..5251b15d7 100644 --- a/server/src/models/Portal.js +++ b/server/src/models/Portal.js @@ -1,7 +1,7 @@ const { Model } = require('objection') const getAreaSql = require('../services/functions/getAreaSql') const { - api: { searchResultsLimit, portalUpdateLimit }, + api: { searchResultsLimit, portalUpdateLimit, queryLimits }, } = require('../services/config') module.exports = class Portal extends Model { @@ -18,7 +18,7 @@ module.exports = class Portal extends Model { if (areaRestrictions?.length) { getAreaSql(query, areaRestrictions) } - return query + return query.limit(queryLimits.portals) } static async search(args, perms, isMad, distance) { diff --git a/server/src/models/ScanCell.js b/server/src/models/ScanCell.js index 0b6b79800..9f961eae1 100644 --- a/server/src/models/ScanCell.js +++ b/server/src/models/ScanCell.js @@ -2,6 +2,7 @@ const { Model, ref } = require('objection') const dbSelection = require('../services/functions/dbSelection') const getPolyVector = require('../services/functions/getPolyVector') const getAreaSql = require('../services/functions/getAreaSql') +const { api: { queryLimits } } = require('../services/config') module.exports = class ScanCell extends Model { static get tableName() { @@ -20,7 +21,7 @@ module.exports = class ScanCell extends Model { if (areaRestrictions?.length) { getAreaSql(query, areaRestrictions, isMad, 's2cell') } - const results = await query + const results = await query.limit(queryLimits.scanCells) return results.map(cell => ({ ...cell, polygon: getPolyVector(cell.id, 'polygon'), diff --git a/server/src/models/Spawnpoint.js b/server/src/models/Spawnpoint.js index 8fb4e787b..952ad4ef9 100644 --- a/server/src/models/Spawnpoint.js +++ b/server/src/models/Spawnpoint.js @@ -1,6 +1,7 @@ const { Model, raw } = require('objection') const dbSelection = require('../services/functions/dbSelection') const getAreaSql = require('../services/functions/getAreaSql') +const { api: { queryLimits } } = require('../services/config') module.exports = class Spawnpoint extends Model { static get tableName() { @@ -32,6 +33,6 @@ module.exports = class Spawnpoint extends Model { if (areaRestrictions?.length) { getAreaSql(query, areaRestrictions, isMad) } - return query + return query.limit(queryLimits.spawnpoints) } } diff --git a/server/src/services/checkForUpdates.js b/server/src/services/checkForUpdates.js index 3cb701fb3..bc789f613 100644 --- a/server/src/services/checkForUpdates.js +++ b/server/src/services/checkForUpdates.js @@ -2,6 +2,8 @@ const { exec } = require('child_process') const fs = require('fs') +let isDocker = false + try { exec('git branch --show-current', async (err, stdout) => { try { @@ -10,6 +12,9 @@ try { if (!gitRef && (err || typeof stdout !== 'string' || !stdout.trim())) { throw new Error('Unable to get current branch', err) } + if (typeof gitRef === 'string' && gitRef.trim()) { + isDocker = true + } const branch = typeof gitRef === 'string' && gitRef.trim() ? gitRef.split('/')[2].trim() : stdout.trim() @@ -33,7 +38,7 @@ try { const remoteSha = stdout3.split('\t')[0] if (remoteSha !== sha) { - console.log('There is a new version available:', remoteSha) + console.log('There is a new version available: ', remoteSha, isDocker ? 'docker-compose pull' : 'git pull', ' to update') } } catch (e) { console.warn('Unable to get remote SHA', e.message, 'Branch:', branch, 'Local SHA:', sha) diff --git a/server/src/services/config.js b/server/src/services/config.js index 294bd97ae..9b30b826e 100644 --- a/server/src/services/config.js +++ b/server/src/services/config.js @@ -46,9 +46,6 @@ config.authMethods = [...new Set(config.authentication.strategies })), ] -// Auto check for scan overlay settings -config.map.noScanAreaOverlay = Boolean(config.manualAreas.length) - // initialize webhooks if (config.webhooks.length) { (async () => { From d27de5f08777b3074643fedb37f57dc6ff57d6e3 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sat, 22 Jan 2022 13:54:33 -0500 Subject: [PATCH 34/77] Popup Adjustment - Fixes popup anchors - Simplifies popup anchor logic --- src/components/markers/gym.jsx | 18 ++++++++++-------- src/components/markers/pokestop.jsx | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/markers/gym.jsx b/src/components/markers/gym.jsx index 408353c53..585c189a5 100644 --- a/src/components/markers/gym.jsx +++ b/src/components/markers/gym.jsx @@ -32,6 +32,7 @@ export default function GymMarker(gym, hasHatched, hasRaid, filters, Icons, user let raidIcon let raidSize = 0 const slotModifier = gymMod[filledSlots] || gymMod['0'] || gymSize * 0.5 + const showDiamond = filters.gymBadges && userSettings.gymBadgeDiamonds && badge if (hasRaid) { const { @@ -58,17 +59,17 @@ export default function GymMarker(gym, hasHatched, hasRaid, filters, Icons, user const ReactIcon = (
- {(filters.gymBadges && userSettings.gymBadgeDiamonds && badge) ? ( + {showDiamond ? ( <>
Date: Sat, 22 Jan 2022 13:56:34 -0500 Subject: [PATCH 35/77] Update Gym.js --- server/src/models/Gym.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index 4badac899..498203842 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -325,7 +325,7 @@ module.exports = class Gym extends Model { query.leftJoin('gymdetails', 'gym.gym_id', 'gymdetails.gym_id') } - if (gymBadgeDb.host === gymDb.host) { + if (gymBadgeDb.host === gymDb.host && gymBadgeDb.user === gymDb.user) { query.leftJoin(`${gymBadgeDb.database}.${gymBadgeTableName}`, isMad ? 'gym.gym_id' : 'gym.id', `${gymBadgeTableName}.gymId`) .where('userId', userId) .andWhere('badge', '>', 0) From a76aeca6ac3e334ad458b058a4d39ba0721e6b83 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sat, 22 Jan 2022 15:08:37 -0500 Subject: [PATCH 36/77] Linting & Cleanup --- src/components/layout/Nav.jsx | 7 +++--- .../layout/dialogs/ResetFilters.jsx | 22 +++++++++---------- src/components/layout/drawer/Settings.jsx | 2 +- src/hooks/useStore.js | 4 ++-- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/components/layout/Nav.jsx b/src/components/layout/Nav.jsx index b9b6065fa..1dae09445 100644 --- a/src/components/layout/Nav.jsx +++ b/src/components/layout/Nav.jsx @@ -39,8 +39,7 @@ export default function Nav({ const setUserProfile = useStatic(state => state.setUserProfile) const feedback = useStatic(state => state.feedback) const setFeedback = useStatic(state => state.setFeedback) - const resetfilters = useStatic(state => state.resetfilters) - const setResetFilters = useStatic(state => state.setResetFilters) + const resetFilters = useStatic(state => state.resetFilters) const filters = useStore(state => state.filters) const setFilters = useStore(state => state.setFilters) @@ -211,10 +210,10 @@ export default function Nav({
- + state.setResetFilters) if (redirect) { return @@ -22,20 +26,16 @@ export default function ResetFilters({ setResetFilters }) { {t('filters_reset_text')}
- -
diff --git a/src/components/layout/drawer/Settings.jsx b/src/components/layout/drawer/Settings.jsx index eb775dc36..36aa671e7 100644 --- a/src/components/layout/drawer/Settings.jsx +++ b/src/components/layout/drawer/Settings.jsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React from 'react' import { FormControl, Grid, InputLabel, MenuItem, Select, Button, } from '@material-ui/core' diff --git a/src/hooks/useStore.js b/src/hooks/useStore.js index 3aeb02208..729bdf784 100644 --- a/src/hooks/useStore.js +++ b/src/hooks/useStore.js @@ -92,8 +92,8 @@ const useStatic = create(set => ({ setUserProfile: (userProfile) => set({ userProfile }), feedback: false, setFeedback: (feedback) => set({ feedback }), - resetfilters: false, - setResetFilters: (resetfilters) => set({ resetfilters }), + resetFilters: false, + setResetFilters: (resetFilters) => set({ resetFilters }), })) export { useStore, useStatic } From 027458b1f12dc24e1b7314aeca5919264cee9687 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sat, 22 Jan 2022 15:13:54 -0500 Subject: [PATCH 37/77] Add Pvp Specific Limit --- server/src/configs/default.json | 3 ++- server/src/models/Pokemon.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/server/src/configs/default.json b/server/src/configs/default.json index 80771d14f..de28e53d5 100644 --- a/server/src/configs/default.json +++ b/server/src/configs/default.json @@ -23,7 +23,8 @@ "nests": false }, "queryLimits": { - "pokemon": 20000, + "pokemon": 10000, + "pokemonPvp": 25000, "pokestops": 5000, "gyms": 5000, "portals": 5000, diff --git a/server/src/models/Pokemon.js b/server/src/models/Pokemon.js index f86e9345a..d479e47f0 100644 --- a/server/src/models/Pokemon.js +++ b/server/src/models/Pokemon.js @@ -319,7 +319,7 @@ module.exports = class Pokemon extends Model { if (areaRestrictions?.length) { getAreaSql(pvpQuery, areaRestrictions, isMad, 'pokemon') } - pvpResults.push(...await pvpQuery.limit(queryLimits.pokemon - results.length)) + pvpResults.push(...await pvpQuery.limit(queryLimits.pokemonPvp - results.length)) } // filter pokes with pvp data From a1cef20cf8952f670236cf875211c01af6c130e9 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sat, 22 Jan 2022 16:10:17 -0500 Subject: [PATCH 38/77] Stuff --- server/src/models/Gym.js | 4 +++- src/components/layout/dialogs/UserProfile.jsx | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index f0367ac1a..dcac81d40 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -13,6 +13,8 @@ const Badge = require('./Badge') const gymBadgeDb = schemas.find(x => x.useFor.includes('user')) const gymDb = schemas.find(x => x.useFor.includes('gym')) +const hasSameDb = gymBadgeDb.host === gymDb.host && gymBadgeDb.user === gymDb.user + module.exports = class Gym extends Model { static get tableName() { return 'gym' @@ -325,7 +327,7 @@ module.exports = class Gym extends Model { query.leftJoin('gymdetails', 'gym.gym_id', 'gymdetails.gym_id') } - if (gymBadgeDb.host === gymDb.host && gymBadgeDb.user === gymDb.user) { + if (hasSameDb) { query.leftJoin(`${gymBadgeDb.database}.${gymBadgeTableName}`, isMad ? 'gym.gym_id' : 'gym.id', `${gymBadgeTableName}.gymId`) .where('userId', userId) .andWhere('badge', '>', 0) diff --git a/src/components/layout/dialogs/UserProfile.jsx b/src/components/layout/dialogs/UserProfile.jsx index 572067c09..2e8a0901c 100644 --- a/src/components/layout/dialogs/UserProfile.jsx +++ b/src/components/layout/dialogs/UserProfile.jsx @@ -281,10 +281,10 @@ const GymBadges = ({ isMobile, t }) => { const BadgeTile = ({ data, rowIndex, columnIndex, style }) => { const { badges, columnCount, Icons, t, map } = data const item = badges[rowIndex * columnCount + columnIndex] - const [badge, setBadge] = useState(item?.badge || 0) + const [badge, setBadge] = useState(item?.badge) const [badgeMenu, setBadgeMenu] = useState(false) - return item ? ( + return item && badge ? ( Date: Sun, 23 Jan 2022 16:37:05 +0100 Subject: [PATCH 39/77] Update de.json --- public/base-locales/de.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/public/base-locales/de.json b/public/base-locales/de.json index 441df0bd6..eb3c86ee1 100644 --- a/public/base-locales/de.json +++ b/public/base-locales/de.json @@ -474,5 +474,8 @@ "all": "Alle", "with_ar": "Mit AR", "without_ar": "Ohne AR", - "both": "Beide" + "both": "Beide", + "confirm_filters_reset": "Filter zurücksetzen", + "filters_reset_text": "Sollen die Einstellungen wirklich auf die Standardwerte zurückgesetzt werden? Das kann nicht rückgängig gemacht werden!", + "filters_reset_title": "Filter zurücksetzen" } From 213b62b8337bb05034cc2fc8056bfb6c120e630a Mon Sep 17 00:00:00 2001 From: pjorritsma Date: Sun, 23 Jan 2022 17:50:45 +0100 Subject: [PATCH 40/77] Update Dutch Translation Translate new entries in Dutch. --- public/base-locales/nl.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/public/base-locales/nl.json b/public/base-locales/nl.json index 0f61a8ab4..f1b0bcf12 100644 --- a/public/base-locales/nl.json +++ b/public/base-locales/nl.json @@ -475,5 +475,8 @@ "webhook_advanced_save_width": 2, "login_button": 5, "join_button": 5, - "all": "Alle" + "all": "Alle", + "confirm_filters_reset": "Bevestig filters resetten", + "filters_reset_text": "Weet je zeker dat je de filters instellingen terug wilt zetten naar standaardwaarden? Dit kan niet ongedaan gemaakt worden!", + "filters_reset_title": "Filters resetten" } From 4745f6f8a79722539c7cac23fb090fcdcd115893 Mon Sep 17 00:00:00 2001 From: pjorritsma Date: Sun, 23 Jan 2022 17:52:55 +0100 Subject: [PATCH 41/77] Undo Area Settings --- package.json | 2 - public/geofence/geofence.json | 181 ---------------------------- server/scripts/geofenceToGeoJSON.js | 70 ----------- server/scripts/poracleToGeoJSON.js | 68 ----------- 4 files changed, 321 deletions(-) delete mode 100644 public/geofence/geofence.json delete mode 100644 server/scripts/geofenceToGeoJSON.js delete mode 100644 server/scripts/poracleToGeoJSON.js diff --git a/package.json b/package.json index df37e30f2..b0790d9a9 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,6 @@ "create-locales": "node server/scripts/createLocales.js", "missing-locales": "node server/scripts/createLocales.js --missing", "config-migrate": "node server/scripts/configMigration.js", - "create-area": "node server/scripts/geofenceToGeoJSON.js", - "create-area-poracle": "node server/scripts/poracleToGeoJSON.js", "console": "node --experimental-repl-await ./server/src/console.js", "migrate:make": "knex --knexfile server/knexfile.cjs migrate:make", "migrate:latest": "knex --knexfile server/knexfile.cjs migrate:latest", diff --git a/public/geofence/geofence.json b/public/geofence/geofence.json deleted file mode 100644 index be7ac713c..000000000 --- a/public/geofence/geofence.json +++ /dev/null @@ -1,181 +0,0 @@ -[ - { - "name": "New York", - "color": "#6CB1E1", - "id": 0, - "path": [ - [ - 40.6758460704592, - -74.0183327629713 - ], - [ - 40.6673832118379, - -74.0032265617995 - ], - [ - 40.6667321782243, - -73.9930985405592 - ], - [ - 40.6638675548225, - -73.9817688896803 - ], - [ - 40.6698570816073, - -73.971984191194 - ], - [ - 40.6612632449602, - -73.9785073235182 - ], - [ - 40.6604819321731, - -73.960997863069 - ], - [ - 40.6595703890216, - -73.9359353020338 - ], - [ - 40.6737630049163, - -73.9182541802077 - ], - [ - 40.6939399635959, - -73.9143059685378 - ], - [ - 40.730963376432, - -73.9388086668346 - ], - [ - 40.7539462208294, - -73.9434547762474 - ], - [ - 40.7677776617157, - -73.9427697204215 - ], - [ - 40.7763577594269, - -73.9439713500602 - ], - [ - 40.7818172447128, - -73.944486334191 - ], - [ - 40.7923449848895, - -73.9341866515738 - ], - [ - 40.8044303320442, - -73.9297234557731 - ], - [ - 40.8090857578706, - -73.9352091337489 - ], - [ - 40.819219447895, - -73.9352091337489 - ], - [ - 40.8288320306508, - -73.9352091337489 - ], - [ - 40.8351963525041, - -73.935037472372 - ], - [ - 40.8420795230808, - -73.9305742765712 - ], - [ - 40.8458454836873, - -73.9431055570888 - ], - [ - 40.8244156115839, - -73.9554651762294 - ], - [ - 40.7959616287814, - -73.9772661711024 - ], - [ - 40.7834848035422, - -73.9848192716884 - ], - [ - 40.7729556587662, - -73.9932306791591 - ], - [ - 40.7673654346462, - -73.9968355680751 - ], - [ - 40.7622948246655, - -73.9999254728602 - ], - [ - 40.752022403571, - -74.0078218962001 - ], - [ - 40.7257160733875, - -74.0104929617871 - ], - [ - 40.7125754713621, - -74.0158144644726 - ], - [ - 40.7041172764294, - -74.017874400996 - ], - [ - 40.7008638384784, - -74.0139261893261 - ], - [ - 40.7050282105779, - -74.0046564749707 - ], - [ - 40.7086718225791, - -73.9972750357617 - ], - [ - 40.7104284928515, - -73.9852587393749 - ], - [ - 40.7142669814306, - -73.9765040091503 - ], - [ - 40.7123152352296, - -73.9689079932202 - ], - [ - 40.7076308109205, - -73.9694015196789 - ], - [ - 40.7017748171234, - -73.9751414469708 - ], - [ - 40.7054186071131, - -73.979508083247 - ], - [ - 40.7033364658143, - -73.9939276389111 - ] - ] - } -] \ No newline at end of file diff --git a/server/scripts/geofenceToGeoJSON.js b/server/scripts/geofenceToGeoJSON.js deleted file mode 100644 index 8dedd61cf..000000000 --- a/server/scripts/geofenceToGeoJSON.js +++ /dev/null @@ -1,70 +0,0 @@ -/** -* Credits: https://gist.github.com/moriakaice -* Editor: PJ0tterr -* Date: 15-01-2022 -*/ - -const fs = require('fs'); -const path = require('path'); - -// Set Path where for area.json -const configFolder = path.resolve(__dirname, '../../src/configs') -const geofencesFolder = path.resolve(__dirname, '../../public/geofence/geofence.json') - -if (!fs.existsSync(geofencesFolder)) { - // eslint-disable-next-line no-console - console.error('Error: Geofence directory does not exist:', geofencesFolder); - return; -} - -const geoJSON = { - type: 'FeatureCollection', - features: [], -}; - -fs.readdir(geofencesFolder, (err, files) => { - if (err) { - // eslint-disable-next-line no-console - console.error(err); - return; - } - // eslint-disable-next-line no-plusplus - for (let i = 0; i < files.length; i++) { - const file = path.resolve(geofencesFolder, files[i]); - // eslint-disable-next-line no-shadow - fs.readFile(file, 'utf8', (err, data) => { - if (err) { - // eslint-disable-next-line no-console - console.error(err); - return; - } - // eslint-disable-next-line no-console - console.log('Converting ini geofence file to geoJSON format', file); - const fences = data.match(/\[([^\]]+)\]([^[]*)/g); - fences.forEach(fence => { - const geofence = { type: 'Feature', - properties: { - name: '', - }, - geometry: { - type: 'Polygon', - coordinates: [[]], - } }; - // eslint-disable-next-line prefer-destructuring - geofence.properties.name = fence.match(/\[([^\]]+)\]/)[1]; - geofence.geometry.coordinates[0] = fence.match(/[0-9\-.]+,\s*[0-9\-.]+/g).map(point => [parseFloat(point.split(',')[1]), parseFloat(point.split(',')[0])]); - geofence.geometry.coordinates[0].push(geofence.geometry.coordinates[0][0]); - - geoJSON.features.push(geofence); - }); - fs.writeFile( - path.resolve(configFolder, 'areas.json'), - JSON.stringify(geoJSON, null, 2), - 'utf8', - () => { }, - ); - // eslint-disable-next-line no-console - console.log('areas.json file saved'); - }); - } -}); diff --git a/server/scripts/poracleToGeoJSON.js b/server/scripts/poracleToGeoJSON.js deleted file mode 100644 index af35acf24..000000000 --- a/server/scripts/poracleToGeoJSON.js +++ /dev/null @@ -1,68 +0,0 @@ -/** -* Credits: https://gist.github.com/moriakaice -* Editor: PJ0tterr -* Date: 15-01-2022 -*/ - -const fs = require('fs'); -const path = require('path'); - -// Set Path where for area.json -const configFolder = path.resolve(__dirname, '../../src/configs') -const geofencesFolder = path.resolve(__dirname, '../../public/geofence/geofence.json') - -if (!fs.existsSync(geofencesFolder)) { - // eslint-disable-next-line no-console - console.error('Error: Geofence directory does not exist:', geofencesFolder); - return; -} - -const outGeoJSON = { - type: 'FeatureCollection', - features: [], -}; - -fs.readFile(geofencesFolder, 'utf8', (err, data) => { - if (err) { - // eslint-disable-next-line no-console - console.error(err); - return; - } - const inGeoJSON = JSON.parse(data); - if (inGeoJSON.length === 0) { - // eslint-disable-next-line no-console - console.error('Failed to parse poracle geofence file'); - return; - } - // eslint-disable-next-line no-plusplus - for (let i = 0; i < inGeoJSON.length; i++) { - const inGeofence = inGeoJSON[i]; - // eslint-disable-next-line no-console - console.log('Converting', inGeofence.name); - const outGeofence = { - type: 'Feature', - properties: { - name: inGeofence.name || '', - color: inGeofence.color || '#000000', - id: inGeofence.id || 0, - - }, - geometry: { - type: 'Polygon', - coordinates: [[]], - }, - }; - // eslint-disable-next-line no-plusplus - for (let j = 0; j < inGeofence.path.length; j++) { - const coord = inGeofence.path[j]; - inGeofence.path[j] = [coord[1], coord[0]]; - } - outGeofence.geometry.coordinates[0] = inGeofence.path; - outGeoJSON.features.push(outGeofence); - } - const outFilePath = path.resolve(path.dirname(configFolder), 'areas.json'); - fs.writeFile(outFilePath, JSON.stringify(outGeoJSON, null, 2), 'utf8', () => { - // eslint-disable-next-line no-console - console.log(`${outFilePath} file saved.`); - }); -}); From 8b17d058ed550924e04d9be2c1b6ce0aa8acd208 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 23 Jan 2022 12:16:07 -0500 Subject: [PATCH 42/77] Manually Decide To Join Tables or Not --- server/src/configs/default.json | 1 + server/src/models/Gym.js | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/server/src/configs/default.json b/server/src/configs/default.json index 5e71eb3a5..43d737197 100644 --- a/server/src/configs/default.json +++ b/server/src/configs/default.json @@ -328,6 +328,7 @@ "gymBadgeTableName": "gymBadges", "sessionTableName": "session", "migrationTableName": "knex_migrations", + "joinGymBadgeTable": false, "hideOldQuests": false, "maxConnections": 10 }, diff --git a/server/src/models/Gym.js b/server/src/models/Gym.js index dcac81d40..bd1add97f 100644 --- a/server/src/models/Gym.js +++ b/server/src/models/Gym.js @@ -7,13 +7,11 @@ const dbSelection = require('../services/functions/dbSelection') const getAreaSql = require('../services/functions/getAreaSql') const { api: { searchResultsLimit, queryLimits }, - database: { schemas, settings: { gymBadgeTableName } }, + database: { schemas, settings: { gymBadgeTableName, joinGymBadgeTable } }, } = require('../services/config') const Badge = require('./Badge') const gymBadgeDb = schemas.find(x => x.useFor.includes('user')) -const gymDb = schemas.find(x => x.useFor.includes('gym')) -const hasSameDb = gymBadgeDb.host === gymDb.host && gymBadgeDb.user === gymDb.user module.exports = class Gym extends Model { static get tableName() { @@ -327,7 +325,7 @@ module.exports = class Gym extends Model { query.leftJoin('gymdetails', 'gym.gym_id', 'gymdetails.gym_id') } - if (hasSameDb) { + if (joinGymBadgeTable) { query.leftJoin(`${gymBadgeDb.database}.${gymBadgeTableName}`, isMad ? 'gym.gym_id' : 'gym.id', `${gymBadgeTableName}.gymId`) .where('userId', userId) .andWhere('badge', '>', 0) @@ -337,7 +335,6 @@ module.exports = class Gym extends Model { } const userGyms = await Badge.query() - .select(['gymId', 'badge']) .where('userId', userId) .andWhere('badge', '>', 0) From 4c4f064bc3f8a5253355b33b6bfb5803844d9715 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 23 Jan 2022 12:26:12 -0500 Subject: [PATCH 43/77] Types Fallbacks --- src/components/popups/Gym.jsx | 4 ++-- src/components/popups/Pokemon.jsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/popups/Gym.jsx b/src/components/popups/Gym.jsx index 269fd12b9..091093329 100644 --- a/src/components/popups/Gym.jsx +++ b/src/components/popups/Gym.jsx @@ -282,10 +282,10 @@ const RaidImage = ({ : Icons.getEggs(raid_level, raid_battle_timestamp < ts, raid_is_exclusive) const getRaidTypes = (id, form) => { - if (pokemon[id].forms[form] && pokemon[id].forms[form].types) { + if (pokemon[id].forms?.[form]?.types) { return pokemon[id].forms[form].types } - return pokemon[id].types + return pokemon[id]?.types || [] } return ( diff --git a/src/components/popups/Pokemon.jsx b/src/components/popups/Pokemon.jsx index 1c38b51f1..e5f82a476 100644 --- a/src/components/popups/Pokemon.jsx +++ b/src/components/popups/Pokemon.jsx @@ -292,7 +292,7 @@ const Info = ({ pokemon, metaData, perms, Icons, isNight, }) => { const { gender, weather, form } = pokemon - const formTypes = metaData.forms[form].types || metaData.types + const formTypes = metaData?.forms?.[form]?.types || metaData?.types || [] return ( Date: Sun, 23 Jan 2022 12:42:25 -0500 Subject: [PATCH 44/77] Add custom images folder for custom components --- .gitignore | 4 ++++ public/images/custom/.gitkeep | 0 2 files changed, 4 insertions(+) create mode 100644 public/images/custom/.gitkeep diff --git a/.gitignore b/.gitignore index ebe916c9b..ba1df17f1 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,10 @@ server/src/models/Custom.js public/images/uicons/* !public/images/uicons/.gitkeep +# Custom Image Folder for Custom Components +public/images/custom/* +!public/images/custom/.gitkeep + # Ignore generated locales public/locales/* public/missing-locales/* diff --git a/public/images/custom/.gitkeep b/public/images/custom/.gitkeep new file mode 100644 index 000000000..e69de29bb From 68b9a2f824c8b12e79d0e4e01662fc3e674f791b Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 23 Jan 2022 13:11:37 -0500 Subject: [PATCH 45/77] Weight and Size Check --- src/components/popups/Pokemon.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/popups/Pokemon.jsx b/src/components/popups/Pokemon.jsx index e5f82a476..75d9eeade 100644 --- a/src/components/popups/Pokemon.jsx +++ b/src/components/popups/Pokemon.jsx @@ -470,7 +470,7 @@ const ExtraInfo = ({ - {i ? `${weight.toFixed(2)}${t('kilogram')}` : `${size.toFixed(2)}${t('meter')}`} + {i ? `${weight ? weight.toFixed(2) : '? '}${t('kilogram')}` : `${size ? size.toFixed(2) : '? '}${t('meter')}`} From d334d360e6b5b1f8e53f9b7ea50c6026781511dd Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 23 Jan 2022 13:49:10 -0500 Subject: [PATCH 46/77] Startup Loading Indicator - Adds basic loading indicator during startup --- public/base-locales/en.json | 3 ++- src/assets/scss/main.scss | 4 ---- src/components/App.jsx | 2 ++ src/components/layout/general/Loading.jsx | 17 +++++++++++++++++ 4 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 src/components/layout/general/Loading.jsx diff --git a/public/base-locales/en.json b/public/base-locales/en.json index 5bb449373..870c03e66 100644 --- a/public/base-locales/en.json +++ b/public/base-locales/en.json @@ -478,5 +478,6 @@ "all": "All", "confirm_filters_reset": "Reset filters", "filters_reset_text": "Are you sure you want to reset settings to default values? This cannot be undone!", - "filters_reset_title": "Reset filters" + "filters_reset_title": "Reset filters", + "loading": "Loading" } diff --git a/src/assets/scss/main.scss b/src/assets/scss/main.scss index 1a37bad25..de7f4a462 100644 --- a/src/assets/scss/main.scss +++ b/src/assets/scss/main.scss @@ -21,10 +21,6 @@ body { background-color: rgb(53, 53, 53); } -.markercluster-map { - height: 90vh; -} - .MuiDrawer-paper { background-color: rgb(51, 51, 51); } diff --git a/src/components/App.jsx b/src/components/App.jsx index 799d92dbf..774a26d00 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -16,6 +16,7 @@ import RouteChangeTracker from './RouteChangeTracker' import Errors from './Errors' import ClearStorage from './ClearStorage' import HolidayEffects from './HolidayEffects' +import Loading from './layout/general/Loading' export default function App() { const [serverSettings, setServerSettings] = useState(null) @@ -49,6 +50,7 @@ export default function App() { + {!serverSettings && } {(process.env && process.env.GOOGLE_ANALYTICS_ID) && } diff --git a/src/components/layout/general/Loading.jsx b/src/components/layout/general/Loading.jsx new file mode 100644 index 000000000..f89821db7 --- /dev/null +++ b/src/components/layout/general/Loading.jsx @@ -0,0 +1,17 @@ +import React from 'react' +import { + CircularProgress, Typography, Backdrop, +} from '@material-ui/core' +import { useTranslation } from 'react-i18next' + +export default function Loading() { + const { t } = useTranslation() + return ( + +    + + {t('loading')} + + + ) +} From c4b062ff006eace3523eded518eb905289d5a353 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 23 Jan 2022 13:57:49 -0500 Subject: [PATCH 47/77] Fix Tutorial for forceTutorial = false - Fixes the session tutorial when forceTutorial = false in config --- server/src/routes/rootRouter.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/src/routes/rootRouter.js b/server/src/routes/rootRouter.js index f463bd550..1dc2be339 100644 --- a/server/src/routes/rootRouter.js +++ b/server/src/routes/rootRouter.js @@ -50,11 +50,10 @@ rootRouter.get('/area/:area/:zoom?', (req, res) => { rootRouter.get('/settings', async (req, res) => { try { - if (!config.authMethods.length || config.authentication.alwaysEnabledPerms.length) { + if (config.authentication.alwaysEnabledPerms.length || !config.authMethods.length) { + req.session.tutorial = !config.map.forceTutorial req.session.perms = { areaRestrictions: [], webhooks: [] } - req.session.save() - } - if (config.authentication.alwaysEnabledPerms.length) { + config.authentication.alwaysEnabledPerms.forEach(perm => { if (config.authentication.perms[perm]) { req.session.perms[perm] = true From 753522502de5669b9dbc28d1d44169270de6582d Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 23 Jan 2022 14:09:44 -0500 Subject: [PATCH 48/77] Update rootRouter.js --- server/src/routes/rootRouter.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/src/routes/rootRouter.js b/server/src/routes/rootRouter.js index 1dc2be339..988481a99 100644 --- a/server/src/routes/rootRouter.js +++ b/server/src/routes/rootRouter.js @@ -51,7 +51,9 @@ rootRouter.get('/area/:area/:zoom?', (req, res) => { rootRouter.get('/settings', async (req, res) => { try { if (config.authentication.alwaysEnabledPerms.length || !config.authMethods.length) { - req.session.tutorial = !config.map.forceTutorial + if (req.session.tutorial === undefined) { + req.session.tutorial = !config.map.forceTutorial + } req.session.perms = { areaRestrictions: [], webhooks: [] } config.authentication.alwaysEnabledPerms.forEach(perm => { From 832328c3839154a3b17f6c78437decda81f43274 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 23 Jan 2022 15:08:41 -0500 Subject: [PATCH 49/77] Icons Adjustments - Additional Nest adjustments - New nest modifier field `nestMonMulti` - Additional Weather adjustments - New weather modifier field `disableColorShift` - Additional Device adjustments - Fix icon centered for small size Pokemon - getPopupOffset => getModifiers method in Icons --- src/assets/scss/main.scss | 4 ++-- src/components/markers/device.js | 8 ++++---- src/components/markers/nest.jsx | 16 +++++++++------- src/components/markers/pokemon.jsx | 11 +++++++---- src/components/markers/weather.jsx | 27 ++++++++++++++------------- src/services/Icons.js | 6 +++--- 6 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/assets/scss/main.scss b/src/assets/scss/main.scss index 1a37bad25..88790b3b7 100644 --- a/src/assets/scss/main.scss +++ b/src/assets/scss/main.scss @@ -258,7 +258,7 @@ img { padding: 4px 3px 0 3px; } -.weather-fancy { +.weather-icon { background-color: rgba(255, 255, 255, 0.5); border: 2px solid rgb(41, 102, 122); border-radius: 48px; @@ -267,7 +267,7 @@ img { height: 30px; } -.weather-fancy > img { +.weather-icon > .fancy { filter: invert(75%) sepia(100%) hue-rotate(151deg) saturate(3.1); } diff --git a/src/components/markers/device.js b/src/components/markers/device.js index fdc819683..49beb92bd 100644 --- a/src/components/markers/device.js +++ b/src/components/markers/device.js @@ -2,12 +2,12 @@ import { Icon } from 'leaflet' export default function getDeviceMarkers(status, Icons) { const size = Icons.getSize('device') - const { x, y } = Icons.getPopupOffset('device') + const { offsetX, offsetY, popupX, popupY, sizeMultiplier } = Icons.getModifiers('device') return new Icon({ iconUrl: Icons.getMisc(status), - iconSize: [size, size], - iconAnchor: [20, 33.96], - popupAnchor: [-5 + x, -37 + y], + iconSize: [size * sizeMultiplier, size * sizeMultiplier], + iconAnchor: [20 * offsetX, 33.96 * offsetY], + popupAnchor: [-5 + popupX, -37 + popupY], className: 'marker', }) } diff --git a/src/components/markers/nest.jsx b/src/components/markers/nest.jsx index 73013220c..3be0521ae 100644 --- a/src/components/markers/nest.jsx +++ b/src/components/markers/nest.jsx @@ -6,7 +6,9 @@ export default function nestMarker(iconUrl, nest, pokemon, filters, Icons, recen const { types } = pokemon const filterId = `${nest.pokemon_id}-${nest.pokemon_form}` const size = Icons.getSize('nest', filters.filter[filterId]) - const { x, y } = Icons.getPopupOffset('nest') + const { + offsetX, offsetY, popupX, popupY, sizeMultiplier, nestMonSizeMulti = 1, + } = Icons.getModifiers('nest') const { nest: nestMod } = Icons.modifiers const opacity = recent ? 1 : 0.5 @@ -37,8 +39,8 @@ export default function nestMarker(iconUrl, nest, pokemon, filters, Icons, recen new Icon({ }) export const fancyMarker = (iconUrl, size, pkmn, glow, ivCircle, Icons, weatherCheck, isNight) => { - const { pokemon: pokemonMod } = Icons.modifiers + const { pokemon: pokemonMod, weather: weatherMod } = Icons.modifiers let badge switch (pkmn.bestPvp) { default: break @@ -54,20 +54,23 @@ export const fancyMarker = (iconUrl, size, pkmn, glow, ivCircle, Icons, weatherC )} {Boolean(weatherCheck) && (
diff --git a/src/components/markers/weather.jsx b/src/components/markers/weather.jsx index b8a055e9c..f3ce373d9 100644 --- a/src/components/markers/weather.jsx +++ b/src/components/markers/weather.jsx @@ -3,22 +3,23 @@ import { renderToString } from 'react-dom/server' import L from 'leaflet' export default function weatherMarker(weather, Icons, isNight) { - const { x, y } = Icons.getPopupOffset('weather') + const { offsetX, offsetY, popupX, popupY, sizeMultiplier, disableColorShift = false } = Icons.getModifiers('weather') + return L.divIcon({ - iconAnchor: [20, 20], - popupAnchor: [-2.5 + x, -20 + y], + iconAnchor: [17 * offsetX, 17 * offsetY], + popupAnchor: [popupX + 1, -20 + popupY], + iconSize: [30 * sizeMultiplier, 30 * sizeMultiplier], className: 'weather-icon', html: renderToString( -
- -
, + , ), }) } diff --git a/src/services/Icons.js b/src/services/Icons.js index 3aebd3b50..a73a811ac 100644 --- a/src/services/Icons.js +++ b/src/services/Icons.js @@ -137,10 +137,10 @@ export default class UIcons { : baseSize } - getPopupOffset(category) { + getModifiers(category) { return this.modifiers[category] - ? { x: this.modifiers[category].popupX || 0, y: this.modifiers[category].popupY || 0 } - : { x: 0, y: 0 } + ? this.modifiers[category] + : this.modifiers.base } getIconById(id) { From 355240e1e412e85de50f040c3f6d3a5585f3017a Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 23 Jan 2022 16:59:23 -0500 Subject: [PATCH 50/77] Fix Timer Offsets --- src/components/tiles/Gym.jsx | 2 +- src/components/tiles/Pokestop.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/tiles/Gym.jsx b/src/components/tiles/Gym.jsx index 3e5441ebb..537809272 100644 --- a/src/components/tiles/Gym.jsx +++ b/src/components/tiles/Gym.jsx @@ -77,7 +77,7 @@ const GymTile = ({ {((showTimer || userSettings.raidTimers) && hasRaid) && ( )} {showCircles && ( diff --git a/src/components/tiles/Pokestop.jsx b/src/components/tiles/Pokestop.jsx index e9fe0f171..c251642c0 100644 --- a/src/components/tiles/Pokestop.jsx +++ b/src/components/tiles/Pokestop.jsx @@ -65,7 +65,7 @@ const PokestopTile = ({ /> {Boolean(timers.length) && ( - + )} {showCircles && ( Date: Sun, 23 Jan 2022 22:05:02 -0500 Subject: [PATCH 51/77] Loading Screen for Pre-React Load - Remove unused index.html - Add some basic styling to load an html loading icon before JS has been loaded - Update text based off of what's being loaded --- public/base-locales/en.json | 2 +- public/index.html | 26 ------- public/index.template.html | 94 +++++++++++++++++++++++ src/components/App.jsx | 41 ++++++---- src/components/layout/general/Loading.jsx | 16 +++- 5 files changed, 135 insertions(+), 44 deletions(-) delete mode 100644 public/index.html diff --git a/public/base-locales/en.json b/public/base-locales/en.json index 870c03e66..49e9c8bc9 100644 --- a/public/base-locales/en.json +++ b/public/base-locales/en.json @@ -479,5 +479,5 @@ "confirm_filters_reset": "Reset filters", "filters_reset_text": "Are you sure you want to reset settings to default values? This cannot be undone!", "filters_reset_title": "Reset filters", - "loading": "Loading" + "loading": "Loading {{category}}" } diff --git a/public/index.html b/public/index.html deleted file mode 100644 index e398317a9..000000000 --- a/public/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - Map - - - - -
- - - - - - - - \ No newline at end of file diff --git a/public/index.template.html b/public/index.template.html index 3e133b188..f734ecf8a 100644 --- a/public/index.template.html +++ b/public/index.template.html @@ -9,7 +9,101 @@ Map + + +
+
+ + + + +
+     +

Loading Map

+
{ const data = await Fetch.getSettings() const Icons = data.masterfile ? new UIcons(data.config.icons, data.masterfile.questRewardTypes) : null if (Icons) { + if (loadingText) { + loadingText.innerHTML = 'Loading Icons' + } await Icons.fetchIcons(data.config.icons.styles) if (data.config.icons.defaultIcons) { Icons.setSelection(data.config.icons.defaultIcons) @@ -36,6 +49,9 @@ export default function App() { if (invasionCache && invasionCache.lastFetched + cacheTime > Date.now()) { data.masterfile.invasions = invasionCache } else { + if (loadingText) { + loadingText.innerHTML = 'Loading Invasions' + } data.masterfile.invasions = await Fetch.getInvasions(data.masterfile.invasions) } } @@ -47,10 +63,9 @@ export default function App() { }, []) return ( - - - - {!serverSettings && } + + + {(process.env && process.env.GOOGLE_ANALYTICS_ID) && } @@ -62,11 +77,11 @@ export default function App() { {serverSettings && ( - + )} @@ -79,8 +94,8 @@ export default function App() { - - - +
+
+ ) } diff --git a/src/components/layout/general/Loading.jsx b/src/components/layout/general/Loading.jsx index f89821db7..c3768929f 100644 --- a/src/components/layout/general/Loading.jsx +++ b/src/components/layout/general/Loading.jsx @@ -2,15 +2,23 @@ import React from 'react' import { CircularProgress, Typography, Backdrop, } from '@material-ui/core' -import { useTranslation } from 'react-i18next' +import { Trans, useTranslation } from 'react-i18next' -export default function Loading() { +export function Text({ category }) { const { t } = useTranslation() + return ( + + {{ category: t(category) }} + + ) +} + +export default function Loading({ category }) { return ( -    +     - {t('loading')} + {category ? : 'Loading Translations'} ) From 49277a7fdc3d8a38dc7f58e90c2eed025c00af37 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 23 Jan 2022 22:39:39 -0500 Subject: [PATCH 52/77] An unreasonable amount of work for slightly better translation support... --- public/base-locales/en.json | 4 +- src/components/App.jsx | 102 ++++-------------------------- src/components/ConfigSettings.jsx | 3 - src/components/ReactRouter.jsx | 97 ++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 93 deletions(-) create mode 100644 src/components/ReactRouter.jsx diff --git a/public/base-locales/en.json b/public/base-locales/en.json index 49e9c8bc9..17220f23e 100644 --- a/public/base-locales/en.json +++ b/public/base-locales/en.json @@ -479,5 +479,7 @@ "confirm_filters_reset": "Reset filters", "filters_reset_text": "Are you sure you want to reset settings to default values? This cannot be undone!", "filters_reset_title": "Reset filters", - "loading": "Loading {{category}}" + "loading": "Loading {{category}}", + "loading_icons": "Fetching Icons", + "loading_invasions": "Fetching Invasions" } diff --git a/src/components/App.jsx b/src/components/App.jsx index e8b6f91d1..8210e22d7 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -1,101 +1,25 @@ import '../assets/scss/main.scss' -import React, { Suspense, useEffect, useState, useCallback } from 'react' +import React, { Suspense } from 'react' import { ApolloProvider } from '@apollo/client' -import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' -import { ThemeProvider } from '@material-ui/styles' - -import setTheme from '@assets/mui/theme' -import UIcons from '@services/Icons' -import Fetch from '@services/Fetch' import client from '@services/apollo' -import Auth from './layout/auth/Auth' -import Login from './layout/auth/Login' -import RouteChangeTracker from './RouteChangeTracker' -import Errors from './Errors' -import ClearStorage from './ClearStorage' -import HolidayEffects from './HolidayEffects' - -export default function App() { - const [serverSettings, setServerSettings] = useState(null) +import ReactRouter from './ReactRouter' - const rootLoading = document.getElementById('loader') +const SetText = () => { const loadingText = document.getElementById('loading-text') - if (rootLoading) { - if (loadingText) { - loadingText.innerHTML = 'Loading Translations' - } - if (serverSettings) { - rootLoading.style.display = 'none' - } - } - - const getServerSettings = useCallback(async () => { - const data = await Fetch.getSettings() - const Icons = data.masterfile ? new UIcons(data.config.icons, data.masterfile.questRewardTypes) : null - if (Icons) { - if (loadingText) { - loadingText.innerHTML = 'Loading Icons' - } - await Icons.fetchIcons(data.config.icons.styles) - if (data.config.icons.defaultIcons) { - Icons.setSelection(data.config.icons.defaultIcons) - } - } - if (data.ui?.pokestops?.invasions && data.config?.map.fetchLatestInvasions) { - const invasionCache = JSON.parse(localStorage.getItem('invasions_cache')) - const cacheTime = data.config.map.invasionCacheHrs * 60 * 60 * 1000 - if (invasionCache && invasionCache.lastFetched + cacheTime > Date.now()) { - data.masterfile.invasions = invasionCache - } else { - if (loadingText) { - loadingText.innerHTML = 'Loading Invasions' - } - data.masterfile.invasions = await Fetch.getInvasions(data.masterfile.invasions) - } - } - setServerSettings({ ...data, Icons }) - }, []) + if (loadingText) loadingText.innerHTML = 'Loading Translations' + return <> +} - useEffect(() => { - getServerSettings() - }, []) +export default function App() { + document.body.classList.add('dark') return ( - - - - - {(process.env && process.env.GOOGLE_ANALYTICS_ID) && } - - - - - - {serverSettings && } - - - {serverSettings && ( - - )} - - - {serverSettings && } - - - {serverSettings && } - - - - - - - - + }> + + + + ) } diff --git a/src/components/ConfigSettings.jsx b/src/components/ConfigSettings.jsx index 25a84ef58..139324538 100644 --- a/src/components/ConfigSettings.jsx +++ b/src/components/ConfigSettings.jsx @@ -15,9 +15,6 @@ export default function ConfigSettings({ }) { Utility.analytics('User', serverSettings.user ? `${serverSettings.user.username} (${serverSettings.user.id})` : 'Not Logged In', 'Permissions', true) - document.title = serverSettings.config.map.headerTitle - document.body.classList.add('dark') - const setUserSettings = useStore(state => state.setUserSettings) const setSettings = useStore(state => state.setSettings) const setFilters = useStore(state => state.setFilters) diff --git a/src/components/ReactRouter.jsx b/src/components/ReactRouter.jsx new file mode 100644 index 000000000..7322c34e6 --- /dev/null +++ b/src/components/ReactRouter.jsx @@ -0,0 +1,97 @@ +import React, { useEffect, useState, useCallback } from 'react' +import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' +import { useTranslation } from 'react-i18next' +import { ThemeProvider } from '@material-ui/styles' + +import setTheme from '@assets/mui/theme' +import UIcons from '@services/Icons' +import Fetch from '@services/Fetch' + +import Auth from './layout/auth/Auth' +import Login from './layout/auth/Login' +import RouteChangeTracker from './RouteChangeTracker' +import Errors from './Errors' +import ClearStorage from './ClearStorage' +import HolidayEffects from './HolidayEffects' + +const rootLoading = document.getElementById('loader') +const loadingText = document.getElementById('loading-text') + +export default function ReactRouter() { + const { t } = useTranslation() + const [serverSettings, setServerSettings] = useState(null) + + if (rootLoading) { + if (serverSettings) { + rootLoading.style.display = 'none' + } + } + + const getServerSettings = useCallback(async () => { + const data = await Fetch.getSettings() + const Icons = data.masterfile ? new UIcons(data.config.icons, data.masterfile.questRewardTypes) : null + if (Icons) { + if (loadingText) { + loadingText.innerHTML = t('loading_icons') + } + await Icons.fetchIcons(data.config.icons.styles) + if (data.config.icons.defaultIcons) { + Icons.setSelection(data.config.icons.defaultIcons) + } + } + if (data.ui?.pokestops?.invasions && data.config?.map.fetchLatestInvasions) { + const invasionCache = JSON.parse(localStorage.getItem('invasions_cache')) + const cacheTime = data.config.map.invasionCacheHrs * 60 * 60 * 1000 + if (invasionCache && invasionCache.lastFetched + cacheTime > Date.now()) { + data.masterfile.invasions = invasionCache + } else { + if (loadingText) { + loadingText.innerHTML = t('loading_invasions') + } + data.masterfile.invasions = await Fetch.getInvasions(data.masterfile.invasions) + } + } + document.title = data.config.map.headerTitle + + setServerSettings({ ...data, Icons }) + }, []) + + useEffect(() => { + if (!serverSettings) { + getServerSettings() + } + }, []) + + return ( + + + {(process.env && process.env.GOOGLE_ANALYTICS_ID) && } + + + + + + {serverSettings && } + + + {serverSettings && ( + + )} + + + {serverSettings && } + + + {serverSettings && } + + + + + + + ) +} From 10162e49c13f1ccb1c9cbffca4f59fb981adc540 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Sun, 23 Jan 2022 23:12:22 -0500 Subject: [PATCH 53/77] Cleanup - Move styling to a CSS file - PL Translations - Loader above text --- public/base-locales/pl.json | 5 ++- public/index.template.html | 85 +----------------------------------- src/assets/scss/loading.scss | 78 +++++++++++++++++++++++++++++++++ src/assets/scss/main.scss | 2 + 4 files changed, 85 insertions(+), 85 deletions(-) create mode 100644 src/assets/scss/loading.scss diff --git a/public/base-locales/pl.json b/public/base-locales/pl.json index 0f95bf287..277331835 100644 --- a/public/base-locales/pl.json +++ b/public/base-locales/pl.json @@ -491,5 +491,8 @@ "join_button": 5, "confirm_filters_reset": "Zresetuj ustawienia", "filters_reset_text": "Czy na pewno chcesz zresetować ustawienia do domyślnych wartości? Ta czynność jest nieodwracalna!", - "filters_reset_title": "Reset ustawień" + "filters_reset_title": "Reset ustawień", + "loading": "Ładowanie {{category}}", + "loading_icons": "Ładowanie ikon", + "loading_invasions": "Ładowanie inwazji" } diff --git a/public/index.template.html b/public/index.template.html index f734ecf8a..862003281 100644 --- a/public/index.template.html +++ b/public/index.template.html @@ -9,89 +9,6 @@ Map - -
-     +

Loading Map

diff --git a/src/assets/scss/loading.scss b/src/assets/scss/loading.scss new file mode 100644 index 000000000..fd88fa135 --- /dev/null +++ b/src/assets/scss/loading.scss @@ -0,0 +1,78 @@ +.loader-flex { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + width: 100%; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: -1; + background-color: rgba(0, 0, 0, 0.5); + -webkit-tap-highlight-color: transparent; + flex-direction: column; +} + +@keyframes circular-rotate { + 0% { + transform-origin: 50% 50%; + } + + 100% { + transform: rotate(360deg); + } +} + +@keyframes circular-dash { + 0% { + stroke-dasharray: 1px, 200px; + stroke-dashoffset: 0px; + } + + 50% { + stroke-dasharray: 100px, 200px; + stroke-dashoffset: -15px; + } + + 100% { + stroke-dasharray: 100px, 200px; + stroke-dashoffset: -125px; + } +} + +.progress-indeterminate { + animation: circular-rotate 1.4s linear infinite; +} + +.progress-root { + display: inline-block; +} + +.progress-svg { + display: block; +} + +.color-primary { + color: #ff5722; +} + +.circle-indeterminate { + animation: circular-dash 1.4s ease-in-out infinite; + stroke-dasharray: 80px, 200px; + stroke-dashoffset: 0px; +} + +.progress-circle { + stroke: currentColor; +} + +.loading-text { + font-size: 1.5625rem; + font-family: "Roboto", "Helvetica", "Arial", sans-serif; + font-weight: 400; + line-height: 1.235; + letter-spacing: 0.00735em; + color: #00b0ff; + margin: 0; +} diff --git a/src/assets/scss/main.scss b/src/assets/scss/main.scss index 41a08c1df..e5a477c18 100644 --- a/src/assets/scss/main.scss +++ b/src/assets/scss/main.scss @@ -1,6 +1,7 @@ @import "~react-leaflet-markercluster/dist/styles.min.css"; @import "~leaflet.locatecontrol/dist/L.Control.Locate.min.css"; @import "holiday.scss"; +@import "loading.scss"; .leaflet-container { position: absolute; @@ -19,6 +20,7 @@ body { background-color: rgb(53, 53, 53); + margin: 0; } .MuiDrawer-paper { From 6c39e1047f6af92ca45ed168b5a1e3597ac034d6 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Mon, 24 Jan 2022 00:15:50 -0500 Subject: [PATCH 54/77] Multi Domain Areas.json Support - Supports multiple areas.json (can be named whatever via config) for multiple domains - Loads and parses them all for area security - Filters the polygons based on the req.headers.host --- server/src/configs/default.json | 3 +- server/src/graphql/resolvers.js | 9 ++++-- server/src/routes/rootRouter.js | 7 +++-- server/src/services/areas.js | 34 +++++++++++----------- server/src/services/config.js | 14 +++++++-- server/src/services/functions/areaPerms.js | 2 +- src/services/apollo.js | 26 +++++++++++++++-- 7 files changed, 66 insertions(+), 29 deletions(-) diff --git a/server/src/configs/default.json b/server/src/configs/default.json index 43d737197..3d3410a24 100644 --- a/server/src/configs/default.json +++ b/server/src/configs/default.json @@ -71,7 +71,8 @@ "interactionRangeZoom": 15, "scanAreasZoom": 12, "scanCellsZoom": 13, - "submissionZoom": 15 + "submissionZoom": 15, + "geoJsonFileName": "areas.json" }, "localeSelection": [ "en", diff --git a/server/src/graphql/resolvers.js b/server/src/graphql/resolvers.js index 799e75463..5f49782c1 100644 --- a/server/src/graphql/resolvers.js +++ b/server/src/graphql/resolvers.js @@ -145,15 +145,18 @@ module.exports = { }, scanAreas: (parent, args, { req }) => { const perms = req.user ? req.user.perms : req.session.perms - if (perms?.scanAreas && config.scanAreas.features.length) { + const scanAreas = config.scanAreas[req.headers.host] + ? config.scanAreas[req.headers.host] + : config.scanAreas.main + if (perms?.scanAreas && scanAreas.features.length) { try { - config.scanAreas.features = config.scanAreas.features + scanAreas.features = scanAreas.features .sort((a, b) => (a.properties.name > b.properties.name) ? 1 : -1) } catch (e) { console.warn('Failed to sort scan areas', e.message) } } - return [config.scanAreas] + return [scanAreas] }, search: async (parent, args, { req }) => { const perms = req.user ? req.user.perms : req.session.perms diff --git a/server/src/routes/rootRouter.js b/server/src/routes/rootRouter.js index 988481a99..f042b8659 100644 --- a/server/src/routes/rootRouter.js +++ b/server/src/routes/rootRouter.js @@ -30,8 +30,11 @@ rootRouter.get('/area/:area/:zoom?', (req, res) => { const { area, zoom } = req.params try { const { scanAreas, manualAreas } = config - if (scanAreas.features.length) { - const foundArea = scanAreas.features.find(a => a.properties.name.toLowerCase() === area.toLowerCase()) + const validScanAreas = scanAreas[req.headers.host] + ? scanAreas[req.headers.host] + : scanAreas.main + if (validScanAreas.features.length) { + const foundArea = validScanAreas.features.find(a => a.properties.name.toLowerCase() === area.toLowerCase()) if (foundArea) { const [lon, lat] = center(foundArea).geometry.coordinates return res.redirect(`/@/${lat}/${lon}/${zoom || 18}`) diff --git a/server/src/services/areas.js b/server/src/services/areas.js index 58e76e6bc..901bd47d4 100644 --- a/server/src/services/areas.js +++ b/server/src/services/areas.js @@ -1,39 +1,39 @@ /* eslint-disable no-console */ -/* eslint-disable no-restricted-syntax */ const config = require('./config') const loadAreas = () => { - let areas = {} try { - // eslint-disable-next-line global-require - const data = config.scanAreas || Error('Areas file not found') - areas = data + const normalized = { type: 'FeatureCollection', features: [] } + Object.values(config.scanAreas).forEach(area => { + if (area?.features.length) { + normalized.features.push(...area.features) + } + }) + return normalized } catch (err) { - const showWarning = config.authentication.areaRestrictions.some(rule => rule.roles.length) - if (showWarning) { + if (config.authentication.areaRestrictions.some(rule => rule.roles.length)) { console.warn('[Area Restrictions] Disabled - `areas.json` file is missing or broken.') } } - return areas } const parseAreas = (areasObj) => { - let names = {} const polygons = {} + const names = [] - if (Object.keys(areasObj).length === 0) { + if (!areasObj) { return { names, polygons } } - areasObj.features.forEach(feature => { - if (feature.geometry.type == 'Polygon' && feature.properties.name) { - polygons[feature.properties.name] = [] - for (const polygonCoordinates of feature.geometry.coordinates) { - polygons[feature.properties.name].push(...polygonCoordinates) - } + const { name } = feature.properties + if (feature.geometry.type == 'Polygon' && name) { + polygons[name] = [] + feature.geometry.coordinates.forEach(coordPair => { + polygons[name].push(...coordPair) + }) + names.push(name) } }) - names = Object.keys(polygons) return { names, polygons } } diff --git a/server/src/services/config.js b/server/src/services/config.js index 9b30b826e..e30f2bc37 100644 --- a/server/src/services/config.js +++ b/server/src/services/config.js @@ -1,3 +1,4 @@ +/* eslint-disable import/no-dynamic-require */ /* eslint-disable global-require */ /* eslint-disable no-console */ process.env.NODE_CONFIG_DIR = `${__dirname}/../configs` @@ -58,11 +59,18 @@ if (config.webhooks.length) { if (!config[opt].length) console.warn(`[${opt}] is empty, you need to add options to it or remove the empty array from your config.`) }) -// Check if an areas.json exists -config.scanAreas = fs.existsSync(`${__dirname}/../configs/areas.json`) - ? require('../configs/areas.json') +// Load each areas.json +const loadScanPolygons = (fileName) => fs.existsSync(`${__dirname}/../configs/${fileName}`) + ? require(`../configs/${fileName}`) : { features: [] } +// Check if an areas.json exists +config.scanAreas = config.multiDomains.length + ? Object.fromEntries( + config.multiDomains.map(d => [d.geoJsonFileName ? d.domain : 'main', loadScanPolygons(d.geoJsonFileName || config.map.geoJsonFileName)]), + ) + : { main: loadScanPolygons(config.map.geoJsonFileName) } + // Map manual areas config.manualAreas = Object.fromEntries(config.manualAreas.map(area => [area.name, area])) diff --git a/server/src/services/functions/areaPerms.js b/server/src/services/functions/areaPerms.js index 58dc17e4d..3dd2cfad3 100644 --- a/server/src/services/functions/areaPerms.js +++ b/server/src/services/functions/areaPerms.js @@ -3,7 +3,7 @@ const config = require('../config') module.exports = function areaPerms(roles) { let perms = [] - if (Object.keys(areas.names).length) { + if (areas.names.length) { roles.forEach(group => { config.authentication.areaRestrictions.forEach(rule => { if (rule.roles.includes(group)) { diff --git a/src/services/apollo.js b/src/services/apollo.js index 70805307a..8e4a18c8f 100644 --- a/src/services/apollo.js +++ b/src/services/apollo.js @@ -10,7 +10,12 @@ export default new ApolloClient({ typePolicies: { Query: { fields: { - pokemon: { + badges: { + merge(existing, incoming) { + return incoming + }, + }, + devices: { merge(existing, incoming) { return incoming }, @@ -20,12 +25,29 @@ export default new ApolloClient({ return incoming }, }, + nests: { + badges: { + merge(existing, incoming) { + return incoming + }, + }, + }, + pokemon: { + merge(existing, incoming) { + return incoming + }, + }, pokestops: { merge(existing, incoming) { return incoming }, }, - badges: { + portals: { + merge(existing, incoming) { + return incoming + }, + }, + spawnpoints: { merge(existing, incoming) { return incoming }, From c4972b3a1580913c8b1b4fdeca361c7b702c50f2 Mon Sep 17 00:00:00 2001 From: ReuschelCGN <82573872+ReuschelCGN@users.noreply.github.com> Date: Mon, 24 Jan 2022 09:33:59 +0100 Subject: [PATCH 55/77] Update de.json --- public/base-locales/de.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/public/base-locales/de.json b/public/base-locales/de.json index c15cfce58..93bf6d511 100644 --- a/public/base-locales/de.json +++ b/public/base-locales/de.json @@ -485,5 +485,8 @@ "gym_badges_subtitle": "Die Arenaorden auf der Karte und als Liste auf der Profilseite anzeigen.", "confirm_filters_reset": "Filter zurücksetzen", "filters_reset_text": "Sollen die Einstellungen wirklich auf die Standardwerte zurückgesetzt werden? Das kann nicht rückgängig gemacht werden!", - "filters_reset_title": "Filter zurücksetzen" + "filters_reset_title": "Filter zurücksetzen", + "loading": "laden von {{category}}", + "loading_icons": "Icons abrufen", + "loading_invasions": "Rocket-Lineup abrufen" } From 2239e750dcb4debbc2947a8004b89f5ae84ca701 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Tue, 25 Jan 2022 21:53:05 -0500 Subject: [PATCH 56/77] Ghetto Translations for Loading --- public/index.template.html | 20 ++++++++++++++++++++ src/components/App.jsx | 18 +++++++++++++++++- src/components/ReactRouter.jsx | 4 ++-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/public/index.template.html b/public/index.template.html index 862003281..abdcfbbfc 100644 --- a/public/index.template.html +++ b/public/index.template.html @@ -21,6 +21,26 @@

Loading Map

+
{ + const locale = { + // de: '', + en: 'Loading Translations', + es: 'Cargando Traducciones', + // fr: '', + it: 'Caricamento Traduzioni', + ja: '翻訳を読み込み中', + ko: '번역 로드 중', + // nl: '', + // pl: '', + 'pt-br': 'Carregando Traduções', + ru: 'Загрузка переводов', + sv: 'Laddar Översättningar', + th: 'กำลังโหลดการแปล', + 'zh-tw': '載入翻譯', + }[localStorage?.getItem('i18nextLng')?.toLowerCase() || 'en'] const loadingText = document.getElementById('loading-text') - if (loadingText) loadingText.innerHTML = 'Loading Translations' + if (loadingText) loadingText.innerText = locale || 'Loading Translations' return <> } diff --git a/src/components/ReactRouter.jsx b/src/components/ReactRouter.jsx index 7322c34e6..9b1fafd8f 100644 --- a/src/components/ReactRouter.jsx +++ b/src/components/ReactRouter.jsx @@ -32,7 +32,7 @@ export default function ReactRouter() { const Icons = data.masterfile ? new UIcons(data.config.icons, data.masterfile.questRewardTypes) : null if (Icons) { if (loadingText) { - loadingText.innerHTML = t('loading_icons') + loadingText.innerText = t('loading_icons') } await Icons.fetchIcons(data.config.icons.styles) if (data.config.icons.defaultIcons) { @@ -46,7 +46,7 @@ export default function ReactRouter() { data.masterfile.invasions = invasionCache } else { if (loadingText) { - loadingText.innerHTML = t('loading_invasions') + loadingText.innerText = t('loading_invasions') } data.masterfile.invasions = await Fetch.getInvasions(data.masterfile.invasions) } From 606085cf538c6448312137fe33564cbd1dd78e59 Mon Sep 17 00:00:00 2001 From: len <10072920+lenisko@users.noreply.github.com> Date: Wed, 26 Jan 2022 04:34:40 +0100 Subject: [PATCH 57/77] pl translations --- public/index.template.html | 2 +- src/components/App.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/index.template.html b/public/index.template.html index abdcfbbfc..2eada4906 100644 --- a/public/index.template.html +++ b/public/index.template.html @@ -31,7 +31,7 @@

Loading Map

ja: 'マップを読み込み中', ko: '맵 로딩 중', // nl: - // pl: + pl: 'Ładowanie mapy', 'pt-br': 'Carregando Mapa', ru: 'Загрузка карты', sv: 'Laddar karta', diff --git a/src/components/App.jsx b/src/components/App.jsx index 4c0064aaf..9a36b4077 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -16,7 +16,7 @@ const SetText = () => { ja: '翻訳を読み込み中', ko: '번역 로드 중', // nl: '', - // pl: '', + pl: 'Ładowanie tłumaczeń', 'pt-br': 'Carregando Traduções', ru: 'Загрузка переводов', sv: 'Laddar Översättningar', From 00d592719c5e52ee3ad5a7c7bbc16337fa3a9f39 Mon Sep 17 00:00:00 2001 From: len <10072920+lenisko@users.noreply.github.com> Date: Wed, 26 Jan 2022 04:49:45 +0100 Subject: [PATCH 58/77] revert machine translations on react & leaflet controls string --- public/base-locales/es.json | 4 ++-- public/base-locales/it.json | 4 ++-- public/base-locales/ja.json | 2 +- public/base-locales/ko.json | 4 ++-- public/base-locales/pl.json | 4 ++-- public/base-locales/pt-br.json | 4 ++-- public/base-locales/ru.json | 4 ++-- public/base-locales/sv.json | 4 ++-- public/base-locales/th.json | 4 ++-- public/base-locales/zh-tw.json | 4 ++-- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/public/base-locales/es.json b/public/base-locales/es.json index 1bc951cb6..ac7313bfa 100644 --- a/public/base-locales/es.json +++ b/public/base-locales/es.json @@ -398,8 +398,8 @@ "webhook_selection": "Selección de {{name}}", "server_dev_error_0": "{{variable_0}}", "navigation_controls": "Controles de navegación", - "navigation_controls_react": "Reaccionar", - "navigation_controls_leaflet": "Folleto", + "navigation_controls_react": "React", + "navigation_controls_leaflet": "Leaflet", "exclusive": "Exclusivo", "all_moves": "Todos los movimientos", "move": "Muevete", diff --git a/public/base-locales/it.json b/public/base-locales/it.json index a1f49d83a..02bb91bef 100644 --- a/public/base-locales/it.json +++ b/public/base-locales/it.json @@ -1,8 +1,8 @@ { "page": "Pagina {{page}}", "navigation_controls": "Controlli di navigazione", - "navigation_controls_react": "Reagire", - "navigation_controls_leaflet": "Volantino", + "navigation_controls_react": "React", + "navigation_controls_leaflet": "Leaflet", "exclusive": "Esclusivo", "all_moves": "Tutte le mosse", "move": "Mossa", diff --git a/public/base-locales/ja.json b/public/base-locales/ja.json index a1abbd6a6..b4770033d 100644 --- a/public/base-locales/ja.json +++ b/public/base-locales/ja.json @@ -395,7 +395,7 @@ "page": "ページ{{page}}", "navigation_controls": "ナビゲーションコントロール", "navigation_controls_react": "React", - "navigation_controls_leaflet": "リーフレット", + "navigation_controls_leaflet": "Leaflet", "exclusive": "エクスクルーシブ", "all_moves": "すべての動き", "move": "動く", diff --git a/public/base-locales/ko.json b/public/base-locales/ko.json index 7e4012f89..54046e8fc 100644 --- a/public/base-locales/ko.json +++ b/public/base-locales/ko.json @@ -34,8 +34,8 @@ "weather_indicator": "날씨 부스트 표시기", "page": "페이지 {{page}}", "navigation_controls": "탐색 컨트롤", - "navigation_controls_react": "반응", - "navigation_controls_leaflet": "전단", + "navigation_controls_react": "React", + "navigation_controls_leaflet": "Leaflet", "exclusive": "독점적 인", "all_moves": "모든 동작", "move": "이동하다", diff --git a/public/base-locales/pl.json b/public/base-locales/pl.json index 0f95bf287..3795cad9b 100644 --- a/public/base-locales/pl.json +++ b/public/base-locales/pl.json @@ -392,8 +392,8 @@ "webhook_selection": "{{name}} wybór", "server_dev_error_0": "{{variable_0}}", "navigation_controls": "Sterowanie nawigacją", - "navigation_controls_react": "Reagować", - "navigation_controls_leaflet": "Ulotka", + "navigation_controls_react": "React", + "navigation_controls_leaflet": "Leaflet", "exclusive": "Ekskluzywny", "all_moves": "Wszystkie ruchy", "move": "Ruch", diff --git a/public/base-locales/pt-br.json b/public/base-locales/pt-br.json index 24d1ae8e7..069dbb183 100644 --- a/public/base-locales/pt-br.json +++ b/public/base-locales/pt-br.json @@ -366,8 +366,8 @@ "weather_indicator": "Indicador de impulso climático", "page": "Página {{page}}", "navigation_controls": "Controles de navegação", - "navigation_controls_react": "Reagir", - "navigation_controls_leaflet": "Folheto", + "navigation_controls_react": "React", + "navigation_controls_leaflet": "Leaflet", "exclusive": "Exclusivo", "all_moves": "Todos os movimentos", "move": "Jogada", diff --git a/public/base-locales/ru.json b/public/base-locales/ru.json index 79ba6cf90..1ded0984d 100644 --- a/public/base-locales/ru.json +++ b/public/base-locales/ru.json @@ -394,8 +394,8 @@ "non_registered_human_desc": "Вы не можете быть зарегистрированы в {{webhook}}\n\nИли сервер в настоящее время недоступен", "page": "Страница {{page}}", "navigation_controls": "Элементы управления навигацией", - "navigation_controls_react": "Реагировать", - "navigation_controls_leaflet": "Листовка", + "navigation_controls_react": "React", + "navigation_controls_leaflet": "Leaflet", "exclusive": "Эксклюзивный", "all_moves": "Все ходы", "move": "Переехать", diff --git a/public/base-locales/sv.json b/public/base-locales/sv.json index 15f367053..875156ec1 100644 --- a/public/base-locales/sv.json +++ b/public/base-locales/sv.json @@ -365,8 +365,8 @@ "weather_indicator": "Väderboostindikator", "page": "Sida {{page}}", "navigation_controls": "Navigationskontroller", - "navigation_controls_react": "Reagera", - "navigation_controls_leaflet": "Folder", + "navigation_controls_react": "React", + "navigation_controls_leaflet": "Leaflet", "exclusive": "Exklusiv", "all_moves": "Alla rörelser", "move": "Flytta", diff --git a/public/base-locales/th.json b/public/base-locales/th.json index a6dd69d3f..50a31057a 100644 --- a/public/base-locales/th.json +++ b/public/base-locales/th.json @@ -365,8 +365,8 @@ "weather_indicator": "ตัวบ่งชี้การเพิ่มสภาพอากาศ", "page": "หน้า {{page}}", "navigation_controls": "การควบคุมการนำทาง", - "navigation_controls_react": "ปฏิกิริยา", - "navigation_controls_leaflet": "แผ่นพับ", + "navigation_controls_react": "React", + "navigation_controls_leaflet": "Leaflet", "exclusive": "พิเศษ", "all_moves": "การเคลื่อนไหวทั้งหมด", "move": "เคลื่อนไหว", diff --git a/public/base-locales/zh-tw.json b/public/base-locales/zh-tw.json index 5959bb2ab..6504f5341 100644 --- a/public/base-locales/zh-tw.json +++ b/public/base-locales/zh-tw.json @@ -366,8 +366,8 @@ "weather_indicator": "天氣增強指標", "page": "第 {{page}} 頁", "navigation_controls": "導航控制", - "navigation_controls_react": "反應", - "navigation_controls_leaflet": "傳單", + "navigation_controls_react": "React", + "navigation_controls_leaflet": "Leaflet", "exclusive": "獨家的", "all_moves": "所有動作", "move": "移動", From 692f7db6de8845132c0a87ff343781e68d77a788 Mon Sep 17 00:00:00 2001 From: ReuschelCGN <82573872+ReuschelCGN@users.noreply.github.com> Date: Wed, 26 Jan 2022 08:55:00 +0100 Subject: [PATCH 59/77] Update index.template.html --- public/index.template.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/index.template.html b/public/index.template.html index 2eada4906..f03c1dd14 100644 --- a/public/index.template.html +++ b/public/index.template.html @@ -25,6 +25,7 @@

Loading Map

const locale = { // de: en: 'Loading Map', + de: 'Map wird geladen', es: 'Cargando Mapa', // fr: it: 'Caricamento Mappa', @@ -53,4 +54,4 @@

Loading Map

- \ No newline at end of file + From c8d1d6cccd5972fbe9c53abe4df1aa75e47330c8 Mon Sep 17 00:00:00 2001 From: ReuschelCGN <82573872+ReuschelCGN@users.noreply.github.com> Date: Wed, 26 Jan 2022 09:01:37 +0100 Subject: [PATCH 60/77] Update App.jsx --- src/components/App.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/App.jsx b/src/components/App.jsx index 9a36b4077..040c52358 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -10,6 +10,7 @@ const SetText = () => { const locale = { // de: '', en: 'Loading Translations', + de: 'Übersetzungen werden geladen', es: 'Cargando Traducciones', // fr: '', it: 'Caricamento Traduzioni', From 3b5ac8395ec5fb1471fdc091e79f2e65b1dadf04 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Wed, 26 Jan 2022 13:41:12 -0500 Subject: [PATCH 61/77] French words Co-Authored-By: Petap0w <47784174+Petap0w@users.noreply.github.com> --- public/base-locales/fr.json | 5 ++++- public/index.template.html | 7 +++---- src/components/App.jsx | 5 ++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/public/base-locales/fr.json b/public/base-locales/fr.json index ec0c47563..a6bc1dacf 100644 --- a/public/base-locales/fr.json +++ b/public/base-locales/fr.json @@ -479,5 +479,8 @@ "gym_badge_menu": "Editer Badge d'Arène", "gym_badges": "Badges d'Arènes", "gym_badge_diamonds": "Afficher les Badges d'Arènes", - "gym_badges_subtitle": "Affiche les badges d'arène sur la carte et une liste dans la page profile." + "gym_badges_subtitle": "Affiche les badges d'arène sur la carte et une liste dans la page profile.", + "loading": "Chargement {{category}}", + "loading_icons": "Récupération des Icônes", + "loading_invasions": "Récupération des Invasions" } \ No newline at end of file diff --git a/public/index.template.html b/public/index.template.html index f03c1dd14..5be48ceee 100644 --- a/public/index.template.html +++ b/public/index.template.html @@ -23,11 +23,10 @@

Loading Map

{ - const locale = { + const locales = { de: 'Übersetzungen werden geladen', en: 'Loading Translations', es: 'Cargando Traducciones', @@ -22,9 +22,10 @@ const SetText = () => { sv: 'Laddar Översättningar', th: 'กำลังโหลดการแปล', 'zh-tw': '載入翻譯', - }[localStorage?.getItem('i18nextLng')?.toLowerCase() || 'en'] + } + const locale = localStorage?.getItem('i18nextLng') || 'en' const loadingText = document.getElementById('loading-text') - if (loadingText) loadingText.innerText = locale || 'Loading Translations' + if (loadingText) loadingText.innerText = locales[locale.toLowerCase()] return <> } From 00fc273e406aab5bcc90a0e22f4165bb807246ef Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Wed, 26 Jan 2022 18:05:46 -0500 Subject: [PATCH 65/77] Fix logic --- server/src/services/config.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/server/src/services/config.js b/server/src/services/config.js index e30f2bc37..06ad18fb0 100644 --- a/server/src/services/config.js +++ b/server/src/services/config.js @@ -65,11 +65,12 @@ const loadScanPolygons = (fileName) => fs.existsSync(`${__dirname}/../configs/${ : { features: [] } // Check if an areas.json exists -config.scanAreas = config.multiDomains.length - ? Object.fromEntries( - config.multiDomains.map(d => [d.geoJsonFileName ? d.domain : 'main', loadScanPolygons(d.geoJsonFileName || config.map.geoJsonFileName)]), - ) - : { main: loadScanPolygons(config.map.geoJsonFileName) } +config.scanAreas = { + main: loadScanPolygons(config.map.geoJsonFileName), + ...Object.fromEntries( + config.multiDomains.map(d => [d.general?.geoJsonFileName ? d.domain : 'main', loadScanPolygons(d.general?.geoJsonFileName || config.map.geoJsonFileName)]), + ), +} // Map manual areas config.manualAreas = Object.fromEntries(config.manualAreas.map(area => [area.name, area])) From 14cd044da49ae53d2b8e88060ed07847f6c07de4 Mon Sep 17 00:00:00 2001 From: ReuschelCGN <82573872+ReuschelCGN@users.noreply.github.com> Date: Fri, 28 Jan 2022 17:48:50 +0100 Subject: [PATCH 66/77] Update de.json --- public/base-locales/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/base-locales/de.json b/public/base-locales/de.json index 93bf6d511..ca2c5b55f 100644 --- a/public/base-locales/de.json +++ b/public/base-locales/de.json @@ -454,7 +454,7 @@ "error_creating_user": "Neuer Benutzer kann derzeit nicht registriert werden", "discord_linked": "Discord Verknüpft", "telegram_linked": "Telegram Verknüpft", - "slider_little": "kleine Schieberegler", + "slider_little": "LittleCup", "tile_servers": "Tileserver", "tile_servers_default": "Standard Tileserver", "alola": "Alola", From bb607ebe0a2e7ea0a2f85a14401581733af3f6df Mon Sep 17 00:00:00 2001 From: ReuschelCGN <82573872+ReuschelCGN@users.noreply.github.com> Date: Fri, 28 Jan 2022 18:58:00 +0100 Subject: [PATCH 67/77] Update de.json --- public/base-locales/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/base-locales/de.json b/public/base-locales/de.json index ca2c5b55f..6300e315d 100644 --- a/public/base-locales/de.json +++ b/public/base-locales/de.json @@ -454,7 +454,7 @@ "error_creating_user": "Neuer Benutzer kann derzeit nicht registriert werden", "discord_linked": "Discord Verknüpft", "telegram_linked": "Telegram Verknüpft", - "slider_little": "LittleCup", + "slider_little": "Mini-Cup", "tile_servers": "Tileserver", "tile_servers_default": "Standard Tileserver", "alola": "Alola", From 8a1117954a220e1404a672ad3ec646a30d74b2f4 Mon Sep 17 00:00:00 2001 From: Petap0w Date: Fri, 28 Jan 2022 22:03:59 +0100 Subject: [PATCH 68/77] Adds option for Floating Profile Button --- server/src/configs/default.json | 1 + src/components/layout/FloatingBtn.jsx | 14 ++++++++++++-- src/components/layout/Nav.jsx | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/server/src/configs/default.json b/server/src/configs/default.json index 43d737197..8a54de660 100644 --- a/server/src/configs/default.json +++ b/server/src/configs/default.json @@ -106,6 +106,7 @@ "invasionCacheHrs": 1, "questMessage": "", "navigationControls": "react", + "enableFloatingProfileButton": false, "forceTutorial": true, "enableTutorial": true, "enableUserProfile": true, diff --git a/src/components/layout/FloatingBtn.jsx b/src/components/layout/FloatingBtn.jsx index 17e5503df..ad40cb592 100644 --- a/src/components/layout/FloatingBtn.jsx +++ b/src/components/layout/FloatingBtn.jsx @@ -1,7 +1,7 @@ import React, { useEffect, useRef } from 'react' import { Grid, Fab } from '@material-ui/core' import { - Menu, LocationOn, ZoomIn, ZoomOut, Search, NotificationsActive, Save, CardMembership, AttachMoney, EuroSymbol, + Menu, LocationOn, ZoomIn, ZoomOut, Search, NotificationsActive, Save, CardMembership, AttachMoney, EuroSymbol, Person, } from '@material-ui/icons' import { useTranslation } from 'react-i18next' import { useMap } from 'react-leaflet' @@ -9,7 +9,7 @@ import L from 'leaflet' import useStyles from '@hooks/useStyles' import useLocation from '@hooks/useLocation' -import { useStore } from '@hooks/useStore' +import { useStore, useStatic } from '@hooks/useStore' const DonationIcons = { dollar: AttachMoney, @@ -21,8 +21,11 @@ export default function FloatingButtons({ toggleDrawer, toggleDialog, safeSearch, isMobile, perms, webhookMode, setWebhookMode, settings, webhooks, donationPage, setDonorPage, + setUserProfile, }) { const { t } = useTranslation() + const { map: { enableFloatingProfileButton } } = useStatic(state => state.config) + const { loggedIn } = useStatic(state => state.auth) const map = useMap() const ref = useRef(null) const classes = useStyles() @@ -54,6 +57,13 @@ export default function FloatingButtons({ + {enableFloatingProfileButton && loggedIn && ( + + setUserProfile(true)} disabled={Boolean(webhookMode)}> + + + + )} {safeSearch.length ? ( diff --git a/src/components/layout/Nav.jsx b/src/components/layout/Nav.jsx index 3852eabfd..b4fe70285 100644 --- a/src/components/layout/Nav.jsx +++ b/src/components/layout/Nav.jsx @@ -123,6 +123,7 @@ export default function Nav({ settings={settings} donationPage={donationPage} setDonorPage={setDonorPage} + setUserProfile={setUserProfile} /> )} Date: Sat, 29 Jan 2022 00:13:38 +0100 Subject: [PATCH 69/77] Update Dutch translations Update Dutch translations --- public/base-locales/nl.json | 13 ++++++++++++- public/index.template.html | 1 + src/components/App.jsx | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/public/base-locales/nl.json b/public/base-locales/nl.json index f1b0bcf12..2f0fb6c72 100644 --- a/public/base-locales/nl.json +++ b/public/base-locales/nl.json @@ -478,5 +478,16 @@ "all": "Alle", "confirm_filters_reset": "Bevestig filters resetten", "filters_reset_text": "Weet je zeker dat je de filters instellingen terug wilt zetten naar standaardwaarden? Dit kan niet ongedaan gemaakt worden!", - "filters_reset_title": "Filters resetten" + "filters_reset_title": "Filters resetten", + "badge_0": "Geen", + "badge_1": "Bronze", + "badge_2": "Silver", + "badge_3": "Gold", + "gym_badge_menu": "Bewerk Gym Badge", + "gym_badges": "Gym Badges", + "gym_badge_diamonds": "Toon Gym Badges", + "gym_badges_subtitle": "Toont Gym Badges op de kaart en een lijst op de profielpagina.", + "loading": "Loading {{category}}", + "loading_icons": "Pictogrammen aan het Ophalen", + "loading_invasions": "Invasions aan het Ophalen" } diff --git a/public/index.template.html b/public/index.template.html index 4cea6d52a..5ada43d9f 100644 --- a/public/index.template.html +++ b/public/index.template.html @@ -25,6 +25,7 @@

Loading Map

const locales = { de: 'Map wird geladen', en: 'Loading Map', + nl: 'Map word geladen', es: 'Cargando Mapa', fr: 'Chargement de la Map', it: 'Caricamento Mappa', diff --git a/src/components/App.jsx b/src/components/App.jsx index 8bc61d152..d69788c16 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -10,6 +10,7 @@ const SetText = () => { const locales = { de: 'Übersetzungen werden geladen', en: 'Loading Translations', + nl: 'Vertalingen worden geladen', es: 'Cargando Traducciones', fr: 'Chargement des traductions', it: 'Caricamento Traduzioni', From 7ec761eb25d6803b0e711e61e067a65701c6cbdb Mon Sep 17 00:00:00 2001 From: Petap0w Date: Sat, 29 Jan 2022 22:49:47 +0100 Subject: [PATCH 70/77] Add title to hover --- src/components/layout/FloatingBtn.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/layout/FloatingBtn.jsx b/src/components/layout/FloatingBtn.jsx index ad40cb592..364229924 100644 --- a/src/components/layout/FloatingBtn.jsx +++ b/src/components/layout/FloatingBtn.jsx @@ -59,7 +59,7 @@ export default function FloatingButtons({
{enableFloatingProfileButton && loggedIn && ( - setUserProfile(true)} disabled={Boolean(webhookMode)}> + setUserProfile(true)} title={t('user_profile')} disabled={Boolean(webhookMode)}> From bdf265ecbdbfd1df91920f2bb2a1d340a60b6b17 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Thu, 3 Feb 2022 20:09:25 -0500 Subject: [PATCH 71/77] Enable All Pokes - Config option to enable all pokes by default (not recommended) --- server/src/configs/default.json | 1 + server/src/models/Filters.js | 2 +- server/src/routes/rootRouter.js | 2 +- server/src/services/defaultFilters/buildDefaultFilters.js | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/server/src/configs/default.json b/server/src/configs/default.json index b83e14b78..bf8d48938 100644 --- a/server/src/configs/default.json +++ b/server/src/configs/default.json @@ -278,6 +278,7 @@ "pokemon": { "enabled": false, "legacyFilter": false, + "allPokemon": false, "globalValues": { "iv": [ 80, diff --git a/server/src/models/Filters.js b/server/src/models/Filters.js index 0d4c6e990..b330a6842 100644 --- a/server/src/models/Filters.js +++ b/server/src/models/Filters.js @@ -9,7 +9,7 @@ class GenericFilter { } class PokemonFilter extends GenericFilter { - constructor(iv, level, atk, def, sta, pvp, enabled, size) { + constructor(enabled, size, iv, level, atk, def, sta, pvp) { super(enabled, size) this.iv = iv || [0, 100] this.atk_iv = atk || [0, 15] diff --git a/server/src/routes/rootRouter.js b/server/src/routes/rootRouter.js index f042b8659..0e9624e46 100644 --- a/server/src/routes/rootRouter.js +++ b/server/src/routes/rootRouter.js @@ -191,7 +191,7 @@ rootRouter.get('/settings', async (req, res) => { serverSettings.available[category].forEach(item => { if (!serverSettings.defaultFilters[category].filter[item] && !item.startsWith('132')) { serverSettings.defaultFilters[category].filter[item] = category === 'pokemon' - ? new PokemonFilter() + ? new PokemonFilter(config.defaultFilters.pokemon.allPokemon) : new GenericFilter() if (!Number.isNaN(parseInt(item.charAt(0)))) { const masterfileRef = masterfile.pokemon[item.split('-')[0]] diff --git a/server/src/services/defaultFilters/buildDefaultFilters.js b/server/src/services/defaultFilters/buildDefaultFilters.js index 3febc32c3..c371a6d2a 100644 --- a/server/src/services/defaultFilters/buildDefaultFilters.js +++ b/server/src/services/defaultFilters/buildDefaultFilters.js @@ -7,8 +7,8 @@ const buildPokestops = require('./buildPokestops') const buildGyms = require('./buildGyms') const { GenericFilter, PokemonFilter } = require('../../models/index') -const base = new PokemonFilter() -const custom = new PokemonFilter(...Object.values(defaultFilters.pokemon.globalValues)) +const base = new PokemonFilter(defaultFilters.pokemon.allPokemon) +const custom = new PokemonFilter(defaultFilters.pokemon.allPokemon, 'md', ...Object.values(defaultFilters.pokemon.globalValues)) module.exports = function buildDefault(perms) { const stopReducer = perms.pokestops || perms.lures || perms.quests || perms.invasions From 98562f5c655690bb9510c61bd959320a42c92b07 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Thu, 3 Feb 2022 20:19:15 -0500 Subject: [PATCH 72/77] Sentry Error Fix --- public/index.template.html | 3 +-- src/components/App.jsx | 3 +-- src/components/ConfigSettings.jsx | 2 ++ src/components/ReactRouter.jsx | 2 -- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/public/index.template.html b/public/index.template.html index 5ada43d9f..65da5cd1b 100644 --- a/public/index.template.html +++ b/public/index.template.html @@ -25,13 +25,12 @@

Loading Map

const locales = { de: 'Map wird geladen', en: 'Loading Map', - nl: 'Map word geladen', es: 'Cargando Mapa', fr: 'Chargement de la Map', it: 'Caricamento Mappa', ja: 'マップを読み込み中', ko: '맵 로딩 중', - // nl: + nl: 'Map word geladen', pl: 'Ładowanie mapy', 'pt-br': 'Carregando Mapa', ru: 'Загрузка карты', diff --git a/src/components/App.jsx b/src/components/App.jsx index d69788c16..01f7980e8 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -10,13 +10,12 @@ const SetText = () => { const locales = { de: 'Übersetzungen werden geladen', en: 'Loading Translations', - nl: 'Vertalingen worden geladen', es: 'Cargando Traducciones', fr: 'Chargement des traductions', it: 'Caricamento Traduzioni', ja: '翻訳を読み込み中', ko: '번역 로드 중', - // nl: '', + nl: 'Vertalingen worden geladen', pl: 'Ładowanie tłumaczeń', 'pt-br': 'Carregando Traduções', ru: 'Загрузка переводов', diff --git a/src/components/ConfigSettings.jsx b/src/components/ConfigSettings.jsx index 139324538..4b6a2a6c9 100644 --- a/src/components/ConfigSettings.jsx +++ b/src/components/ConfigSettings.jsx @@ -15,6 +15,8 @@ export default function ConfigSettings({ }) { Utility.analytics('User', serverSettings.user ? `${serverSettings.user.username} (${serverSettings.user.id})` : 'Not Logged In', 'Permissions', true) + document.title = serverSettings.config?.map?.headerTitle + const setUserSettings = useStore(state => state.setUserSettings) const setSettings = useStore(state => state.setSettings) const setFilters = useStore(state => state.setFilters) diff --git a/src/components/ReactRouter.jsx b/src/components/ReactRouter.jsx index 9b1fafd8f..b967437c7 100644 --- a/src/components/ReactRouter.jsx +++ b/src/components/ReactRouter.jsx @@ -51,8 +51,6 @@ export default function ReactRouter() { data.masterfile.invasions = await Fetch.getInvasions(data.masterfile.invasions) } } - document.title = data.config.map.headerTitle - setServerSettings({ ...data, Icons }) }, []) From 24e554501ad2278a9e9745547af96961b0610e0c Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Thu, 3 Feb 2022 20:27:20 -0500 Subject: [PATCH 73/77] Correct Scrolling Issue Addresses #359 --- public/base-locales/fr.json | 4 +++- src/components/layout/auth/Login.jsx | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/public/base-locales/fr.json b/public/base-locales/fr.json index a6bc1dacf..3ead6b7b9 100644 --- a/public/base-locales/fr.json +++ b/public/base-locales/fr.json @@ -482,5 +482,7 @@ "gym_badges_subtitle": "Affiche les badges d'arène sur la carte et une liste dans la page profile.", "loading": "Chargement {{category}}", "loading_icons": "Récupération des Icônes", - "loading_invasions": "Récupération des Invasions" + "loading_invasions": "Récupération des Invasions", + "login_button": 12, + "join_button": 12 } \ No newline at end of file diff --git a/src/components/layout/auth/Login.jsx b/src/components/layout/auth/Login.jsx index 911f5674b..0eb94dc40 100644 --- a/src/components/layout/auth/Login.jsx +++ b/src/components/layout/auth/Login.jsx @@ -41,7 +41,7 @@ const Login = ({ clickedTwice, location, serverSettings, getServerSettings }) => direction="column" justifyContent="center" alignItems="center" - style={{ minHeight: '95vh' }} + style={{ minHeight: '95vh', width: '100%' }} > @@ -49,17 +49,17 @@ const Login = ({ clickedTwice, location, serverSettings, getServerSettings }) => {serverSettings?.authMethods?.includes('discord') && ( - + {serverSettings.config.map.discordInvite && ( - + )} From 99818e37722b05352507706de0274112902e9a00 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Thu, 3 Feb 2022 21:26:54 -0500 Subject: [PATCH 74/77] Average Nest Slider - Adds a slider in the nest section to filter avg number of spawns - Renames withSliders to Pokemon, because it only serves Pokemon really - New config key, doesn't necessarily set defaults, sets the slider min/max as well - translation key --- public/base-locales/en.json | 3 +- server/src/configs/default.json | 3 +- server/src/models/Nest.js | 3 +- .../defaultFilters/buildDefaultFilters.js | 1 + server/src/services/ui/primary.js | 13 +++++++-- src/components/layout/drawer/Drawer.jsx | 5 ++-- .../drawer/{WithSliders.jsx => Pokemon.jsx} | 0 src/components/layout/drawer/WithSubItems.jsx | 28 +++++++++++++++---- 8 files changed, 43 insertions(+), 13 deletions(-) rename src/components/layout/drawer/{WithSliders.jsx => Pokemon.jsx} (100%) diff --git a/public/base-locales/en.json b/public/base-locales/en.json index d0a320586..374b0ed7b 100644 --- a/public/base-locales/en.json +++ b/public/base-locales/en.json @@ -489,5 +489,6 @@ "filters_reset_title": "Reset filters", "loading": "Loading {{category}}", "loading_icons": "Fetching Icons", - "loading_invasions": "Fetching Invasions" + "loading_invasions": "Fetching Invasions", + "slider_avgFilter": "Spawns/hr" } diff --git a/server/src/configs/default.json b/server/src/configs/default.json index bf8d48938..19121e54e 100644 --- a/server/src/configs/default.json +++ b/server/src/configs/default.json @@ -261,7 +261,8 @@ "enabled": false, "polygons": false, "pokemon": false, - "allPokemon": true + "allPokemon": true, + "avgFilter": [0, 200] }, "pokestops": { "enabled": false, diff --git a/server/src/models/Nest.js b/server/src/models/Nest.js index 101899902..1a898a556 100644 --- a/server/src/models/Nest.js +++ b/server/src/models/Nest.js @@ -18,7 +18,7 @@ module.exports = class Nest extends Model { const { areaRestrictions } = perms const pokemon = [] Object.keys(args.filters).forEach(pkmn => { - if (!pkmn.startsWith('g')) { + if (!pkmn.startsWith('o')) { pokemon.push(pkmn.split('-')[0]) } }) @@ -26,6 +26,7 @@ module.exports = class Nest extends Model { .whereBetween('lat', [args.minLat, args.maxLat]) .andWhereBetween('lon', [args.minLon, args.maxLon]) .whereIn('pokemon_id', pokemon) + .andWhereBetween('pokemon_avg', args.filters.onlyAvgFilter) if (areaRestrictions?.length) { getAreaSql(query, areaRestrictions) } diff --git a/server/src/services/defaultFilters/buildDefaultFilters.js b/server/src/services/defaultFilters/buildDefaultFilters.js index c371a6d2a..35368c1dd 100644 --- a/server/src/services/defaultFilters/buildDefaultFilters.js +++ b/server/src/services/defaultFilters/buildDefaultFilters.js @@ -35,6 +35,7 @@ module.exports = function buildDefault(perms) { enabled: defaultFilters.nests.enabled, pokemon: defaultFilters.nests.pokemon, polygons: defaultFilters.nests.polygons, + avgFilter: defaultFilters.nests.avgFilter, filter: pokemon.nests, } : undefined, pokestops: stopReducer ? { diff --git a/server/src/services/ui/primary.js b/server/src/services/ui/primary.js index b0482424f..fd89b5427 100644 --- a/server/src/services/ui/primary.js +++ b/server/src/services/ui/primary.js @@ -3,14 +3,22 @@ const { api: { pvp: { leagues } } } = require('../config') module.exports = function generateUi(filters, perms) { const ui = {} - const ignoredKeys = ['enabled', 'filter', 'showQuestSet', 'badge'] + const ignoredKeys = ['enabled', 'filter', 'showQuestSet', 'badge', 'avgFilter'] // builds the initial categories for (const [key, value] of Object.entries(filters)) { let sliders if (value) { switch (key) { - default: ui[key] = {}; break + case 'nests': + ui[key] = {} + sliders = { + secondary: [ + { + name: 'avgFilter', label: '', min: filters.nests.avgFilter[0], max: filters.nests.avgFilter[1], perm: 'nests', + }, + ], + }; break case 'pokemon': ui[key] = {} sliders = { @@ -46,6 +54,7 @@ module.exports = function generateUi(filters, perms) { case 'devices': if (!ui.admin) ui.admin = {} ui.admin[key] = true; break + default: ui[key] = {}; break } // builds each subcategory for (const [subKey, subValue] of Object.entries(value)) { diff --git a/src/components/layout/drawer/Drawer.jsx b/src/components/layout/drawer/Drawer.jsx index fd6c87f96..41f6d376c 100644 --- a/src/components/layout/drawer/Drawer.jsx +++ b/src/components/layout/drawer/Drawer.jsx @@ -9,7 +9,7 @@ import Utility from '@services/Utility' import SettingsMenu from './Settings' import WithSubItems from './WithSubItems' -import WithSliders from './WithSliders' +import PokemonSection from './Pokemon' import useStyles from '../../../hooks/useStyles' import { useStore, useStatic } from '../../../hooks/useStore' import Areas from './Areas' @@ -41,6 +41,7 @@ export default function Sidebar({ { @@ -32,8 +32,7 @@ export default function WithSubItems({ }} /> ) - } else { - filterCategory = ( + : ( { @@ -47,6 +46,23 @@ export default function WithSubItems({ }} /> ) + + if (category === 'nests' && subItem === 'sliders') { + return ( + + setFilters({ + ...filters, + [category]: { + ...filters[category], + avgFilter: values, + }, + })} + filterValues={filters[category]} + /> + + ) } return ( From 3e959e20371f773a0230c16876609f2a025e3493 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Fri, 4 Feb 2022 07:34:51 -0500 Subject: [PATCH 75/77] Remove unneeded sort --- server/src/services/initWebhooks.js | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/services/initWebhooks.js b/server/src/services/initWebhooks.js index 4c68bdc31..0f6e13ea1 100644 --- a/server/src/services/initWebhooks.js +++ b/server/src/services/initWebhooks.js @@ -44,7 +44,6 @@ module.exports = async function initWebhooks(config) { if (areas.geoJSON?.features) { areas.geoJSON.features = areas.geoJSON.features - .sort((a, b) => a.properties.name.localeCompare(b.properties.name)) .filter(x => !webhook.areasToSkip.includes(x.properties.name.toLowerCase())) } else { console.warn('No geofences found') From f5ab6c79585e71fab5f74acf2d6f87f98e8cd8a0 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Fri, 4 Feb 2022 17:12:20 -0500 Subject: [PATCH 76/77] Null Check & Locale Fix - Don't filter if slider range is "full" - Use existing locales - Add step adjustment in config --- public/base-locales/en.json | 3 +-- server/src/configs/default.json | 3 ++- server/src/models/Nest.js | 9 +++++++-- server/src/services/ui/primary.js | 7 +++++-- src/components/layout/dialogs/filters/SliderTile.jsx | 5 +++-- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/public/base-locales/en.json b/public/base-locales/en.json index 374b0ed7b..d0a320586 100644 --- a/public/base-locales/en.json +++ b/public/base-locales/en.json @@ -489,6 +489,5 @@ "filters_reset_title": "Reset filters", "loading": "Loading {{category}}", "loading_icons": "Fetching Icons", - "loading_invasions": "Fetching Invasions", - "slider_avgFilter": "Spawns/hr" + "loading_invasions": "Fetching Invasions" } diff --git a/server/src/configs/default.json b/server/src/configs/default.json index 19121e54e..4b3a90004 100644 --- a/server/src/configs/default.json +++ b/server/src/configs/default.json @@ -262,7 +262,8 @@ "polygons": false, "pokemon": false, "allPokemon": true, - "avgFilter": [0, 200] + "avgFilter": [0, 100], + "avgSliderStep": 1 }, "pokestops": { "enabled": false, diff --git a/server/src/models/Nest.js b/server/src/models/Nest.js index 1a898a556..19f4f5019 100644 --- a/server/src/models/Nest.js +++ b/server/src/models/Nest.js @@ -3,7 +3,10 @@ const i18next = require('i18next') const { pokemon: masterfile } = require('../data/masterfile.json') const getAreaSql = require('../services/functions/getAreaSql') const { pokemon: masterPkmn } = require('../data/masterfile.json') -const { api: { searchResultsLimit, queryLimits } } = require('../services/config') +const { + api: { searchResultsLimit, queryLimits }, + defaultFilters: { nests: { avgFilter } }, +} = require('../services/config') module.exports = class Nest extends Model { static get tableName() { @@ -26,7 +29,9 @@ module.exports = class Nest extends Model { .whereBetween('lat', [args.minLat, args.maxLat]) .andWhereBetween('lon', [args.minLon, args.maxLon]) .whereIn('pokemon_id', pokemon) - .andWhereBetween('pokemon_avg', args.filters.onlyAvgFilter) + if (!avgFilter.every((x, i) => x === args.filters.onlyAvgFilter[i])) { + query.andWhereBetween('pokemon_avg', args.filters.onlyAvgFilter) + } if (areaRestrictions?.length) { getAreaSql(query, areaRestrictions) } diff --git a/server/src/services/ui/primary.js b/server/src/services/ui/primary.js index fd89b5427..22516a821 100644 --- a/server/src/services/ui/primary.js +++ b/server/src/services/ui/primary.js @@ -1,5 +1,8 @@ /* eslint-disable no-restricted-syntax */ -const { api: { pvp: { leagues } } } = require('../config') +const { + api: { pvp: { leagues } }, + defaultFilters: { nests: { avgSliderStep } }, +} = require('../config') module.exports = function generateUi(filters, perms) { const ui = {} @@ -15,7 +18,7 @@ module.exports = function generateUi(filters, perms) { sliders = { secondary: [ { - name: 'avgFilter', label: '', min: filters.nests.avgFilter[0], max: filters.nests.avgFilter[1], perm: 'nests', + name: 'avgFilter', i18nKey: 'spawns_per_hour', label: '', min: filters.nests.avgFilter[0], max: filters.nests.avgFilter[1], perm: 'nests', step: avgSliderStep, }, ], }; break diff --git a/src/components/layout/dialogs/filters/SliderTile.jsx b/src/components/layout/dialogs/filters/SliderTile.jsx index 58c4de421..9e404795a 100644 --- a/src/components/layout/dialogs/filters/SliderTile.jsx +++ b/src/components/layout/dialogs/filters/SliderTile.jsx @@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next' export default function SliderTile({ filterSlide: { - name, min, max, color, disabled, label, low, high, + name, min, max, color, disabled, label, low, high, step, i18nKey, }, handleChange, filterValues, }) { const { t } = useTranslation() @@ -57,7 +57,7 @@ export default function SliderTile({ > setFullName(!fullName)} style={{ color: textColor }}> - {t(`slider_${name}`)} + {t(i18nKey || `slider_${name}`)} {['min', 'max'].map((each, index) => ( @@ -96,6 +96,7 @@ export default function SliderTile({ }} disabled={disabled} valueLabelDisplay="auto" + step={step} /> From 13077d5eca40df037d87ba9b5a49e55cd5856b34 Mon Sep 17 00:00:00 2001 From: TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com> Date: Fri, 4 Feb 2022 17:51:48 -0500 Subject: [PATCH 77/77] Block Error Reports for Node Modules - Return nothing if an external library has an error - Version Bump --- package.json | 2 +- src/index.jsx | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index fbb775ec1..ebce3818f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "reactmap", - "version": "1.0.15", + "version": "1.0.16", "description": "React based frontend map.", "main": "index.js", "author": "TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com>", diff --git a/src/index.jsx b/src/index.jsx index c8e924356..098776d54 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -24,6 +24,14 @@ if (process.env) { tracesSampleRate: SENTRY_TRACES_SAMPLE_RATE || 0.1, release: VERSION, environment: isDevelopment ? 'development' : 'production', + debug: true, + beforeSend(event) { + if (event?.exception?.values?.[0]?.stacktrace?.frames?.some(f => f.filename.includes('node_modules'))) { + // do nothing for external libraries + return + } + return event + }, }) // eslint-disable-next-line no-console console.log('ReactMap Version:', VERSION)