1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
11 background-color: #ffffff;
12 transition: opacity 2s, background-color 2s, background-position 2s;
13 transition-timing-function: ease-in;
17 font-family: 'sans-serif';
21 html.session_starting {
25 .session_starting body {
27 background-color: rgba(0, 0, 0, 0);
28 background-position-y: -100%;
34 display: -webkit-flex;
36 -webkit-flex-direction: column;
37 flex-direction: column;
40 .topBox, .inputBox, .messageBox {
64 box-sizing: border-box;
74 background: rgba(0, 0, 0, 0.05);
76 box-sizing: border-box;
79 border: none !important;
80 padding: 14px 4% !important;
83 background-color: #fff;
86 border-radius: 3px !important;
90 background: rgba(0, 0, 0, 0.1);
91 color: rgba(0, 0, 0, 0.75);
94 input#entry:focus::placeholder {
95 color: rgba(255, 255, 255, 0.3);
101 background-color: black;
113 .splash-screen-content {
122 /* border: 8px solid red; */
125 filter: blur(15px) contrast(127%) brightness(80%);
132 box-shadow: inset 0 0 100px black;
137 <script src="js/jquery-3.4.1.min.js"></script>
138 <script src="js/moment-with-locales.js"></script>
162 "text-align": "center",
164 "font-family": "Noto Sans",
165 "margin-top": "calc(50vh - 90pt)",
166 "text-shadow": "rgba(0, 0, 0, 0.8) 0px 7px 10px",
175 this.clock = setInterval(() => {
176 $(this).trigger("tick");
181 // initilize golbal values
182 this.$vignette = $("#vignette");
183 this.$ss_clock = $("#clock");
185 // adjust each background image
186 let $imgs = $('.splash-screen-img');
188 $imgs.each(function () {
189 self.adjustBackground($(this));
192 // copy the default options into the effective
193 $.extend(true, this.eff_opt, this.def_opt);
194 $.extend(true, this.eff_opt, this.usr_opt);
196 let ss = this.eff_opt["splash-screen"];
197 if (typeof ss == "object") {
198 if (ss.filter == true)
199 $imgs.addClass("filter");
200 if (ss.vignette == true)
201 this.$vignette.show();
202 if (typeof ss.clock == "object")
203 this.initClock(this.$ss_clock, ss.clock);
205 $(this).trigger("ready");
208 initClock($clock, opts) {
209 if (typeof opts != "object")
215 $clock.css(opts.css);
218 $clock.text(moment().format(opts.format || this.def_opt.clock.format));
219 $(this).on("tick", () => {
220 $clock.text(moment().format(opts.format || this.def_opt.clock.format));
224 * Scale an image up or down until it's larger than or equal to the viewport
225 * and then center it.
227 adjustBackground ($img) {
228 var viewportWidth = screen.width;
229 var viewportHeight = screen.height;
230 var viewportAspect = viewportWidth/viewportHeight;
231 var imgWidth = $img.width();
232 var imgHeight = $img.height();
233 var imgAspect = imgWidth/imgHeight;
235 /* First determine what is
236 the limiting factor (ie. if the image is wider, then the height is
237 is the limiting factor and needs to be adjustested */
238 if (imgAspect < viewportAspect) {
239 /* The view port is wider compared to its height than
240 the image is compared to the image height meaning
241 the width is the limiting dimension. Therefore we
242 set image width = view ports width use the aspect
243 ratio to set the correct height */
244 $img.width(viewportWidth);
245 $img.height(viewportWidth/imgAspect);
247 /* The image is wider than it is tall compared to the
248 viewport so we adjust the to fit */
249 $img.height(viewportHeight);
250 $img.width(viewportHeight*imgAspect);
252 this.centerImage($img);
256 var overlapWidth = $img.width() - screen.width;
257 var overlapHeight = $img.height() - screen.height;
259 console.log("overlapwidth: " + overlapWidth + " overlapHeight " + overlapHeight);
260 // image overlaps viewport, move the image back
261 // half the length of the overlap
263 position: "relative",
264 right: overlapWidth/2,
265 bottom: overlapHeight/2
269 login(username, password, callback) {
270 // set default values
271 if (typeof lightdm == 'undefined') {
272 console.warn("Cannot attempt login without lightdm");
273 // call async so that events can be binded in cascade
274 setTimeout(() => $(this).trigger("access-deny"));
277 username = username || lightdm.select_user;
278 password = password || "";
279 // session_key = session_key || lightdm.sessions[0].key;
281 let auth_cb = () => {
282 lightdm.respond(password);
284 let auth_complete_cb = () => {
285 if (typeof callback == "function")
286 callback(lightdm.is_authenticated);
288 $(this).trigger(lightdm.is_authenticated ? "access-grant" : "access-deny");
290 window.show_prompt = auth_cb;
291 window.authentication_complete = auth_complete_cb;
292 lightdm.authenticate(username);
297 const greeter = new LoginManager();
299 $(document).ready(function() {
301 greeter.login("jay", "");
302 $(greeter).on("access-grant", () => {
303 lightdm.start_session_sync("i3");
304 }).on("access-deny", () => console.log("denied!"));
310 <div class="container">
311 <div id="splash-screen">
312 <img class="splash-screen-img" src="images/splash-screen.jpg">
313 <div class="vignette"></div>
314 <div class="splash-screen-content">
315 <div id="clock">12:48</div>
319 <img onclick="javascript:lightdm.shutdown();" src="power_button.png"/>
321 <div class="inputBox">
322 <div class="wrapper">
323 <div id="prompt"></div>
324 <form action="javascript:handle_input();">
329 <div class="messageBox" id="messages"></div>
332 /*********************************************************/
333 /* Callbacks for the greeter */
334 /*********************************************************/
337 * show_prompt callback.
339 window.show_prompt = function(text, type) {
340 // type is either "text" or "password"
341 let prompt = document.getElementById("prompt"),
342 entry = document.getElementById("entry");
344 entry.placeholder = text.charAt(0).toUpperCase() + text.slice(1, -1);
352 * show_message callback.
354 window.show_message = function(text, type) {
355 if (0 === text.length) {
358 let messages = document.getElementById('messages');
359 messages.style.visibility = "visible";
360 // type is either "info" or "error"
361 if (type == 'error') {
362 text = `<p style="color:red;">${text}</p>`;
364 messages.innerHTML = `${messages.innerHTML}${text}`;
368 * authentication_complete callback.
370 var ac = function(session_key) {
371 if (lightdm.is_authenticated) {
372 // Start default session
373 document.documentElement.addEventListener('transitionend', () => lightdm.start_session_sync(session_key));
374 document.documentElement.className = 'session_starting';
376 window.show_message("Authentication Failed", "error");
377 setTimeout(window.start_authentication, 3000);
382 * autologin_timer_expired callback.
384 function autologin_timer_expired(username) {
385 /* Stub. Does nothing. */
388 /*******************************************************************/
389 /* Functions local to this theme */
390 /*******************************************************************/
395 function clear_messages() {
396 let messages = document.getElementById("messages");
397 messages.innerHTML = "";
398 messages.style.visibility = "hidden";
402 * Kickoff the authentication process
404 window.start_authentication = function() {
406 // start without providing "user" to make the greeter prompt for "user"
407 lightdm.authenticate();
411 * handle the input from the entry field.
413 window.handle_input = function() {
414 // let entry = document.getElementById("entry");
415 // lightdm.respond(entry.value);
419 // setTimeout(() => login("jay", "", () => {
420 // for(var x = 0; x < lightdm.sessions.length; x++){
421 // window.show_message(lightdm.sessions[x].key, "info");