1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
"""Default landing page for the pgt TUI."""
from __future__ import annotations
from typing import Literal
from unicurses import ( # type: ignore[import-untyped]
A_REVERSE,
KEY_RESIZE,
)
from pygittools.tui.branches import current_branch_name
from pygittools.tui.changes_list import ChangesList
from pygittools.tui.commit_draft import load_commit_draft
from pygittools.tui.draw import draw_line
from pygittools.tui.input_context import InputContext, InputMode, input_context, nav_context
from pygittools.tui.log_list import CommitLogList
from pygittools.tui.project_label import repo_project_label
from pygittools.tui.tabs import draw_tab_row
from pygittools.tui.types import Page, PageAction, PageContext, PageResult
_PROJECT_ROW = 0
_BRANCH_ROW = 1
_HEADER_ROWS = 2
_TABS: tuple[str, ...] = ("Status", "Log")
_HeaderFocus = Literal["changes", "repo", "branch"]
_HomeTab = Literal["status", "log"]
class HomePage:
title = "pgt"
def __init__(self) -> None:
self._ctx: PageContext | None = None
self._changes = ChangesList()
self._log = CommitLogList()
self._active_tab: _HomeTab = "status"
self._header_focus: _HeaderFocus = "changes"
self._input_mode: InputMode = nav_context()
@property
def header_focus(self) -> _HeaderFocus:
return self._header_focus
def set_header_focus(self, focus: _HeaderFocus) -> None:
self._header_focus = focus
@property
def page_context(self) -> PageContext | None:
return self._ctx
@property
def changes(self) -> ChangesList:
return self._changes
@property
def log(self) -> CommitLogList:
return self._log
@property
def active_tab(self) -> _HomeTab:
return self._active_tab
def set_active_tab(self, tab: _HomeTab) -> None:
self._active_tab = tab
def on_enter(self, ctx: PageContext) -> None:
self._ctx = ctx
self._active_tab = "status"
self._header_focus = "changes"
self._input_mode = nav_context()
self._changes.set_commit_message(load_commit_draft(ctx.repo_path, ctx.repo))
self._changes.refresh(ctx.repo)
self._log.refresh(ctx.repo)
def status_text(self) -> str:
return self._input_mode.status_hint(self)
def draw(self, stdscr: int, height: int, width: int) -> None:
del stdscr
ctx = self._ctx
if ctx is None:
return
self._changes.refresh(ctx.repo)
self._log.refresh(ctx.repo)
project_label = repo_project_label(ctx.repo_path)
branch = current_branch_name(ctx.repo)
if height > _PROJECT_ROW:
active_index = 0 if self._active_tab == "status" else 1
prefix_attr = A_REVERSE if self._header_focus == "repo" else 0
draw_tab_row(_PROJECT_ROW, width, project_label, _TABS, active_index, prefix_attr=prefix_attr)
if height > _BRANCH_ROW:
branch_attr = A_REVERSE if self._header_focus == "branch" else 0
draw_line(_BRANCH_ROW, 0, f"Branch: {branch}", width, branch_attr)
list_height = max(0, height - _HEADER_ROWS)
if list_height > 0 and height > _HEADER_ROWS:
content_highlight = self._header_focus == "changes"
commit_input = isinstance(self._input_mode, InputContext)
if self._active_tab == "status":
self._changes.draw(
_HEADER_ROWS,
list_height,
width,
highlight=content_highlight,
commit_input=commit_input,
)
else:
self._log.draw(_HEADER_ROWS, list_height, width, highlight=content_highlight)
def handle_key(self, key: int) -> PageResult:
if key in (ord("q"), ord("Q")):
return PageResult(action=PageAction.QUIT)
if key == KEY_RESIZE:
return PageResult()
dispatch = self._input_mode.dispatch_key(self, key)
if dispatch.next_mode == "input":
self._input_mode = input_context()
elif dispatch.next_mode == "nav":
self._input_mode = nav_context()
if dispatch.page_result is not None:
return dispatch.page_result
return PageResult()
def home_page() -> Page:
return HomePage()