Migrate bos-settings from GTK4 to Tauri + Svelte 5
Ports every remaining view (Keybinds, the last one — dual Flat/MultiLayout schema detection, per-action dedicated fields with a raw-JSON fallback for anything not modeled) and removes the now-fully-dead GTK4 crate (root Cargo.toml + src/), leaving src-tauri/ as the single Rust binary crate. Also folds in the UX pass done alongside the migration: responsive multi-column layout instead of a single centered column, chip/dropdown pickers replacing free-typed fields (Wi-Fi networks, Bar style, keyboard layout, tag lists), consistent pill-switch toggles and boxed-list card styling across every page, and a sidebar scroll-chaining fix.
This commit is contained in:
parent
62365ebf10
commit
93c3b88b10
147 changed files with 15804 additions and 7516 deletions
105
frontend/src/lib/views/Power.svelte
Normal file
105
frontend/src/lib/views/Power.svelte
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import ViewScaffold from "$lib/components/ViewScaffold.svelte";
|
||||
import InfoRow from "$lib/components/InfoRow.svelte";
|
||||
import Row from "$lib/components/Row.svelte";
|
||||
import Group from "$lib/components/Group.svelte";
|
||||
import Hint from "$lib/components/Hint.svelte";
|
||||
|
||||
interface PowerInfo {
|
||||
battery: [string, string][];
|
||||
power_source: string;
|
||||
brightness_pct: number | null;
|
||||
charge_start: number | null;
|
||||
charge_end: number | null;
|
||||
tlp_profile: string | null;
|
||||
}
|
||||
|
||||
let info = $state<PowerInfo | null>(null);
|
||||
let brightness = $state(0);
|
||||
let chargeStart = $state(0);
|
||||
let chargeEnd = $state(100);
|
||||
|
||||
onMount(async () => {
|
||||
info = await invoke<PowerInfo>("get_power_info");
|
||||
brightness = info.brightness_pct ?? 0;
|
||||
chargeStart = info.charge_start ?? 0;
|
||||
chargeEnd = info.charge_end ?? 100;
|
||||
});
|
||||
|
||||
async function setBrightness(percent: number) {
|
||||
brightness = percent;
|
||||
await invoke("set_brightness", { percent });
|
||||
}
|
||||
|
||||
async function setChargeThreshold(which: "start" | "end", percent: number) {
|
||||
if (which === "start") chargeStart = percent;
|
||||
else chargeEnd = percent;
|
||||
await invoke("set_charge_threshold", { which, percent });
|
||||
}
|
||||
</script>
|
||||
|
||||
<ViewScaffold title="Power">
|
||||
{#if info}
|
||||
<Group title="Battery">
|
||||
{#each info.battery as [label, value] (label)}
|
||||
<InfoRow {label} {value} />
|
||||
{/each}
|
||||
<InfoRow label="Power source" value={info.power_source} />
|
||||
</Group>
|
||||
|
||||
<Group title="Brightness">
|
||||
{#if info.brightness_pct !== null}
|
||||
<Row label="Screen brightness">
|
||||
<input type="range" min="1" max="100" bind:value={brightness} onchange={() => setBrightness(brightness)} />
|
||||
<span class="pct">{brightness}%</span>
|
||||
</Row>
|
||||
{:else}
|
||||
<Hint text="No controllable backlight found." />
|
||||
{/if}
|
||||
</Group>
|
||||
|
||||
{#if info.charge_start !== null && info.charge_end !== null}
|
||||
<Group
|
||||
title="Charge limits"
|
||||
hint="Some laptops let you cap charging below 100% to slow battery wear on a machine that's mostly plugged in."
|
||||
>
|
||||
<Row label="Start charging below (%)">
|
||||
<input type="number" min="0" max="100" bind:value={chargeStart} onchange={() => setChargeThreshold("start", chargeStart)} />
|
||||
</Row>
|
||||
<Row label="Stop charging at (%)">
|
||||
<input type="number" min="1" max="100" bind:value={chargeEnd} onchange={() => setChargeThreshold("end", chargeEnd)} />
|
||||
</Row>
|
||||
</Group>
|
||||
{/if}
|
||||
|
||||
<Group
|
||||
title="TLP"
|
||||
hint="TLP automatically applies a power-saving profile on battery and a performance profile on AC — there's no manual switch by design."
|
||||
>
|
||||
<InfoRow label="Current profile" value={info.tlp_profile ?? "unknown"} />
|
||||
</Group>
|
||||
{/if}
|
||||
</ViewScaffold>
|
||||
|
||||
<style>
|
||||
input[type="range"] {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
input[type="number"] {
|
||||
width: 8ch;
|
||||
background-color: var(--bg);
|
||||
color: var(--on-surface);
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--radius-secondary, 6px);
|
||||
padding: var(--space-xs, 4px) var(--space-sm, 8px);
|
||||
}
|
||||
|
||||
.pct {
|
||||
margin-left: var(--space-sm, 8px);
|
||||
font-size: var(--font-size-secondary, 12px);
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue