Compare commits
47 Commits
master
...
d3bd7a1925
| Author | SHA1 | Date | |
|---|---|---|---|
| d3bd7a1925 | |||
| 23c5460698 | |||
| c4dba2d7c1 | |||
| 593d5a04b9 | |||
| 0ff1fd050d | |||
| 2c792efd64 | |||
| 5101d754db | |||
| 18dc79243d | |||
| 203b08d044 | |||
| 3ceaeeafda | |||
| 898bd01b83 | |||
| de7e38855a | |||
| 40748d6f8c | |||
| 4da471af9f | |||
| d20e80c866 | |||
| a1cff8417a | |||
| a157669815 | |||
| 5de2dc09f4 | |||
| ca2cedc3a2 | |||
| de1c0bebff | |||
| 914be41a0a | |||
| 62a6937c20 | |||
| 7b0acd007b | |||
| 000bb3ea47 | |||
| 297f96ab99 | |||
| 3112316e7d | |||
| 1ca991e4b9 | |||
| c827757fb8 | |||
| 01c994aa13 | |||
| 1de4bf249b | |||
| 28c29f0d30 | |||
| 8a832250a0 | |||
| 225f2af48b | |||
| 2144038970 | |||
| 512a810122 | |||
| 2e5696f767 | |||
| 1751b590aa | |||
| a95f13943f | |||
| 7f23f234cd | |||
| b227a41a43 | |||
| bf5f265116 | |||
| 1cf12f91f0 | |||
| 00eec8be70 | |||
| 542e432596 | |||
| 0791f417f3 | |||
| 2439dfa78d | |||
| e0248abb46 |
@@ -4,9 +4,6 @@ on: pull_request
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
# Skip if PR base is master/dev
|
|
||||||
if: github.base_ref != 'master' && github.base_ref != 'dev'
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,2 @@
|
|||||||
public/
|
public/
|
||||||
!static/public/
|
|
||||||
*.swp
|
*.swp
|
||||||
|
|||||||
45
Makefile
45
Makefile
@@ -1,41 +1,10 @@
|
|||||||
# -------- Config --------
|
all: clean format build
|
||||||
SHELL := /bin/sh
|
|
||||||
|
|
||||||
ZOLA ?= zola
|
format:
|
||||||
BIOME ?= npx biome
|
biome format --write .
|
||||||
|
|
||||||
BUILD_DIR := public
|
build:
|
||||||
|
zola build
|
||||||
# -------- Targets --------
|
|
||||||
.PHONY: help serve build clean format lint fix fix-unsafe check ci
|
|
||||||
|
|
||||||
help: ## Show this help
|
|
||||||
@awk 'BEGIN{FS":.*##"; printf "\nTargets:\n"} /^[a-zA-Z0-9_.-]+:.*##/{printf " \033[36m%-14s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST); echo
|
|
||||||
|
|
||||||
serve: ## Run Zola dev server (http://127.0.0.1:1111)
|
|
||||||
$(ZOLA) serve
|
|
||||||
|
|
||||||
build: ## Build site into ./public
|
|
||||||
$(ZOLA) build
|
|
||||||
|
|
||||||
clean: ## Remove ./public
|
|
||||||
rm -rf "$(BUILD_DIR)"
|
|
||||||
|
|
||||||
format: ## Format JS/JSON/CSS with Biome (no linting)
|
|
||||||
$(BIOME) format --write .
|
|
||||||
|
|
||||||
lint: ## Lint with Biome (no writes)
|
|
||||||
$(BIOME) ci .
|
|
||||||
|
|
||||||
fix: ## Lint+auto-fix safe changes with Biome
|
|
||||||
$(BIOME) check --write .
|
|
||||||
|
|
||||||
fix-unsafe: ## Lint+auto-fix incl. unsafe (e.g., template literals)
|
|
||||||
$(BIOME) check --write --unsafe .
|
|
||||||
|
|
||||||
check: ## Zola link/content checks
|
|
||||||
$(ZOLA) check
|
|
||||||
|
|
||||||
ci: ## CI-friendly: lint (Biome) + Zola checks
|
|
||||||
$(BIOME) ci . && $(ZOLA) check
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf public/
|
||||||
|
|||||||
34
biome.json
34
biome.json
@@ -1,41 +1,15 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://biomejs.dev/schemas/2.2.2/schema.json",
|
"$schema": "https://biomejs.dev/schemas/1.7.3/schema.json",
|
||||||
"vcs": {
|
|
||||||
"enabled": true,
|
|
||||||
"clientKind": "git",
|
|
||||||
"useIgnoreFile": true
|
|
||||||
},
|
|
||||||
"files": {
|
"files": {
|
||||||
"includes": ["**", "!public", "!content", "!templates", "!static/img", "!**/*.min.js"]
|
"ignore": [".vscode/", "node_modules/", "public/"]
|
||||||
},
|
},
|
||||||
"formatter": {
|
"organizeImports": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
},
|
||||||
"linter": {
|
"linter": {
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"rules": {
|
"rules": {
|
||||||
"recommended": true
|
"recommended": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"javascript": {
|
|
||||||
"formatter": {
|
|
||||||
"lineWidth": 100,
|
|
||||||
"quoteStyle": "double",
|
|
||||||
"jsxQuoteStyle": "double",
|
|
||||||
"trailingCommas": "all",
|
|
||||||
"semicolons": "always"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"json": {
|
|
||||||
"formatter": {
|
|
||||||
"lineWidth": 100
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"css": {
|
|
||||||
"formatter": {
|
|
||||||
"enabled": true,
|
|
||||||
"lineWidth": 100,
|
|
||||||
"quoteStyle": "single"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# The URL the site will be built for
|
# The URL the site will be built for
|
||||||
base_url = "https://www.filiprojek.cz"
|
base_url = "https://dev.filiprojek.cz"
|
||||||
title = "Filip Rojek"
|
title = "Filip Rojek"
|
||||||
|
|
||||||
compile_sass = true
|
compile_sass = true
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ As a member of [Microlab](https://microlab.space), the university's hackerspace,
|
|||||||
|
|
||||||
## Work
|
## Work
|
||||||
|
|
||||||
Currently employed as a Linux DevOps engineer, focusing primarily on Debian-based systems across a variety of hardware platforms.
|
Currently employed as a Linux Devops engineer. Most of my work involves Debian-based systems on various hardware platforms.
|
||||||
|
|
||||||
I also create custom websites from time to time.
|
I also create custom websites from time to time.
|
||||||
|
|
||||||
|
|||||||
@@ -1,141 +0,0 @@
|
|||||||
+++
|
|
||||||
title = "Friendship ended with dwm, now River is my best friend"
|
|
||||||
date = 2025-10-21
|
|
||||||
description = "Moving from X11 with dwm to River on Wayland"
|
|
||||||
+++
|
|
||||||
|
|
||||||
After years with dwm on X11, I started hitting the limits of Xorg — especially screen tearing, smoothness, and missing Wayland-only features. I decided it was time to switch.
|
|
||||||
|
|
||||||
## Weapon of choice - River
|
|
||||||
|
|
||||||
I wanted an experience as close as possible to my existing X11/dwm/dwmblocks setup. Before i jumped into `river`, I looked at `dwl`, `sway`, and `Qtile`.
|
|
||||||
|
|
||||||
`dwl` sounded like the best choice for me since it aims to replicate dwm on Wayland. But development is slow, many protocols are still missing, and adding them takes time.
|
|
||||||
|
|
||||||
Sway wasn't bad, but it's closer to i3 than dwm, so not ideal for me.
|
|
||||||
|
|
||||||
Qtile looked good, but I didn't like configuring it in Python.
|
|
||||||
|
|
||||||
Then my friend [Emil](https://em.0x45.cz/) told me about his `river` setup. He was happy with it, so I gave it a shot.
|
|
||||||
|
|
||||||
What I really like about river is that I can configure it on the fly. The whole configuration is a single Bash script that sends commands to river live - no recompiling or restarting required.
|
|
||||||
|
|
||||||
As a layout manager I chose [Filtile](https://github.com/pkulak/filtile) as it's very similar to dwm behavior.
|
|
||||||
|
|
||||||
## Bar dwmblocks => waybar
|
|
||||||
As an alternative to `dwmblock`, I found Waybar to be the best fit for me.
|
|
||||||
|
|
||||||
It has plenty of modules for displaying almost anything on my bar, including my IP address, speaker/headphones state and battery status.
|
|
||||||
|
|
||||||
Besides using built-in modules, it's also possible to create custom ones using scripts. I've made my own module for displaying speaker/headphones volume with possibility to mute or change the default audio output on mouse click.
|
|
||||||
|
|
||||||
- `~/.config/waybar/config.jsonc`
|
|
||||||
```jsonc
|
|
||||||
...
|
|
||||||
|
|
||||||
"custom/audio": {
|
|
||||||
"exec": "~/.local/bin/waybar_audio.sh",
|
|
||||||
"return-type": "json",
|
|
||||||
"format": "{icon} {text}",
|
|
||||||
"format-icons": {
|
|
||||||
"speaker": ["", "", " "],
|
|
||||||
"speaker-muted": "",
|
|
||||||
"headphones": "",
|
|
||||||
"headphones-muted": ""
|
|
||||||
},
|
|
||||||
"interval": 2,
|
|
||||||
"on-click": "pamixer --toggle-mute",
|
|
||||||
"on-click-right": "~/.local/bin/toggle_audio",
|
|
||||||
"on-scroll-up": "pamixer --increase 5",
|
|
||||||
"on-scroll-down": "pamixer --decrease 5"
|
|
||||||
},
|
|
||||||
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
Where `waybar_audio.sh` and `toggle_audio` are my custom Bash scripts both available in my [dotfiles repository](https://git.filiprojek.cz/fr/dotfiles/src/branch/master/.local/bin).
|
|
||||||
|
|
||||||
## Application starter dmenu => Wmenu
|
|
||||||
I found Wmenu to be the most similar app launcher to dmenu and I don't like changes, so I picked it.
|
|
||||||
I was able to customize it to my liking - vertical list of apps.
|
|
||||||
The only thing that didn't work and I missed that feature so much was fuzzy search. Wmenu doesn't support it and there was no patch available. So I've decided to create my own version of wmenu with fuzzy search support with help of chatgpt codex :D. As much as I hate AI, Codex was actually able to modify that C code in just single prompt. My modified version of Wmenu is available in [this github repository](https://github.com/filiprojek/wmenu).
|
|
||||||
|
|
||||||
## passmenu integration to wmenu
|
|
||||||
For my password manager GUI I like to use passmenu - an dmenu script that helps me pick my password anywhere I am. But there was a problem. Passmenu was written only for dmenu. That's where chatgpt helped me again and together we created [this rewrite of passmenu](https://github.com/filiprojek/passmenu-wmenu) for Wmenu.
|
|
||||||
Passmenu is an excellent example of where I use the fuzzy search feature the most.
|
|
||||||
|
|
||||||
## Terminal alacritty => foot
|
|
||||||
Since Alacritty sucks at displaying images inside the terminal, I moved to foot as an alternative. It supports displaying images natively.
|
|
||||||
There was an issue with spawning new terminal inside the current working directory. I was used to Alacritty's <CTRL+Shift+Enter> shortcut. I fixed that with the following addition to my `.bashrc`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
osc7_cwd() {
|
|
||||||
local strlen=${#PWD}
|
|
||||||
local encoded=""
|
|
||||||
local pos c o
|
|
||||||
for (( pos=0; pos<strlen; pos++ )); do
|
|
||||||
c=${PWD:$pos:1}
|
|
||||||
case "$c" in
|
|
||||||
[-/:_.!\'\(\)~[:alnum:]] ) o="${c}" ;;
|
|
||||||
* ) printf -v o '%%%02X' "'${c}" ;;
|
|
||||||
esac
|
|
||||||
encoded+="${o}"
|
|
||||||
done
|
|
||||||
printf '\e]7;file://%s%s\e\\' "${HOSTNAME}" "${encoded}"
|
|
||||||
}
|
|
||||||
PROMPT_COMMAND=${PROMPT_COMMAND:+${PROMPT_COMMAND%;}; }osc7_cwd
|
|
||||||
```
|
|
||||||
|
|
||||||
And this keybind in `foot.ini`:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[key-bindings]
|
|
||||||
spawn-terminal=Control+Shift+Return
|
|
||||||
```
|
|
||||||
|
|
||||||
## Screenshare
|
|
||||||
Once I had my setup ready, one of the first issues after using it for some time was screen sharing. I dug into the issue and found a solution.
|
|
||||||
I had to add this to my River init file:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Fix screen share
|
|
||||||
export XDG_CURRENT_DESKTOP=river
|
|
||||||
export XDG_SESSION_TYPE=wayland
|
|
||||||
|
|
||||||
## Start portals
|
|
||||||
dbus-update-activation-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
|
||||||
xdg-desktop-portal-wlr &
|
|
||||||
xdg-desktop-portal &
|
|
||||||
```
|
|
||||||
|
|
||||||
## Screenshots
|
|
||||||
On my X.org setup I was using screenshots with `shotgun` and `slop` based on my friend's tutorial: [Taking screenshots with shotgun and slop](https://em.0x45.cz/posts/taking-screenshots-with-shotgun-and-slop/). Fortunately he already wrote a guide for wayland alternative: [Taking screenshots on Wayland with Grim and Slurp](https://em.0x45.cz/posts/taking-screenshots-on-wayland-with-grim-and-slurp/).
|
|
||||||
|
|
||||||
But I had issues with the combination of `grim` and `slurp`. While pasting an image from clipboard to telegram, it pasted raw PNG data instead of a file. This was the fix:
|
|
||||||
```bash
|
|
||||||
riverctl map normal None Print spawn 'file="/home/$USER/Pictures/Screenshots/$(date +%F_%T).png"; grim -g "$(slurp -d)" "$file" && wl-copy --type text/uri-list "file://$file"'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Other alternatives
|
|
||||||
This is a list of other software that I used on X.org and their alternatives on Wayland:
|
|
||||||
- `xclip` => `wl-copy`
|
|
||||||
- `ranger` => `yazi`
|
|
||||||
- `slock` => `waylock`
|
|
||||||
|
|
||||||
## Final thoughts
|
|
||||||
After a few weeks with River, I don’t miss Xorg much. The setup feels lighter, screenshots and screen sharing work fine now, and I can still keep my DWM-like workflow.
|
|
||||||
|
|
||||||
There's just one thing I didn't get working and that is the indication of how many windows are open in monocle layout. Dwm used `[X]` where `X` was the number of open windows on that tag.
|
|
||||||
|
|
||||||
River feels more responsive overall, and I haven’t run into any crashes so far.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## References
|
|
||||||
- [River - dynamic tiling Wayland compositor](https://codeberg.org/river/river-classic)
|
|
||||||
- [Filtile](https://github.com/pkulak/filtile)
|
|
||||||
- [Waybar](https://github.com/Alexays/Waybar)
|
|
||||||
- [Wmenu](https://codeberg.org/adnano/wmenu)
|
|
||||||
- [My fork of Wmenu with Fuzzy search support](https://github.com/filiprojek/wmenu)
|
|
||||||
- [Passmenu for wmenu](https://github.com/filiprojek/passmenu-wmenu)
|
|
||||||
- [Foot - Wayland terminal emulator](https://codeberg.org/dnkl/foot)
|
|
||||||
@@ -35,9 +35,7 @@
|
|||||||
.project {
|
.project {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin: 1rem 0;
|
margin: 1rem 30%;
|
||||||
width: 100%;
|
|
||||||
max-width: 40%;
|
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
.title {
|
.title {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
@@ -57,7 +55,6 @@
|
|||||||
}
|
}
|
||||||
.latest-projects-posts .project {
|
.latest-projects-posts .project {
|
||||||
margin: 1rem 5%;
|
margin: 1rem 5%;
|
||||||
max-width: 90%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,6 @@ code {
|
|||||||
p {
|
p {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.link-back {
|
.link-back {
|
||||||
|
|||||||
@@ -1,28 +1,30 @@
|
|||||||
const codes = document.querySelectorAll("pre");
|
let codes = document.querySelectorAll("pre")
|
||||||
|
|
||||||
codes.forEach((code) => {
|
codes.forEach(code => {
|
||||||
const elWrapper = document.createElement("div");
|
const elWrapper = document.createElement("div")
|
||||||
elWrapper.classList.add("copy-code-wrapper");
|
elWrapper.classList.add("copy-code-wrapper")
|
||||||
|
|
||||||
const el = document.createElement("span");
|
|
||||||
el.textContent = "Copy";
|
|
||||||
el.classList.add("copy-code");
|
|
||||||
|
|
||||||
elWrapper.appendChild(el);
|
const el = document.createElement("span")
|
||||||
|
el.textContent = "Copy"
|
||||||
|
el.classList.add("copy-code")
|
||||||
|
|
||||||
code.parentNode.insertBefore(elWrapper, code);
|
elWrapper.appendChild(el)
|
||||||
|
|
||||||
let textContent = "";
|
code.parentNode.insertBefore(elWrapper, code)
|
||||||
code.childNodes.forEach((child) => {
|
|
||||||
|
let textContent = ""
|
||||||
|
code.childNodes.forEach(child => {
|
||||||
textContent += child.textContent;
|
textContent += child.textContent;
|
||||||
});
|
})
|
||||||
|
|
||||||
elWrapper.addEventListener("click", (e) => {
|
elWrapper.addEventListener("click", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
navigator.clipboard.writeText(textContent);
|
navigator.clipboard.writeText(textContent)
|
||||||
el.textContent = "Copied!";
|
el.textContent = "Copied!"
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
el.textContent = "Copy";
|
el.textContent = "Copy"
|
||||||
}, 5000);
|
}, 5000);
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
|
|||||||
107
static/js/console.js
Normal file
107
static/js/console.js
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
const c = document.querySelector(".console")
|
||||||
|
const ps1 = "[fr@website ~]$ "
|
||||||
|
const motd = "Welcome to my website!<br>You can use `help` for more informations :)"
|
||||||
|
let line = "";
|
||||||
|
|
||||||
|
function exec(command) {
|
||||||
|
switch (command[0]) {
|
||||||
|
case "help":
|
||||||
|
line = "help<br>author<br>contact<br>clear<br>echo"
|
||||||
|
break;
|
||||||
|
case "author":
|
||||||
|
line = "Filip Rojek, 2023"
|
||||||
|
break
|
||||||
|
case "contact":
|
||||||
|
line = "Filip Rojek <<a href='mailto: filip@filiprojek.cz'>filip@filiprojek.cz</a>><br>web: <a href='https://filiprojek.cz' target='_blank'>www.filiprojek.cz</a><br>telegram: <a href='https://t.me/filiprojek' target='_blank'>@filiprojek</a>"
|
||||||
|
break
|
||||||
|
case "clear":
|
||||||
|
write("000ctrll")
|
||||||
|
return false
|
||||||
|
case "echo":
|
||||||
|
line = ""
|
||||||
|
command.forEach((cmd, i) => {
|
||||||
|
if (i === 0) return
|
||||||
|
line += cmd + " "
|
||||||
|
});
|
||||||
|
line = line.substring(0, line.length - 1) // remove last space
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
line = "frsh: " + command[0] + ": command not found"
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
|
||||||
|
function write(key, payload) {
|
||||||
|
switch(key) {
|
||||||
|
case "Enter":
|
||||||
|
command = c.lastChild.textContent.replace(ps1, "")
|
||||||
|
command = command.split(" ");
|
||||||
|
let out = exec(command)
|
||||||
|
if(out !== false) {
|
||||||
|
line = document.createElement("p")
|
||||||
|
line.innerHTML += out
|
||||||
|
line.innerHTML += "<br>"
|
||||||
|
c.appendChild(line)
|
||||||
|
line = document.createElement("p")
|
||||||
|
line.innerHTML += ps1
|
||||||
|
c.appendChild(line)
|
||||||
|
}
|
||||||
|
command = ""
|
||||||
|
break
|
||||||
|
case "000ctrll":
|
||||||
|
c.innerHTML = ""
|
||||||
|
if(payload == motd) c.innerHTML = motd
|
||||||
|
line = document.createElement("p")
|
||||||
|
line.innerHTML += ps1
|
||||||
|
c.appendChild(line)
|
||||||
|
break
|
||||||
|
case "000backspace":
|
||||||
|
if(c.lastChild.textContent.slice(0, -1) !== ps1.slice(0, -1)) {
|
||||||
|
c.lastChild.innerHTML = c.lastChild.textContent.slice(0, -1)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
c.lastChild.innerHTML += key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function customCtrlShortcuts(plusKey) {
|
||||||
|
document.addEventListener("keydown", e => {
|
||||||
|
if(e.ctrlKey && e.key == plusKey) {
|
||||||
|
e.preventDefault()
|
||||||
|
write("000ctrl"+plusKey)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// On load init the terminal
|
||||||
|
window.addEventListener("load", () => {
|
||||||
|
write("000ctrll", motd)
|
||||||
|
if (navigator.userAgent.toLowerCase().includes("mobile")) {
|
||||||
|
const mi = document.querySelector(".mobile-input")
|
||||||
|
mi.style="opacity: 0; width: 0; height: 0"
|
||||||
|
c.addEventListener("click", e => {
|
||||||
|
mi.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Capture the keypress
|
||||||
|
window.addEventListener("keypress", e => {
|
||||||
|
e.preventDefault()
|
||||||
|
write(e.key)
|
||||||
|
})
|
||||||
|
|
||||||
|
window.addEventListener("keydown", e => {
|
||||||
|
if(e.key == "Backspace") {
|
||||||
|
e.preventDefault()
|
||||||
|
write("000backspace")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Register custom ctrl shortcuts
|
||||||
|
customCtrlShortcuts("l") // ctrl + l
|
||||||
|
customCtrlShortcuts("c") // ctrl + c
|
||||||
@@ -1,24 +1,26 @@
|
|||||||
const burger = document.querySelector(".hamburger");
|
const burger = document.querySelector(".hamburger")
|
||||||
const links = document.querySelector(".links");
|
const links = document.querySelector(".links")
|
||||||
const body = document.querySelector("body");
|
const body = document.querySelector("body")
|
||||||
const main = document.querySelector("main");
|
const main = document.querySelector("main")
|
||||||
|
|
||||||
let shown = false;
|
let shown = false
|
||||||
|
|
||||||
burger.addEventListener("click", (e) => {
|
burger.addEventListener("click", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
|
|
||||||
if (!shown) {
|
if (!shown) {
|
||||||
links.style.display = "flex";
|
links.style.display = "flex"
|
||||||
body.classList.add("disable-scroll");
|
body.classList.add("disable-scroll")
|
||||||
burger.textContent = "x";
|
burger.textContent = "x"
|
||||||
main.style.visibility = "hidden";
|
main.style.visibility = "hidden"
|
||||||
} else {
|
} else {
|
||||||
links.style.display = "none";
|
links.style.display = "none"
|
||||||
body.classList.remove("disable-scroll");
|
body.classList.remove("disable-scroll")
|
||||||
burger.textContent = "☰";
|
burger.textContent = "☰"
|
||||||
main.style.visibility = "visible";
|
main.style.visibility = "visible"
|
||||||
}
|
}
|
||||||
|
|
||||||
shown = !shown;
|
shown = !shown
|
||||||
});
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 379 KiB |
@@ -28,7 +28,6 @@
|
|||||||
<script defer src="/js/mobile-navbar.js"></script>
|
<script defer src="/js/mobile-navbar.js"></script>
|
||||||
{% block styles %}
|
{% block styles %}
|
||||||
{% endblock styles %}
|
{% endblock styles %}
|
||||||
<script defer data-domain="filiprojek.cz" src="https://analytics.fofrweb.com/js/script.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
|
|||||||
Reference in New Issue
Block a user