building out ui, still not done

This commit is contained in:
2026-02-04 21:34:48 +11:00
parent 9b32c417e9
commit 6d7a3b3146
6 changed files with 164 additions and 11 deletions

View File

@@ -0,0 +1,78 @@
#top {
background: $boost;
padding: 1 2 0 2;
#title {
height: 100%;
content-align: left middle;
width: auto;
}
#buttons {
layout: horizontal;
Button {
margin-left: 1;
max-width: 13;
}
}
Tabs {
width: 100%;
}
margin-bottom: 1;
}
#repo-info {
width: 45;
padding: 0 1;
#search-query {
width: 1fr;
}
#search-btn {
max-width: 5;
}
}
#files {
height: 5;
background: red 50%;
margin-left: 1;
border: tall $surface;
background: $background;
& > .datatable--header {
background: $surface;
}
}
#description {
margin-left: 1;
}
#branch-info {
padding: 0 1;
background: $surface-darken-1;
border: tall $surface;
margin-bottom: 1;
Static {
width: 1fr;
text-align: center;
}
}
#branch-options {
margin-bottom: 1;
#new-pull-request {
max-width: 4;
}
Select {
width: 16;
margin-right: 1;
}
Button {
max-width: 16;
margin-right: 1;
}
}

View File

@@ -1,13 +1,12 @@
from textual.app import App, ComposeResult
from screens.welcome_screen import WelcomeScreen
from screens.search_screen import SearchScreen
class TuiGithub(App):
GITEA_HOST = "https://chookspace.com/"
def on_compose(self):
self.push_screen(SearchScreen())
self.push_screen(WelcomeScreen())
if __name__ == "__main__":

View File

@@ -1,11 +1,76 @@
from textual.screen import Screen
from textual.app import ComposeResult
from textual.widgets import Input, Select, Static, DataTable, ContentSwitcher, Tabs, Tab, Button
from textual.containers import VerticalGroup, Vertical, HorizontalGroup, Right
from widgets import Navbar
import requests
class RepoViewScreen(Screen):
def __init__(self, repo_id: int):
super().__init__(self)
CSS_PATH = "../assets/repo_view_screen.tcss"
def __init__(self, owner_name: str, repo_name: str):
super().__init__()
self.owner_name = owner_name
self.repo_name = repo_name
def compose(self) -> ComposeResult:
# get repo data via a request
response = requests.get(
url=self.app.GITEA_HOST + f"api/v1/repos/{self.owner_name}/{self.repo_name}"
)
if not response.ok:
self.notify(response.text, title="Failed to get repo:", severity="error")
yield Navbar()
return
data = response.json()
yield Navbar()
with VerticalGroup(id="top"):
with HorizontalGroup():
yield Static(f" {self.owner_name}/[b]{self.repo_name}[/]", id="title")
with Right(id="buttons"):
yield Button("Star [d](0)", variant="warning", flat=True)
yield Button("Watch [d](0)", flat=True)
yield Tabs(
"\uf44f Code",
"\uebf8 Issues",
"\ue726 Pull Requests",
"\uf500 Actions",
"\ueb29 Packages",
"\uf502 Projects",
"\uf02b Releases",
"\ueaa4 Wiki",
"\uf21e Activity"
)
with ContentSwitcher(initial="Code"):
with HorizontalGroup(id="Code"):
with Vertical(id="commits"):
with HorizontalGroup(id="branch-info"):
yield Static("\uf4b6 1 Commits")
yield Static("\uf418 1 Branch")
yield Static("\uf02b 0 Tags")
with HorizontalGroup(id="branch-options"):
yield Select.from_values([
"main"
], allow_blank=False, id="branch")
yield Button("\ue726", flat=True, id="new-pull-request", tooltip="New Pull Request")
yield Button("Go to file", flat=True)
table = DataTable(id="files", show_cursor=False)
table.add_columns("SpookyDervish [r]9b32c417e9[/]", "switched from tabs to spaces", "51 minutes ago")
table.add_row("\ue5ff screens", "[d]switched from tabs to spaces", "[d]51 minutes ago")
yield table
with Vertical(id="repo-info"):
with HorizontalGroup():
yield Input("Search code...", id="search-query")
yield Button("\uf002", flat=True, id="search-btn")
yield Static("\n[b] Description")
yield Static("[d]" + data["description"], id="description")

View File

@@ -4,6 +4,8 @@ from textual.widgets import Input, Select, LoadingIndicator, Static
from textual.containers import HorizontalGroup, ScrollableContainer
from textual.app import ComposeResult
from screens.repo_view_screen import RepoViewScreen
from human_readable import time_delta
from datetime import datetime, timedelta
@@ -38,9 +40,11 @@ class SearchResult(HorizontalGroup):
self.is_fork = repo_data["fork"]
self.updated_at = datetime.fromisoformat(repo_data["updated_at"]).replace(tzinfo=None)
def compose(self) -> ComposeResult:
updated_string = time_delta(datetime.now() - self.updated_at)
yield Static(f"[@click='view_user({self.author["id"]})']{self.author["login"]}[/] / [@click=view_repo('')]{self.repo_name}[/]{' [d]\[[cyan]fork[/]]' if self.is_fork else ''}\n{self.description}\n[d]Updated {updated_string} ago")
yield Static(f"[@click='view_user({self.author["id"]})']{self.author["login"]}[/] / [@click='screen.view_repo(\"{self.author["login"]}\",\"{self.repo_name}\")']{self.repo_name}[/]{' [d]\[[cyan]fork[/]]' if self.is_fork else ''}\n{self.description}\n[d]Updated {updated_string} ago")
class SearchScreen(Screen):
DEFAULT_CSS = """
@@ -59,6 +63,9 @@ class SearchScreen(Screen):
}
"""
def action_view_repo(self, author: str, repo_name: str):
self.app.switch_screen(RepoViewScreen(author, repo_name))
def action_search_query(self):
query_input = self.query_one("#query")
loading = self.query_one(LoadingIndicator)

View File

@@ -4,6 +4,7 @@ from textual.app import ComposeResult
from textual.widgets import Static, Button
from textualeffects.widgets import EffectLabel, EffectType, effects
from screens.search_screen import SearchScreen
from widgets import Navbar
from random import choice
@@ -34,14 +35,17 @@ class WelcomeScreen(Screen):
}
"""
def on_button_pressed(self, event: Button.Pressed):
if event.button.id == "explore":
self.app.switch_screen(SearchScreen())
def compose(self) -> ComposeResult:
yield Navbar()
with Center():
with open("banner.txt", "r") as f:
with open("assets/banner.txt", "r") as f:
yield EffectLabel(text=f.read(), effect=choice(list(effects.keys())))
yield Static("[d]Gitea, in your terminal.[/]")
yield Static("[white]Gitea, in your terminal.")
with HorizontalGroup(id="buttons"):
yield Button("Explore", variant="primary", flat=True)
yield Button("another button lol", flat=True)
yield Button("\uee45 Explore", variant="primary", flat=True, id="explore")