clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

refactor/root-tui-model
puzzletea / app / route_manager.go
route_manager.go 1.9K
1package app23import tea "charm.land/bubbletea/v2"45// routeManager owns the route/screen management boundary: current view state,6// cached screen instances, window dimensions, and screen lifecycle operations7// (lookup, initialization, resize, and window-size handling).8//9// It follows the same *model pattern as sessionController: methods read and10// mutate model fields via the pointer. The model keeps thin delegation11// wrappers so call sites remain unchanged.12type routeManager struct {13 model *model14}1516func newRouteManager(m *model) routeManager {17 return routeManager{model: m}18}1920// activeScreen returns the cached screen for the current route, or nil if21// no screen has been initialized.22func (r routeManager) activeScreen() screenModel {23 return r.model.screens[r.model.state]24}2526// initScreen creates a fresh screen for the given state using the registry27// factory, resizes it to current dimensions, and stores it in the cache.28func (r routeManager) initScreen(state viewState) {29 factory, ok := screenRegistry[state]30 if !ok {31 return32 }33 if r.model.screens == nil {34 r.model.screens = make(map[viewState]screenModel)35 }36 r.model.screens[state] = factory(*r.model).Resize(r.model.width, r.model.height)37}3839// resizeActiveScreen resizes the screen at the current route to the current40// window dimensions. Safe to call when no screen is cached.41func (r routeManager) resizeActiveScreen() {42 screen := r.model.screens[r.model.state]43 if screen == nil {44 return45 }46 r.model.screens[r.model.state] = screen.Resize(r.model.width, r.model.height)47}4849// handleWindowSize updates window dimensions and resizes the active screen.50// In gameView the game handles its own sizing, so the screen cache is left51// untouched.52func (r routeManager) handleWindowSize(msg tea.WindowSizeMsg) {53 r.model.width = msg.Width54 r.model.height = msg.Height55 if r.model.state == gameView {56 return57 }58 r.resizeActiveScreen()59}