lazy-github 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lazy_github-0.2.1 → lazy_github-0.2.2}/PKG-INFO +19 -20
- lazy_github-0.2.2/README.md +31 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/cli.py +3 -1
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/config.py +18 -3
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/constants.py +2 -0
- lazy_github-0.2.2/lazy_github/lib/github_cli.py +37 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/models/github.py +1 -1
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/app.py +1 -1
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/screens/primary.py +78 -3
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/screens/settings.py +9 -2
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/widgets/info.py +7 -3
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github.egg-info/PKG-INFO +19 -20
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github.egg-info/SOURCES.txt +1 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/pyproject.toml +1 -1
- lazy_github-0.2.1/README.md +0 -32
- {lazy_github-0.2.1 → lazy_github-0.2.2}/LICENSE +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/__main__.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/context.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/git_cli.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/github/auth.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/github/branches.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/github/client.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/github/issues.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/github/pull_requests.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/github/repositories.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/github/workflows.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/logging.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/messages.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/lib/utils.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/screens/auth.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/screens/edit_issue.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/screens/new_comment.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/screens/new_issue.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/screens/new_pull_request.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/widgets/command_log.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/widgets/common.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/widgets/conversations.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/widgets/issues.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/widgets/pull_requests.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/widgets/repositories.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github/ui/widgets/workflows.py +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github.egg-info/dependency_links.txt +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github.egg-info/entry_points.txt +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github.egg-info/requires.txt +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/lazy_github.egg-info/top_level.txt +0 -0
- {lazy_github-0.2.1 → lazy_github-0.2.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lazy-github
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A terminal UI for interacting with Github
|
|
5
5
|
Author-email: Chris Chapline <gizmo385@users.noreply.github.com>
|
|
6
6
|
Maintainer-email: Chris Chapline <gizmo385@users.noreply.github.com>
|
|
@@ -40,35 +40,34 @@ Requires-Dist: textual
|
|
|
40
40
|
Requires-Dist: textual-dev
|
|
41
41
|
Requires-Dist: click>=8.1.7
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
This is a **WIP** terminal UI client for interacting with [GitHub](https://github.com). It draws heavy
|
|
46
|
-
inspiration from the [lazygit](https://github.com/jesseduffield/lazygit) project and uses
|
|
47
|
-
[Textual](https://textual.textualize.io/) to drive the terminal UI interactions.
|
|
43
|
+
 
|
|
48
44
|
|
|
45
|
+
LazyGithub is a terminal UI client for interacting with [GitHub](https://github.com). It draws heavy inspiration from the
|
|
46
|
+
[lazygit](https://github.com/jesseduffield/lazygit) project and uses [Textual](https://textual.textualize.io/) to drive the terminal UI interactions.
|
|
49
47
|
|
|
50
48
|

|
|
51
49
|
|
|
50
|
+
## How to Use It
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
You can run the [most recently built version](https://pypi.org/project/lazy-github/) by installing it from PyPI. If you have [uv installed](https://github.com/astral-sh/uv), you can do that easily with `uvx lazy-github`.
|
|
54
53
|
|
|
54
|
+
When you first start LazyGithub, you will be prompted with a device login code and a link to GitHub
|
|
55
|
+
where you will be able to authenticate the app against your account. This allows the app to act on
|
|
56
|
+
your behalf and is necessary for LazyGithub to function.
|
|
57
|
+
|
|
58
|
+
Currently, it supports the following:
|
|
55
59
|
|
|
56
60
|
- Listing the repositories associated with your account
|
|
57
|
-
- Listing the issues
|
|
61
|
+
- Listing the issues, pull requests, and actions on your repositories
|
|
58
62
|
- Listing the details, diff, and reviews on any of those pull requests
|
|
59
|
-
- Detailed issue views, including conversation participation
|
|
63
|
+
- Detailed issue and pull request views, including conversation participation
|
|
60
64
|
|
|
61
|
-
|
|
62
|
-
- Local caching, improving reload times and making it easier to use within a terminal or editor
|
|
63
|
-
environment.
|
|
64
|
-
- A more wholeistic summary view for the currently selected repository
|
|
65
|
-
- The ability to list, view, and trigger actions on a repository
|
|
66
|
-
- More fleshed out PR interactions, including commenting and eventually submitting full PR reviews
|
|
67
|
-
from within your terminal.
|
|
65
|
+
If you wish to run it from a local clone of the repository, you can do so by running the `./start.sh` located in the root of the repo.
|
|
68
66
|
|
|
67
|
+
## Customization
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
LazyGithub supports a number of customization options, all of which are stored in `$HOME/.config/lazy-github/config.json`.
|
|
70
|
+
These can be edited manually via changing the config or by opening the settings management UI within LazyGithub. That UI
|
|
71
|
+
can be accessed via the command pallete (`CMD+p`) and then searching for settings.
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
`uvx lazy-github`. Alternatively, you can pull the repo and run it locally by running the
|
|
74
|
-
`./start.sh` script in the root of the repo.
|
|
73
|
+

|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
 
|
|
2
|
+
|
|
3
|
+
LazyGithub is a terminal UI client for interacting with [GitHub](https://github.com). It draws heavy inspiration from the
|
|
4
|
+
[lazygit](https://github.com/jesseduffield/lazygit) project and uses [Textual](https://textual.textualize.io/) to drive the terminal UI interactions.
|
|
5
|
+
|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## How to Use It
|
|
9
|
+
|
|
10
|
+
You can run the [most recently built version](https://pypi.org/project/lazy-github/) by installing it from PyPI. If you have [uv installed](https://github.com/astral-sh/uv), you can do that easily with `uvx lazy-github`.
|
|
11
|
+
|
|
12
|
+
When you first start LazyGithub, you will be prompted with a device login code and a link to GitHub
|
|
13
|
+
where you will be able to authenticate the app against your account. This allows the app to act on
|
|
14
|
+
your behalf and is necessary for LazyGithub to function.
|
|
15
|
+
|
|
16
|
+
Currently, it supports the following:
|
|
17
|
+
|
|
18
|
+
- Listing the repositories associated with your account
|
|
19
|
+
- Listing the issues, pull requests, and actions on your repositories
|
|
20
|
+
- Listing the details, diff, and reviews on any of those pull requests
|
|
21
|
+
- Detailed issue and pull request views, including conversation participation
|
|
22
|
+
|
|
23
|
+
If you wish to run it from a local clone of the repository, you can do so by running the `./start.sh` located in the root of the repo.
|
|
24
|
+
|
|
25
|
+
## Customization
|
|
26
|
+
|
|
27
|
+
LazyGithub supports a number of customization options, all of which are stored in `$HOME/.config/lazy-github/config.json`.
|
|
28
|
+
These can be edited manually via changing the config or by opening the settings management UI within LazyGithub. That UI
|
|
29
|
+
can be accessed via the command pallete (`CMD+p`) and then searching for settings.
|
|
30
|
+
|
|
31
|
+

|
|
@@ -6,8 +6,10 @@ from lazy_github.lib.config import _CONFIG_FILE_LOCATION, Config
|
|
|
6
6
|
from lazy_github.lib.context import LazyGithubContext
|
|
7
7
|
from lazy_github.ui.app import app
|
|
8
8
|
|
|
9
|
+
_CLI_CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
@click.group(invoke_without_command=True, context_settings=_CLI_CONTEXT_SETTINGS)
|
|
11
13
|
@click.pass_context
|
|
12
14
|
def cli(ctx: click.Context) -> None:
|
|
13
15
|
"""A Terminal UI for interacting with Github"""
|
|
@@ -16,11 +16,13 @@ ISSUE_OWNER_FILTER = Literal["mine"] | Literal["all"]
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class ApiConfig(BaseModel):
|
|
19
|
+
"""Controlling how the GitHub API is accessed in LazyGithub"""
|
|
20
|
+
|
|
19
21
|
base_url: str = "https://api.github.com"
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
class PullRequestSettings(BaseModel):
|
|
23
|
-
"""Changes how
|
|
25
|
+
"""Changes how pull requests are retrieved from the Github API"""
|
|
24
26
|
|
|
25
27
|
state_filter: IssueStateFilter = IssueStateFilter.ALL
|
|
26
28
|
owner_filter: IssueOwnerFilter = IssueOwnerFilter.ALL
|
|
@@ -34,10 +36,14 @@ class IssueSettings(BaseModel):
|
|
|
34
36
|
|
|
35
37
|
|
|
36
38
|
class RepositorySettings(BaseModel):
|
|
39
|
+
"""Repository-specific settings"""
|
|
40
|
+
|
|
37
41
|
favorites: list[str] = []
|
|
38
42
|
|
|
39
43
|
|
|
40
44
|
class CacheSettings(BaseModel):
|
|
45
|
+
"""Settings that control how long data will be cached from the GitHub API"""
|
|
46
|
+
|
|
41
47
|
cache_directory: Path = CONFIG_FOLDER / ".cache"
|
|
42
48
|
default_ttl: int = int(timedelta(minutes=10).total_seconds())
|
|
43
49
|
list_repos_ttl: int = int(timedelta(days=1).total_seconds())
|
|
@@ -45,6 +51,8 @@ class CacheSettings(BaseModel):
|
|
|
45
51
|
|
|
46
52
|
|
|
47
53
|
class AppearanceSettings(BaseModel):
|
|
54
|
+
"""Settings focused on altering the appearance of LazyGithub, including hiding or showing different sections."""
|
|
55
|
+
|
|
48
56
|
theme: Theme = BUILTIN_THEMES["textual-dark"]
|
|
49
57
|
# Settings to configure which UI elements to display by default
|
|
50
58
|
show_command_log: bool = True
|
|
@@ -67,18 +75,25 @@ class CoreConfig(BaseModel):
|
|
|
67
75
|
logfile_path: Path = CONFIG_FOLDER / "lazy_github.log"
|
|
68
76
|
|
|
69
77
|
|
|
78
|
+
class NotificationSettings(BaseModel):
|
|
79
|
+
"""Controls the settings for the optional notification feature, which relies on the standard GitHub CLI."""
|
|
80
|
+
|
|
81
|
+
enabled: bool = False
|
|
82
|
+
show_all_notifications: bool = True
|
|
83
|
+
|
|
84
|
+
|
|
70
85
|
_CONFIG_INSTANCE: Optional["Config"] = None
|
|
71
86
|
|
|
72
87
|
|
|
73
88
|
class Config(BaseModel):
|
|
74
|
-
# This field is aliased because I can't spell :)
|
|
75
89
|
appearance: AppearanceSettings = AppearanceSettings()
|
|
90
|
+
notifications: NotificationSettings = NotificationSettings()
|
|
76
91
|
repositories: RepositorySettings = RepositorySettings()
|
|
77
92
|
pull_requests: PullRequestSettings = PullRequestSettings()
|
|
78
93
|
issues: IssueSettings = IssueSettings()
|
|
79
94
|
cache: CacheSettings = CacheSettings()
|
|
80
|
-
api: ApiConfig = ApiConfig()
|
|
81
95
|
core: CoreConfig = CoreConfig()
|
|
96
|
+
api: ApiConfig = ApiConfig()
|
|
82
97
|
|
|
83
98
|
@classmethod
|
|
84
99
|
def load_config(cls) -> "Config":
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from asyncio.subprocess import Process, PIPE
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
NOTIFICATIONS_PAGE_COUNT = 30
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
async def _run_gh_cli_command(command: str) -> Process:
|
|
9
|
+
"""Simple wrapper around running a Github CLI command"""
|
|
10
|
+
return await asyncio.create_subprocess_shell(f"gh {command}", stdout=PIPE, stderr=PIPE)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
async def is_logged_in() -> bool:
|
|
14
|
+
"""Checks to see if the user is currently logged into the GitHub CLI"""
|
|
15
|
+
try:
|
|
16
|
+
result = await _run_gh_cli_command("auth status")
|
|
17
|
+
await result.wait()
|
|
18
|
+
return result.returncode == 0
|
|
19
|
+
except Exception:
|
|
20
|
+
return False
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
async def fetch_notifications(all: bool) -> list[str]:
|
|
24
|
+
"""Fetches notifications on GitHub. If all=True, then previously read notifications will also be returned"""
|
|
25
|
+
result = await _run_gh_cli_command(f'api "/notifications?all={str(all).lower()}"')
|
|
26
|
+
await result.wait()
|
|
27
|
+
notifications: list[str] = []
|
|
28
|
+
if result.stdout:
|
|
29
|
+
stdout = await result.stdout.read()
|
|
30
|
+
parsed = json.loads(stdout.decode())
|
|
31
|
+
notifications = [n["subject"]["title"] for n in parsed]
|
|
32
|
+
return notifications
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
async def unread_notification_count() -> int:
|
|
36
|
+
"""Returns the number of currently unread notifications on GitHub"""
|
|
37
|
+
return len(await fetch_notifications(all=False))
|
|
@@ -145,7 +145,7 @@ class WorkflowState(StrEnum):
|
|
|
145
145
|
DELETED = "deleted"
|
|
146
146
|
DISABLED_FORK = "disabled_fork"
|
|
147
147
|
DISABLED_INACTIVITY = "disabled_inactivity"
|
|
148
|
-
DISABLED_MANUALLY = "disabled_manually
|
|
148
|
+
DISABLED_MANUALLY = "disabled_manually"
|
|
149
149
|
|
|
150
150
|
|
|
151
151
|
class Workflow(BaseModel):
|
|
@@ -26,7 +26,7 @@ class LazyGithub(App):
|
|
|
26
26
|
async def on_ready(self):
|
|
27
27
|
await self.authenticate_with_github()
|
|
28
28
|
|
|
29
|
-
def on_settings_modal_dismissed(self, message: SettingsModalDismissed) -> None:
|
|
29
|
+
async def on_settings_modal_dismissed(self, message: SettingsModalDismissed) -> None:
|
|
30
30
|
if not message.changed:
|
|
31
31
|
return
|
|
32
32
|
|
|
@@ -5,14 +5,17 @@ from httpx import HTTPError
|
|
|
5
5
|
from textual import work
|
|
6
6
|
from textual.app import ComposeResult
|
|
7
7
|
from textual.command import Hit, Hits, Provider
|
|
8
|
-
from textual.containers import Container
|
|
8
|
+
from textual.containers import Container, Horizontal
|
|
9
|
+
from textual.timer import Timer
|
|
9
10
|
from textual.reactive import reactive
|
|
10
11
|
from textual.screen import Screen
|
|
11
12
|
from textual.types import IgnoreReturnCallbackType
|
|
12
13
|
from textual.widget import Widget
|
|
13
14
|
from textual.widgets import Footer, TabbedContent
|
|
14
15
|
|
|
16
|
+
from lazy_github.lib.constants import NOTIFICATION_REFRESH_INTERVAL
|
|
15
17
|
from lazy_github.lib.context import LazyGithubContext
|
|
18
|
+
from lazy_github.lib.github_cli import is_logged_in, unread_notification_count
|
|
16
19
|
from lazy_github.lib.logging import lg
|
|
17
20
|
from lazy_github.lib.github.issues import list_issues
|
|
18
21
|
from lazy_github.lib.github.pull_requests import get_full_pull_request
|
|
@@ -51,17 +54,46 @@ class CurrentlySelectedRepo(Widget):
|
|
|
51
54
|
return "No repository selected"
|
|
52
55
|
|
|
53
56
|
|
|
57
|
+
class UnreadNotifications(Widget):
|
|
58
|
+
notification_count: reactive[int | None] = reactive(None)
|
|
59
|
+
|
|
60
|
+
def render(self):
|
|
61
|
+
if self.notification_count is None:
|
|
62
|
+
return ""
|
|
63
|
+
elif self.notification_count == 0:
|
|
64
|
+
return "[green]No unread notifications[/green]"
|
|
65
|
+
else:
|
|
66
|
+
count = f"{self.notification_count}+" if self.notification_count >= 30 else str(self.notification_count)
|
|
67
|
+
return f"[red]• Unread Notifications: {count}[/red]"
|
|
68
|
+
|
|
69
|
+
|
|
54
70
|
class LazyGithubStatusSummary(Container):
|
|
55
71
|
DEFAULT_CSS = """
|
|
56
72
|
LazyGithubStatusSummary {
|
|
57
73
|
max-height: 3;
|
|
58
74
|
width: 100%;
|
|
75
|
+
max-width: 100%;
|
|
76
|
+
layout: horizontal;
|
|
59
77
|
border: solid $secondary;
|
|
60
78
|
}
|
|
79
|
+
|
|
80
|
+
CurrentlySelectedRepo {
|
|
81
|
+
max-width: 50%;
|
|
82
|
+
height: 100%;
|
|
83
|
+
content-align: left middle;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
UnreadNotifications {
|
|
87
|
+
height: 100%;
|
|
88
|
+
max-width: 50%;
|
|
89
|
+
content-align: right middle;
|
|
90
|
+
}
|
|
61
91
|
"""
|
|
62
92
|
|
|
63
93
|
def compose(self):
|
|
64
|
-
|
|
94
|
+
with Horizontal():
|
|
95
|
+
yield CurrentlySelectedRepo(id="currently_selected_repo")
|
|
96
|
+
yield UnreadNotifications(id="unread_notifications")
|
|
65
97
|
|
|
66
98
|
|
|
67
99
|
class SelectionDetailsContainer(LazyGithubContainer):
|
|
@@ -128,7 +160,6 @@ class SelectionsPane(Container):
|
|
|
128
160
|
yield workflows
|
|
129
161
|
|
|
130
162
|
def update_displayed_sections(self) -> None:
|
|
131
|
-
lg.debug("Updating displayed UI components after settings update")
|
|
132
163
|
self.pull_requests.display = LazyGithubContext.config.appearance.show_pull_requests
|
|
133
164
|
self.issues.display = LazyGithubContext.config.appearance.show_issues
|
|
134
165
|
self.workflows.display = LazyGithubContext.config.appearance.show_workflows
|
|
@@ -279,6 +310,16 @@ class MainScreenCommandProvider(Provider):
|
|
|
279
310
|
),
|
|
280
311
|
LazyGithubCommand("Change Settings", self.screen.action_show_settings_modal, "Adjust LazyGithub settings"),
|
|
281
312
|
]
|
|
313
|
+
|
|
314
|
+
if LazyGithubContext.config.notifications.enabled:
|
|
315
|
+
_commands.append(
|
|
316
|
+
LazyGithubCommand(
|
|
317
|
+
"Refresh notifications",
|
|
318
|
+
self.screen.action_refresh_notifications,
|
|
319
|
+
"Refresh the unread notifications count",
|
|
320
|
+
)
|
|
321
|
+
)
|
|
322
|
+
|
|
282
323
|
return tuple(_commands)
|
|
283
324
|
|
|
284
325
|
async def search(self, query: str) -> Hits:
|
|
@@ -295,6 +336,7 @@ class MainScreenCommandProvider(Provider):
|
|
|
295
336
|
|
|
296
337
|
class LazyGithubMainScreen(Screen):
|
|
297
338
|
COMMANDS = {MainScreenCommandProvider}
|
|
339
|
+
notification_refresh_timer: Timer | None = None
|
|
298
340
|
|
|
299
341
|
def compose(self):
|
|
300
342
|
with Container():
|
|
@@ -302,6 +344,33 @@ class LazyGithubMainScreen(Screen):
|
|
|
302
344
|
yield MainViewPane()
|
|
303
345
|
yield Footer()
|
|
304
346
|
|
|
347
|
+
async def on_mount(self) -> None:
|
|
348
|
+
if LazyGithubContext.config.notifications.enabled:
|
|
349
|
+
self.refresh_notification_count()
|
|
350
|
+
if self.notification_refresh_timer is None:
|
|
351
|
+
self.notification_refresh_timer = self.set_interval(
|
|
352
|
+
NOTIFICATION_REFRESH_INTERVAL, self.refresh_notification_count
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
@work
|
|
356
|
+
async def refresh_notification_count(self) -> None:
|
|
357
|
+
widget = self.query_one("#unread_notifications", UnreadNotifications)
|
|
358
|
+
if LazyGithubContext.config.notifications.enabled:
|
|
359
|
+
if not await is_logged_in():
|
|
360
|
+
error_message = "Cannot load notifications - please login to the gh CLI: gh auth login"
|
|
361
|
+
self.notify(error_message, title="Failed to Load Notifiations", severity="error")
|
|
362
|
+
lg.error(error_message)
|
|
363
|
+
return
|
|
364
|
+
|
|
365
|
+
unread_count = await unread_notification_count()
|
|
366
|
+
widget.notification_count = unread_count
|
|
367
|
+
else:
|
|
368
|
+
widget.notification_count = None
|
|
369
|
+
|
|
370
|
+
async def action_refresh_notifications(self) -> None:
|
|
371
|
+
"""Action handler that retriggers the notification loading"""
|
|
372
|
+
self.refresh_notification_count()
|
|
373
|
+
|
|
305
374
|
async def action_toggle_ui(self, ui_to_hide: str):
|
|
306
375
|
widget = self.query_one(f"#{ui_to_hide}", Widget)
|
|
307
376
|
widget.display = not widget.display
|
|
@@ -312,5 +381,11 @@ class LazyGithubMainScreen(Screen):
|
|
|
312
381
|
def handle_settings_update(self) -> None:
|
|
313
382
|
self.query_one("#selections_pane", SelectionsPane).update_displayed_sections()
|
|
314
383
|
|
|
384
|
+
self.refresh_notification_count()
|
|
385
|
+
if self.notification_refresh_timer is None:
|
|
386
|
+
self.notification_refresh_timer = self.set_interval(
|
|
387
|
+
NOTIFICATION_REFRESH_INTERVAL, self.refresh_notification_count
|
|
388
|
+
)
|
|
389
|
+
|
|
315
390
|
def on_repo_selected(self, message: RepoSelected) -> None:
|
|
316
391
|
self.query_one("#currently_selected_repo", CurrentlySelectedRepo).current_repo_name = message.repo.full_name
|
|
@@ -66,7 +66,7 @@ class FieldSetting(Container):
|
|
|
66
66
|
self.value = value
|
|
67
67
|
|
|
68
68
|
def compose(self) -> ComposeResult:
|
|
69
|
-
yield Label(f"{_field_name_to_readable_name(self.field_name)}:")
|
|
69
|
+
yield Label(f"[bold]{_field_name_to_readable_name(self.field_name)}:[/bold]")
|
|
70
70
|
yield self._field_to_widget()
|
|
71
71
|
|
|
72
72
|
|
|
@@ -76,6 +76,10 @@ class SettingsSection(Vertical):
|
|
|
76
76
|
border: blank white;
|
|
77
77
|
height: auto;
|
|
78
78
|
}
|
|
79
|
+
|
|
80
|
+
Markdown {
|
|
81
|
+
margin-bottom: 1;
|
|
82
|
+
}
|
|
79
83
|
"""
|
|
80
84
|
|
|
81
85
|
def __init__(self, parent_field_name: str, model: BaseModel) -> None:
|
|
@@ -85,8 +89,11 @@ class SettingsSection(Vertical):
|
|
|
85
89
|
self.fields = model.model_fields
|
|
86
90
|
|
|
87
91
|
def compose(self) -> ComposeResult:
|
|
88
|
-
|
|
92
|
+
setting_description = self.model.__doc__ or ""
|
|
93
|
+
yield Markdown(f"## {_field_name_to_readable_name(self.parent_field_name)}\n{setting_description}".strip())
|
|
89
94
|
for field_name, field_info in self.fields.items():
|
|
95
|
+
if field_info.exclude:
|
|
96
|
+
continue
|
|
90
97
|
current_value = getattr(self.model, field_name)
|
|
91
98
|
yield FieldSetting(field_name, field_info, current_value)
|
|
92
99
|
|
|
@@ -13,15 +13,19 @@ retrieved and displayed below it.
|
|
|
13
13
|
|
|
14
14
|
## Pull Requests
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
You can interact with a PR by viewing its details, viewing the PR diff, and participating in any active conversations
|
|
17
|
+
happening on the PR. You can also create a new PR for the currently selected repo. It doesn't currently support merging
|
|
18
|
+
a PR from within LazyGithub.
|
|
17
19
|
|
|
18
20
|
## Issues
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
You can interact with an issue by viewing its details, partipcating in any activate conversations happening on the
|
|
23
|
+
issue, and by editing the issue itself. This means that you can close an issue from within LazyGithub.
|
|
21
24
|
|
|
22
25
|
## Actions
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
Github action and workflow support is pretty limited. It currently only supports listing the workflows and the most
|
|
28
|
+
recent runs across all actions on the currently selected repo.
|
|
25
29
|
""".strip()
|
|
26
30
|
|
|
27
31
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lazy-github
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A terminal UI for interacting with Github
|
|
5
5
|
Author-email: Chris Chapline <gizmo385@users.noreply.github.com>
|
|
6
6
|
Maintainer-email: Chris Chapline <gizmo385@users.noreply.github.com>
|
|
@@ -40,35 +40,34 @@ Requires-Dist: textual
|
|
|
40
40
|
Requires-Dist: textual-dev
|
|
41
41
|
Requires-Dist: click>=8.1.7
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
This is a **WIP** terminal UI client for interacting with [GitHub](https://github.com). It draws heavy
|
|
46
|
-
inspiration from the [lazygit](https://github.com/jesseduffield/lazygit) project and uses
|
|
47
|
-
[Textual](https://textual.textualize.io/) to drive the terminal UI interactions.
|
|
43
|
+
 
|
|
48
44
|
|
|
45
|
+
LazyGithub is a terminal UI client for interacting with [GitHub](https://github.com). It draws heavy inspiration from the
|
|
46
|
+
[lazygit](https://github.com/jesseduffield/lazygit) project and uses [Textual](https://textual.textualize.io/) to drive the terminal UI interactions.
|
|
49
47
|
|
|
50
48
|

|
|
51
49
|
|
|
50
|
+
## How to Use It
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
You can run the [most recently built version](https://pypi.org/project/lazy-github/) by installing it from PyPI. If you have [uv installed](https://github.com/astral-sh/uv), you can do that easily with `uvx lazy-github`.
|
|
54
53
|
|
|
54
|
+
When you first start LazyGithub, you will be prompted with a device login code and a link to GitHub
|
|
55
|
+
where you will be able to authenticate the app against your account. This allows the app to act on
|
|
56
|
+
your behalf and is necessary for LazyGithub to function.
|
|
57
|
+
|
|
58
|
+
Currently, it supports the following:
|
|
55
59
|
|
|
56
60
|
- Listing the repositories associated with your account
|
|
57
|
-
- Listing the issues
|
|
61
|
+
- Listing the issues, pull requests, and actions on your repositories
|
|
58
62
|
- Listing the details, diff, and reviews on any of those pull requests
|
|
59
|
-
- Detailed issue views, including conversation participation
|
|
63
|
+
- Detailed issue and pull request views, including conversation participation
|
|
60
64
|
|
|
61
|
-
|
|
62
|
-
- Local caching, improving reload times and making it easier to use within a terminal or editor
|
|
63
|
-
environment.
|
|
64
|
-
- A more wholeistic summary view for the currently selected repository
|
|
65
|
-
- The ability to list, view, and trigger actions on a repository
|
|
66
|
-
- More fleshed out PR interactions, including commenting and eventually submitting full PR reviews
|
|
67
|
-
from within your terminal.
|
|
65
|
+
If you wish to run it from a local clone of the repository, you can do so by running the `./start.sh` located in the root of the repo.
|
|
68
66
|
|
|
67
|
+
## Customization
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
LazyGithub supports a number of customization options, all of which are stored in `$HOME/.config/lazy-github/config.json`.
|
|
70
|
+
These can be edited manually via changing the config or by opening the settings management UI within LazyGithub. That UI
|
|
71
|
+
can be accessed via the command pallete (`CMD+p`) and then searching for settings.
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
`uvx lazy-github`. Alternatively, you can pull the repo and run it locally by running the
|
|
74
|
-
`./start.sh` script in the root of the repo.
|
|
73
|
+

|
lazy_github-0.2.1/README.md
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# LazyGithub
|
|
2
|
-
|
|
3
|
-
This is a **WIP** terminal UI client for interacting with [GitHub](https://github.com). It draws heavy
|
|
4
|
-
inspiration from the [lazygit](https://github.com/jesseduffield/lazygit) project and uses
|
|
5
|
-
[Textual](https://textual.textualize.io/) to drive the terminal UI interactions.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-

|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Currently, it supports the following:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- Listing the repositories associated with your account
|
|
15
|
-
- Listing the issues and pull requests on those repositories
|
|
16
|
-
- Listing the details, diff, and reviews on any of those pull requests
|
|
17
|
-
- Detailed issue views, including conversation participation
|
|
18
|
-
|
|
19
|
-
Planned features:
|
|
20
|
-
- Local caching, improving reload times and making it easier to use within a terminal or editor
|
|
21
|
-
environment.
|
|
22
|
-
- A more wholeistic summary view for the currently selected repository
|
|
23
|
-
- The ability to list, view, and trigger actions on a repository
|
|
24
|
-
- More fleshed out PR interactions, including commenting and eventually submitting full PR reviews
|
|
25
|
-
from within your terminal.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
## Running Locally
|
|
29
|
-
|
|
30
|
-
If you have [uv](https://github.com/astral-sh/uv) installed, then you can try LazyGithub by running
|
|
31
|
-
`uvx lazy-github`. Alternatively, you can pull the repo and run it locally by running the
|
|
32
|
-
`./start.sh` script in the root of the repo.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|