src/Models/Settings.ps1
|
# Settings — Preferencias del usuario serializables a JSON. # Reemplaza el `UserPreferences` con 11 sub-modelos del v2 (ADR-003). # Forma plana: una sola clase, propiedades simples. class Settings { # Apariencia [string] $ThemeKey = 'midnight' [string] $Language = 'es' # 'es' | 'en' [bool] $ShowAliases = $true [bool] $ShowTags = $true [bool] $ShowLastCommit = $true # Paths [string] $ReposPath # raíz donde escanea [string[]] $AdditionalPaths = @() # paths extra opcionales [string[]] $HiddenRepoIds = @() # repos ocultados manualmente # Aliases del usuario: id → @{ alias='', color='c5' } [hashtable] $RepoAliases = @{} # Timestamp del último fetch exitoso por repo: id → ISO string. # Se actualiza después de pull/fetch/push exitoso. La UI lo lee para mostrar # "(fetch hace 12 min)" como hint sutil — el user sabe que el ahead/behind # puede estar desactualizado y no se confunde. [hashtable] $LastFetchByRepo = @{} # Favoritos [string[]] $FavoriteIds = @() # Si on, los favoritos se renderean primero en la lista del MainScreen # (manteniendo orden alfabético adentro de cada grupo). Off = orden original # del discovery (alfabético plano). [bool] $FavoritesFirst = $false # Git [int] $GitCacheTtlSeconds = 30 [bool] $AutoFetch = $false # BackgroundFetchInterval: cada cuántos segundos correr 'git fetch --quiet' # en los repos visibles, en background, sin bloquear la UI. 0 = off (default). # Sugerencias: 300 (5min), 600 (10min), 1800 (30min). ConfigScreen cyclea # entre estos valores. [int] $BackgroundFetchInterval = 0 # AutoLoadMode controla cuántos repos cargan git status al boot: # 'All' → todos los visibles (default — UX más rico) # 'Favorites' → solo los repos en FavoriteIds; el resto on-demand # 'None' → ninguno; user pulsa R o navega para cargar # Útil para usuarios con muchos repos o red lenta. ConfigScreen lo # expone como cycle, init lo pregunta interactivo. [string] $AutoLoadMode = 'All' # UI [bool] $UseAlternateBuffer = $true # entrar en alt screen [int] $RefreshDebounceMs = 200 Settings() { } [bool] IsFavorite([string]$repoId) { return $this.FavoriteIds -contains $repoId } [bool] IsHidden([string]$repoId) { return $this.HiddenRepoIds -contains $repoId } [hashtable] GetAlias([string]$repoId) { return $this.RepoAliases[$repoId] } [bool] HasAlias([string]$repoId) { if ([string]::IsNullOrWhiteSpace($repoId)) { return $false } return $this.RepoAliases.ContainsKey($repoId) } [void] SetAlias([string]$repoId, [string]$alias, [string]$color) { if ([string]::IsNullOrWhiteSpace($repoId)) { return } if ([string]::IsNullOrWhiteSpace($alias)) { return } $this.RepoAliases[$repoId] = @{ alias = $alias.Trim() color = $color } } [void] RemoveAlias([string]$repoId) { if ([string]::IsNullOrWhiteSpace($repoId)) { return } if ($this.RepoAliases.ContainsKey($repoId)) { $this.RepoAliases.Remove($repoId) } } # Marca "fetcheamos este repo recién" — se llama después de un fetch/pull/push # exitoso. Usa ISO 8601 UTC para que sea estable cross-timezone. [void] RecordFetch([string]$repoId) { if ([string]::IsNullOrWhiteSpace($repoId)) { return } $this.LastFetchByRepo[$repoId] = [DateTime]::UtcNow.ToString('o') } # Devuelve $null si nunca se fetcheó, sino [DateTime] UTC. [object] GetLastFetch([string]$repoId) { if ([string]::IsNullOrWhiteSpace($repoId)) { return $null } $iso = $this.LastFetchByRepo[$repoId] if (-not $iso) { return $null } try { return [DateTime]::Parse($iso, [System.Globalization.CultureInfo]::InvariantCulture, [System.Globalization.DateTimeStyles]::RoundtripKind) } catch { return $null } } } |