Compare commits

..

13 Commits

  1. 2
      .copyignore
  2. 2
      .gear/rules
  3. 52
      README.md
  4. 8
      index.html
  5. 2
      index.yml
  6. 92
      main.js
  7. 20
      secondary.html
  8. 67
      style.css
  9. 30
      wallpapper.js
  10. BIN
      wallpappers/Space_Launch.jpg
  11. 53
      web-greeter-theme-basealt.spec

2
.copyignore

@ -0,0 +1,2 @@
*.md
*.spec

2
.gear/rules

@ -0,0 +1,2 @@
tar: .

52
README.md

@ -1,13 +1,59 @@
# Basealt web-greeter-theme
The lightdm web-greeter theme for altlinux OSes
![](https://git.markow.su/markow/git-utils/raw/branch/master/screenshots/web-greeter-theme-basealt-1.png)
The lightdm web-greeter theme for altlinux OSes<br/>
![](https://git.markow.su/markow/git-utils/raw/branch/master/screenshots/web-greeter-theme-basealt.gif)
# Install
```
# apt-repo add rpm http://packages.markow.su/altlinux p10/branch/x86_64 classic
# apt-repo add rpm http://packages.markow.su/altlinux p10/branch/noarch classic
# apt-get update
# apt-get install web-greeter-theme-basealt
```
# Configure
## Set web-greeter as greeter-session for lightdm
```
# pluma /etc/lightdm/lightdm.conf
```
Set greeter-session to web-greeter
## Set basealt theme
```
# pluma /etc/lightdm/web-greeter.yml
```
Change "theme" config to basealt
## Set user logo for theme
```
# mkdir -p /var/lib/lightdm-data/$USER
# cp <your logo file>.png /var/lib/lightdm-data/$USER/face.png
```
# Packaging
To pack own rpm pckage:
```
# apt-get update
# apt-get install hasher gear
$ git clone https://git.markow.su/markow/web-greeter-theme-basealt.git
$ cd web-greeter-theme-basealt
$ mkdir ~/.hasher
$ hsh --initroot ~/.hasher
$ gear-hsh -v ~/.hasher --target=noarch --no-sisyphus-check
```
To use your own rpm:
1. point your apt to your local hasher repo
2. do apt-get update
3. do apt-get install web-greeter-theme-basealt
# Features
* Select a user
* Select a session
* Select a wallpapper
* Store settings
* User logo ca be shown if it is set in greeter for the user
* User logo can be shown if it is set in greeter for the user

8
index.html

@ -3,7 +3,8 @@
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css" class="style">
<script type="text/javascript" src="main.js"></script>
<script type="text/javascript" src="wallpapper.js"></script>
<script type="text/javascript" src="main.js"></script>
<title>Example Theme</title>
</head>
<body>
@ -32,6 +33,7 @@
<option value="Elbrus1.jpg">Эльбрус - 1</option>
<option value="Elbrus2.jpg">Эльбрус - 2</option>
<option value="Elbrus3.jpg">Эльбрус - 3</option>
<option value="User">Пользовательский</option>
</select>
</dev>
</td>
@ -46,7 +48,9 @@
<p id="user" />
<form onSubmit="doLogin()">
<table>
<tr><td colspan="2"><div id="underline"><input type="password" name="password" id="password" class="input" autocomplete="off" placeholder="Введите пароль" autofocus /><img src="images/eye.png" id="eye" onClick="togglePasswordVisibility()" style="width:18px;height:18px;vertical-align: middle" /></div></td></tr>
<tr><td colspan="2"><div class="view_port"><div id="underline"><input type="password" name="password" id="password" autocomplete="off" placeholder="Введите пароль" autofocus /><img src="images/eye.png" id="eye" onClick="togglePasswordVisibility()" style="width:18px;height:18px;vertical-align: middle" /></div>
<div id="cylon_eye"/></div>
</td></tr>
<tr><td><select name="sessions" id="sessions" /></td><td align="right"><button type="submit" id="submit" class='input_submit'>Поехали!</button></td></tr>
</table>
</form>

2
index.yml

@ -0,0 +1,2 @@
primary_html: "index.html"
secondary_html: "secondary.html"

92
main.js

@ -1,6 +1,6 @@
const DEFAULT_USER = "defaultUser";
const DEFAULT_SESSION = "defaultSession";
const DEFAULT_WALLPAPPER = "defaultWallpapper";
const WAITING_CLASS = "waiting";
function togglePasswordVisibility() {
var passwd = document.getElementById("password");
@ -14,17 +14,45 @@ function togglePasswordVisibility() {
}
}
function toggleWaitingState(waiting) {
var cylon_eye = document.getElementById("cylon_eye");
var passwd = document.getElementById("password");
passwd.disabled = waiting;
var submit = document.getElementById("submit");
// submit.disabled = waiting;
if (waiting) {
cylon_eye.classList.add(WAITING_CLASS);
} else {
cylon_eye.classList.remove(WAITING_CLASS);
}
}
function updateDefaults(user, session) {
localStorage.setItem(DEFAULT_USER, user)
localStorage.setItem(DEFAULT_SESSION, session)
console.log(user)
console.log(session)
window.localStorage.setItem(DEFAULT_USER, user)
window.localStorage.setItem(DEFAULT_SESSION, session)
var wallpapper = document.getElementById("wallpappers").value
var wallpapper = document.getElementById(WALLPAPPER_ELEMENT).value
if(wallpapper) {
localStorage.setItem(DEFAULT_WALLPAPPER, wallpapper)
console.log(wallpapper)
window.localStorage.setItem(DEFAULT_WALLPAPPER, wallpapper)
}
}
function updateDefaultsInLocalstorage() {
var user = document.getElementById("user").textContent
var session = document.getElementById("sessions").value
if (!user || !session) {
return false;
}
updateDefaults(user, session);
}
function dateFormat(date) {
var parts=date.split('.');
var options = { weekday: 'long', month: 'long', day: 'numeric' };
@ -48,22 +76,14 @@ function selectItemByValue(elmnt, value){
function doLogin() {
event.preventDefault();
var user = document.getElementById("user").textContent
var password = document.getElementById("password").value
var session = document.getElementById("sessions").value
if (!user || !password || !session) {
if (!user || !session) {
return false;
}
lightdm.cancel_authentication()
lightdm.cancel_authentication();
lightdm.show_prompt.connect((text, type) => {
lightdm.respond(password);
})
lightdm.authentication_complete.connect(() => {
lightdm.start_session(session);
})
updateDefaults(user, session);
toggleWaitingState(true);
lightdm.authenticate(user)
return false;
}
@ -82,17 +102,14 @@ function updateUser(username) {
}
}
});
}
function updateWallpapper(wallpapper) {
var body = document.getElementsByTagName('body')[0];
body.style.backgroundImage = `url(wallpappers/${wallpapper})`;
updateDefaultsInLocalstorage();
}
function initGreeter() {
let users = lightdm.users
let defaultUser = localStorage.getItem(DEFAULT_USER) || users[0].username;
let defaultUser = window.localStorage.getItem(DEFAULT_USER) || users[0].username;
updateUser(defaultUser);
let select = document.getElementById('user-dropdown-content')
@ -106,20 +123,22 @@ function initGreeter() {
select.appendChild(btn)
}
const wallpappers = document.getElementById('wallpappers');
const wallpappers = document.getElementById(WALLPAPPER_ELEMENT);
wallpappers.addEventListener('change', (event) => {
updateWallpapper(event.target.value);
updateDefaultsInLocalstorage();
});
let defaultWallpapper = localStorage.getItem(DEFAULT_WALLPAPPER);
let defaultWallpapper = window.localStorage.getItem(DEFAULT_WALLPAPPER);
if(defaultWallpapper) {
selectItemByValue(wallpappers, defaultWallpapper);
updateWallpapper(defaultWallpapper);
updateDefaultsInLocalstorage();
}
let sessions = lightdm.sessions
let defaultSession = localStorage.getItem(DEFAULT_SESSION) || sessions[0].key;
let defaultSession = window.localStorage.getItem(DEFAULT_SESSION) || sessions[0].key;
let sessionsSelect = document.getElementById('sessions')
for (let i = 0; i < sessions.length; i++) {
var opt = document.createElement('option')
@ -133,8 +152,33 @@ function initGreeter() {
}
sessionsSelect.value = defaultSession;
sessionsSelect.addEventListener('change', (event) => {
updateDefaultsInLocalstorage();
});
document.getElementById("date").textContent=dateFormat(theme_utils.get_current_localized_date());
document.getElementById("time").textContent=theme_utils.get_current_localized_time();
lightdm.show_prompt.connect((text, type) => {
var password = document.getElementById("password").value
lightdm.respond(password);
});
lightdm.authentication_complete.connect(() => {
toggleWaitingState(false);
if (lightdm.is_authenticated) {
var session = document.getElementById("sessions").value
lightdm.start_session(session);
} else {
var password = document.getElementById("password")
// Add a class that defines an animation
password.classList.add('error');
// remove the class after the animation completes
setTimeout(function() {
password.classList.remove('error');
}, 300);
}
});
}
window.addEventListener("GreeterReady", initGreeter)

20
secondary.html

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css" class="style">
<script type="text/javascript" src="wallpapper.js"></script>
<script type="text/javascript">
function initGreeter() {
let defaultWallpapper = window.localStorage.getItem(DEFAULT_WALLPAPPER);
if(defaultWallpapper) {
updateWallpapper(defaultWallpapper);
}
}
window.addEventListener("GreeterReady", initGreeter)
</script>
<title>Example Theme</title>
</head>
<body />
</html>

67
style.css

@ -1,9 +1,11 @@
* {
--bg: rgb(255,165,0);
--bg: rgb(255,165,0);
--btbg: gray;
--main-buttons-color: rgb(255, 154, 0);
--opacity: 0.9;
--color: white;
--color-wait : var(--btbg);
}
html, body {
@ -14,11 +16,11 @@ html, body {
body {
background-image: url("wallpappers/Rosatomflot.jpg");
background-repeat: no-repeat;
background-size: 100% 100%;
background-size: 100% 100%;
}
#submit {
background-color: rgba(255, 140, 0, 1);
background-color: var(--main-buttons-color);
border: 0;
color: var(--color);
font-weight:bold;
@ -118,7 +120,7 @@ table, tr, td {
}
#buttons {
background-color: gray;
background-color: var(--btbg);
opacity: var(--opacity);
width: 150px;
margin: 0;
@ -146,7 +148,7 @@ table, tr, td {
}
#sessions, #sessions option {
background-color: rgba(255, 140, 0, 1);
background-color: var(--main-buttons-color);
opacity: 1;
border: 0;
width: 150px;
@ -182,8 +184,8 @@ table, tr, td {
}
.user-dropdown {
display: inline-block;
position: relative;
display: inline-block;
position: relative;
background-color: var(--bg);
opacity: var(--opacity);
}
@ -195,23 +197,23 @@ table, tr, td {
font-weight:bold;
}
.user-dropdown-content {
display: none;
position: absolute;
width: 100%;
overflow: auto;
box-shadow: 0px 10px 10px 0px rgba(0,0,0,0.4);
display: none;
position: absolute;
width: 100%;
overflow: auto;
box-shadow: 0px 10px 10px 0px rgba(0,0,0,0.4);
background-color: var(--bg);
opacity: var(--opacity);
}
.user-dropdown:hover .user-dropdown-content {
display: block;
display: block;
}
.user-dropdown-content button {
border: 0;
width:100%;
display: block;
padding: 5px;
text-decoration: none;
display: block;
padding: 5px;
text-decoration: none;
text-align: start;
background-color: var(--bg);
opacity: var(--opacity);
@ -222,3 +224,36 @@ table, tr, td {
background-color: #00A4BD;
}
.error {
position: relative;
animation: shake .1s linear;
animation-iteration-count: 3;
}
@keyframes shake {
0% { left: -5px; }
100% { right: -5px; }
}
.view_port {
overflow: hidden;
}
#cylon_eye {
position: relative;
top: -7px;
left: 0px;
color: white;
height: 2px;
width: 30%;
}
.waiting {
background-color: var(--color-wait);
background-image: linear-gradient(to right, var(--color) 15%, var(--color-wait) 50%, var(--color) 85%);
animation: 4s linear 0s infinite alternate move_eye;
}
@keyframes move_eye { from { margin-left:-30%; } to { margin-left:100%; } }

30
wallpapper.js

@ -0,0 +1,30 @@
const DEFAULT_WALLPAPPER = "defaultWallpapper";
const WALLPAPPER_ELEMENT = "wallpappers";
function setWallpapper(wallpapper) {
console.log(wallpapper)
var body = document.getElementsByTagName('body')[0];
body.style.backgroundImage = wallpapper;
}
function updateWallpapper(wallpapper) {
let wall_file = `url(wallpappers/${wallpapper})`
if (wallpapper === 'User') {
setWallpapper(`url(wallpappers/Rosatomflot.jpg)`)
theme_utils.dirlist(`/usr/share/web-greeter/themes/basealt/wallpappers`, true, (images) => {
if(images) {
console.log(images)
for (let i = 0; i < images.length; i++) {
let image = images[i]
if(image.indexOf("/wallpapper.png") == image.length - 15) {
setWallpapper(`url(${image})`)
console.log(wall_file)
}
}
}
});
} else {
setWallpapper(`url(wallpappers/${wallpapper})`)
}
}

BIN
wallpappers/Space_Launch.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 KiB

After

Width:  |  Height:  |  Size: 1.6 MiB

53
web-greeter-theme-basealt.spec

@ -0,0 +1,53 @@
%define shortname basealt
Name: web-greeter-theme-basealt
Version: 1.0.5
Release: alt1
Summary: A theme for web-greeter on AltLinux
License: MIT
Group: System/Configuration/Boot and Init
Url: https://git.markow.su/markow/web-greeter-theme-basealt
Source: %name-%version.tar
Packager: Sergey-V Markov <markow@altlinux.org>
Requires: lightdm lightdm-webkit2-greeter
BuildRequires:rsync
%description
A theme for web-greeter on AltLinux, it has Russian pretty interface with Basealt logos and so on
%prep
%setup
%build
%install
mkdir -p %buildroot%_datadir/web-greeter/themes/%shortname
rsync -rv --exclude-from=./.copyignore ./* %buildroot%_datadir/web-greeter/themes/%shortname/
%files
%_datadir/web-greeter/themes/%shortname/*
%changelog
* Mon Apr 3 2023 Sergey-V Markov <markow@altlinux.org> 1.0.5-alt1
- Allow to set user wallpapper
* Sun Jan 8 2023 Sergey-V Markov <sergey@markow.su> 1.0.4-alt1
- Bug fix with defaults updating storage
* Tue Oct 25 2022 Sergey-V Markov <sergey@markow.su> 1.0.3-alt1
- New feature to wait authentication
* Sat Oct 22 2022 Sergey-V Markov <sergey@markow.su> 1.0.2-alt3
- Add shortname usage
* Sat Oct 22 2022 Sergey-V Markov <sergey@markow.su> 1.0.2-alt2
- Do not copy garbage files
* Fri Oct 21 2022 Sergey-V Markov <sergey@markow.su> 1.0.2-alt1
- New theme
Loading…
Cancel
Save