File size: 15,172 Bytes
7dfb20b
 
83db369
7dfb20b
9714f25
6b90a39
5120737
791ed17
7dfb20b
 
4f299cc
7dfb20b
4f299cc
 
fa49064
8e34432
4577c39
987a004
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1fee843
a3aac3d
bab82e1
ba4b0e6
 
 
7dfb20b
 
 
 
 
 
 
 
 
 
 
 
 
f44f27e
f1cc368
f44f27e
7dfb20b
 
 
 
 
f44f27e
 
7dfb20b
 
 
6319fe5
7dfb20b
 
 
83db369
 
4290743
83db369
36b91fc
b51cdf6
8922313
4340f17
4148bc2
a91bd7e
3fc96e5
7733a26
bb11ed7
89cb58d
4c37348
8503381
a3aac3d
 
 
 
 
 
 
 
 
2ebacf2
a3aac3d
dcc1609
 
7e61031
 
dcc1609
 
 
 
d57d8c9
7096b82
98cf34f
d57d8c9
 
d42d504
d06738a
d57d8c9
a2eeb49
 
 
0fb642d
 
 
 
83db369
 
 
cac676c
c47440a
12354f8
ab1173c
ba4b0e6
c65ceca
ba4b0e6
cac676c
12354f8
0fb642d
 
 
9714f25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
926c8ef
1bf46d0
 
 
ad998a1
50aa50b
1432bc1
b3bed5a
50aa50b
 
 
 
ad998a1
1abd420
9714f25
01ca5b7
fe001e3
194b422
fe001e3
01d3f74
4c37348
0da4ce6
1bce8d2
 
b51cdf6
1bce8d2
8055803
 
 
 
 
1df6078
 
 
718ca2f
3fc96e5
5d59cd3
7c2bc7f
c4766dd
1bce8d2
8ab940a
f839496
8ab940a
 
 
860c411
7dfb20b
 
 
 
 
4c73afa
0d33197
 
6b90a39
0d33197
 
 
b44051a
ba4b0e6
ef88e89
335ffd7
5d4c219
f57d935
ba4b0e6
83db369
335ffd7
83db369
f57d935
ba4b0e6
247198f
335ffd7
247198f
9714f25
 
335ffd7
1abd420
 
2ecdfa1
ad998a1
85d7da7
61219ad
2ecdfa1
1abd420
ad998a1
61219ad
85d7da7
6c0c3d9
85d7da7
be182e5
7d18a75
be182e5
1abd420
ef9369f
493358e
15acfc8
da03cdb
15acfc8
 
 
493358e
042373d
15acfc8
7dfb20b
 
83db369
 
7dfb20b
9714f25
 
7e945ae
3361d0f
c7c01be
3c8edf7
 
cccdf12
 
3361d0f
e012afc
1cddda2
b44051a
1cddda2
 
 
ef88e89
930564b
547afc5
3c8edf7
5d3e07e
13793ca
5d3e07e
 
 
 
 
 
 
 
 
 
 
 
13793ca
fc0cfed
 
 
c7c01be
 
 
 
72f6a3f
22d6195
c22fee2
930564b
22d6195
 
 
b44051a
2fe1ea1
1cddda2
 
 
 
d35e436
6b188da
fc0cfed
13793ca
fc0cfed
042d85b
 
 
ccfb10d
 
 
 
 
 
 
 
 
 
fc0cfed
5d3e07e
fc0cfed
3c8edf7
462c77b
9714f25
462c77b
 
 
 
 
 
 
 
 
 
 
 
 
11f9dba
462c77b
 
9714f25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b5b4524
 
 
4e95b67
b5b4524
4e95b67
b5b4524
4e95b67
b5b4524
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4e95b67
 
 
 
b5b4524
 
4e95b67
 
 
 
e5c0c47
 
 
 
 
 
ad998a1
 
 
 
 
60731a9
6c0c3d9
9bed813
 
 
 
 
 
ad998a1
9bed813
 
 
06d4cc3
9bed813
 
06d4cc3
b3bed5a
ad998a1
 
60731a9
b3bed5a
9bed813
462c77b
7dfb20b
 
 
 
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
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<head>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
  <link rel="preload" href="{{ url_for('static', filename='eye.gif') }}" as="image">
  <link rel="icon" type="image/png" href="https://i.ibb.co/gvKPXJD/eye.gif">
    <title>{{ page_title }}</title>
    <style>
        body {
            justify-content: center;
            background-color: black;
            display: flex;
            align-items:center;
            height: 100vh;
            margin: auto;
        }
      /* Webkit browsers like Chrome, Safari */
        ::-webkit-scrollbar {
            width: 10px;
            border-radius: 5px;
        }

        ::-webkit-scrollbar-thumb {
            background:  black;
            border-radius: 5px;
        }

        ::-webkit-scrollbar-thumb:hover {
            background:  black;
        }

        /* Firefox */
        * {
            scrollbar-width: thin;
            scrollbar-color: black yellow;
        }
        h3 {
            margin-bottom: 0px;
            margin-top: 0px !important;
            border-bottom: 2px solid yellow; 
            color:rgb(53, 53, 53); 
            font-family: 'Helvetica'; font-weight: 50;
        }
        .pulse {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            position: absolute;
            background-color: yellow;
            opacity: 0.5;
            animation: pulse-animation 5s infinite;
            margin-left: -20px;
            margin-top: -20px; 
        }
        .dot {
            border-style: solid;
            border-width: 2px;
            border-color: black;
            width: 5px;
            height: 5px;
            border-radius: 50%;
            position: absolute;
            background-color: yellow;
            margin-left: -4.5px;
            margin-top: -4.5px;
        }
        @keyframes pulse-animation {
            0% { transform: scale(0.1); opacity: 0.4; }
            100% { transform: scale(3); opacity: 0; }
        }
        .flex-container {
            display: flex;
            justify-content: left;
            align-items: top;
        }
        .outer-container {
            display: inline-block;
            justify-content: left;
            max-width: 70vw;
        }
        #feed-div {
            display: flex;
            justify-content: right; 
            width: 90%;
            height: 90%;
            position: relative;
            margin-right: 20px;
        }
        h1 {
          margin: 0px;
          margin-top: 20px;
        }
        .feed {
          transition: 0.3s ease;
          width: 100%;
          height: 100%;
          max-height: 80vh;
          border-radius: 5px;
        }
        .map-div {
            position: relative;
            width: 280px;
            height: 190px;
            margin-top: 3%;
            margin-bottom: 3%;
            box-sizing: border-box;
        }
        .info {
            cursor: default;
            display: flex;
            flex-direction: column;
            align-items: flex-start;
            width: 300px;
            transition 0.3s ease;
        }
        #info {
            transition 0.5s ease;
        }
        #info-text {
            margin-top: 20px;
            margin-bottom: 20px;
        }
        a:hover {
            background-color: yellow;
            color: black;
            transition: 0.5s ease;
        }
        a {
            background-color: transparent;
            border-radius: 5px;
            text-decoration: none;
            color:rgb(53, 53, 53);
            transition: 0.5s ease;
        }
        .hoverButton {
              color: rgb(53,53,53);
        }
        .tag {
            font-family: 'Helvetica'; 
            font-weight: 50;
            margin: auto;
            color:yellow;
        }

        #share {
          margin: auto;
          margin-left: 10px;
          color: yellow;
          transition: 0.3s ease;
        }
        #share:hover {
          opacity: 0.5;
        }
        #show-more {
          cursor: pointer;
        }
        #additional-info {
          display: block;
          height: 0px;
          overflow: hidden;
          transition: height 0.3s ease;
        }
        #additional-info.expanded {
          height: auto; 
        }


        @media only screen and (orientation: portrait) {
            .body {
              height: 85vh;
            }  
            h1 {
              margin-top: 20px !important;
            }
            .flex-container {
                flex-direction: column;
                align-items: left;
            }

            .map-div {
                width: 100%;
                height: 100%;
            }
            .outer-container {
                max-width: 85vw;
            }
            #feed-div {
                justify-content: left;
                width: 100%;
                max-height: 45%;
                margin-right: 0;
            }
            .feed {
              height: 100%;
              width: 100%;
              max-height: 100%;
            }
        }
    </style>
</head>

<body style="background-color: black;">
    <div class="outer-container">
            <div class="flex-container">

                    <div id="feed-div">
                      <img id="feed" class="feed" src="{{ url_for('static', filename='eye.gif') }}" />
                    </div>

              
                    <div class="info" id="info">
                      <h1 id="country" style="color:rgb(53, 53, 53); margin-top: 10px; font-family: 'Helvetica'; font-weight: 50; margin-bottom: 10px;"> searching...</h1>        
                      <a href="{{ ip_link }}" target="_blank"> <h3 style="border-bottom: 2px solid yellow;" id="location-name">{{ page_title }}</h3></a>

                      <div style="display: flex; margin-top: 22px; margin-bottom: 0%;">
                        <a href="?new=true" style="margin-right: 10px; display: inline-block;">
                          <button class="hoverButton" style="border-radius: 5px; border: 2px solid yellow; background-color: transparent; padding: 10px;">
                            another
                          </button>
                        </a>
                        <a href="?new=false&id={{ id }}" id="refreshSameFeedButton" style="display: inline-block;">
                          <button class="hoverButton" style="border-radius: 5px; border: 2px solid rgb(53, 53, 53); background-color: transparent; padding: 10px;">
                            refresh
                          </button>
                        </a>
                        <i id="share" class="fa-solid fa-link" data-id="{{ id }}"></i>
                        <p id="copied" class="tag" style="visibility: hidden;">copied</p>
                      </div>

                        <p id="info-text" style="color:rgb(53, 53, 53); font-family: 'Helvetica'; font-weight: 50;">

                          time: <span id="time"></span><br>

                          <span id="additional-info">
                            owner: {{ owner }}<br>
                            ip: {{ ip }}<br>  
                            lat, lon: {{ loc }}
                          </span>
                          
                          <span id="show-more">more <i style="margin-bottom:20px; color:rgb(53, 53, 53);" id="more-button" class="fa-solid fa-caret-down"></i></span>

                          <span class="tag"><br>a brayden moore website<br></span>thanks for visiting
                        
                        </p>
                    

                      <!--
                        <div class="map-div">
                            <img id="map" src="{{ url_for('static', filename='map_populated.png') }}" style="width: 100%; height: 100%;" />
                            <div class="dot" style="left: {{ X }}%; top: {{ Y }}%;"></div>
                            <div class="pulse" style="left: {{ X }}%; top: {{ Y }}%;"></div>
                        </div>
                      -->
                    </div>

                </div>
    </div>


    <script>

    // Handle feed load and refresh
    let loadingGif = "{{ url_for('static', filename='eye.gif') }}";
    let currentFeed;
    let firstLoad = true;
    document.addEventListener("DOMContentLoaded", function() {
        const feed = document.getElementById("feed");
        feed.style.width = "80px";
        feed.style.height = "50px";
        feed.src = loadingGif;
        feed.style.opacity = "0.2";

        const infoDiv = document.getElementById("info");
        const infoText = document.getElementById("info-text");
        infoText.style.opacity = "0";
      
        const locationName = document.getElementById('location-name');
        locationName.textContent = "{{ page_title }}";
      
        const newUrl = "{{ url }}";
        
        function refreshImage() {
            let xhr = new XMLHttpRequest();
            xhr.open('HEAD', newUrl + '?t=' + new Date().getTime(), true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        if (xhr.getResponseHeader('Content-Type') === 'image/jpeg') {
                            img.src = newUrl + '?t=' + new Date().getTime();
                        }
                    }
                }
            };
            xhr.send();
        }
        
        const img = new Image();
        img.onload = function() {
            if (firstLoad) {
              infoDiv.style.opacity = "0";
            }
            firstLoad = false;
            old = newUrl;
            setTimeout(() => {
              feed.src = this.src;
              locationName.textContent = "{{ name }}";
              feed.style.width = "100%";
              feed.style.height = "70%";
              feed.style.opacity = "1";
              infoDiv.style.opacity = "1";
            }, 100);

            const infoText = document.getElementById("info-text");
            infoText.style.opacity = "1";
          
            setTimeout(refreshImage, 1000);
            country.textContent = "{{ country }}"
        };
        
        img.onerror = function() {
            feed.style.width = "80px";
            feed.style.height = "50px";
            feed.src = loadingGif;
            
            const urlParams = new URLSearchParams(window.location.search);
            const countryElement = document.getElementById("country");
            if (urlParams.get('new') === 'false') {
                countryElement.textContent = "couldn't connect.";
            }
            else {
                window.location.href = "?new=true";
            }

        };
        
        img.src = newUrl;
    });

    // Time count
    document.addEventListener("DOMContentLoaded", function() {
      const timezone = "{{ timezone }}"; 
      setInterval(() => {
        const now = new Date();
        const options = { 
          timeZone: timezone, 
          hour: '2-digit', 
          minute: '2-digit', 
          second: '2-digit',
          hour12: true
        };
        const timeString = now.toLocaleTimeString('en-US', options);
        document.getElementById("time").textContent = timeString;
      }, 200);
    });

    // Copy link
    document.addEventListener("DOMContentLoaded", function() {
      const shareIcon = document.getElementById("share");
      const copiedText = document.getElementById("copied");

      shareIcon.addEventListener("click", function() {
          const id = this.getAttribute("data-id");
          const urlToCopy = `${window.location.origin}/?new=false&id=${id}`;
          
          navigator.clipboard.writeText(urlToCopy).then(() => {
              console.log("URL copied to clipboard");
              shareIcon.className = "fa-solid fa-check";
              //copiedText.style.visibility = "visible";
          }).catch(err => {
              console.log("Could not copy text: ", err);
          });
      });
  });

  // Connect vs search
  document.addEventListener("DOMContentLoaded", function() {
      const urlParams = new URLSearchParams(window.location.search);
      const countryElement = document.getElementById("country");

      if (urlParams.get('new') === 'false') {
          countryElement.textContent = "connecting...";
      }
  });


  // Fullscreen
    document.addEventListener("DOMContentLoaded", function() {
    const feed = document.getElementById("feed");
    let isFullscreen = false; 

    function toggleFullScreen() {
        if (!isFullscreen) {
            if (this.requestFullscreen) {
                this.requestFullscreen();
            } else if (this.mozRequestFullScreen) {
                this.mozRequestFullScreen();
            } else if (this.webkitRequestFullscreen) {
                this.webkitRequestFullscreen();
            } else if (this.msRequestFullscreen) {
                this.msRequestFullscreen();
            }
        } else {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        }
    }

    feed.addEventListener("click", toggleFullScreen);
    feed.addEventListener("touchstart", toggleFullScreen);

    document.addEventListener("fullscreenchange", function() {
        isFullscreen = !isFullscreen;
    });
});

  // Change feed on space bar press
    document.addEventListener('keydown', function(event) {
      if (event.keyCode === 32) { 
        window.location.href = '/?new=true';
      }
    });

  // Show more info
  document.addEventListener('DOMContentLoaded', function() {
    const infoText = document.getElementById('info-text');
    const additionalInfo = document.getElementById('additional-info');
    const showMore = document.getElementById('show-more');
    const moreButton = document.getElementById('more-button');
  
    // Initial setup
    additionalInfo.style.height = '0';
    additionalInfo.style.overflow = 'hidden';
    additionalInfo.style.transition = 'height 0.3s ease-in-out';
  
    infoText.addEventListener('click', function() {
      if (additionalInfo.style.height === '0px') {
        const scrollHeight = additionalInfo.scrollHeight;
        additionalInfo.style.height = `${scrollHeight}px`;
        showMore.textContent = 'less <i style="margin-bottom:20px; color:rgb(53, 53, 53);" id="more-button" class="fa-solid fa-caret-up"></i>';
      } else {
        additionalInfo.style.height = '0';
        showMore.textContent = 'more <i style="margin-bottom:20px; color:rgb(53, 53, 53);" id="more-button" class="fa-solid fa-caret-down"></i>';
      }
    });
  });



      
    </script>
</body>

</html>