Files
GiTui/screens/search_screen.py

114 lines
2.7 KiB
Python

from widgets import Navbar
from textual.screen import Screen
from textual.widgets import Input, Select, LoadingIndicator, Static
from textual.containers import HorizontalGroup, ScrollableContainer
from textual.app import ComposeResult
from human_readable import time_delta
from datetime import datetime, timedelta
import requests
class SearchResult(HorizontalGroup):
DEFAULT_CSS = """
SearchResult {
padding: 0 1;
margin: 0 1;
margin-top: 1;
border: tall $surface;
Static {
width: auto;
link-style: bold;
link-color: $primary;
}
}
"""
def __init__(
self,
repo_data: dict
):
super().__init__()
self.repo_data = repo_data
self.author = repo_data["owner"]
self.repo_name = repo_data["name"]
self.description = repo_data["description"]
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")
class SearchScreen(Screen):
DEFAULT_CSS = """
#search-box {
padding: 1;
padding-bottom: 0;
border-bottom: hkey $surface;
#query {
width: 1fr;
}
#search-select {
width: 25;
}
}
"""
def action_search_query(self):
query_input = self.query_one("#query")
loading = self.query_one(LoadingIndicator)
results = self.query_one(ScrollableContainer)
loading.display = True
# send off a request
response = requests.get(
url=self.app.GITEA_HOST + "api/v1/repos/search",
params={
"q": query_input.value,
"limit": 20
}
)
loading.display = False
# error handling
if not response.ok:
self.notify(response.text, title="Error while getting search results:", severity="error")
return
# display results
results.remove_children(SearchResult)
to_mount = []
print(response.json())
for result in response.json()["data"]:
to_mount.append(SearchResult(result))
results.mount_all(to_mount)
# self explanitory
query_input.clear()
def on_input_submitted(self, event: Input.Submitted):
if event.input.id == "query":
self.action_search_query()
def on_mount(self):
self.action_search_query()
#self.query_one(LoadingIndicator).display = False
def compose(self) -> ComposeResult:
yield Navbar()
with HorizontalGroup(id="search-box"):
yield Input(placeholder="Search repos...", id="query")
yield Select.from_values([
"Repositories",
], id="search-select", allow_blank=False)
with ScrollableContainer(id="results"):
yield LoadingIndicator()