"""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, "Prole", fill="#6e6e73", font=("SF Pro Text", 32, "bold"), anchor="ne", ) ui.canvas_text( self, right_margin, 85, "Infrastructure Automated.", 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 Prole 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 Prole 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 Prole", style="Title.TLabel").pack( anchor="w", padx=24, pady=(24, 6) ) msg = "Thanks for joining Prole. We will prepare your system and install the software needed to build and run Prole." ttk.Label( f, text=msg, style="Body.TLabel", wraplength=800, justify="left" ).pack(anchor="w", padx=24) # self._register_page('welcome', f)