AkurAI Build
Menu

BifrOSt-Apps

public

Latest change f35619cfe0419c596645328bf0e1b682ad3a4473 - Harden RÚV for the 0.1.1 candidate by Ólafur Búi Ólafsson

//! Minimal, sandboxed BifrOSt desktop application rendered with Dioxus.
//!
//! System decorations are disabled and a COSMIC-styled header bar is drawn by
//! the app itself, wired to real window controls, so the window matches other
//! COSMIC applications instead of showing GTK chrome.

use dioxus::desktop::tao::event_loop::EventLoopBuilder;
use dioxus::desktop::tao::platform::unix::EventLoopBuilderExtUnix;
use dioxus::desktop::{use_window, Config, WindowBuilder};
use dioxus::prelude::*;

/// Must stay identical to the desktop file and icon name so the shell can
/// match the window to its launcher entry and taskbar icon.
const APP_ID: &str = "@@APP_ID@@";
const APP_NAME: &str = "@@RS_APP_NAME@@";

const STYLE: &str = r#"
:root { color-scheme: dark; }
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
    margin: 0;
    background: transparent;
    color: #eeeeee;
    font-family: system-ui, sans-serif;
    font-size: 14px;
}
#window {
    display: flex;
    flex-direction: column;
    height: 100vh;
    background: #1c1c1e;
    border: 1px solid #333336;
    border-radius: 12px;
    overflow: hidden;
}
header {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    height: 46px;
    padding: 0 6px 0 16px;
    background: #29292c;
    border-bottom: 1px solid #38383b;
    user-select: none;
    -webkit-user-select: none;
}
header .title {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
header .controls { display: flex; gap: 4px; }
header .controls button {
    width: 34px;
    height: 34px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: #eeeeee;
    font-size: 15px;
    line-height: 1;
    cursor: default;
}
header .controls button:hover { background: #3d3d41; }
header .controls button.close:hover { background: #f16161; color: #1c1c1e; }
main {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 2rem;
}
main h1 { font-weight: 600; }
main p { color: #a4a4a8; line-height: 1.5; max-width: 36rem; }
"#;

/// True when the session locale asks for Icelandic user-facing text.
fn locale_is_icelandic() -> bool {
    ["LC_ALL", "LC_MESSAGES", "LANG"]
        .iter()
        .filter_map(|name| std::env::var(name).ok())
        .find(|value| !value.is_empty())
        .is_some_and(|value| value.starts_with("is"))
}

fn app() -> Element {
    let window = use_window();
    let (ready, description) = if locale_is_icelandic() {
        ("Tilbúið til notkunar", "@@RS_DESCRIPTION_IS@@")
    } else {
        ("Ready to use", "@@RS_DESCRIPTION@@")
    };
    rsx! {
        style { {STYLE} }
        div { id: "window",
            header {
                onmousedown: {
                    let window = window.clone();
                    move |_| window.drag()
                },
                ondoubleclick: {
                    let window = window.clone();
                    move |_| {
                        let maximized = window.is_maximized();
                        window.set_maximized(!maximized);
                    }
                },
                span { class: "title", "{APP_NAME}" }
                div { class: "controls",
                    button {
                        aria_label: "Minimize",
                        onmousedown: |event| event.stop_propagation(),
                        onclick: {
                            let window = window.clone();
                            move |_| window.set_minimized(true)
                        },
                        "–"
                    }
                    button {
                        aria_label: "Maximize",
                        onmousedown: |event| event.stop_propagation(),
                        onclick: {
                            let window = window.clone();
                            move |_| {
                                let maximized = window.is_maximized();
                                window.set_maximized(!maximized);
                            }
                        },
                        "□"
                    }
                    button {
                        class: "close",
                        aria_label: "Close",
                        onmousedown: |event| event.stop_propagation(),
                        onclick: {
                            let window = window.clone();
                            move |_| window.close()
                        },
                        "✕"
                    }
                }
            }
            main {
                h1 { "{ready}" }
                p { "{description}" }
            }
        }
    }
}

fn main() {
    // The Wayland app id must match the desktop file name so the shell can
    // associate the window with its launcher entry and taskbar icon.
    let mut event_loop = EventLoopBuilder::with_user_event();
    event_loop.with_app_id(APP_ID);
    dioxus::LaunchBuilder::desktop()
        .with_cfg(
            Config::new()
                .with_event_loop(event_loop.build())
                .with_background_color((0, 0, 0, 0))
                .with_window(
                    WindowBuilder::new()
                        .with_title(APP_NAME)
                        .with_decorations(false)
                        .with_transparent(true),
                ),
        )
        .launch(app);
}