mirror of
https://github.com/spoopyghosty0/frameport.git
synced 2026-10-20 05:01:29 +02:00
Sections now run from what most users need to what only some need: Updates, Installing, Library folders, Appearance, Data, Problems and feedback, Install links, Tools, This PC, About, Uninstall. Updates gains a Games part: game recipes from GitHub (moved from Data) and the new "Check games from install links for new versions" switch with its last check and Check now. Inside sections the common options come first (Installing: parallel uploads and video before keep-copies; Updates: dev build last; Appearance: language first when a translation exists). The demo manifest (site + built-in copy) names version 1.0.0 as an example; the demo link is still never fetched or checked (test).
95 lines
3.8 KiB
Python
95 lines
3.8 KiB
Python
"""Setup checklist items, the Settings index and the Reduce motion setting."""
|
|
import flet as ft
|
|
|
|
from frameport.core import library
|
|
from frameport.ui import components as C
|
|
from frameport.ui import theme as T
|
|
from frameport.ui.views import settings
|
|
|
|
|
|
def fix():
|
|
return ("Install", ft.Icons.DOWNLOAD_ROUNDED, lambda: None)
|
|
|
|
|
|
def test_check_defaults_and_tuples():
|
|
c = C.Check(True, "Steam")
|
|
assert (c.detail, c.help, c.fix, c.extra) == ("", None, None, None)
|
|
assert C.Check(*(False, "Java", "missing", "java")).help == "java"
|
|
|
|
|
|
def test_check_marks():
|
|
assert C.check_look(True) == (ft.Icons.CHECK_CIRCLE_ROUNDED, T.OK)
|
|
assert C.check_look(False) == (ft.Icons.ERROR_ROUNDED, T.ERROR)
|
|
assert C.check_look("warn")[1] == T.WARN
|
|
assert C.check_look(None)[0] is None # pending: a spinner
|
|
|
|
|
|
def test_fix_only_while_not_ready():
|
|
f = fix()
|
|
assert C.check_fix(C.Check(False, "x", fix=f)) is f
|
|
assert C.check_fix(C.Check("warn", "x", fix=f)) is f
|
|
assert C.check_fix(C.Check(True, "x", fix=f)) is None
|
|
assert C.check_fix(C.Check(None, "x", fix=f)) is None
|
|
|
|
|
|
def test_checklist_builds_rows_with_fix_and_extra():
|
|
calls = []
|
|
col = C.checklist([C.Check(False, "Lepton", "missing", None, ("Install", None, lambda: calls.append(1))),
|
|
(True, "Proton", "ready", "proton", None, C.secondary("Test")),
|
|
C.Check(None, "Checking…")])
|
|
assert len(col.controls) == 3
|
|
first = col.controls[0].content.controls
|
|
button = first[-1]
|
|
button.on_click(None)
|
|
assert calls == [1]
|
|
assert len(col.controls[1].content.controls) == 3 # mark, text, the extra button (no fix: ready)
|
|
assert isinstance(col.controls[2].content.controls[0].content, ft.ProgressRing)
|
|
|
|
|
|
def test_settings_sections_order():
|
|
s = settings.SECTIONS
|
|
assert s[0] == "updates" and s[-1] == "remove"
|
|
# what most users need before what only some need
|
|
assert s.index("installing") < s.index("appearance") < s.index("links") < s.index("tools")
|
|
assert len(set(s)) == len(s)
|
|
assert set(settings.section_titles()) == set(s)
|
|
assert s.index("data") < s.index("tools") < s.index("pc") < s.index("about")
|
|
|
|
|
|
def test_reduce_motion_default_off():
|
|
from frameport.ui.app import REDUCE_MOTION, reduce_motion_setting
|
|
|
|
assert reduce_motion_setting() is False
|
|
library.set_setting(REDUCE_MOTION, True)
|
|
assert reduce_motion_setting() is True
|
|
|
|
|
|
def test_callout_icon_alignment():
|
|
"""A bar (text + buttons in a Row) centres its icon; wrapping text keeps it at the first line."""
|
|
bar = C.callout(ft.Row([C.body("Update available"), C.ghost("Not now")]), "info")
|
|
assert bar.content.vertical_alignment == ft.CrossAxisAlignment.CENTER
|
|
text = C.callout("A long note that wraps over several lines.", "warn")
|
|
assert text.content.vertical_alignment == ft.CrossAxisAlignment.START
|
|
|
|
|
|
def test_solid_glyph_for_filled_buttons():
|
|
"""Filled (accent) buttons use a glyph's filled variant: the thin outline faded into the orange."""
|
|
from frameport.ui import glyphs
|
|
|
|
assert glyphs.solid(glyphs.FRAME) == "fp:frame-solid"
|
|
assert glyphs.solid(glyphs.PATCH) == glyphs.PATCH # no filled variant: unchanged
|
|
assert glyphs.solid(ft.Icons.PLAY_ARROW_ROUNDED) == ft.Icons.PLAY_ARROW_ROUNDED
|
|
|
|
|
|
def test_cover_button_states():
|
|
"""The cover button springs in on hover, hides while a game starts and only Play buttons launch."""
|
|
play = C.CoverButton(ft.Icons.PLAY_ARROW_ROUNDED, "Play on Frame", lambda e: None, 72, launch="Starting…")
|
|
assert play.circle.scale < 1 and play.status.visible is False and len(play.rings) == 2
|
|
play.show(True)
|
|
assert play.circle.scale == 1.0
|
|
play.starting = True
|
|
play.show(True)
|
|
assert play.circle.scale == 0 # the "Starting…" pill stands in for it
|
|
install = C.CoverButton(ft.Icons.DOWNLOAD_ROUNDED, "Install", lambda e: None, 72)
|
|
assert install.launch is None
|