diff --git a/tui/app.py b/tui/app.py index 34d5804..bb09c00 100644 --- a/tui/app.py +++ b/tui/app.py @@ -1,7 +1,6 @@ import os import httpx -from platformdirs import user_data_dir from textual.app import App, ComposeResult from textual.binding import Binding @@ -10,7 +9,10 @@ from textual.containers import Vertical from textual.screen import Screen from textual.widgets import Button, Footer, Static +from tui.paths import DATA_DIR +from tui.screens.activity import ActivityScreen from tui.screens.home import HomeScreen +from tui.screens.login import LoginScreen class LogoutConfirmScreen(Screen): @@ -49,9 +51,6 @@ class LogoutConfirmScreen(Screen): self.app.pop_screen() -DATA_DIR = os.environ.get("ATBBS_DATA_DIR", user_data_dir("atbbs")) - - class AtbbsApp(App): TITLE = "@bbs" CSS_PATH = "app.tcss" @@ -99,8 +98,6 @@ class AtbbsApp(App): if self.user_session: self.push_screen(LogoutConfirmScreen()) else: - from tui.screens.login import LoginScreen - self.push_screen(LoginScreen()) def do_logout(self) -> None: @@ -116,8 +113,6 @@ class AtbbsApp(App): if not self.user_session: self.notify("Log in to see your messages.", severity="warning") return - from tui.screens.activity import ActivityScreen - self.push_screen(ActivityScreen()) def action_refresh(self) -> None: diff --git a/tui/paths.py b/tui/paths.py new file mode 100644 index 0000000..34e23cf --- /dev/null +++ b/tui/paths.py @@ -0,0 +1,7 @@ +"""Filesystem paths for the TUI.""" + +import os + +from platformdirs import user_data_dir + +DATA_DIR = os.environ.get("ATBBS_DATA_DIR", user_data_dir("atbbs")) diff --git a/tui/screens/activity.py b/tui/screens/activity.py index e68e05f..228fdb6 100644 --- a/tui/screens/activity.py +++ b/tui/screens/activity.py @@ -4,6 +4,8 @@ from textual.screen import Screen from textual.widgets import Footer, Static from textual import work +from tui.screens.thread import ThreadScreen +from tui.widgets.breadcrumb import Breadcrumb from tui.widgets.post import Post @@ -18,8 +20,6 @@ class ActivityScreen(Screen): self._items: list[dict] = [] def compose(self) -> ComposeResult: - from tui.widgets.breadcrumb import Breadcrumb - yield Breadcrumb( ("@bbs", 1), ("inbox", 0), @@ -89,8 +89,6 @@ class ActivityScreen(Screen): updated_at=rec.value.get("updatedAt"), attachments=rec.value.get("attachments"), ) - from tui.screens.thread import ThreadScreen - self.app.push_screen(ThreadScreen(bbs, handle, thread)) except Exception: self.notify("Could not open thread.", severity="error") diff --git a/tui/screens/board.py b/tui/screens/board.py index 350e5bf..5f5d378 100644 --- a/tui/screens/board.py +++ b/tui/screens/board.py @@ -6,8 +6,11 @@ from textual.widgets import Button, Footer, ListItem, ListView, Static from core.models import BBS, Board from core.records import hydrate_threads as fetch_threads +from tui.screens.compose import ComposeThreadScreen +from tui.screens.thread import ThreadScreen from tui.util import require_session from tui.util import format_datetime +from tui.widgets.breadcrumb import Breadcrumb class BoardScreen(Screen): @@ -32,8 +35,6 @@ class BoardScreen(Screen): self.page = 0 def compose(self) -> ComposeResult: - from tui.widgets.breadcrumb import Breadcrumb - yield Breadcrumb( ("@bbs", 2), (self.bbs.site.name, 1), @@ -94,8 +95,6 @@ class BoardScreen(Screen): # Find thread by URI thread = next((t for t in self.threads if t.uri == uri), None) if thread: - from tui.screens.thread import ThreadScreen - self.app.push_screen(ThreadScreen(self.bbs, self.handle, thread)) def refresh_data(self) -> None: @@ -111,6 +110,4 @@ class BoardScreen(Screen): def action_new_thread(self) -> None: if not require_session(self): return - from tui.screens.compose import ComposeThreadScreen - self.app.push_screen(ComposeThreadScreen(self.bbs, self.handle, self.board)) diff --git a/tui/screens/compose.py b/tui/screens/compose.py index 1c9fafa..697aa61 100644 --- a/tui/screens/compose.py +++ b/tui/screens/compose.py @@ -12,6 +12,7 @@ from core.models import AtUri from core.models import AuthError from core.records import create_thread_record, create_reply_record, upload_blob from tui.util import require_session +from tui.widgets.breadcrumb import Breadcrumb async def _upload_file(screen, file_path: str, session: dict) -> list[dict] | None: @@ -53,8 +54,6 @@ class ComposeThreadScreen(Screen): self.board = board def compose(self) -> ComposeResult: - from tui.widgets.breadcrumb import Breadcrumb - yield Breadcrumb( ("@bbs", 3), (self.bbs.site.name, 2), @@ -132,8 +131,6 @@ class ComposeReplyScreen(Screen): self.thread = thread def compose(self) -> ComposeResult: - from tui.widgets.breadcrumb import Breadcrumb - yield Breadcrumb( ("@bbs", 3), (self.bbs.site.name, 2), diff --git a/tui/screens/home.py b/tui/screens/home.py index b5effc4..209ad52 100644 --- a/tui/screens/home.py +++ b/tui/screens/home.py @@ -10,6 +10,7 @@ from core import lexicon from core.models import BBSNotFoundError, NetworkError, NoBBSError from core.resolver import resolve_bbs from core.slingshot import resolve_identities_batch +from tui.screens.site import SiteScreen class HomeScreen(Screen): @@ -96,8 +97,6 @@ class HomeScreen(Screen): self.notify("You have been banned from this BBS.", severity="error") return - from tui.screens.site import SiteScreen - self.app.push_screen(SiteScreen(bbs, handle)) self.query_one("#handle-input", Input).value = "" diff --git a/tui/screens/login.py b/tui/screens/login.py index 11508e0..19f1462 100644 --- a/tui/screens/login.py +++ b/tui/screens/login.py @@ -22,6 +22,8 @@ from tui.local_server import wait_for_callback from core.lexicon import OAUTH_SCOPE +from tui.paths import DATA_DIR +from tui.widgets.breadcrumb import Breadcrumb CALLBACK_PORT = 23847 @@ -30,8 +32,6 @@ class LoginScreen(Screen): BINDINGS = [("escape", "app.pop_screen", "back")] def compose(self) -> ComposeResult: - from tui.widgets.breadcrumb import Breadcrumb - yield Breadcrumb( ("@bbs", 1), ("log in", 0), @@ -71,8 +71,6 @@ class LoginScreen(Screen): return # Load client secrets from TUI data dir - from tui.app import DATA_DIR - secrets = load_secrets(DATA_DIR) client_secret_jwk = json.loads(secrets["client_secret_jwk"]) diff --git a/tui/screens/news.py b/tui/screens/news.py index 3de1327..2c9875c 100644 --- a/tui/screens/news.py +++ b/tui/screens/news.py @@ -4,6 +4,7 @@ from textual.screen import Screen from textual.widgets import Footer from core.models import BBS, News +from tui.widgets.breadcrumb import Breadcrumb from tui.widgets.post import Post @@ -17,8 +18,6 @@ class NewsScreen(Screen): self.news = news def compose(self) -> ComposeResult: - from tui.widgets.breadcrumb import Breadcrumb - yield Breadcrumb( ("@bbs", 2), (self.bbs.site.name, 1), diff --git a/tui/screens/site.py b/tui/screens/site.py index 17095c7..ba65975 100644 --- a/tui/screens/site.py +++ b/tui/screens/site.py @@ -6,7 +6,10 @@ from textual import work from core.models import BBS from core.resolver import resolve_bbs +from tui.screens.board import BoardScreen +from tui.screens.news import NewsScreen from tui.util import format_datetime +from tui.widgets.breadcrumb import Breadcrumb class SiteScreen(Screen): @@ -18,8 +21,6 @@ class SiteScreen(Screen): self.handle = handle def compose(self) -> ComposeResult: - from tui.widgets.breadcrumb import Breadcrumb - yield Breadcrumb( ("@bbs", 1), (self.handle, 0), @@ -75,14 +76,10 @@ class SiteScreen(Screen): slug = event.item.name board = next((b for b in self.bbs.site.boards if b.slug == slug), None) if board: - from tui.screens.board import BoardScreen - self.app.push_screen(BoardScreen(self.bbs, self.handle, board)) elif event.list_view.id == "news-list": idx = int(event.item.name) if 0 <= idx < len(self.bbs.news): - from tui.screens.news import NewsScreen - self.app.push_screen( NewsScreen(self.bbs, self.handle, self.bbs.news[idx]) ) diff --git a/tui/screens/thread.py b/tui/screens/thread.py index 820a30f..14cc998 100644 --- a/tui/screens/thread.py +++ b/tui/screens/thread.py @@ -8,7 +8,9 @@ from textual.widgets import Footer, Static from core import lexicon from core.models import AtUri, AuthError, BBS, Thread from core.records import delete_record, hydrate_replies as fetch_replies +from tui.screens.compose import ComposeReplyScreen from tui.util import require_session +from tui.widgets.breadcrumb import Breadcrumb from tui.widgets.post import Post @@ -39,8 +41,6 @@ class ThreadScreen(Screen): board_name = next( (b.name for b in self.bbs.site.boards if b.slug == board_slug), board_slug ) - from tui.widgets.breadcrumb import Breadcrumb - yield Breadcrumb( ("@bbs", 3), (self.bbs.site.name, 2), @@ -168,8 +168,6 @@ class ThreadScreen(Screen): ): quote = self._replies_map.get(focused.record_uri) - from tui.screens.compose import ComposeReplyScreen - self.app.push_screen( ComposeReplyScreen(self.bbs, self.handle, self.thread, quote=quote) )