rustream/templates/
profile.rs1pub fn get_content() -> String {
11 r###"<!DOCTYPE html>
12<!--suppress JSUnresolvedLibraryURL -->
13<html lang="en">
14<head>
15 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
16 <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
17 <meta http-equiv="Pragma" content="no-cache">
18 <meta http-equiv="Expires" content="0">
19 <title>RuStream - Self-hosted Streaming Engine - v{{ version }}</title>
20 <meta property="og:type" content="MediaStreaming">
21 <meta name="keywords" content="Rust, streaming, actix, JavaScript, HTML, CSS">
22 <meta name="author" content="Vignesh Rao">
23 <meta content="width=device-width, initial-scale=1" name="viewport">
24 <!-- Favicon.ico and Apple Touch Icon -->
25 <link rel="icon" href="https://thevickypedia.github.io/open-source/images/logo/actix.ico">
26 <link rel="apple-touch-icon" href="https://thevickypedia.github.io/open-source/images/logo/actix.png">
27 <!-- Font Awesome icons -->
28 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/fontawesome.min.css">
29 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/solid.css">
30 <!-- CSS and JS for night mode -->
31 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
32 <script type="text/javascript" src="https://thevickypedia.github.io/open-source/nightmode/night.js" defer></script>
33 <link rel="stylesheet" type="text/css" href="https://thevickypedia.github.io/open-source/nightmode/night.css">
34 <!-- Button CSS -->
35 <style>
36 /* Google fonts with a backup alternative */
37 @import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;500;700&display=swap');
38 * {
39 font-family: 'Ubuntu', 'PT Serif', sans-serif;
40 }
41 body {
42 margin-left: 1%; /* 1% away from left corner */
43 padding: 0.5% /* 0.5% away from any surrounding elements */
44 }
45 .upload {
46 position: absolute;
47 top: 3.8%;
48 right: 313px;
49 border: none;
50 padding: 10px 14px;
51 font-size: 16px;
52 cursor: pointer;
53 }
54 .home {
55 position: absolute;
56 top: 3.8%;
57 right: 217px;
58 border: none;
59 padding: 10px 14px;
60 font-size: 16px;
61 cursor: pointer;
62 }
63 .back {
64 position: absolute;
65 top: 3.8%;
66 right: 132px;
67 border: none;
68 padding: 10px 14px;
69 font-size: 16px;
70 cursor: pointer;
71 }
72 </style>
73 <style>
74 .dropbtn {
75 position: absolute;
76 top: 3.8%;
77 right: 30px;
78 padding: 10px 24px;
79 font-size: 16px;
80 border: none;
81 cursor: pointer;
82 }
83 .dropdown {
84 position: absolute;
85 top: 3.8%;
86 right: 30px;
87 padding: 10px 24px;
88 display: inline-block;
89 }
90 .dropdown-content {
91 display: none;
92 position: absolute;
93 top: 40px; /* Distance from the user icon button */
94 right: 30px;
95 width: 160px;
96 min-width: auto;
97 box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); /* Basically, black with 20% opacity */
98 z-index: 1;
99 }
100 .dropdown-content a {
101 padding: 12px 16px;
102 text-decoration: none;
103 display: block;
104 }
105 .dropdown:hover .dropdown-content {display: block;}
106 </style>
107 <!-- Title list CSS -->
108 <style>
109 a:hover, a:active { font-size: 120%; opacity: 0.7; }
110 a:link { color: blue; }
111 a:visited { color: blue; }
112 </style>
113</head>
114<noscript>
115 <style>
116 body {
117 width: 100%;
118 height: 100%;
119 overflow: hidden;
120 }
121 </style>
122 <div style="position: fixed; text-align:center; height: 100%; width: 100%; background-color: #151515;">
123 <h2 style="margin-top:5%">This page requires JavaScript
124 to be enabled.
125 <br><br>
126 Please refer <a href="https://www.enable-javascript.com/">enable-javascript</a> for how to.
127 </h2>
128 <form>
129 <button type="submit" onClick="<meta httpEquiv='refresh' content='0'>">RETRY</button>
130 </form>
131 </div>
132</noscript>
133<body translate="no" onload="displayTimer(); displayExpiryUTC(); displayExpiryLocal()">
134<div class="toggler fa fa-moon-o"></div>
135<button class="upload" onclick="upload()"><i class="fa-solid fa-cloud-arrow-up"></i> Upload</button>
136<button class="home" onclick="goHome()"><i class="fa fa-home"></i> Home</button>
137<button class="back" onclick="goBack()"><i class="fa fa-backward"></i> Back</button>
138<div class="dropdown">
139 <button class="dropbtn"><i class="fa fa-user"></i></button>
140 <div class="dropdown-content">
141 <a onclick="goProfile()" style="cursor: pointer;"><i class="fa-solid fa-user-lock"></i> {{ user }}</a>
142 <a onclick="logOut()" style="cursor: pointer"><i class="fa fa-sign-out"></i> logout</a>
143 </div>
144</div>
145<br><br><br><br>
146<hr>
147<br><br>
148<h4 style="text-align: center">Welcome {{ user }}</h3>
149<h4>Session Validity</h4>
150<p id="secondsCountDown"><p>
151<p id="validityUTC"></h5>
152<p id="validityLocal"></h5>
153{% if file %}
154 <h4>Last Accessed</h4>
155 <i class="{{ file.font }}"></i> <a href="{{ file.path }}">{{ file.name }}</a>
156{% endif %}
157<script>
158 function goHome() { window.location.href = "/home"; }
159 function goProfile() { window.location.href = '/profile'; }
160 function logOut() { window.location.href = "/logout"; }
161 function upload() { window.location.href = "/upload"; }
162 function goBack() { window.history.back(); }
163</script>
164<script>
165 function secondsToStr(seconds) {
166 let levels = [
167 [Math.floor(seconds / 31536000), 'years'],
168 [Math.floor((seconds % 31536000) / 86400), 'days'],
169 [Math.floor(((seconds % 31536000) % 86400) / 3600), 'hours'],
170 [Math.floor((((seconds % 31536000) % 86400) % 3600) / 60), 'minutes'],
171 [Math.floor((((seconds % 31536000) % 86400) % 3600) % 60), 'seconds'],
172 ];
173 let returntext = '';
174
175 for (let i = 0, max = levels.length; i < max; i++) {
176 if (levels[i][0] === 0) continue;
177 returntext += ', ' + levels[i][0] + ' ' + (levels[i][0] === 1 ? levels[i][1].substr(0, levels[i][1].length - 1) : levels[i][1]);
178 }
179 return returntext.trim();
180 }
181
182 function displayTimer() {
183 let seconds = '{{ time_left }}';
184 let display = document.getElementById('secondsCountDown');
185 display.innerHTML = secondsToStr(seconds).substring(1);
186 let countdown = setInterval(function () {
187 seconds--;
188 display.innerHTML = secondsToStr(seconds).substring(1) + "s";
189 if (seconds <= 0) {
190 clearInterval(countdown);
191 }
192 }, 1000);
193 }
194</script>
195<script>
196 function displayExpiryUTC() {
197 let seconds = '{{ time_left }}';
198 let expiryTime = new Date(Date.now() + seconds * 1000);
199 let display = document.getElementById('validityUTC');
200 display.innerHTML = expiryTime.toUTCString();
201 }
202</script>
203<script>
204 function displayExpiryLocal() {
205 let seconds = '{{ time_left }}';
206 let expiryTime = new Date(Date.now() + seconds * 1000);
207 let display = document.getElementById('validityLocal');
208 // Options for date and time formatting
209 let options = {
210 weekday: 'short',
211 day: '2-digit',
212 month: 'short',
213 year: 'numeric',
214 hour: '2-digit',
215 minute: '2-digit',
216 second: '2-digit',
217 timeZoneName: 'short'
218 };
219 display.innerHTML = expiryTime.toLocaleString('en-US', options);
220 }
221
222 function setCookieWithShortExpiration(name, value, secondsToExpire) {
223 // Calculate the expiration date
224 var expirationDate = new Date();
225 expirationDate.setTime(expirationDate.getTime() + (secondsToExpire * 1000)); // Convert seconds to milliseconds
226
227 // Construct the cookie string
228 var cookieString = name + "=" + encodeURIComponent(value);
229 cookieString += "; expires=" + expirationDate.toUTCString();
230
231 // Set the cookie
232 document.cookie = cookieString;
233 }
234
235 setInterval(function () {
236 setCookieWithShortExpiration("detail", "Session Expired", 5);
237 window.location.href = "/error";
238 }, {{ time_left }} * 1000 - 1000); // Convert time_left to milliseconds and subract 1 second
239</script>
240</body>
241</html>
242"###.to_string()
243}