prole/knoe/ui/screens/welcome.py

138 lines
5.1 KiB
Python

"""Welcome / splash screen."""
import threading
import time
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
from knoe import screen as ui
class WelcomeScreenMixin:
"""Welcome / splash screen."""
def _render_welcome_page(self):
# Letterhead at top right
content_width = self.bg_canvas.winfo_width() or 975 # 1300 * 0.75 approx
right_margin = content_width - 48
ui.canvas_text(
self,
right_margin,
40,
"knoe.dev",
fill="#6e6e73",
font=("SF Pro Text", 32, "bold"),
anchor="ne",
)
ui.canvas_text(
self,
right_margin,
85,
"infrastructure.auto()",
fill="#6e6e73",
font=("SF Pro Text", 18),
anchor="ne",
)
# Welcome title
self._render_title("Welcome", y=150)
welcome_text = (
"This installer will guide you through the process of setting up the Knoe Database and its supporting "
"infrastructure. We have designed this process to be as automated as possible, ensuring that your "
"deployment is secure, efficient, and tailored to your specific network environment.\n\n"
"What to expect:\n"
"• Network Environment Discovery: We'll scan for existing services like Active Directory and DNS.\n"
"• System Configuration: Setting up local paths and environment variables.\n"
"• Dependency Management: Ensuring all required tools (Docker, k3d, etc.) are ready.\n"
"• Database Initialization: Configuring passwords, Kerberos authentication, and deploying the database cluster.\n\n"
"We are excited to have you join our community and start building with us. "
"Welcome to the neighborhood! Let's get started by preparing your system for the Knoe experience."
)
ui.canvas_text(
self,
48,
220,
welcome_text,
fill="black",
font=("SF Pro Text", 13),
width=750,
)
# Ensure footer is updated (Next button visible)
self.update_footer()
def _start_welcome_dependency_scan(self):
self.splash_scan_running = True
self.splash_scan_done_at = None
self.splash_scan_started_at = time.time()
deps = list(self.dependencies)
total = len(deps)
results = {}
def set_status(text: str):
try:
if self._splash_status_item is not None:
# Replace existing text to avoid creating many items
self.bg_canvas.itemconfig(self._splash_status_item, text=text)
except Exception:
pass
def worker():
missing_names = []
for idx, dep in enumerate(deps, start=1):
try:
ok, location, version = self.get_dep_info(dep)
except Exception:
ok, location, version = False, None, None
results[dep["id"]] = (ok, location, version)
# Update status text progressively
if ok:
txt = f"[{idx}/{total}] {dep['name']}: Installed"
else:
txt = f"[{idx}/{total}] {dep['name']}: Not installed"
missing_names.append(dep["name"])
self.safe_after(lambda s=txt: set_status(s))
# tiny sleep to keep UI responsive without being too fast
try:
time.sleep(0.02)
except Exception:
pass
# Final message
final_msg = (
"All dependencies installed."
if not missing_names
else ("Preparing to install ... " + ", ".join(missing_names))
)
def on_done():
set_status(final_msg)
self.splash_scan_running = False
self.splash_scan_done_at = time.time()
# Re-evaluate footer to potentially show Next
self.update_footer()
# Important: schedule a follow-up refresh slightly after the debounce window
# so the Next button becomes visible without requiring further UI events.
self.safe_after(self.update_footer, delay=600)
self.safe_after(on_done)
t = threading.Thread(target=worker, daemon=True)
t.start()
# Failsafe refresh slightly after the 8s gating window in case no UI events fire.
self.safe_after(self.update_footer, delay=9000)
def _create_page_welcome(self):
f = self._page_container()
ttk.Label(f, text="Welcome to Knoe.DB", style="Title.TLabel").pack(
anchor="w", padx=24, pady=(24, 6)
)
msg = "Thanks for joining Knoe. We will prepare your system and install the software needed to build and run Knoe."
ttk.Label(
f, text=msg, style="Body.TLabel", wraplength=800, justify="left"
).pack(anchor="w", padx=24)
# self._register_page('welcome', f)