mirror of
https://github.com/kittywitch/nixfiles.git
synced 2026-02-09 12:29:19 -08:00
Compare commits
5 commits
9ae22c832f
...
0e91b2184d
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e91b2184d | |||
| a3eba2f54f | |||
| 375c15c0a8 | |||
| b0b1afc339 | |||
| 1ba98534eb |
25 changed files with 305 additions and 41 deletions
26
TODO.md
26
TODO.md
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
- [ ] Make personal homepage o:
|
||||
- [ ] Figure out storing bookmarks, lists, data ...
|
||||
- [ ] Make my own quickshell config
|
||||
- [ ] Look into Matrix and Fedi accounts and setting up app(s)
|
||||
- [ ] matrix.org or nix.dev
|
||||
- [ ] Desktop
|
||||
- [ ] Test performance for virtual machines on laptop and desktop
|
||||
|
||||
## New service deployments
|
||||
|
|
@ -11,9 +12,30 @@
|
|||
- [ ] Fauna
|
||||
- [ ] Jellyfin
|
||||
- [ ] Immich
|
||||
- [ ] Prosody
|
||||
- [x] Prosody
|
||||
- [x] continuwuation
|
||||
|
||||
## Quickshell
|
||||
|
||||
- [x] Clock
|
||||
- [x] Stylix
|
||||
- [x] Workspaces
|
||||
- [x] State Colours
|
||||
- [x] System Tray
|
||||
- [x] Notification Area
|
||||
- [x] Active Window Title & Icon
|
||||
- [x] Battery
|
||||
- [ ] Pipewire
|
||||
- [ ] Bluetooth
|
||||
- [ ] Control Area
|
||||
- [x] NixOS Logo button
|
||||
- [ ] User icon & username
|
||||
- [ ] Media Widgets
|
||||
- [ ] VRAM usage
|
||||
- [ ] Lockscreen
|
||||
- [ ] Konawall / booru API integration?
|
||||
- [ ] Tooltip type that doesn't suck
|
||||
|
||||
## Migrations
|
||||
|
||||
- [ ] Move away from flakes to either npins or lon (not that they replied; https://github.com/nikstur/lon/issues/57#issue-3652308987)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
telegram-desktop # Telegram
|
||||
signal-desktop
|
||||
fluffychat
|
||||
dino
|
||||
mumble
|
||||
keymapp
|
||||
# Archivery
|
||||
|
|
|
|||
46
nixos/servers/prosody.nix
Normal file
46
nixos/servers/prosody.nix
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
_: {
|
||||
services.prosody = {
|
||||
enable = true;
|
||||
ssl.cert = "/var/lib/prosody/xmpp-fullchain.pem";
|
||||
ssl.key = "/var/lib/prosody/xmpp-key.pem";
|
||||
admins = ["kat@kittywit.ch"];
|
||||
muc = [{domain = "conference.kittywit.ch";}];
|
||||
virtualHosts."kittywit.ch" = {
|
||||
enabled = true;
|
||||
domain = "kittywit.ch";
|
||||
ssl.cert = "/var/lib/prosody/xmpp-fullchain.pem";
|
||||
ssl.key = "/var/lib/prosody/xmpp-key.pem";
|
||||
};
|
||||
httpPorts = [5280];
|
||||
httpFileShare = {
|
||||
domain = "upload.xmpp.kittywit.ch";
|
||||
};
|
||||
};
|
||||
|
||||
security.acme.certs."kittywit.ch" = {
|
||||
postRun = ''
|
||||
cp key.pem /var/lib/prosody/xmpp-key.pem
|
||||
chown prosody:prosody /var/lib/prosody/xmpp-key.pem
|
||||
cp fullchain.pem /var/lib/prosody/xmpp-fullchain.pem
|
||||
chown prosody:prosody /var/lib/prosody/xmpp-fullchain.pem
|
||||
systemctl reload prosody
|
||||
'';
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."upload.xmpp.kittywit.ch" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://127.0.0.1:5280";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
5222
|
||||
5223
|
||||
5269
|
||||
];
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
{config, ...}: {
|
||||
_: {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedTlsSettings = true;
|
||||
|
|
@ -6,32 +6,5 @@
|
|||
recommendedGzipSettings = true;
|
||||
recommendedProxySettings = true;
|
||||
statusPage = true;
|
||||
virtualHosts = let
|
||||
vHost = {
|
||||
extraConfig = ''
|
||||
add_header Content-Type text/plain;
|
||||
return 200 "meep?";
|
||||
'';
|
||||
/*
|
||||
locations = {
|
||||
"/" = {
|
||||
extraConfig = ''
|
||||
add_header Content-Type text/plain;
|
||||
return 200 "meep?";
|
||||
'';
|
||||
};
|
||||
};
|
||||
*/
|
||||
};
|
||||
in {
|
||||
"${config.networking.fqdn}" =
|
||||
vHost
|
||||
// {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
default = true;
|
||||
};
|
||||
"localhost" = vHost;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ _: let
|
|||
secretConfig = {
|
||||
format = "yaml";
|
||||
sopsFile = ./secrets.yaml;
|
||||
owner = "acme";
|
||||
group = "acme";
|
||||
};
|
||||
in {
|
||||
sops.secrets.acme_credentials = secretConfig;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
acme_credentials: ENC[AES256_GCM,data:hYjKLjGWMq9PiCobwo7PCWa/VF0ifJmLOrU4BP+vQMCFn19Ukl1gLnbDrLLzXfg9nAhkMGn5FiQJwl06ZX8E4qELXGkzSuLMvyDioEi6Plev/Wmx9szkCUd5,iv:hplC4l+aVnTLKH+bJZHCU2+NHh6154yPGMyozCUzwjM=,tag:bgOBFauegLvbFWc9sK0rcg==,type:str]
|
||||
acme_credentials: ENC[AES256_GCM,data:lxriLt0fdDp/M/JvzRv73dLjqMRrdwX+AzfxBoX/9p/uT0nusICMxTrV+AuKVxY3lztodT6knGiRjikB7QClyiq6Q4SIjAwtwPOYP3Yybfqh2NwZWBkRIQ==,iv:WLYpKBpZZOEyICM7IPP18ibJKaOA+WdUE8sZM+Vxgh4=,tag:E4b5DR6I0xHI4W2fhSRLcw==,type:str]
|
||||
sops:
|
||||
shamir_threshold: 1
|
||||
age:
|
||||
|
|
@ -101,8 +101,8 @@ sops:
|
|||
M0Y5OGtrcEJMUVcrRUdlUnNOUGNYOGsKTk5EolDKBHZPw9FSPdw1I9gs0HMylPnh
|
||||
bQ2vhwy96O487LbQ+qo29mmd5Ov+zlIvViRLjKl++171xKgj7CQQdA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-07-13T12:22:35Z"
|
||||
mac: ENC[AES256_GCM,data:MXKAesYZVdW9N1BOeNqXi8IkBjWLw1VLgXwanaM0cHe63iS17VegEGhZet0WgiMuvcroPKRNzkRSXmv8pgLsaoVMAswgJAEGJjiVDMUKnvuMd7jIs9PYp16k94VRdl/eEmVUhEmXnfpNI4QeASDbxgbRuRFIXUqGYvqYj+FlJcE=,iv:RejxH3dUgj1oxzMnMeYZ5T+XXCbbPzsyAFGyUIKcrz8=,tag:bGaOeEnvqiOAVMLzTIxS5w==,type:str]
|
||||
lastmodified: "2025-12-07T17:36:09Z"
|
||||
mac: ENC[AES256_GCM,data:+ZcOBSYxUnwtGGK7/82yiJ0p+zk8xIwe9GkX2ut051kOE9I7lENxxCCURTkO/zAAmlYZgaln287HRBBtMDE24tjUvw9UKNZm9Dfh0IQxzFnIceTQDnMTOwyvhMWXEFiwbzI2rIEihrwTH0jSwasuI9W+pusiDhk4vXkz6DlcIsk=,iv:X6OqsZ4UAcS/B1VuYRPKc2KSJO7P6JUfr6GXkh3j5Tc=,tag:0P78aet5sKwS8hoV6wUpjA==,type:str]
|
||||
pgp:
|
||||
- created_at: "2025-12-04T04:58:12Z"
|
||||
enc: |-
|
||||
|
|
@ -125,4 +125,4 @@ sops:
|
|||
-----END PGP MESSAGE-----
|
||||
fp: CD8CE78CB0B3BDD4
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
version: 3.11.0
|
||||
|
|
|
|||
95
quickshell/Components/Battery.qml
Normal file
95
quickshell/Components/Battery.qml
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.UPower
|
||||
import "root:/DataSources"
|
||||
|
||||
Loader {
|
||||
property UPowerDevice mainBat: UPower.displayDevice
|
||||
active: mainBat.isLaptopBattery
|
||||
sourceComponent: batIcon
|
||||
|
||||
function findClosestIndex(percent) {
|
||||
return Math.round(percent*10)
|
||||
}
|
||||
|
||||
property list<string> percentIcons: [
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
]
|
||||
|
||||
property string chargingIcon: ""
|
||||
|
||||
function getIcon(percent) {
|
||||
if (mainBat.timeToEmpty == 0) {
|
||||
return chargingIcon
|
||||
} else {
|
||||
var percentIcon = percentIcons[findClosestIndex(percent)];
|
||||
return percentIcon
|
||||
}
|
||||
}
|
||||
|
||||
function getTimeLeft(allSeconds, filling) {
|
||||
const hours = Math.floor(allSeconds / 3600)
|
||||
const minutes = Math.floor((allSeconds % 3600) / 60)
|
||||
const fillString = filling ? "full" : "empty"
|
||||
|
||||
return `${hours}h${minutes}m remain until ${fillString}`
|
||||
}
|
||||
|
||||
function getTimeLeftT() {
|
||||
if (mainBat.timeToEmpty != 0) {
|
||||
return getTimeLeft(mainBat.timeToEmpty, false)
|
||||
} else if (mainBat.timeToFull != 0) {
|
||||
return getTimeLeft(mainBat.timeToFull, true)
|
||||
}
|
||||
}
|
||||
|
||||
function changeRate() {
|
||||
return `${Math.round(mainBat.changeRate*100)/100}W`
|
||||
}
|
||||
|
||||
function energyLeft() {
|
||||
return `${Math.round(mainBat.energy*100)/100}Wh total`
|
||||
}
|
||||
|
||||
function getTooltip() {
|
||||
return `${getTimeLeftT()}, ${energyLeft()}, ${changeRate()}`
|
||||
}
|
||||
|
||||
Component {
|
||||
id: batIcon
|
||||
Item {
|
||||
MarginWrapperManager { margin: 10 }
|
||||
Text {
|
||||
color: Stylix.base05
|
||||
text: `${getIcon(mainBat.percentage)} ${mainBat.percentage*100} %`
|
||||
|
||||
ToolTip {
|
||||
id: dismissTooltip
|
||||
visible: false
|
||||
delay: 500
|
||||
timeout: 5000
|
||||
text: getTooltip()
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: dismissHover
|
||||
onHoveredChanged: {
|
||||
dismissTooltip.visible = hovered
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@ Item {
|
|||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
|
||||
onClicked: mouse => {
|
||||
modelData.triggered();
|
||||
|
|
@ -33,16 +33,15 @@ Item {
|
|||
property real clicky
|
||||
id: wrapperPopup
|
||||
anchor.window: root.QsWindow.window
|
||||
anchor.rect.y: parentWindow.height
|
||||
anchor.rect.y: parentWindow?.height ?? 0
|
||||
anchor.rect.x: clicky
|
||||
implicitWidth: systray.width + 10
|
||||
implicitHeight: systray.height + 10
|
||||
implicitHeight: systray?.height + 10
|
||||
color: "transparent"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Stylix.base01
|
||||
bottomLeftRadius: 5
|
||||
bottomRightRadius: 5
|
||||
radius: 5
|
||||
SystemTray {
|
||||
id: systray
|
||||
}
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import "root:/DataSources"
|
||||
import "root:/Components"
|
||||
import "root:/Components/NotificationSystem"
|
||||
import "root:/Components/WorkspaceControl"
|
||||
import "root:/Components/SystemTray"
|
||||
import "root:/Components/NotificationArea"
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
|
|
@ -34,7 +37,13 @@ Scope {
|
|||
|
||||
Rectangle {
|
||||
id: bar
|
||||
anchors.fill: parent
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
MarginWrapperManager { margin: 10 }
|
||||
radius: 10
|
||||
color: Stylix.base00
|
||||
|
||||
|
|
@ -54,11 +63,22 @@ Scope {
|
|||
}
|
||||
FocusedWindow {}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: 20
|
||||
}
|
||||
Rectangle {
|
||||
MarginWrapperManager { margin: 10 }
|
||||
id: bar3
|
||||
radius: 10
|
||||
color: Stylix.base00
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors {
|
||||
|
|
@ -71,6 +91,7 @@ Scope {
|
|||
|
||||
spacing: 15
|
||||
|
||||
Battery {}
|
||||
SystemTrayWrapper {}
|
||||
Clock {}
|
||||
NotificationDisplay {}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
_: let
|
||||
hostConfig = {
|
||||
tree,
|
||||
config,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
|
|
@ -53,6 +54,21 @@ _: let
|
|||
# };
|
||||
#};
|
||||
|
||||
services.nginx.virtualHosts = let
|
||||
vHost = {
|
||||
extraConfig = ''
|
||||
add_header Content-Type text/plain;
|
||||
return 200 "meep?";
|
||||
'';
|
||||
};
|
||||
in {
|
||||
${config.networking.fqdn} = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
default = true;
|
||||
};
|
||||
"localhost" = vHost;
|
||||
};
|
||||
security.acme.defaults.email = "acme@inskip.me";
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ _: let
|
|||
++ (with tree.nixos.servers; [
|
||||
mail
|
||||
continuwuity
|
||||
prosody
|
||||
web
|
||||
]);
|
||||
|
||||
boot = {
|
||||
|
|
|
|||
|
|
@ -199,3 +199,89 @@ resource "cloudflare_record" "dork_mail_imaps_autodiscover" {
|
|||
}
|
||||
zone_id = local.zone_ids.dork
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "kittywitch_xmpp_server" {
|
||||
name = "_xmpp-server._tcp"
|
||||
proxied = false
|
||||
ttl = 3600
|
||||
type = "SRV"
|
||||
|
||||
data {
|
||||
service = "_xmpp-server"
|
||||
proto = "_tcp"
|
||||
priority = 5
|
||||
weight = 0
|
||||
port = 5269
|
||||
target = "rinnosuke.inskip.me"
|
||||
}
|
||||
zone_id = local.zone_ids.kittywitch
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "kittywitch_xmpp_server_ssl" {
|
||||
name = "_xmpps-server._tcp"
|
||||
proxied = false
|
||||
ttl = 3600
|
||||
type = "SRV"
|
||||
|
||||
data {
|
||||
service = "_xmpps-server"
|
||||
proto = "_tcp"
|
||||
priority = 5
|
||||
weight = 0
|
||||
port = 5269
|
||||
target = "rinnosuke.inskip.me"
|
||||
}
|
||||
zone_id = local.zone_ids.kittywitch
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "kittywitch_xmpp_client" {
|
||||
name = "_xmpp-client._tcp"
|
||||
proxied = false
|
||||
ttl = 3600
|
||||
type = "SRV"
|
||||
|
||||
data {
|
||||
service = "_xmpp-server"
|
||||
proto = "_tcp"
|
||||
priority = 5
|
||||
weight = 0
|
||||
port = 5222
|
||||
target = "rinnosuke.inskip.me"
|
||||
}
|
||||
zone_id = local.zone_ids.kittywitch
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "kittywitch_xmpp_client_ssl" {
|
||||
name = "_xmpps-client._tcp"
|
||||
proxied = false
|
||||
ttl = 3600
|
||||
type = "SRV"
|
||||
|
||||
data {
|
||||
service = "_xmpps-client"
|
||||
proto = "_tcp"
|
||||
priority = 5
|
||||
weight = 0
|
||||
port = 5223
|
||||
target = "rinnosuke.inskip.me"
|
||||
}
|
||||
zone_id = local.zone_ids.kittywitch
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "xmpp" {
|
||||
name = "xmpp"
|
||||
proxied = false
|
||||
ttl = 3600
|
||||
type = "CNAME"
|
||||
value = "rinnosuke.inskip.me"
|
||||
zone_id = local.zone_ids.kittywitch
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "xmpp_upload" {
|
||||
name = "xmpp.upload"
|
||||
proxied = false
|
||||
ttl = 3600
|
||||
type = "CNAME"
|
||||
value = "rinnosuke.inskip.me"
|
||||
zone_id = local.zone_ids.kittywitch
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue