-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
363 lines (321 loc) · 16.2 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
<!doctype HTML>
<html>
<head>
<title>Nearby Seattle Pokemon</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" crossorigin="anonymous"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous" />
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" crossorigin="anonymous"
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous" />
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" crossorigin="anonymous" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"></script>
<!-- The discord.io client file -->
<script src="index.js"></script>
<!--font awesome -->
<script src="https://use.fontawesome.com/b45c3c60e3.js"></script>
<!-- vue -->
<script src="https://unpkg.com/vue"></script>
<style>
.pokemon {
margin: 1em;
border-bottom: 1pt solid gray;
padding: 1em;
min-height: 100px;
}
</style>
<link rel="apple-touch-icon" sizes="57x57" href="apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">
<link rel="manifest" href="manifest.json">
<meta name="msapplication-TileColor" content="#f6bd20">
<meta name="msapplication-TileImage" content="ms-icon-144x144.png">
<meta name="theme-color" content="#f6bd20">
</head>
<body style='background:lightgray;'>
<div class='container' style='background:white;min-height:100vh'>
<div class="page-header">
<h1>Nearby Pokemon <small id='status-text'>Loading GPS...</small></h1>
</div>
<div id="app">
<p>This is powered by the incredibly generous people at SeattlePokeMaps. They do an amazing job and make this possible.
This simply aggregates the results and displays what's near to you and hides the ones that have already fled.
Your current accuracy: {{Math.round(accuracy)}}</p>
<div class="media pokemon" v-for="pokemon in pokemons">
<div class="media-left">
<a href="#">
<img class="media-object" :src=pokemon.pic_url width="60" alt="...">
</a>
</div>
<div class="media-body">
<a class='pull-right btn btn-success btn-lg' :class='{"btn-danger": pokemon.time_to_catch < 5*60}' :href=pokemon.href>Go!</a>
<h4 class="media-heading">{{pokemon.name}} <small>about {{pokemon.distance}} </small></h4>
<p>{{pokemon.desc}}</p>
<p>Leaves at {{pokemon.leave_time}}. We estimate it's about {{pokemon.travel_time}} away.
<span v-if="pokemon.time_to_catch < 0">You will probably not make it in time</span>
<span v-else> You'll have about {{Math.round(pokemon.time_to_catch/60)}} minutes to catch it. </span> {{pokemon.message}}
</p>
</div>
</div>
<div v-if="pokemons.length == 0" class='text-center'>
<i class="fa fa-circle-o-notch fa-spin fa-5x fa-fw"></i>
<span class="sr-only">Loading...</span>
<h2>Loading</h2>
</div>
</div>
</div>
<script>
/**
* Pokefinder by Matthew Carlson
* This is very much still a hack
* Yes it does include a token for a test throw away account. Please be responsible and don't abuse it.
* Todo items:
* Integrate with new messages coming from the server
* Update count downs
* Refresh geolocation data every few minutes and change lists
* Integrate google maps for more accurate estimation of time? Without overdoing my requests per second?
*
* Feel free to open up issues on github.com
* */
var clientReady = false;
var gpsReady = false;
var gpsChanged = false;
var pokemonDeferedProcessing = [];
var coord = null;
var client = new Discord.Client({
token: "Mjg3NzkxMjM2MDA0MzE1MTM3.C50a-w.5ncXcE4SX8Cj16xAY4pJWylll50",
autorun: true
});
//connect to discord
client.connect();
navigator.geolocation.getCurrentPosition(function (location) {
if (clientReady == false) $("#status-text").text("Loading Discord Client");
else if (pokemonDeferedProcessing.length == 0) $("#status-text").text("Loading Pokemon");
else $("#status-text").text("");
console.log(location.coords);
gpsReady = true;
coord = location.coords;
app.accuracy = location.coords.accuracy;
if (pokemonDeferedProcessing.length != 0) {
updatePokemon();
}
navigator.geolocation.watchPosition(updated_position);
});
function updated_position(position) {
console.log("position has changed");
console.log(position);
coord = location.coords;
app.accuracy = location.coords.accuracy;
gpsChanged = true;
}
var app = new Vue({
el: '#app',
data: {
progress: 0,
accuracy: "N/A",
pokemons: []
}
})
var channels_to_fetch = [];
var channel_names_to_fetch = ["kirkland", "redmond", "bellevue", "mercer-island", "seattle"];
client.on('ready', function () {
console.log("%s (%s)... in the browser!", client.username, client.id);
clientReady = true;
if (gpsReady == false) $("#status-text").text("Loading GPS");
else $("#status-text").text("Loading Pokemon");
console.log(client.channels);
for (var i in client.channels) {
console.log(client.channels[i].id + " = " + client.channels[i].name);
if ($.inArray(client.channels[i].name, channel_names_to_fetch) != -1) {
channels_to_fetch.push(client.channels[i].id);
}
}
console.log(channels_to_fetch);
updatePokemon();
});
client.on('message', function (user, userID, channelID, message, event) {
console.log(user);
//if it's not the bot, don't bother
if (user != "harmony") return;
console.log(channelID);
//check if this is on the list of approved channels
if (!$.inArray(channelID, channels_to_fetch)) {
console.log("Ignoring message from " + channelID + " channel");
}
//TODO: process channel id
console.log(message);
console.log(event);
});
/*
index.html:143 264632263331807234 = central-seattle
index.html:143 264632263789117440 = General
index.html:143 265335143118536707 = south-seattle
index.html:143 266107119286091777 = chat
index.html:143 267072007093354496 = total-area-scanned
index.html:143 267446101261549578 = scan-filter-list
index.html:143 267727262831476738 = admin-channel
index.html:143 267760025672351765 = events-page
index.html:143 268075363890888705 = harmony-support
index.html:143 268195439675834378 = 100iv
index.html:143 268678885858607104 = channel-news
index.html:143 270326510299250689 = faq
index.html:143 271184253784424448 = donations
index.html:143 271759700633190401 = announcements
index.html:143 272151297208352772 = lower-east
index.html:143 272230046566055936 = huze-heatmap
index.html:143 273599411425247235 = donor-area
index.html:143 279148663643570176 = north-seattle
index.html:143 279486769471422464 = upper-east
*/
//fetchs all the pokemon from the lists in discord
function updatePokemon() {
if (clientReady == false) return;
// check if there's pokemon we need to process
if (pokemonDeferedProcessing.length != 0 && gpsReady == true) {
console.log("Processing " + pokemonDeferedProcessing.length + " defered pokemon");
for (var i = 0; i < pokemonDeferedProcessing.length; i++) {
processPokemon(pokemonDeferedProcessing[i].embeds[0]);
}
pokemonDeferedProcessing = [];
}
else {
for (var index = 0; index < channels_to_fetch.length; index++) {
// the pokemon from the clients
console.log("Fetching channel " + channels_to_fetch[index]);
client.getMessages({ channelID: channels_to_fetch[index], limit: 100 }, function gotNewPokemons(error, pokemons) {
for (var i = 0; i < pokemons.length; i++) {
if (gpsReady)
processPokemon(pokemons[i].embeds[0]);
else
pokemonDeferedProcessing.push(pokemons[i]);
}
});
}
}
if (gpsReady) $("#status-text").text("");
}
//reprocesses the pokemon and figure out how far it is
function reprocessPokemon() {
if (!gpsChanged) return;
for (var i = 0; i < app.pokemons.length; i++) {
var pokemon = app.pokemons[i];
}
gpsChanged = false;
}
var directionsService = null;
//processes a pokemon
function processPokemon(pokemon) {
console.log("Processing pokemon", pokemon);
//Figure out when it will disappear
var time_exp = /\d?\d\:\d\d\:\d\d/;
var leave_time = pokemon.description.search(time_exp);
var leave_time = pokemon.description.substring(leave_time, leave_time + 8);
var curr_time = new Date();
var leave_time = new Date(curr_time.toDateString() + " " + leave_time);
var time_left = (leave_time.getTime() - curr_time.getTime()) / 1000; //difference between them in seconds
//if they've already disappeared
if (time_left <= 0) {
console.log("skipping " + pokemon.title + " leaving at " + leave_time.toLocaleTimeString("en-US"));
return;
}
//if there's more than 8 hours on the clock, something is wrong
if (time_left >= 8 * 60 * 60) {
console.log("Skipping " + pokemon.title + " because it's from yesterday probably");
return;
}
//calculate distance
var location_exp = /-?\d+\.\d+,-?\d+\.\d+/;
var location = pokemon.url.substring(pokemon.url.search(location_exp));
//console.log(location);
var lat = location.substring(0, location.indexOf(","));
var long = location.substring(location.indexOf(',') + 1);
var raw_dist = distance(coord.latitude, coord.longitude, lat, long);
var dist = raw_dist.toFixed(2) + " miles";
if (dist <= 1) {
raw_dist *= 5280;
distance = Math.round(raw_dist * 5280) + " ft";
}
//get an accurate estimation of how long it will take
//console.log(pokemon);
//see if we can get there quickly enough
var time_to_catch = time_left - Math.round(raw_dist / 25 * 60 * 60);
//compute new pokemon
var newpokemon = {
name: pokemon.title,
pic_url: pokemon.thumbnail.url,
raw_dist: raw_dist,
distance: dist,
location: { "lat": lat, "long": long },
desc: pokemon.description.substring(0, pokemon.description.indexOf('Until')),
leave_time: leave_time.toLocaleTimeString("en-US"),
href: pokemon.url,
travel_time: Math.round(raw_dist / 25 * 60) + " minutes",
time_to_catch: time_to_catch,
}
//expirment with google map api's
/*if (directionsService == null) directionsService = new google.maps.DirectionsService;
directionsService.route({
origin: lat + "," + long,
destination: coord.latitude + "," + coord.longitude,
travelMode: 'DRIVING'
}, function (response, status) {
if (status === 'OK') {
console.log(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});*/
//add it to the list
app.pokemons.push(newpokemon);
//sort the pokemon based on distance
app.pokemons.sort(pokemonSorter);
}
//Sorts pokemon by distance
function pokemonSorter(a, b) {
return a.raw_dist - b.raw_dist;
}
//only call this is we have resonable accuracy
function estimate_time(lat1, lon1, lat2, lon2) {
//http://maps.googleapis.com/maps/api/directions/outputFormat?parameters
}
//::: Passed to function: :::
//::: lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees) :::
//::: lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees) :::
//::: unit = the unit you desire for results :::
//::: where: 'M' is statute miles (default) :::
//::: 'K' is kilometers :::
//::: 'N' is nautical miles :::
//::: :::
//::: Official Web site: http://www.geodatasource.com :::
//::: :::
//::: GeoDataSource.com (C) All Rights Reserved 2015
function distance(lat1, lon1, lat2, lon2, unit) {
var radlat1 = Math.PI * lat1 / 180
var radlat2 = Math.PI * lat2 / 180
var theta = lon1 - lon2
var radtheta = Math.PI * theta / 180
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
dist = Math.acos(dist)
dist = dist * 180 / Math.PI
dist = dist * 60 * 1.1515
if (unit == "K") { dist = dist * 1.609344 }
if (unit == "N") { dist = dist * 0.8684 }
return dist;
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAlAbMOQfYXIASAEo4ThAIPrA6Vpare09E" async defer></script>
</body>
</html>