Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/routes/api.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ const router = express.Router();
const map = require('../data/map.js');
const utils = require('../services/utils.js');
const masterfile = require('../../static/data/masterfile.json');
const { config } = require('../services/discord.js');
const skipForms = ['shadow', 'purified'];

router.get('/get_data', async (req, res) => {
Expand DownExpand Up@@ -57,6 +58,31 @@ const getSettings = (perms) => {
const level50String = i18n.__('filter_level50_stats');
const level51String = i18n.__('filter_level51_stats');
const weatherDetailsString = i18n.__('settings_weather_details');
const pokemonNotificationsString = i18n.__('settings_pokemon_notifications');

// Check if perms is not set and discord config not set, then allow all permissions
if (!config.discord.enabled && !perms) {
perms = {
map: true,
pokemon: true,
raids: true,
gyms: true,
pokestops: true,
quests: true,
lures: true,
invasions: true,
spawnpoints: true,
iv: true,
pvp: true,
s2cells: true,
submissionCells: true,
nests: true,
portals: true,
scanAreas: true,
weather: true,
devices: true,
};
}

if (perms.pokemon) {
/*
Expand DownExpand Up@@ -98,6 +124,14 @@ const getSettings = (perms) => {
'filter': generateShowHideButtons('pokemon-timers', 'pokemon-timers'),
'type': pokemonSettingsString,
});
settingsData.push({
'id': {
'sort': utils.zeroPad(3, 3),
},
'name': pokemonNotificationsString,
'filter': generateShowHideButtons('pokemon-notifications', 'pokemon-notifications'),
'type': pokemonSettingsString,
});
}
if (perms.gyms || perms.raids) {
settingsData.push({
Expand Down
2 changes: 2 additions & 0 deletions src/views/header.mustache
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@
<link rel="stylesheet" type="text/css" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css" />
<link rel="stylesheet" type="text/css" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/leaflet.locatecontrol@v0.70.0/dist/L.Control.Locate.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" />
<link rel="stylesheet" type="text/css" href="/css/all.css" />

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
Expand All@@ -27,6 +28,7 @@
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.18/r-2.2.2/rg-1.1.0/sc-1.5.0/datatables.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/leaflet.locatecontrol@v0.70.0/dist/L.Control.Locate.min.js" charset="utf-8"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
{{#google_analytics_id}}
<script type="text/javascript" src="//google-analytics.com/analytics.js"></script>
{{/google_analytics_id}}
Expand Down
86 changes: 81 additions & 5 deletions static/js/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -123,6 +123,8 @@ let showPopupPvp;
let showMinPokePopup;
let showWeatherDetails;

let showPokemonNotifications;

let tileLayer;
let nestLayer = new L.LayerGroup();
let scanAreaLayer = new L.LayerGroup();
Expand All@@ -135,6 +137,8 @@ let scanAreasDb = {};
let cpMultipliers = {};
let defaultRarity = {};

let pokemonNotificationsSent = {};

let skipForms = ['Shadow', 'Purified'];

const kanto = [1, 151];
Expand DownExpand Up@@ -430,6 +434,7 @@ $(function () {
portal: portalFilterNew,
weather: weatherFilterNew,
device: deviceFilterNew,
// TODO: Export all settings
};
let json = JSON.stringify(settings);
let el = document.createElement('a');
Expand DownExpand Up@@ -1170,6 +1175,9 @@ function loadStorage () {
if (defaultSettings['level51-stats'] === undefined) {
defaultSettings['level51-stats'] = { show: configPvp.l51stats };
}
if (defaultSettings['pokemon-notifications'] == undefined) {
defaultSettings['pokemon-notifications'] = { show: false }; // TODO: Configurable as default value
}
store('settings', JSON.stringify(defaultSettings));
settings = defaultSettings;
} else {
Expand DownExpand Up@@ -1234,6 +1242,9 @@ function loadStorage () {
if (settings['level51-stats'] === undefined) {
settings['level51-stats'] = { show: configPvp.l51stats };
}
if (settings['pokemon-notifications'] === undefined) {
settings['pokemon-notifications'] = { show: false }; // TODO: Configurable as default value
}
}
clusterPokemon = settings['pokemon-cluster'].show;
clusterGyms = settings['gym-cluster'].show;
Expand All@@ -1255,6 +1266,7 @@ function loadStorage () {
showLevel41Stats = settings['level41-stats'].show;
showLevel50Stats = settings['level50-stats'].show;
showLevel51Stats = settings['level51-stats'].show;
showPokemonNotifications = settings['pokemon-notifications'].show;
}

function initMap () {
Expand DownExpand Up@@ -1577,6 +1589,7 @@ function initMap () {
const newShowLevel41Stats = settingsNew['level41-stats'].show;
const newShowLevel50Stats = settingsNew['level50-stats'].show;
const newShowLevel51Stats = settingsNew['level51-stats'].show;
const newShowPokemonNotifications = settingsNew['pokemon-notifications'].show;
if (clusterPokemon !== newClusterPokemon ||
showPokemonGlow !== newShowPokemonGlow ||
showPokemonTimers !== newShowPokemonTimers ||
Expand All@@ -1586,7 +1599,8 @@ function initMap () {
showLevel40Stats !== newShowLevel40Stats ||
showLevel41Stats !== newShowLevel41Stats ||
showLevel50Stats !== newShowLevel50Stats ||
showLevel51Stats !== newShowLevel51Stats) {
showLevel51Stats !== newShowLevel51Stats ||
showPokemonNotifications !== newShowPokemonNotifications) {
$.each(pokemonMarkers, function (index, pokemon) {
if (clusterPokemon) {
clusters.removeLayer(pokemon.marker);
Expand DownExpand Up@@ -1647,6 +1661,7 @@ function initMap () {
showLevel41Stats = newShowLevel41Stats;
showLevel50Stats = newShowLevel50Stats;
showLevel51Stats = newShowLevel51Stats;
showPokemonNotifications = newShowPokemonNotifications;
store('show_pokemon_timers', newShowPokemonTimers);
store('show_raid_timers', newShowRaidTimers);
store('show_invasion_timers', newShowInvasionTimers);
Expand All@@ -1662,6 +1677,7 @@ function initMap () {
store('level41_stats', newShowLevel41Stats);
store('level50_stats', newShowLevel50Stats);
store('level51_stats', newShowLevel51Stats);
store('show_pokemon_notifications', newShowPokemonNotifications);

if (pokemonMarkers.length === 0 ||
gymMarkers.length === 0 ||
Expand DownExpand Up@@ -1938,7 +1954,7 @@ function loadSearchData (id, value) {
}

function centerOnMap(lat, lon) {
$('#searchModal').modal('toggle');
$('#searchModal').modal('hide');
let latlng = new L.LatLng(lat, lon);
let zoom = maxZoom;
map.setView(latlng, zoom);
Expand DownExpand Up@@ -2411,6 +2427,9 @@ function loadData () {
} else {
pokemon.marker.addTo(map);
}
// Show Pokemon notification
// TODO: Check if setting is set for notifications
showPokemonNotification(pokemon);

} else {
if (oldPokemon.expire_timestamp !== pokemon.expire_timestamp) {
Expand DownExpand Up@@ -3081,7 +3100,7 @@ const getPokemonPopupContent = (pokemon) => {
const getIV = (pokemon) => {
if (pokemon.atk_iv !== null && pokemon.atk_iv !== undefined && popupDetails.pokemon.iv) {
const ivColors = { 0: 'red', 66: 'orange', 82: 'yellow', 100: 'green' }
const ivPercent = ((pokemon.atk_iv + pokemon.def_iv + pokemon.sta_iv) / .45).toFixed(2);
const ivPercent = calculateIV(pokemon);
let selectedColor
Object.keys(ivColors).forEach(range => ivPercent >= parseInt(range) ? selectedColor = ivColors[range] : '');
return `
Expand DownExpand Up@@ -4732,7 +4751,8 @@ function manageSelectButton(e, isNew) {
type === 'pvp-level40-stats' ||
type === 'pvp-level41-stats' ||
type === 'pvp-level50-stats' ||
type === 'pvp-level51-stats') {
type === 'pvp-level51-stats' ||
type === 'pokemon-notifications') {
switch (info) {
case 'hide':
shouldShow = settingsNew[id].show === false;
Expand DownExpand Up@@ -5264,7 +5284,8 @@ function manageSelectButton(e, isNew) {
type === 'pvp-level40-stats' ||
type === 'pvp-level41-stats' ||
type === 'pvp-level50-stats' ||
type === 'pvp-level51-stats') {
type === 'pvp-level51-stats' ||
type === 'pokemon-notifications') {
switch (info) {
case 'hide':
settingsNew[id].show = false;
Expand DownExpand Up@@ -6135,6 +6156,58 @@ function getCpAtLevel(id, form, level, isMax) {
return 0;
}

const showPokemonNotification = (pokemon) => {
// Check if we have at least rendered the map once before showing notifications
if (lastUpdate === 0)
return;

// Check if pokemon notifications are enabled
if (!showPokemonNotifications) {
return;
}
if (pokemonNotificationsSent[pokemon.id]) {
// Prevent notifications of the same pokemon twice
return;
}
pokemonNotificationsSent[pokemon.id] = true;
const iv = pokemon.atk_iv !== null ? calculateIV(pokemon) : '?';
const name = getPokemonName(pokemon.pokemon_id);
const formName = getFormName(pokemon.form);
// TODO: Add pokemon costume to notification
const genderIcon = getGenderIcon(pokemon.gender);
const title = `Found Pokemon: ${name}${pokemon.form > 0 ? ' (Form: ' + formName + ')' : ''}`;
const message = `IV: ${iv}% Lvl: ${pokemon.level || '?'} Gender: ${genderIcon}`;
const icon = getPokemonIcon(pokemon.pokemon_id, pokemon.form, 0, pokemon.gender, pokemon.costume);
const iconUrl = `${availableIconStyles[selectedIconStyle].path}/${icon}.png`;
let notification = toastr.info(message, title, {
closeButton: true,
positionClass: 'toast-top-right',
preventDuplicates: true,
onclick: () => {
centerOnMap(pokemon.lat, pokemon.lon);
},
showDuration: '2000',
hideDuration: '1000',
timeOut: '6000',
extendedTimeOut: '1500',
showEasing: 'swing',
hideEasing: 'linear',
showMethod: 'fadeIn',
hideMethod: 'fadeOut',
});
notification.removeClass('toast-info');
notification.css({
'padding-left': '74px',
'background-image': `url('${iconUrl}')`,
'background-size': '48px',
'background-color': '#15151D', // TODO: Check dark mode?
});
};

const calculateIV = (pokemon) => {
return ((pokemon.atk_iv + pokemon.def_iv + pokemon.sta_iv) / .45).toFixed(2);
};

// MARK: - Init Filter

function populateImage (row, type, set, meta) {
Expand DownExpand Up@@ -7340,6 +7413,9 @@ function loadFilterSettings (e) {
showLevel51Stats = obj.level51_stats;
store('level51_stats', showLevel51Stats);

showPokemonNotifications = obj.show_pokemon_notifications;
store('show_pokemon_notifications', showPokemonNotifications);

if (showGyms) {
$('#show-gyms').addClass('active');
$('#hide-gyms').removeClass('active');
Expand Down