Skip to content

Commit

Permalink
Merge pull request #22 from xTrayambak/auto-updater
Browse files Browse the repository at this point in the history
Add autoupdater
  • Loading branch information
xTrayambak authored Dec 31, 2024
2 parents 4aa2172 + 28bfa82 commit bc074b2
Show file tree
Hide file tree
Showing 12 changed files with 275 additions and 54 deletions.
49 changes: 18 additions & 31 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,23 @@
# Lucem 2.0.1 is here!
Yay. This is a hotfix release and you should update to it ASAP!

**NOTICE**: Please run `lucem init` upon installing this release!
# Lucem 2.1.0 is here!
Yay. \
This changelog contains every feature from 2.0.2 to 2.1.0

## Fixed Bugs
* Editing the configuration with `lucem shell` would result in your configuration getting borked

## Thank you to all these people :3
* The Sober team for creating Sober (plox open source it so that I can rewrite it in Nim :3)
* adverbialsatz for reporting the bug

## Installation
Run `nimble install https://github.com/xTrayambak/lucem` in your terminal. Remember, this requires a Nim toolchain with version 2.0 or higher.

# Lucem 2.0.0 is here!
Yay.

**NOTICE**: Please run `lucem init` upon installing this release!

This release rewrites a huge part of Lucem by splitting it up into three components - the lucem CLI you all know (and love? hate? I don't know!) to be more modular.

# What's Changed?
Lucem stands at 2.4K lines of code.

## New Features
* Lucem now allows you to change the renderer with the `client:renderer` backend. Correct values for this are `opengl` or `vulkan`.
* Lucem now has an overlay on platforms that support it (KDE, Hyprland, Sway, Cosmic, or basically anything that isn't GNOME)
* Lucem now defaults to using Sober's RPC implementation as it is better. `lucem:discord_rpc` still works as intended.

## Thank you to all of these people :3
* The Sober team for creating Sober (plox open source it so that I can rewrite it in Nim :3)
* AshtakaOof for beta-testing the early rewrite builds
* The Flatpak command that'd install Sober would get stuck on a confirmation (2.0.2)
* `lucemd` no longer causes CPU spikes (2.0.3)
* `lucem_overlay` lets your compositor blur its surface (2.0.3)
* Added support for the new Sober configuration interface (2.0.3)
* Fixed botched symbolic icons in the settings shell (2.0.4)
* Fixed arbitrary daemon sleep time (2.0.4)
* Don't emit `--opengl` flag, use configuration instead (2.0.4)
* Lock FPS to 60 by default, preventing coil whine (2.1.0)

## Additions
* Added autoupdater, this checks for updates every time Lucem is run. (2.1.0)
* You can now update Lucem by running `lucem update`. (2.1.0)
* Added update alert that shows up every time a new release is available. (2.1.0)
* Overhauled Lucem shell to make it nicer to use (2.1.0)
* Added new Lucem icon (2.0.4)

## Installation
Run `nimble install https://github.com/xTrayambak/lucem` in your terminal. Remember, this requires a Nim toolchain with version 2.0 or higher.
4 changes: 3 additions & 1 deletion lucem.nimble
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Package

version = "2.0.4"
version = "2.1.0"
author = "xTrayambak"
description = "A small wrapper over Sober that provides quality of life improvements"
license = "MIT"
Expand Down Expand Up @@ -31,3 +31,5 @@ after install:
echo "\e[1mThanks for installing Lucem!"
echo "If you run `lucem` in the terminal and no command is found, try running the command below:\e[0m"
echo "\e[1:32mexport PATH=\"$HOME/.nimble/bin:$PATH\"\e[0m"

requires "semver >= 1.2.3"
3 changes: 2 additions & 1 deletion shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mkShell {
xorg.libXext
libxkbcommon
libGL.dev
wayland
wayland.dev
wayland-protocols
wayland-scanner.dev
];
Expand All @@ -24,5 +24,6 @@ mkShell {
pkg-config
curl.dev
openssl.dev
wayland.dev
];
}
Binary file added src/assets/lucem.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/commands/run.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import ../api/[games, thumbnails, ipinfo]
import
../patches/[bring_back_oof, patch_fonts, sun_and_moon_textures, windowing_backend]
import ../shell/loading_screen
import ../proto
import ../sober_config
import ../[updater, sober_config, proto]
import
../[
argparser, config, flatpak, common, meta, sugar, notifications, fflags, log_file,
Expand Down Expand Up @@ -158,6 +157,7 @@ proc eventWatcher*(

proc runRoblox*(input: Input, config: Config) =
info "lucem: running Roblox via Sober"
runUpdateChecker(config)

writeFile(getSoberLogPath(), newString(0))

Expand Down
1 change: 1 addition & 0 deletions src/config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type

LucemConfig* = object
discord_rpc*: bool = false
auto_updater*: bool = true
notify_server_region*: bool = true
loading_screen*: bool = true
polling_delay*: uint = 100
Expand Down
8 changes: 6 additions & 2 deletions src/http.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Reducing code clutter when making HTTP requests
import std/[logging, monotimes]
import pkg/[curly]
import pkg/[curly, webby]
import ./meta

{.passC: gorge("pkg-config --cflags libcurl").}
Expand All @@ -10,10 +10,14 @@ var curl = newCurly()
proc httpGet*(url: string): string =
debug "http: making HTTP/GET request to " & url & "; allocating HttpClient"
let
headers = toWebby(@[
("User-Agent", "lucem/" & Version)
])
startReq = getMonoTime()
req = curl.get(url)
req = curl.get(url, headers)
endReq = getMonoTime()

debug "http: HTTP/GET request to " & url & " took " & $(endReq - startReq)
debug "http: response body:\n" & req.body

req.body
1 change: 1 addition & 0 deletions src/internal_fonts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
const
IbmPlexSans* = staticRead("IBMPlexSans-Regular.ttf")
LucemIcon* = staticRead("assets/lucem.svg")
LucemIconPng* = staticRead("assets/lucem.png")
7 changes: 6 additions & 1 deletion src/lucem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import std/[os, logging, strutils, terminal]
import colored_logger, nimgl/vulkan
import ./[meta, argparser, config, cache_calls, desktop_files, sober_state, gpu_info, systemd]
import ./[meta, argparser, config, cache_calls, desktop_files, sober_state, gpu_info, systemd, updater]
import ./shell/core
import ./commands/[init, run, edit_config, explain]

Expand All @@ -17,6 +17,7 @@ Commands:
run Run Sober
meta Get build metadata
list-gpus List all GPUs on this system
update Check for Lucem updates and install them
edit-config Edit the configuration file
clear-cache Clear the API caches that Lucem maintains
shell Launch the Lucem configuration GUI
Expand Down Expand Up @@ -95,6 +96,10 @@ proc main() {.inline.} =
initializeSober(input)
createLucemDesktopFile()
installSystemdService()
of "update":
updateLucem()
of "check-for-updates":
runUpdateChecker(parseConfig(input))
of "install-systemd-service":
installSystemdService()
of "relaunch-daemon":
Expand Down
85 changes: 70 additions & 15 deletions src/lucem_overlay.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,36 @@ privateAccess(WindowWaylandObj)
privateAccess(WindowWayland)
privateAccess(Window)

{.passC: gorge("pkg-config --cflags wayland-client").}
{.passL: gorge("pkg-config --libs wayland-client").}
{.passC: gorge("pkg-config --cflags x11").}
{.passL: gorge("pkg-config --libs x11").}
{.passC: gorge("pkg-config --cflags xcursor").}
{.passL: gorge("pkg-config --libs xcursor").}
{.passC: gorge("pkg-config --cflags xext").}
{.passL: gorge("pkg-config --libs xext").}
{.passC: gorge("pkg-config --cflags xkbcommon").}
{.passL: gorge("pkg-config --libs xkbcommon").}
{.passC: gorge("pkg-config --cflags gl").}
{.passL: gorge("pkg-config --libs gl").}

type
OverlayState* = enum
osOverlay
osUpdateAlert

Overlay* = object
heading*: string
description*: string
expireTime*: float
state*: OverlayState = osOverlay

icon*: Option[string]
closed*: bool
config*: Config

lucemImage*: Image

vg*: NVGContext
wl*: WindowWaylandOpengl
size*: IVec2 = ivec2(600, 200)
Expand Down Expand Up @@ -47,13 +68,26 @@ proc draw*(overlay: var Overlay) =
overlay.vg.textAlign(haLeft, vaTop)
overlay.vg.fontSize(overlay.config.overlay.headingSize)
overlay.vg.fillColor(white(255))
discard overlay.vg.text(16f, 16f, overlay.heading)

var icon = cast[seq[byte]](LucemIconPng)
overlay.lucemImage = overlay.vg.createImageMem(data = icon)

if overlay.state == osOverlay:
discard overlay.vg.text(16f, 16f, overlay.heading)
else:
let imgPaint = overlay.vg.imagePattern(16, 16, 60, 60, 0, overlay.lucemImage, 1f)
overlay.vg.beginPath()
overlay.vg.rect(16, 16, 60, 60)
overlay.vg.fillPaint(imgPaint)
overlay.vg.fill()

discard overlay.vg.text(100f, 16f, overlay.heading)

overlay.vg.fontFace("heading")
overlay.vg.textAlign(haLeft, vaTop)
overlay.vg.fontSize(overlay.config.overlay.descriptionSize)
overlay.vg.fillColor(white(255))
discard overlay.vg.text(16f, 64f, overlay.description)
overlay.vg.textBox(16f, 100f, 512f, overlay.description, nil)

# TODO: icon rendering, even though we don't use them yet
# but it'd be useful for the future
Expand All @@ -62,15 +96,29 @@ proc draw*(overlay: var Overlay) =

proc initOverlay*(input: Input) {.noReturn.} =
var overlay: Overlay
for opt in [

let opts = if not input.enabled("update-alert"):
@[
"heading",
"description",
"expire-time"
]:
]
else:
@[
"update-heading",
"update-message"
]

overlay.state = if input.enabled("update-alert"):
osUpdateAlert
else:
osOverlay

for opt in opts:
if (let maybeOpt = input.flag(opt); *maybeOpt):
case opt
of "heading": overlay.heading = decode(&maybeOpt)
of "description": overlay.description = decode(&maybeOpt)
of "heading", "update-heading": overlay.heading = decode(&maybeOpt)
of "description", "update-message": overlay.description = decode(&maybeOpt)
of "expire-time": overlay.expireTime = parseFloat(&maybeOpt)
else:
error "overlay: expected flag: " & opt
Expand All @@ -92,15 +140,19 @@ proc initOverlay*(input: Input) {.noReturn.} =
)
overlay.wl.setKeyboardInteractivity(LayerInteractivityMode.None)
var anchors: seq[LayerEdge]
for value in config.overlay.anchors.split('-'):
debug "overlay: got anchor: " & value
case value.toLowerAscii()
of "left", "l": anchors &= LayerEdge.Left
of "right", "r": anchors &= LayerEdge.Right
of "top", "up", "u": anchors &= LayerEdge.Top
of "bottom", "down", "d": anchors &= LayerEdge.Bottom
else:
warn "overlay: unhandled anchor: " & value

if overlay.state == osOverlay:
for value in config.overlay.anchors.split('-'):
debug "overlay: got anchor: " & value
case value.toLowerAscii()
of "left", "l": anchors &= LayerEdge.Left
of "right", "r": anchors &= LayerEdge.Right
of "top", "up", "u": anchors &= LayerEdge.Top
of "bottom", "down", "d": anchors &= LayerEdge.Bottom
else:
warn "overlay: unhandled anchor: " & value
else:
anchors = @[LayerEdge.Left, LayerEdge.Right, LayerEdge.Top, LayerEdge.Bottom]

overlay.wl.setAnchor(anchors)
overlay.wl.setExclusiveZone(10000)
Expand Down Expand Up @@ -133,6 +185,9 @@ proc initOverlay*(input: Input) {.noReturn.} =
overlay.draw()

overlay.wl.eventsHandler.onTick = proc(event: TickEvent) =
if overlay.expireTime == 0f:
return # Infinite alert

let epoch = epochTime()
let elapsed = epoch - overlay.lastEpoch

Expand Down
23 changes: 22 additions & 1 deletion src/notifications.nim
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ proc notifyFallback*(
expireTime: uint64 = 240000,
icon: Option[string] = none(string),
) =
debug "notifications: using libnotify fallback... (cringe guhnome user detected)"
debug "notifications: using libnotify fallback (cringe guhnome user detected)"
debug "notifications: preparing notify-send command"
debug "notifications: heading = $1, description = $2, expireTime = $3" %
[heading, description, $expireTime]
Expand Down Expand Up @@ -59,3 +59,24 @@ proc notify*(
debug "notifications: executing command: " & cmd
discard execCmd(cmd)
quit(0)

proc presentUpdateAlert*(
heading: string,
message: string
) =
var worker = findExe("lucem_overlay")
if getEnv("XDG_CURRENT_DESKTOP") == "GNOME" or (defined(release) and worker.len < 1):
warn "notifications: we're either on GNOME or the lucem overlay binary is missing, something went horribly wrong!"
notifyFallback(heading, message, 240000)
return

let pid = fork()

if worker.len < 1 and not defined(release):
worker = "./lucem_overlay"

if pid == 0:
let cmd = worker & " --update-alert --update-heading:\"" & heading.encode() & "\" --update-message:\"" & message.encode() & '"'
debug "notifications: executing command: " & cmd
discard execCmd(cmd)
quit(0)
Loading

0 comments on commit bc074b2

Please sign in to comment.