|
<!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|safe }}</title> |
|
<style> |
|
body { |
|
justify-content: center; |
|
background-color: black; |
|
display: flex; |
|
align-items:center; |
|
height: 100vh; |
|
margin: auto; |
|
} |
|
|
|
::-webkit-scrollbar { |
|
width: 10px; |
|
border-radius: 5px; |
|
} |
|
|
|
::-webkit-scrollbar-thumb { |
|
background: black; |
|
border-radius: 5px; |
|
} |
|
|
|
::-webkit-scrollbar-thumb:hover { |
|
background: black; |
|
} |
|
|
|
|
|
* { |
|
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: opacity 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:rgb(53,53,53); |
|
} |
|
|
|
#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|safe }}</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<br> |
|
<a href="https://huggingface.co/spaces/BraydenMoore/a-random-unsecured-camera/tree/main" target="_blank">see the code</a> |
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
</div> |
|
|
|
|
|
<script> |
|
|
|
|
|
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.15"; |
|
|
|
const infoDiv = document.getElementById("info"); |
|
const infoText = document.getElementById("info-text"); |
|
infoText.style.opacity = "0"; |
|
|
|
const locationName = document.getElementById('location-name'); |
|
const countryElement = document.getElementById("country"); |
|
locationName.textContent = "{{ page_title|safe }}"; |
|
|
|
const newUrl = decodeURIComponent("{{ url|safe }}"); |
|
|
|
async function refreshImage() { |
|
const timestamp = new Date().getTime(); |
|
|
|
const fetchUrl = newUrl; |
|
|
|
try { |
|
const response = await fetch(fetchUrl, { method: 'HEAD' }); |
|
|
|
if (response.ok && response.headers.get('Content-Type') === 'image/jpeg') { |
|
|
|
img.src = newUrl; |
|
} |
|
} catch (error) { |
|
console.error('Fetch failed:', error); |
|
} |
|
} |
|
|
|
const img = new Image(); |
|
img.onload = function() { |
|
if (firstLoad) { |
|
countryElement.textContent = "connecting..."; |
|
infoDiv.style.opacity = "0"; |
|
} |
|
firstLoad = false; |
|
setTimeout(() => { |
|
feed.src = newUrl; |
|
locationName.textContent = "{{ name|safe }}"; |
|
countryElement.textContent = "{{ country|safe }}"; |
|
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"; |
|
|
|
refreshImage(); |
|
}; |
|
|
|
img.onerror = function() { |
|
console.error('Error loading image', this.src); |
|
const urlParams = new URLSearchParams(window.location.search); |
|
|
|
if (urlParams.get('id')) { |
|
firstLoad = false; |
|
feed.style.width = "80px"; |
|
feed.style.height = "50px"; |
|
feed.src = loadingGif; |
|
feed.style.opacity = "0.15"; |
|
countryElement.textContent = "couldn't connect."; |
|
} |
|
else if (firstLoad) { |
|
window.location.href = "?new=true"; |
|
} |
|
else { |
|
firstLoad = false; |
|
console.log("Trying again") |
|
setTimeout(refreshImage, 250); |
|
} |
|
}; |
|
|
|
console.log('Feed load success'); |
|
}); |
|
|
|
|
|
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); |
|
}); |
|
|
|
|
|
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"; |
|
|
|
}).catch(err => { |
|
console.log("Could not copy text: ", err); |
|
}); |
|
}); |
|
}); |
|
|
|
|
|
document.addEventListener("DOMContentLoaded", function() { |
|
const urlParams = new URLSearchParams(window.location.search); |
|
const countryElement = document.getElementById("country"); |
|
|
|
if (urlParams.get('new') === 'false') { |
|
countryElement.textContent = "connecting..."; |
|
} |
|
}); |
|
|
|
|
|
|
|
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; |
|
}); |
|
}); |
|
|
|
|
|
document.addEventListener('keydown', function(event) { |
|
if (event.keyCode === 32) { |
|
window.location.href = '/?new=true'; |
|
} |
|
}); |
|
|
|
|
|
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'); |
|
|
|
|
|
additionalInfo.style.height = '0'; |
|
additionalInfo.style.overflow = 'hidden'; |
|
additionalInfo.style.transition = 'height 0.3s ease-in-out'; |
|
|
|
showMore.addEventListener('click', function() { |
|
if (additionalInfo.style.height === '0px') { |
|
const scrollHeight = additionalInfo.scrollHeight; |
|
additionalInfo.style.height = `${scrollHeight}px`; |
|
showMore.innerHTML = '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.innerHTML = 'more <i style="margin-bottom:20px; color:rgb(53, 53, 53);" id="more-button" class="fa-solid fa-caret-down"></i>'; |
|
} |
|
}); |
|
}); |
|
|
|
|
|
|
|
|
|
</script> |
|
</body> |
|
|
|
</html> |