index.ejs

1<!doctype html>
2<html lang="en">
3	<head>
4		<meta charset="UTF-8" />
5		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6		<title><%= title %></title>
7		<link
8			href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
9			rel="stylesheet"
10			integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
11			crossorigin="anonymous"
12		/>
13		<script
14			src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"
15			integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r"
16			crossorigin="anonymous"
17		></script>
18		<script
19			src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
20			integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy"
21			crossorigin="anonymous"
22		></script>
23	</head>
24	<body>
25		<%- include('_partials/header') %>
26		<main>
27			<div class="px-4 pt-5 my-5 text-center">
28				<h1 class="display-4 fw-bold text-body-emphasis">
29					Welcome to the Image Uploader
30				</h1>
31				<div class="col-lg-6 mx-auto">
32					<p class="lead mb-4">
33						This is an
34						<a
35							href="https://github.com/stellaOnEstrogen/image-uploader"
36							class="text-body-emphasis"
37							>open-source project</a
38						>
39						that allows you to upload images and videos to a server, However,
40						you must have the master key to register.
41					</p>
42					<div class="d-grid gap-2 d-sm-flex justify-content-sm-center mb-5">
43						<a href="/register" class="btn btn-primary btn-lg px-4 me-sm-3"
44							>Register</a
45						>
46						<a href="/login" class="btn btn-outline-secondary btn-lg px-4"
47							>Login</a
48						>
49					</div>
50				</div>
51				<div class="overflow-hidden" style="max-height: 30vh">
52					<div class="container px-5">
53						<img
54							src="https://contrib.rocks/image?repo=stellaOnEstrogen/image-uploader"
55							class="img-fluid rounded-3 mb-4"
56							alt="Contributors"
57							loading="lazy"
58						/>
59					</div>
60				</div>
61			</div>
62			<div class="album py-5">
63				<div class="container">
64					<% if (media.length === 0) { %>
65					<div class="alert alert-danger" role="alert">
66						No media found. Please <a href="/upload">upload</a> some media.
67					</div>
68					<% } %>
69
70					<% if (deleteSuccess) { %>
71					<div class="alert alert-warning" role="alert">
72						Media with ID "<%= deletedId %>" has been deleted.
73					</div>
74					<% } %>
75
76					<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">
77						<% media.forEach(image => { %>
78						<div class="col">
79							<div class="card shadow-sm">
80								<% if (image.ContentType.includes("image")) { %>
81								<img
82									src="/view/<%= image.Id %>?raw=true"
83									loading="lazy"
84									class="bd-placeholder-img card-img-top"
85									width="100%"
86									height="100%"
87								/>
88								<% } else { %>
89								<video
90									src="/view/<%= image.Id %>?raw=true"
91									class="bd-placeholder-img card-img-top card-video"
92									width="100%"
93									height="100%"
94								></video>
95								<% } %>
96								<div class="card-body">
97									<p class="card-text"><%= image.Caption %></p>
98									<div
99										class="d-flex justify-content-between align-items-center"
100									>
101										<div class="btn-group">
102											<a
103												href="/view/<%= image.Id %>"
104												class="btn btn-sm btn-outline-secondary"
105											>
106												View
107											</a>
108										</div>
109										<small class="text-body-secondary"
110											><%= new Date(image.UploadedAt).toLocaleDateString() %>
111											(<%= timeDifference(new Date(image.UploadedAt)) %>)</small
112										>
113									</div>
114								</div>
115							</div>
116						</div>
117						<% }) %>
118					</div>
119				</div>
120			</div>
121		</main>
122
123		<script>
124			// Clean up the URL
125			const url = window.location.href;
126			const cleanUrl = url.split('?')[0];
127			window.history.replaceState({}, document.title, cleanUrl);
128
129			const cardVideos = document.querySelectorAll('.card-video');
130
131			cardVideos.forEach((video) => {
132				let lastCurrentTime = 0;
133				let isPlaying = false;
134
135				video.addEventListener('mouseover', () => {
136					if (isPlaying) return; // Avoid multiple hover events
137
138					lastCurrentTime = video.currentTime;
139					video.currentTime = 0; // Start from the beginning
140					video.play();
141					video.muted = true;
142					isPlaying = true;
143
144					// Stop previewing after 4 seconds
145					setTimeout(() => {
146						video.pause();
147						video.currentTime = lastCurrentTime; // Resume where it was
148						isPlaying = false;
149					}, 4000);
150				});
151
152				// Ensure the video is stopped if the mouse leaves
153				video.addEventListener('mouseout', () => {
154					if (isPlaying) {
155						video.pause();
156						video.currentTime = lastCurrentTime;
157						isPlaying = false;
158					}
159				});
160			});
161		</script>
162	</body>
163</html>
164