@ -0,0 +1,30 @@ |
|||||||
|
# Web Greeter gruvbox theme |
||||||
|
|
||||||
|
## Overview |
||||||
|
This is a web-greeter theme with gruvbox color scheme, included with [web-greeter][web-greeter]. |
||||||
|
|
||||||
|
Based on [glorious-theme][glorious] by manilarome. |
||||||
|
|
||||||
|
- It's simple |
||||||
|
- Simple keyboard navigation |
||||||
|
- Vanilla Javascript |
||||||
|
- Includes battery and brightness support |
||||||
|
- Gruvbox everywhere! |
||||||
|
|
||||||
|
## Screenshots |
||||||
|
|
||||||
|
<center> |
||||||
|
<img src="assets/screenshots/theme-show-1.png" alt="Gruvbox theme"/> |
||||||
|
|
||||||
|
<img src="assets/screenshots/theme-show-2.png" alt="Shutting down"/> |
||||||
|
</center> |
||||||
|
|
||||||
|
## Installation |
||||||
|
This theme is shipped with `web-greeter`. To use it, set the `theme` as `gruvbox` inside `/etc/lightdm/web-greeter.yml` |
||||||
|
|
||||||
|
## TODO |
||||||
|
- Background selector |
||||||
|
- Translations support |
||||||
|
|
||||||
|
[web-greeter]: https://github.com/JezerM/web-greeter "Web Greeter" |
||||||
|
[glorious]: https://github.com/manilarome/lightdm-webkit2-theme-glorious "Glorious" |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 612 B |
After Width: | Height: | Size: 107 KiB |
After Width: | Height: | Size: 132 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 222 KiB |
After Width: | Height: | Size: 94 KiB |
@ -0,0 +1,375 @@ |
|||||||
|
:root { |
||||||
|
/* Background */ |
||||||
|
--bg: #282828; |
||||||
|
--bg0: #282828; |
||||||
|
--bg0_s: #32302f; |
||||||
|
--bg1: #3c3836; |
||||||
|
--bg2: #504945; |
||||||
|
--bg3: #665c54; |
||||||
|
--bg4: #7c6f64; |
||||||
|
|
||||||
|
/* Foreground */ |
||||||
|
--fg: #ebdbb2; |
||||||
|
--fg0: #fbf1c7; |
||||||
|
--fg1: #ebdbb2; |
||||||
|
--fg2: #d5c4a1; |
||||||
|
--fg3: #bdae93; |
||||||
|
--fg4: #a89984; |
||||||
|
|
||||||
|
/* Grayer */ |
||||||
|
--gray: #928374; |
||||||
|
--gray1: #a89984; |
||||||
|
--gray2: #928374; |
||||||
|
|
||||||
|
/* Normal colors */ |
||||||
|
--red: #cc241d; |
||||||
|
--green: #98971a; |
||||||
|
--yellow: #d79921; |
||||||
|
--blue: #458588; |
||||||
|
--purple: #b16286; |
||||||
|
--aqua: #689d6a; |
||||||
|
--orange: #d65d0e; |
||||||
|
|
||||||
|
/* Light colors */ |
||||||
|
--light_red: #fb4934; |
||||||
|
--light_green: #b8bb26; |
||||||
|
--light_yellow: #fabd2f; |
||||||
|
--light_blue: #83a598; |
||||||
|
--light_purple: #d3869b; |
||||||
|
--light_aqua: #8ec07c; |
||||||
|
--light_orange: #fe8019; |
||||||
|
|
||||||
|
color-scheme: light dark; |
||||||
|
--animation-duration: 300ms; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
html { |
||||||
|
height: 100vh; |
||||||
|
width: 100vw; |
||||||
|
color: var(--fg); |
||||||
|
background: black; |
||||||
|
font-family: system-ui; |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
|
||||||
|
html > * { |
||||||
|
font-family: system-ui; |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
|
||||||
|
body { |
||||||
|
height: 100vh; |
||||||
|
width: 100vw; |
||||||
|
margin: 0; |
||||||
|
transition: var(--animation-duration); |
||||||
|
} |
||||||
|
|
||||||
|
.button { |
||||||
|
background: var(--bg4); |
||||||
|
border: 0; |
||||||
|
padding: 0.8em; |
||||||
|
font-size: inherit; |
||||||
|
cursor: pointer; |
||||||
|
border-radius: 5px; |
||||||
|
transition: var(--animation-duration); |
||||||
|
} |
||||||
|
|
||||||
|
.info { |
||||||
|
position: absolute; |
||||||
|
bottom: 0; |
||||||
|
margin: 10px; |
||||||
|
font-size: 2em; |
||||||
|
padding: 8px; |
||||||
|
border-radius: 5px; |
||||||
|
transition: var(--animation-duration); |
||||||
|
cursor: default; |
||||||
|
} |
||||||
|
|
||||||
|
.info:hover { |
||||||
|
background: #3c3836aa; |
||||||
|
backdrop-filter: blur(10px); |
||||||
|
} |
||||||
|
|
||||||
|
button { |
||||||
|
color: var(--fg); |
||||||
|
border: 0; |
||||||
|
font-size: inherit; |
||||||
|
font-family: inherit; |
||||||
|
} |
||||||
|
|
||||||
|
#background { |
||||||
|
height: 100vh; |
||||||
|
width: 100vw; |
||||||
|
position: absolute; |
||||||
|
|
||||||
|
background-color: var(--bg); |
||||||
|
background-image: url("../assets/bubbles.svg") |
||||||
|
} |
||||||
|
|
||||||
|
#cover { |
||||||
|
height: 100vh; |
||||||
|
width: 100vw; |
||||||
|
position: absolute; |
||||||
|
z-index: 10; |
||||||
|
transition: var(--animation-duration); |
||||||
|
|
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
|
||||||
|
background-color: #282828aa; |
||||||
|
backdrop-filter: blur(5px); |
||||||
|
} |
||||||
|
|
||||||
|
#cover > #message { |
||||||
|
font-size: 4em; |
||||||
|
font-weight: bold; |
||||||
|
cursor: default; |
||||||
|
} |
||||||
|
|
||||||
|
#screen { |
||||||
|
height: 100vh; |
||||||
|
width: 100vw; |
||||||
|
position: relative; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
|
||||||
|
#login-form { |
||||||
|
background: var(--bg0_s); |
||||||
|
border-radius: 10px; |
||||||
|
border-color: var(--bg4); |
||||||
|
border-bottom: 8px solid; |
||||||
|
max-height: 90vh; |
||||||
|
box-sizing: border-box; |
||||||
|
height: 22em; |
||||||
|
transition: var(--animation-duration); |
||||||
|
} |
||||||
|
|
||||||
|
#login-form:focus-within, #login-form:hover { |
||||||
|
filter: drop-shadow(2px 6px 10px rgba(0,0,0,0.8)); |
||||||
|
} |
||||||
|
|
||||||
|
#login-form-box { |
||||||
|
position: relative; |
||||||
|
height: -webkit-fill-available; |
||||||
|
display: flex; |
||||||
|
padding: 1.5em 3em; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
flex-direction: column; |
||||||
|
border-bottom: 8px solid; |
||||||
|
border-color: var(--bg3); |
||||||
|
border-radius: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
input { |
||||||
|
background-color: var(--bg1); |
||||||
|
color: var(--fg); |
||||||
|
border: 0; |
||||||
|
border-radius: 5px; |
||||||
|
padding: 0.8em; |
||||||
|
margin: 0.5em; |
||||||
|
font-family: inherit; |
||||||
|
font-size: inherit; |
||||||
|
} |
||||||
|
input:focus, input:focus-visible { |
||||||
|
border: 0; |
||||||
|
outline: auto var(--fg); |
||||||
|
} |
||||||
|
|
||||||
|
:focus { |
||||||
|
outline: auto var(--fg) !important; |
||||||
|
} |
||||||
|
|
||||||
|
::placeholder { |
||||||
|
color: var(--fg3); |
||||||
|
} |
||||||
|
|
||||||
|
#background-image { |
||||||
|
background: var(--blue); |
||||||
|
position: absolute; |
||||||
|
width: calc(10em + 12px); |
||||||
|
height: calc(10em + 12px); |
||||||
|
clip-path: circle(); |
||||||
|
border-radius: 100%; |
||||||
|
transition: var(--animation-duration); |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
|
||||||
|
#background-image > i { |
||||||
|
font-size: 6em; |
||||||
|
} |
||||||
|
|
||||||
|
#user-image { |
||||||
|
margin: 0 0 0.5em 0; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
|
||||||
|
#user-image > img { |
||||||
|
width: 10em; |
||||||
|
height: 10em; |
||||||
|
clip-path: circle(); |
||||||
|
border-radius: 100%; |
||||||
|
transition: var(--animation-duration); |
||||||
|
} |
||||||
|
|
||||||
|
#login-form.failed #user-image > #background-image { |
||||||
|
background: var(--light_red); |
||||||
|
} |
||||||
|
#login-form.success #user-image > #background-image { |
||||||
|
background: var(--light_aqua); |
||||||
|
} |
||||||
|
|
||||||
|
#user-label { |
||||||
|
margin: 0.5em; |
||||||
|
font-size: calc(1em + 4px); |
||||||
|
} |
||||||
|
|
||||||
|
#pass-form > form { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
|
||||||
|
#submit-button { |
||||||
|
background: var(--aqua); |
||||||
|
} |
||||||
|
#submit-button:hover, #submit-button:focus { |
||||||
|
background: var(--light_aqua); |
||||||
|
} |
||||||
|
|
||||||
|
#session-label { |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.label-bar { |
||||||
|
position: absolute; |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
margin: 10px; |
||||||
|
transition: var(--animation-duration); |
||||||
|
} |
||||||
|
|
||||||
|
.label-bar > * { |
||||||
|
padding: 8px; |
||||||
|
transition: var(--animation-duration); |
||||||
|
border-radius: 5px; |
||||||
|
cursor: default; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
.label-bar > *.hide { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
.label-bar > *:hover { |
||||||
|
background: #3c3836aa; |
||||||
|
backdrop-filter: blur(10px); |
||||||
|
} |
||||||
|
|
||||||
|
#system-status { |
||||||
|
top: 0; |
||||||
|
right: 0; |
||||||
|
} |
||||||
|
|
||||||
|
#system-power { |
||||||
|
bottom: 0; |
||||||
|
right: 0; |
||||||
|
} |
||||||
|
#system-power > * { |
||||||
|
font-size: 2em; |
||||||
|
} |
||||||
|
|
||||||
|
#sessions-list { |
||||||
|
position: absolute; |
||||||
|
left: 0; |
||||||
|
top: 0; |
||||||
|
display: flex; |
||||||
|
align-items: flex-start; |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
#users-list { |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
top: 0; |
||||||
|
display: flex; |
||||||
|
align-items: flex-end; |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
|
||||||
|
#sessions-button { |
||||||
|
background: var(--blue); |
||||||
|
margin: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
#users-button { |
||||||
|
background: var(--purple); |
||||||
|
margin: 10px; |
||||||
|
float: right; |
||||||
|
} |
||||||
|
|
||||||
|
.hide { |
||||||
|
opacity: 0; |
||||||
|
visibility: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.dropdown { |
||||||
|
margin: 2px 10px 10px 10px; |
||||||
|
background: var(--bg3); |
||||||
|
transition: var(--animation-duration); |
||||||
|
padding: 0; |
||||||
|
min-width: 8em; |
||||||
|
max-height: 60vh; |
||||||
|
overflow-y: auto; |
||||||
|
} |
||||||
|
.dropdown button { |
||||||
|
background: transparent; |
||||||
|
color: var(--fg); |
||||||
|
padding: 0.8em; |
||||||
|
width: -webkit-fill-available; |
||||||
|
} |
||||||
|
.dropdown button:hover, .dropdown button:focus { |
||||||
|
background: var(--bg4); |
||||||
|
} |
||||||
|
.dropdown.hide { |
||||||
|
visibility: hidden; |
||||||
|
max-height: 0; |
||||||
|
opacity: 0; |
||||||
|
} |
||||||
|
.dropdown:not(.hide) { |
||||||
|
visibility: visible; |
||||||
|
} |
||||||
|
|
||||||
|
li { |
||||||
|
text-decoration: none; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
#users-button:hover, #users-button:focus { |
||||||
|
background: var(--light_purple); |
||||||
|
} |
||||||
|
#sessions-button:hover, #sessions-button:focus { |
||||||
|
background: var(--light_blue); |
||||||
|
} |
||||||
|
|
||||||
|
::-webkit-scrollbar { |
||||||
|
width: 6px; |
||||||
|
} |
||||||
|
|
||||||
|
::-webkit-scrollbar-track { |
||||||
|
background: var(--bg1); |
||||||
|
} |
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb { |
||||||
|
background: var(--blue); |
||||||
|
} |
||||||
|
::-webkit-scrollbar-thumb:hover { |
||||||
|
background: var(--light_blue) |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
Pictogrammers Free License |
||||||
|
-------------------------- |
||||||
|
|
||||||
|
This icon collection is released as free, open source, and GPL friendly by |
||||||
|
the [Pictogrammers](http://pictogrammers.com/) icon group. You may use it |
||||||
|
for commercial projects, open source projects, or anything really. |
||||||
|
|
||||||
|
# Icons: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) |
||||||
|
Some of the icons are redistributed under the Apache 2.0 license. All other |
||||||
|
icons are either redistributed under their respective licenses or are |
||||||
|
distributed under the Apache 2.0 license. |
||||||
|
|
||||||
|
# Fonts: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) |
||||||
|
All web and desktop fonts are distributed under the Apache 2.0 license. Web |
||||||
|
and desktop fonts contain some icons that are redistributed under the Apache |
||||||
|
2.0 license. All other icons are either redistributed under their respective |
||||||
|
licenses or are distributed under the Apache 2.0 license. |
||||||
|
|
||||||
|
# Code: MIT (https://opensource.org/licenses/MIT) |
||||||
|
The MIT license applies to all non-font and non-icon files. |
@ -0,0 +1,25 @@ |
|||||||
|
> *Note:* Please use the main [MaterialDesign](https://github.com/Templarian/MaterialDesign/issues) repo to report issues. This repo is for distribution of the Webfont files only. |
||||||
|
|
||||||
|
# Webfont - Material Design Icons |
||||||
|
|
||||||
|
Webfont distribution for the [Material Design Icons](https://materialdesignicons.com). |
||||||
|
|
||||||
|
``` |
||||||
|
npm install @mdi/font |
||||||
|
``` |
||||||
|
|
||||||
|
> Package built with [@mdi/font-build](https://github.com/Templarian/MaterialDesign-Font-Build). |
||||||
|
|
||||||
|
## Related Packages |
||||||
|
|
||||||
|
[NPM @MDI Organization](https://npmjs.com/org/mdi) |
||||||
|
|
||||||
|
- JavaScript/Typescript: [MaterialDesign-JS](https://github.com/Templarian/MaterialDesign-JS) |
||||||
|
- SVG: [MaterialDesign-SVG](https://github.com/Templarian/MaterialDesign-SVG) |
||||||
|
- Font-Build [MaterialDesign-Font-Build](https://github.com/Templarian/MaterialDesign-Font-Build) |
||||||
|
- Desktop Font: [MaterialDesign-Font](https://github.com/Templarian/MaterialDesign-Font) |
||||||
|
|
||||||
|
## Learn More |
||||||
|
|
||||||
|
- [MaterialDesignIcons.com](https://materialdesignicons.com) |
||||||
|
- https://github.com/Templarian/MaterialDesign |
@ -0,0 +1,93 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta name="viewport" content="width=device-width, viewport-fit=cover, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> |
||||||
|
<link rel="stylesheet" href="css/style.css" class="style"> |
||||||
|
<link rel="stylesheet" href="fonts/material/css/materialdesignicons.css" class="style"> |
||||||
|
<title>Gruvbox greeter</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div id="background"></div> |
||||||
|
<div id="cover" class="hide"> |
||||||
|
<div id="message"></div> |
||||||
|
</div> |
||||||
|
<div id="screen"> |
||||||
|
<div id="login-form"> |
||||||
|
<div id="login-form-box"> |
||||||
|
<div id="user-image"> |
||||||
|
<div id="background-image"> |
||||||
|
<i class="mdi mdi-account"></i> |
||||||
|
</div> |
||||||
|
<img src="" alt=""> |
||||||
|
</div> |
||||||
|
<div id="user-label"> |
||||||
|
<b>User</b> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div id="pass-form"> |
||||||
|
<form action="POST"> |
||||||
|
<div id="input"> |
||||||
|
<input id="input-password" name="password" type="password" autocomplete="off" autofocus="true" placeholder="Enter your password"> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<button id="submit-button" type="submit" class="button"> |
||||||
|
<i class="mdi mdi-chevron-right"></i> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div id="sessions-list"> |
||||||
|
<button id="sessions-button" class="button"> |
||||||
|
<span class="mdi mdi-chevron-down"></span> |
||||||
|
</button> |
||||||
|
<ul id="sessions-dropdown" class="dropdown hide"> |
||||||
|
<li><button>Awesome</button></li> |
||||||
|
<li><button>Ubuntu</button></li> |
||||||
|
</div> |
||||||
|
</ul> |
||||||
|
<div id="users-list"> |
||||||
|
<button id="users-button" class="button"> |
||||||
|
<i class="mdi mdi-chevron-down"></i> |
||||||
|
</button> |
||||||
|
<ul id="users-dropdown" class="dropdown hide"> |
||||||
|
<li><button>Normal sheer</button></li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div id="session-label" class="info"> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div id="system-status" class="label-bar"> |
||||||
|
<div id="brightness-label"></div> |
||||||
|
<div id="battery-label"></div> |
||||||
|
</div> |
||||||
|
<div id="system-power" class="label-bar"> |
||||||
|
<div id="shutdown-btn" class="hide"> |
||||||
|
<span class="mdi mdi-power"></span> |
||||||
|
</div> |
||||||
|
<div id="restart-btn" class="hide"> |
||||||
|
<span class="mdi mdi-restart"></span> |
||||||
|
</div> |
||||||
|
<div id="suspend-btn" class="hide"> |
||||||
|
<span class="mdi mdi-power-sleep"></span> |
||||||
|
</div> |
||||||
|
<div id="hibernate-btn" class="hide"> |
||||||
|
<span class="mdi mdi-power-cycle"></span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script src="js/debug.js"></script> |
||||||
|
<script src="js/authenticate.js"></script> |
||||||
|
<script src="js/accounts.js"></script> |
||||||
|
<script src="js/sessions.js"></script> |
||||||
|
<script src="js/power.js"></script> |
||||||
|
<script src="js/battery.js"></script> |
||||||
|
<script src="js/brightness.js"></script> |
||||||
|
<script src="js/index.js"></script> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,6 @@ |
|||||||
|
[theme] |
||||||
|
name=gruvbox |
||||||
|
description=A grubox lightdm web-greeter theme |
||||||
|
engine=web-greeter |
||||||
|
url=index.html |
||||||
|
session=awesome |
@ -0,0 +1,91 @@ |
|||||||
|
class Accounts { |
||||||
|
constructor() { |
||||||
|
this._localStorage = window.localStorage |
||||||
|
this._userImage = document.querySelector("#user-image") |
||||||
|
this._userLabel = document.querySelector("#user-label") |
||||||
|
this._accountsList = document.querySelector("#users-list") |
||||||
|
this._accountsButton = document.querySelector("#users-button") |
||||||
|
this._defaultUser = null |
||||||
|
this._usersObject = null |
||||||
|
this._init() |
||||||
|
} |
||||||
|
|
||||||
|
getDefaultUserName() { |
||||||
|
return this._defaultUser.username |
||||||
|
} |
||||||
|
|
||||||
|
_setAccountDefault() { |
||||||
|
var img = this._userImage.querySelector("img") |
||||||
|
img.src = this._defaultUser.image |
||||||
|
img.onerror = function() { |
||||||
|
img.src = "" |
||||||
|
} |
||||||
|
this._userLabel.innerHTML = `<b>${this._defaultUser.display_name}</b>` |
||||||
|
} |
||||||
|
|
||||||
|
_updateOnStartup() { |
||||||
|
var username = this._localStorage.getItem('defaultUser') || this._usersObject[0].username |
||||||
|
var display_name = this._localStorage.getItem('defaultUserDisplayName') || this._usersObject[0].display_name |
||||||
|
var image = this._localStorage.getItem("defaultUserProfileImage") || this._usersObject[0].image |
||||||
|
this._defaultUser = { |
||||||
|
username, |
||||||
|
display_name, |
||||||
|
image, |
||||||
|
} |
||||||
|
this._setAccountDefault() |
||||||
|
} |
||||||
|
|
||||||
|
_setAccountList() { |
||||||
|
var dropdown = this._accountsList.querySelector(".dropdown") |
||||||
|
dropdown.innerHTML = "" |
||||||
|
for (let i = 0; i < this._usersObject.length; i++) { |
||||||
|
var name = this._usersObject[i].display_name |
||||||
|
var li = document.createElement("li") |
||||||
|
var button = document.createElement("button") |
||||||
|
button.innerHTML = name |
||||||
|
button.addEventListener("click", () => { |
||||||
|
this._updateDefaults(this._usersObject[i]) |
||||||
|
this._setAccountDefault() |
||||||
|
authenticate.startAuthentication() |
||||||
|
}) |
||||||
|
|
||||||
|
li.appendChild(button) |
||||||
|
dropdown.appendChild(li) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
_setButton() { |
||||||
|
var dropdown = this._accountsList.querySelector(".dropdown") |
||||||
|
this._accountsButton.addEventListener("click", (ev) => { |
||||||
|
ev.stopPropagation() |
||||||
|
if (dropdown.classList.contains("hide")) { |
||||||
|
dropdown.classList.remove("hide") |
||||||
|
} else { |
||||||
|
dropdown.classList.add("hide") |
||||||
|
} |
||||||
|
}) |
||||||
|
var screen = document.querySelector("#screen") |
||||||
|
screen.addEventListener("click", (ev) => { |
||||||
|
if (ev.target != dropdown) { |
||||||
|
dropdown.classList.add("hide") |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
_updateDefaults(userObject) { |
||||||
|
if (!userObject) return |
||||||
|
this._defaultUser = userObject |
||||||
|
|
||||||
|
this._localStorage.setItem("defaultUser", this._defaultUser.username) |
||||||
|
this._localStorage.setItem("defaultUserDisplayName", this._defaultUser.display_name) |
||||||
|
this._localStorage.setItem("defaultUserProfileImage", this._defaultUser.image) |
||||||
|
} |
||||||
|
|
||||||
|
_init() { |
||||||
|
this._usersObject = lightdm.users |
||||||
|
this._updateOnStartup() |
||||||
|
this._setAccountList() |
||||||
|
this._setButton() |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
class Authenticate { |
||||||
|
constructor() { |
||||||
|
this._input = document.querySelector("#input-password") |
||||||
|
this._form = document.querySelector("#pass-form > form") |
||||||
|
this._password = "" |
||||||
|
this._init() |
||||||
|
} |
||||||
|
|
||||||
|
_setForm() { |
||||||
|
this._form.addEventListener("submit", (e) => { |
||||||
|
e.preventDefault() |
||||||
|
var inputs = this._form.querySelectorAll('input') |
||||||
|
var data = getArrayForm(inputs) |
||||||
|
if (!data) return false |
||||||
|
this._password = data.password |
||||||
|
this._respond() |
||||||
|
}) |
||||||
|
} |
||||||
|
_setAuthentication_done() { |
||||||
|
window.authentication_done = () => { |
||||||
|
if (lightdm.is_authenticated) { |
||||||
|
this._authentication_done() |
||||||
|
} else { |
||||||
|
this._authentication_failed() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
_respond() { |
||||||
|
var input = document.querySelector("#input-password") |
||||||
|
input.blur() |
||||||
|
input.disabled = true |
||||||
|
lightdm.respond(this._password) |
||||||
|
} |
||||||
|
|
||||||
|
startAuthentication() { |
||||||
|
lightdm.cancel_authentication() |
||||||
|
lightdm.authenticate(String(accounts.getDefaultUserName())) |
||||||
|
} |
||||||
|
|
||||||
|
async _authentication_done() { |
||||||
|
var form = document.querySelector("#login-form") |
||||||
|
var input = document.querySelector("#input-password") |
||||||
|
form.classList.add("success") |
||||||
|
|
||||||
|
await wait(500) |
||||||
|
var defSession = String(sessions.getDefaultSession()) |
||||||
|
var body = document.querySelector("body") |
||||||
|
body.style.opacity = 0 |
||||||
|
|
||||||
|
await wait(1000) |
||||||
|
console.log("Session started with", defSession) |
||||||
|
lightdm.start_session(defSession) |
||||||
|
} |
||||||
|
|
||||||
|
async _authentication_failed() { |
||||||
|
this.startAuthentication() |
||||||
|
var input = document.querySelector("#input-password") |
||||||
|
document.querySelector("#login-form").classList.add("failed") |
||||||
|
input.blur() |
||||||
|
input.value = "" |
||||||
|
input.disabled = false |
||||||
|
|
||||||
|
await wait(2000) |
||||||
|
document.querySelector("#login-form").classList.remove("failed") |
||||||
|
} |
||||||
|
|
||||||
|
_init() { |
||||||
|
this._setForm() |
||||||
|
this._setAuthentication_done() |
||||||
|
console.log("Start authentication") |
||||||
|
this.startAuthentication() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
class Battery { |
||||||
|
constructor() { |
||||||
|
this._battery = document.querySelector("#battery-label") |
||||||
|
this._info = {} |
||||||
|
this._init() |
||||||
|
} |
||||||
|
|
||||||
|
_updateData() { |
||||||
|
lightdm.batteryUpdate() |
||||||
|
this._info = lightdm.batteryData |
||||||
|
var level = this._info.level |
||||||
|
var state = this._info.state |
||||||
|
var icon = 0 |
||||||
|
var charging = "" |
||||||
|
var blevel = Math.floor(level / 10) * 10 |
||||||
|
icon = `-${blevel}` |
||||||
|
charging = state == "Charging" ? "-charging" : "" |
||||||
|
|
||||||
|
if (blevel < 10) icon = "-outline" |
||||||
|
if (state == "Full" ) { icon = ""; charging = ""} |
||||||
|
if (level >= 0) { |
||||||
|
this._battery.style.visibility = "visible" |
||||||
|
this._battery.innerHTML = `<span class="mdi mdi-battery${charging}${icon}"></span> ${level}%` |
||||||
|
} else { |
||||||
|
this._battery.innerHTML = "" |
||||||
|
this._battery.style.visibility = "hidden" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
_setTimer() { |
||||||
|
if (!lightdm.can_access_battery) return |
||||||
|
this._updateData() |
||||||
|
setTimeout(() => { |
||||||
|
this._updateData() |
||||||
|
}, 5 * 1000) |
||||||
|
setInterval(() => { |
||||||
|
this._updateData() |
||||||
|
}, 20 * 1000) // Every 20 seconds
|
||||||
|
} |
||||||
|
|
||||||
|
_init() { |
||||||
|
this._setTimer() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
class Brightness { |
||||||
|
constructor() { |
||||||
|
this._brightness = document.querySelector("#brightness-label") |
||||||
|
this._level = 0 |
||||||
|
this._init() |
||||||
|
} |
||||||
|
|
||||||
|
_updateData() { |
||||||
|
this._level = lightdm.brightness |
||||||
|
if (this._level >= 0) { |
||||||
|
this._brightness.style.visibility = "visible" |
||||||
|
var icon = this._level > 50 ? 7: this._level > 10 ? 6 : 5 |
||||||
|
this._brightness.innerHTML = `<span class="mdi mdi-brightness-${icon}"></span> ${this._level}%` |
||||||
|
} else { |
||||||
|
this._brightness.innerHTML = "" |
||||||
|
this._brightness.style.visibility = "hidden" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
_setTimer() { |
||||||
|
if (!lightdm.can_access_brightness) return |
||||||
|
this._updateData() |
||||||
|
setInterval(() => { |
||||||
|
this._updateData() |
||||||
|
}, 1000) // Every second
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
_init() { |
||||||
|
this._setTimer() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,120 @@ |
|||||||
|
class Debug { |
||||||
|
constructor() { |
||||||
|
this._debugPass = "just" |
||||||
|
this._init() |
||||||
|
} |
||||||
|
|
||||||
|
_init() { |
||||||
|
console.log("DEBUG") |
||||||
|
|
||||||
|
window.theme_utils = {} |
||||||
|
window.theme_utils.dirlist = function(path) { |
||||||
|
return false |
||||||
|
} |
||||||
|
|
||||||
|
window.lightdm = { |
||||||
|
is_authenticated: false, |
||||||
|
authentication_user: null, |
||||||
|
default_session: "awesome", |
||||||
|
can_suspend: true, |
||||||
|
can_hibernate: true, |
||||||
|
can_shutdown: true, |
||||||
|
can_restart: true, |
||||||
|
can_access_battery: true, |
||||||
|
can_access_brightness: true, |
||||||
|
sessions: [ |
||||||
|
{ |
||||||
|
name: "awesome wm", |
||||||
|
key: "awesome" |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "Ubuntu", |
||||||
|
key: "ubuntu" |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "i3wm", |
||||||
|
key: "i3" |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "bspwm", |
||||||
|
key: "bspwm" |
||||||
|
} |
||||||
|
], |
||||||
|
users: [ |
||||||
|
{ |
||||||
|
display_name: "Miyuki Shirogane", |
||||||
|
username: "Arsène", |
||||||
|
image: "./assets/users/Arsene.jpg" |
||||||
|
}, |
||||||
|
{ |
||||||
|
display_name: "Kaguya Shinomiya", |
||||||
|
username: "Ice princess", |
||||||
|
image: "./assets/users/Ice princess.jpg" |
||||||
|
}, |
||||||
|
{ |
||||||
|
display_name: "Easper", |
||||||
|
username: "espaiar", |
||||||
|
image: "" |
||||||
|
} |
||||||
|
], |
||||||
|
languages: [ |
||||||
|
{ |
||||||
|
name: 'American English', |
||||||
|
code: 'en_US.utf8' |
||||||
|
} |
||||||
|
], |
||||||
|
language: 'American English', |
||||||
|
authenticate: username => { |
||||||
|
console.log(`Starting authentication with user: "${username}"`) |
||||||
|
}, |
||||||
|
cancel_authentication: () => { |
||||||
|
console.log(`Authentication cancelled`) |
||||||
|
}, |
||||||
|
respond: async (password) => { |
||||||
|
console.log(`Password provided: "${password}"`) |
||||||
|
if (password == this._debugPass) { |
||||||
|
lightdm.is_authenticated = true |
||||||
|
} else { |
||||||
|
await wait(2000) |
||||||
|
} |
||||||
|
authentication_done() |
||||||
|
}, |
||||||
|
start_session: session => { |
||||||
|
alert(`Logged with session: "${session}"`) |
||||||
|
location.reload() |
||||||
|
}, |
||||||
|
shutdown: () => { |
||||||
|
console.log("System is shutting down...") |
||||||
|
}, |
||||||
|
restart: () => { |
||||||
|
console.log("System is rebooting...") |
||||||
|
}, |
||||||
|
hibernate: () => { |
||||||
|
console.log("System is hibernating") |
||||||
|
}, |
||||||
|
suspend: () => { |
||||||
|
console.log("System is suspending") |
||||||
|
}, |
||||||
|
batteryData: { |
||||||
|
name: "Battery 0", |
||||||
|
level: 85, |
||||||
|
state: "Discharging" |
||||||
|
}, |
||||||
|
batteryUpdate: () => { |
||||||
|
console.log("Battery updated") |
||||||
|
}, |
||||||
|
brightness: 50, |
||||||
|
brightnessSet: (quantity) => { |
||||||
|
lightdm.brightness = quantity |
||||||
|
}, |
||||||
|
brightnessIncrease: (quantity) => { |
||||||
|
lightdm.brightness += quantity |
||||||
|
if (lightdm.brightness > 100) lightdm.brightness = 100 |
||||||
|
}, |
||||||
|
brightnessDecrease: (quantity) => { |
||||||
|
lightdm.brightness -= quantity |
||||||
|
if (lightdm.brightness < 0) lightdm.brightness = 0 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
|
||||||
|
form = document.querySelector("#form > form") |
||||||
|
|
||||||
|
function getArrayForm(inputs) { |
||||||
|
if (!inputs) return false |
||||||
|
var data = {} |
||||||
|
inputs.forEach((x) => { |
||||||
|
data[x.name] = x.value |
||||||
|
}) |
||||||
|
return data |
||||||
|
} |
||||||
|
|
||||||
|
async function wait(ms) { |
||||||
|
return new Promise( resolve => { |
||||||
|
setTimeout(() => { |
||||||
|
resolve() |
||||||
|
}, ms) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
async function initGreeter() { |
||||||
|
if (lightdm.authentication_complete) { |
||||||
|
lightdm.authentication_complete.connect(() => authentication_done()) |
||||||
|
} |
||||||
|
|
||||||
|
if (greeter_config.greeter.debug_mode) { |
||||||
|
debug = new Debug() |
||||||
|
} |
||||||
|
|
||||||
|
accounts = new Accounts() |
||||||
|
|
||||||
|
sessions = new Sessions() |
||||||
|
|
||||||
|
authenticate = new Authenticate() |
||||||
|
|
||||||
|
power = new Power() |
||||||
|
|
||||||
|
battery = new Battery() |
||||||
|
|
||||||
|
brightness = new Brightness() |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
const notGreeter = false |
||||||
|
|
||||||
|
if (notGreeter) { |
||||||
|
debug = new Debug() |
||||||
|
initGreeter() |
||||||
|
} else { |
||||||
|
window.addEventListener("GreeterReady", initGreeter) |
||||||
|
} |
@ -0,0 +1,79 @@ |
|||||||
|
class Power { |
||||||
|
constructor() { |
||||||
|
this._shutdown = document.querySelector("#shutdown-btn") |
||||||
|
this._restart = document.querySelector("#restart-btn") |
||||||
|
this._hibernate = document.querySelector("#hibernate-btn") |
||||||
|
this._suspend = document.querySelector("#suspend-btn") |
||||||
|
this._cover = document.querySelector("#cover") |
||||||
|
this._covermsg = document.querySelector("#cover > #message") |
||||||
|
this._init() |
||||||
|
} |
||||||
|
|
||||||
|
_show_message(text) { |
||||||
|
this._covermsg.innerHTML = text |
||||||
|
this._cover.classList.remove("hide") |
||||||
|
} |
||||||
|
|
||||||
|
_do_shutdown() { |
||||||
|
this._show_message("Shutting down") |
||||||
|
lightdm.shutdown() |
||||||
|
} |
||||||
|
_do_restart() { |
||||||
|
this._show_message("Restarting") |
||||||
|
lightdm.restart() |
||||||
|
} |
||||||
|
_do_hibernate() { |
||||||
|
this._show_message("Hibernating") |
||||||
|
lightdm.hibernate() |
||||||
|
} |
||||||
|
_do_suspend() { |
||||||
|
this._show_message("Suspending") |
||||||
|
lightdm.suspend() |
||||||
|
} |
||||||
|
|
||||||
|
_setShutdown() { |
||||||
|
if (!lightdm.can_shutdown) return |
||||||
|
this._shutdown.addEventListener("click", () => { |
||||||
|
this._do_shutdown() |
||||||
|
}) |
||||||
|
this._shutdown.classList.remove("hide") |
||||||
|
} |
||||||
|
_setRestart() { |
||||||
|
if (!lightdm.can_restart) return |
||||||
|
this._restart.addEventListener("click", () => { |
||||||
|
this._do_restart() |
||||||
|
}) |
||||||
|
this._restart.classList.remove("hide") |
||||||
|
} |
||||||
|
_setHibernate() { |
||||||
|
if (!lightdm.can_hibernate) return |
||||||
|
this._hibernate.addEventListener("click", () => { |
||||||
|
this._do_hibernate() |
||||||
|
}) |
||||||
|
this._hibernate.classList.remove("hide") |
||||||
|
} |
||||||
|
_setSuspend() { |
||||||
|
if (!lightdm.can_suspend) return |
||||||
|
this._suspend.addEventListener("click", () => { |
||||||
|
this._do_suspend() |
||||||
|
}) |
||||||
|
this._suspend.classList.remove("hide") |
||||||
|
} |
||||||
|
_setCover() { |
||||||
|
this._cover.addEventListener("click", () => { |
||||||
|
this._cover.classList.add("hide") |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
_setButtons() { |
||||||
|
this._setShutdown() |
||||||
|
this._setRestart() |
||||||
|
this._setHibernate() |
||||||
|
this._setSuspend() |
||||||
|
this._setCover() |
||||||
|
} |
||||||
|
|
||||||
|
_init() { |
||||||
|
this._setButtons() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,84 @@ |
|||||||
|
class Sessions { |
||||||
|
constructor() { |
||||||
|
this._localStorage = window.localStorage |
||||||
|
this._sessionLabel = document.querySelector("#session-label") |
||||||
|
this._sessionList = document.querySelector("#sessions-list") |
||||||
|
this._sessionsButton = document.querySelector("#sessions-button") |
||||||
|
this._defaultSession = null |
||||||
|
this._sessionsObject = null |
||||||
|
this._init() |
||||||
|
} |
||||||
|
|
||||||
|
getDefaultSession() { |
||||||
|
return this._defaultSession.key |
||||||
|
} |
||||||
|
|
||||||
|
_setSessionDefault() { |
||||||
|
this._sessionLabel.innerHTML = `<b>${this._defaultSession.name}</b>` |
||||||
|
} |
||||||
|
|
||||||
|
_updateOnStartup() { |
||||||
|
var session_key = this._localStorage.getItem("defaultSession") || this._sessionsObject[0].key || lightdm.default_session |
||||||
|
|
||||||
|
var defaultSession = this._sessionsObject.find(el => el.key == session_key) |
||||||
|
|
||||||
|
var session_name = defaultSession ? defaultSession.name : "awesome wm" |
||||||
|
session_key = defaultSession ? defaultSession.key : "awesome" |
||||||
|
|
||||||
|
this._defaultSession = { |
||||||
|
key: session_key, |
||||||
|
name: session_name |
||||||
|
} |
||||||
|
this._setSessionDefault() |
||||||
|
} |
||||||
|
|
||||||
|
_setSessionList() { |
||||||
|
var dropdown = this._sessionList.querySelector(".dropdown") |
||||||
|
dropdown.innerHTML = "" |
||||||
|
for (let i = 0; i < this._sessionsObject.length; i++) { |
||||||
|
var name = this._sessionsObject[i].name |
||||||
|
var li = document.createElement("li") |
||||||
|
var button = document.createElement("button") |
||||||
|
button.innerHTML = name |
||||||
|
button.addEventListener("click", () => { |
||||||
|
this._updateDefaults(this._sessionsObject[i]) |
||||||
|
this._setSessionDefault() |
||||||
|
}) |
||||||
|
|
||||||
|
li.appendChild(button) |
||||||
|
dropdown.appendChild(li) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
_setButton() { |
||||||
|
var dropdown = this._sessionList.querySelector(".dropdown") |
||||||
|
this._sessionsButton.addEventListener("click", (ev) => { |
||||||
|
ev.stopPropagation() |
||||||
|
if (dropdown.classList.contains("hide")) { |
||||||
|
dropdown.classList.remove("hide") |
||||||
|
} else { |
||||||
|
dropdown.classList.add("hide") |
||||||
|
} |
||||||
|
}) |
||||||
|
var screen = document.querySelector("#screen") |
||||||
|
screen.addEventListener("click", (ev) => { |
||||||
|
if (ev.target != dropdown) { |
||||||
|
dropdown.classList.add("hide") |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
_updateDefaults(sessionObj) { |
||||||
|
if (!sessionObj) return |
||||||
|
this._defaultSession = sessionObj |
||||||
|
this._localStorage.setItem("defaultSession", this._defaultSession.key) |
||||||
|
} |
||||||
|
|
||||||
|
_init() { |
||||||
|
this._sessionsObject = lightdm.sessions |
||||||
|
this._updateOnStartup() |
||||||
|
this._setSessionList() |
||||||
|
this._setButton() |
||||||
|
} |
||||||
|
} |