building out ui, still not done
This commit is contained in:
78
assets/repo_view_screen.tcss
Normal file
78
assets/repo_view_screen.tcss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
3
main.py
3
main.py
@@ -1,13 +1,12 @@
|
|||||||
from textual.app import App, ComposeResult
|
from textual.app import App, ComposeResult
|
||||||
from screens.welcome_screen import WelcomeScreen
|
from screens.welcome_screen import WelcomeScreen
|
||||||
from screens.search_screen import SearchScreen
|
|
||||||
|
|
||||||
|
|
||||||
class TuiGithub(App):
|
class TuiGithub(App):
|
||||||
GITEA_HOST = "https://chookspace.com/"
|
GITEA_HOST = "https://chookspace.com/"
|
||||||
|
|
||||||
def on_compose(self):
|
def on_compose(self):
|
||||||
self.push_screen(SearchScreen())
|
self.push_screen(WelcomeScreen())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -1,11 +1,76 @@
|
|||||||
from textual.screen import Screen
|
from textual.screen import Screen
|
||||||
from textual.app import ComposeResult
|
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
|
from widgets import Navbar
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
class RepoViewScreen(Screen):
|
class RepoViewScreen(Screen):
|
||||||
def __init__(self, repo_id: int):
|
CSS_PATH = "../assets/repo_view_screen.tcss"
|
||||||
super().__init__(self)
|
|
||||||
|
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:
|
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()
|
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")
|
||||||
@@ -4,6 +4,8 @@ from textual.widgets import Input, Select, LoadingIndicator, Static
|
|||||||
from textual.containers import HorizontalGroup, ScrollableContainer
|
from textual.containers import HorizontalGroup, ScrollableContainer
|
||||||
from textual.app import ComposeResult
|
from textual.app import ComposeResult
|
||||||
|
|
||||||
|
from screens.repo_view_screen import RepoViewScreen
|
||||||
|
|
||||||
from human_readable import time_delta
|
from human_readable import time_delta
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
@@ -38,9 +40,11 @@ class SearchResult(HorizontalGroup):
|
|||||||
self.is_fork = repo_data["fork"]
|
self.is_fork = repo_data["fork"]
|
||||||
self.updated_at = datetime.fromisoformat(repo_data["updated_at"]).replace(tzinfo=None)
|
self.updated_at = datetime.fromisoformat(repo_data["updated_at"]).replace(tzinfo=None)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
updated_string = time_delta(datetime.now() - self.updated_at)
|
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):
|
class SearchScreen(Screen):
|
||||||
DEFAULT_CSS = """
|
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):
|
def action_search_query(self):
|
||||||
query_input = self.query_one("#query")
|
query_input = self.query_one("#query")
|
||||||
loading = self.query_one(LoadingIndicator)
|
loading = self.query_one(LoadingIndicator)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from textual.app import ComposeResult
|
|||||||
from textual.widgets import Static, Button
|
from textual.widgets import Static, Button
|
||||||
from textualeffects.widgets import EffectLabel, EffectType, effects
|
from textualeffects.widgets import EffectLabel, EffectType, effects
|
||||||
|
|
||||||
|
from screens.search_screen import SearchScreen
|
||||||
from widgets import Navbar
|
from widgets import Navbar
|
||||||
|
|
||||||
from random import choice
|
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:
|
def compose(self) -> ComposeResult:
|
||||||
yield Navbar()
|
yield Navbar()
|
||||||
with Center():
|
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 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"):
|
with HorizontalGroup(id="buttons"):
|
||||||
yield Button("Explore", variant="primary", flat=True)
|
yield Button("\uee45 Explore", variant="primary", flat=True, id="explore")
|
||||||
yield Button("another button lol", flat=True)
|
|
||||||
Reference in New Issue
Block a user