/* * * Copyright © 2015-2016 Antergos * * greeter.js * * This file is part of lightdm-webkit-theme-antergos * * lightdm-webkit-theme-antergos is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, * or any later version. * * lightdm-webkit-theme-antergos is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * The following additional terms are in effect as per Section 7 of this license: * * The preservation of all legal notices and author attributions in * the material or in the Appropriate Legal Notices displayed * by works containing it is required. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /** * This is used to access our classes from within jQuery callbacks. */ let _self = null; let _bg_self = null; /** * Capitalize a string. * * @returns {string} */ String.prototype.capitalize = function () { return this.charAt(0).toUpperCase() + this.slice(1); }; /** * This is the base class for the theme's components. */ class GreeterThemeComponent { constructor() { this.debug = this.cache_get('debug', 'enabled'); this.lang = window.navigator.language.split('-')[0].toLowerCase(); this.translations = window.ant_translations; if ('undefined' === typeof window.navigator.languages) { window.navigator.languages = [window.navigator.language]; } this.init_config_values(); } /** * Add text to the debug log element (accessible from the login screen). * * @param {string} text - To be added to the log. */ log(text) { if ('true' === this.debug) { console.log(text); } $('#logArea').append(`${ text }
`); } /** * Get a key's value from localStorage. Keys can have two or more parts. * For example: "ant:user:john:session". * * @param {...string} key_parts - Strings that are combined to form the key. */ cache_get(...key_parts) { var key = `ant`; for (var part of key_parts) { key += `:${ part }`; } return localStorage.getItem(key); } /** * Set a key's value in localStorage. Keys can have two or more parts. * For example: "ant:user:john:session". * * @param {string} value - The value to set. * @param {...string} key_parts - Strings that are combined to form the key. */ cache_set(value, ...key_parts) { var key = `ant`; for (var part of key_parts) { key += `:${ part }`; } return localStorage.setItem(key, value); } /** * Get some values from `lightdm-webkit2-greeter.conf` and save them for later. */ init_config_values() { let logo = '', user_image = '', background_images = [], background_images_dir = ''; if ('undefined' !== typeof config) { if (this instanceof AntergosTheme) { logo = config.get_str('branding', 'logo') || ''; user_image = config.get_str('branding', 'user_image') || ''; } else if (this instanceof AntergosBackgroundManager) { background_images_dir = config.get_str('branding', 'background_images') || ''; if (background_images_dir) { background_images = greeterutil.dirlist(background_images_dir) || []; } if (background_images.length) { let images = []; for (var file of background_images) { if (file.match(/(png|PNG)|(jpg|JPEG)|(bmp|BMP)/)) { images.push(file); } } background_images = images; } } } this.logo = logo; this.user_image = user_image; this.background_images = background_images; this.background_images_dir = background_images_dir; } } /** * This class handles the theme's background switcher. */ class AntergosBackgroundManager extends GreeterThemeComponent { constructor() { super(); if (null === _bg_self) { _bg_self = this; } this.current_background = this.cache_get('background_manager', 'current_background'); if (!this.background_images_dir.length || !this.background_images.length) { this.log('AntergosBackgroundManager: [ERROR] No background images detected.'); $('.header').fadeTo(300, 0.5, function () { $('.header').css("background", '#000000'); }).fadeTo(300, 1); } return _bg_self; } initialize() { if (!this.current_background) { // For backwards compatibility if (null !== localStorage.getItem('bgsaved') && '0' === localStorage.getItem('bgrandom')) { this.current_background = localStorage.getItem('bgsaved'); this.cache_set(this.current_background, 'background_manager', 'current_background'); localStorage.removeItem('bgrandom'); localStorage.removeItem('bgsaved'); } else if ('0' === localStorage.getItem('bgrandom')) { this.current_background = this.get_random_image(); this.cache_set('true', 'background_manager', 'random_background'); localStorage.removeItem('bgrandom'); } } if (!this.current_background) { // For current and future versions let current_background = this.cache_get('background_manager', 'current_background'), random_background = this.cache_get('background_manager', 'random_background'); if ('true' === random_background || !current_background) { current_background = this.get_random_image(); } this.current_background = current_background; } this.do_background(); } do_background() { $('.header').fadeTo(300, 0.5, function () { let tpl = `url('file://${ this.current_background }')`; $('.header').css("background-image", tpl); }).fadeTo(300, 1); } get_random_image() { let random_bg; random_bg = Math.floor(Math.random() * this.background_images.length); return this.background_images[random_bg]; } setup_background_thumbnails() { if (this.background_images.length) { for (var image_file of this.background_images) { let $link = $(''), $img_el = $link.children('img'), tpl = `file://${ image_file }`; $link.addClass('bg clearfix').attr('data-img', tpl); $img_el.attr('src', tpl); $link.appendTo($('.bgs')).click(this.background_selected_handler); } } } background_selected_handler(event) { let img = $(this).attr('data-img'); if ('random' === img) { this.cache_set('true', 'background_manager', 'randmom_background'); img = this.get_random_image(); } this.cache_set(img, 'background_manager', 'current_background'); this.current_background = img; this.do_background(); } } /** * This is the theme's main class object. It contains almost all the theme's logic. */ class AntergosTheme extends GreeterThemeComponent { constructor() { super(); if (null === _self) { _self = this; } this.tux = 'img/antergos-logo-user.png'; this.user_list_visible = false; this.auth_pending = false; this.selected_user = null; this.$user_list = $('#user-list2'); this.$session_list = $('#sessions'); this.$clock_container = $('#collapseOne'); this.$clock = $("#current_time"); this.$actions_container = $("#actionsArea"); this.$msg_area_container = $('#statusArea'); this.$msg_area = $('#showMsg'); this.background_manager = new AntergosBackgroundManager(); this.background_manager.initialize(); this.initialize(); return _self; } initialize() { this.prepare_translations(); this.do_static_translations(); this.initialize_clock(); this.prepare_login_panel_header(); this.prepare_user_list(); this.prepare_session_list(); this.prepare_system_action_buttons(); $("#login").addClass("in"); this.register_callbacks(); this.background_manager.setup_background_thumbnails(); } /** * Register callbacks for the LDM Greeter as well as any others that haven't been registered * elsewhere. */ register_callbacks() { var events = 'shown.bs.collapse, hidden.bs.collapse'; this.$user_list.parents('.collapse').on(events, this.user_list_collapse_handler); $(document).keydown(this.key_press_handler); $('.cancel_auth').click(this.cancel_authentication); $('.submit_passwd').click(this.submit_password); window.show_prompt = this.show_prompt; window.show_message = this.show_message; window.start_authentication = this.start_authentication; window.cancel_authentication = this.cancel_authentication; window.authentication_complete = this.authentication_complete; window.autologin_timer_expired = this.cancel_authentication; } /** * Initialize the user list. */ prepare_user_list() { var template; // Loop through the array of LightDMUser objects to create our user list. for (var user of lightdm.users) { var last_session = this.cache_get('user', user.name, 'session'), image_src = user.image.length ? user.image : this.user_image; if (null === last_session) { // For backwards compatibility last_session = localStorage.getItem(user.name); if (null === last_session) { // This user has never logged in before let's enable the system's default // session. last_session = lightdm.default_session; } this.cache_set(last_session, 'user', user.name, 'session'); } this.log(`Last session for ${ user.name } was: ${ last_session }`); template = ` ${ user.display_name } ${ user.display_name } `; // Register event handler here so we don't have to iterate over the users again later. $(template).appendTo(this.$user_list).click(this.start_authentication).on('error.antergos', this.user_image_error_handler); } // END for ( var user of lightdm.users ) if ($(this.$user_list).children().length > 3) { // Make the user list two columns instead of one. $(this.$user_list).css('column-count', '2').parent().css('max-width', '85%'); } } /** * Initialize the session selection dropdown. */ prepare_session_list() { // Loop through the array of LightDMSession objects to create our session list. for (var session of lightdm.sessions) { var css_class = session.name.replace(/ /g, ''), template; this.log(`Adding ${ session.name } to the session list...`); template = `
  • ${ session.name }
  • `; $(template).appendTo(this.$session_list).click(this.session_toggle_handler); } // END for (var session of lightdm.sessions) $('.dropdown-toggle').dropdown(); } /** * Initialize the system action buttons */ prepare_system_action_buttons() { var actions = { shutdown: "power-off", hibernate: "asterisk", suspend: "arrow-down", restart: "refresh" }, template; for (var action of Object.keys(actions)) { var cmd = `can_${ action }`; template = ` `; if (lightdm[cmd]) { $(template).appendTo($(this.$actions_container)).click(this.system_action_handler); } } // END for (var [action, icon] of actions) $('[data-toggle=tooltip]').tooltip(); $('.modal').modal({ show: false }); } initialize_clock() { var saved_format = this.cache_get('clock', 'time_format'), format = null !== saved_format ? saved_format : 'LT'; moment.locale(window.navigator.languages); this.$clock.html(moment().format(format)); setInterval(() => { this.$clock.html(moment().format(format)); }, 60000); } /** * Show the user list if its not already shown. This is used to allow the user to * display the user list by pressing Enter or Spacebar. */ show_user_list() { if ($(this.$clock_container).hasClass('in')) { $('#trigger').trigger('click'); } if ($(this.$user_list).length <= 1) { $(this.$user_list).find('a').trigger('click', this); } } prepare_login_panel_header() { var greeting = this.translations.greeting ? this.translations.greeting : 'Welcome!', logo = '' !== this.logo ? this.logo : 'img/antergos.png'; $('.welcome').text(greeting); $('#hostname').append(lightdm.hostname); $('[data-greeter-config="logo"]').attr('src', logo); } prepare_translations() { if (!this.translations.hasOwnProperty(this.lang)) { for (var lang of window.navigator.languages) { if (this.translations.hasOwnProperty(lang)) { this.lang = lang; break; } } } if (!this.translations.hasOwnProperty(this.lang)) { this.lang = 'en'; } this.translations = this.translations[this.lang]; } /** * Replace '${i18n}' with translated string for all elements that * have the data-i18n attribute. This is for elements that are not generated * dynamically (they can be found in index.html). */ do_static_translations() { $('[data-i18n]').each(function () { var key = $(this).attr('data-i18n'), html = $(this).html(), translated = _self.translations[key], new_html = html.replace('${i18n}', translated); $(this).html(new_html); }); } /** * Start the authentication process for the selected user. * * @param {object} event - jQuery.Event object from 'click' event. */ start_authentication(event) { var user_id = $(this).attr('id'), selector = `.${ user_id }`, user_session = _self.cache_get('user', user_id, 'session'); if (_self.auth_pending || null !== _self.selected_user) { lightdm.cancel_authentication(); _self.log(`Authentication cancelled for ${ _self.selected_user }`); _self.selected_user = null; } _self.log(`Starting authentication for ${ user_id }.`); _self.selected_user = user_id; // CSS hack to workaround webkit bug if ($(_self.$user_list).children().length > 3) { $(_self.$user_list).css('column-count', 'initial').parent().css('max-width', '50%'); } $(selector).addClass('hovered').siblings().hide(); $('.fa-toggle-down').hide(); _self.log(`Session for ${ user_id } is ${ user_session }`); $(`[data-session-id="${ user_session }"]`).parent().trigger('click', this); $('#session-list').removeClass('hidden').show(); $('#passwordArea').show(); $('.dropdown-toggle').dropdown(); _self.auth_pending = true; lightdm.authenticate(user_id); } /** * Cancel the pending authentication. * * @param {object} event - jQuery.Event object from 'click' event. */ cancel_authentication(event) { var selectors = ['#statusArea', '#timerArea', '#passwordArea', '#session-list']; for (var selector of selectors) { $(selector).hide(); } lightdm.cancel_authentication(); _self.log('Cancelled authentication.'); // CSS hack to work-around webkit bug if ($(_self.$user_list).children().length > 3) { $(_self.$user_list).css('column-count', '2').parent().css('max-width', '85%'); } $('.hovered').removeClass('hovered').siblings().show(); $('.fa-toggle-down').show(); _self.selected_user = null; _self.auth_pending = false; } /** * Called when the user attempts to authenticate (inputs password). * We check to see if the user successfully authenticated and if so tell the LDM * Greeter to log them in with the session they selected. */ authentication_complete() { var selected_session = $('.selected').attr('data-session-id'), err_msg = _self.translations.auth_failed[_self.lang]; _self.auth_pending = false; _self.cache_set(selected_session, 'user', lightdm.authentication_user, 'session'); $('#timerArea').hide(); if (lightdm.is_authenticated) { // The user entered the correct password. Let's log them in. $('body').fadeOut(1000); lightdm.login(lightdm.authentication_user, selected_session); } else { // The user did not enter the correct password. Show error message. $('#statusArea').show(); } } submit_password(event) { lightdm.respond($('#passwordField').val()); $('#passwordArea').hide(); $('#timerArea').show(); } session_toggle_handler(event) { var $session = $(this).children('a'), session_name = $session.text(), session_key = $session.attr('data-session-id'); $session.parents('.btn-group').find('.selected').attr('data-session-id', session_key).html(session_name); } key_press_handler(event) { var action; switch (event.which) { case 13: action = _self.auth_pending ? _self.submit_password() : !_self.user_list_visible ? _self.show_user_list() : 0; _self.log(action); break; case 27: action = _self.auth_pending ? _self.cancel_authentication() : 0; _self.log(action); break; case 32: action = !_self.user_list_visible && !_self.auth_pending ? _self.show_user_list() : 0; _self.log(action); break; default: break; } } system_action_handler() { var action = $(this).attr('id'), $modal = $('.modal'); $modal.find('.btn-primary').text(_self.translations[action]).click(action, event => { $(this).off('click'); lightdm[event.data](); }); $modal.find('.btn-default').click(() => { $(this).next().off('click'); }); $modal.modal('toggle'); } user_list_collapse_handler() { _self.user_list_visible = _self.$user_list.hasClass('in') ? true : false; } user_image_error_handler(event) { $(this).off('error.antergos'); $(this).attr('src', _self.tux); } /** * LightDM Callback - Show password prompt to user. * * @param text * @param type */ show_prompt(text, type) { if ('password' === type) { $('#passwordField').val(""); $('#passwordArea').show(); $('#passwordField').focus(); } } /** * LightDM Callback - Show message to user. * * @param text */ show_message(text, type) { if (text.length > 0) { $(this.$msg_area).html(text); $('#passwordArea').hide(); $(this.$msg_area_container).show(); } } } /** * Initialize the theme once the window has loaded. */ $(window).load(() => { _self = new AntergosTheme(); }); //# sourceMappingURL=greeter-compiled.js.map