Skip to content

Commit cf51e6e

Browse files
feat: add TUI changelog viewer and issue reporting
1 parent bd19064 commit cf51e6e

3 files changed

Lines changed: 47 additions & 2 deletions

File tree

β€ŽREADME.mdβ€Ž

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ Controls:
125125
- `←→` adjust font or numeric settings
126126
- `Enter` edit or toggle the selected field
127127
- `Ctrl+V` paste from clipboard (in text input fields)
128+
- `c` toggle changelog view
129+
- `i` report an issue
128130
- `a` toggle auto-size info display (shows terminal-relative sizing)
129131
- `l` load a saved preset or load from a custom preset file
130132
- `e` open the export dialog

β€Žbangen/tui/app.pyβ€Ž

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44

55
import sys
66
import time
7+
import webbrowser
8+
import urllib.request
79
from dataclasses import dataclass, field
810
from typing import Any, Callable
911

1012
from rich import box
1113
from rich.console import Console
1214
from rich.layout import Layout
1315
from rich.live import Live
16+
from rich.markdown import Markdown
1417
from rich.panel import Panel
1518
from rich.table import Table
1619
from rich.text import Text
@@ -53,6 +56,9 @@ class TUIState:
5356
t: float = 0.0
5457
show_size_info: bool = False
5558
size_info: str = ""
59+
show_changelog: bool = False
60+
changelog_content: str = ""
61+
changelog_scroll_pos: int = 0
5662

5763

5864
class TUIApp:
@@ -177,6 +183,15 @@ def _handle(self, key: str) -> None:
177183
def _handle_nav(self, key: str) -> None:
178184
state = self._state
179185

186+
if state.show_changelog:
187+
if key == "\x1b[A": # Up
188+
state.changelog_scroll_pos = max(0, state.changelog_scroll_pos - 1)
189+
elif key == "\x1b[B": # Down
190+
state.changelog_scroll_pos += 1
191+
elif key in ("c", "C"):
192+
state.show_changelog = False
193+
return
194+
180195
if key == "\x1b[A":
181196
state.current_field = (state.current_field - 1) % _NUM_FIELDS
182197
elif key == "\x1b[B":
@@ -187,6 +202,23 @@ def _handle_nav(self, key: str) -> None:
187202
self._nudge(+1)
188203
elif key == "\x1b[D":
189204
self._nudge(-1)
205+
elif key in ("c", "C"):
206+
if not state.changelog_content:
207+
try:
208+
with urllib.request.urlopen("https://raw.githubusercontent.com/programmersd21/bangen/refs/heads/main/CHANGELOG.md") as response:
209+
content = response.read().decode("utf-8")
210+
lines = content.splitlines()
211+
if lines and lines[0].strip() == "# Changelog":
212+
content = "\n".join(lines[1:]).strip()
213+
state.changelog_content = content
214+
state.changelog_scroll_pos = 0
215+
except Exception as exc:
216+
state.status = f"Changelog error: {exc}"
217+
if state.changelog_content:
218+
state.show_changelog = not state.show_changelog
219+
elif key in ("i", "I"):
220+
webbrowser.open("https://github.com/programmersd21/bangen/issues/new")
221+
state.status = "Opened issues page in browser"
190222
elif key in ("e", "E"):
191223
try:
192224
self.open_export_dialog()
@@ -198,7 +230,6 @@ def _handle_nav(self, key: str) -> None:
198230
except Exception as exc:
199231
state.status = f"Preset loader unavailable: {exc}"
200232
elif key in ("a", "A"):
201-
# Toggle auto-size info display
202233
state.show_size_info = not state.show_size_info
203234
if state.show_size_info:
204235
state.status = "Auto-size info: ON"
@@ -293,8 +324,18 @@ def _quick_save(self) -> None:
293324
def _build_layout(self):
294325
if self.active_modal is not None:
295326
return self.active_modal.render()
327+
if self._state.show_changelog:
328+
lines = self._state.changelog_content.splitlines()
329+
display_lines = lines[self._state.changelog_scroll_pos:]
330+
return Panel(
331+
Markdown("\n".join(display_lines)),
332+
title="[bold cyan]Changelog[/bold cyan]",
333+
subtitle="[dim]↑↓ to scroll, 'c' to close[/dim]",
334+
box=box.ROUNDED,
335+
)
296336
return self._build_main_layout()
297337

338+
298339
def _build_main_layout(self) -> Layout:
299340
layout = Layout()
300341
layout.split_row(Layout(name="ctrl", ratio=1), Layout(name="prev", ratio=2))
@@ -477,6 +518,8 @@ def _help_line() -> Text:
477518
("↑↓", "navigate"),
478519
("←→", "adjust"),
479520
("Enter", "edit/toggle"),
521+
("c", "changelog"),
522+
("i", "report issue"),
480523
("l", "load presets"),
481524
("a", "size info"),
482525
("e", "export"),

β€Žpyproject.tomlβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "bangen"
7-
version = "2.2.3"
7+
version = "2.2.4"
88
description = "ASCII banner rendering engine with a tiered effect library, live TUI, and transparent PNG/GIF export."
99
readme = "README.md"
1010
requires-python = ">=3.11"

0 commit comments

Comments
Β (0)