mirror of
https://github.com/ihabunek/toot.git
synced 2025-02-02 15:07:51 -05:00
Pass tui options through cli options
This commit is contained in:
parent
ac77ea75ce
commit
bbf67c6736
@ -20,6 +20,17 @@ T = t.TypeVar("T")
|
||||
PRIVACY_CHOICES = ["public", "unlisted", "private"]
|
||||
VISIBILITY_CHOICES = ["public", "unlisted", "private", "direct"]
|
||||
|
||||
TUI_COLORS = {
|
||||
"1": 1,
|
||||
"16": 16,
|
||||
"88": 88,
|
||||
"256": 256,
|
||||
"16777216": 16777216,
|
||||
"24bit": 16777216,
|
||||
}
|
||||
TUI_COLORS_CHOICES = list(TUI_COLORS.keys())
|
||||
TUI_COLORS_VALUES = list(TUI_COLORS.values())
|
||||
|
||||
DURATION_EXAMPLES = """e.g. "1 day", "2 hours 30 minutes", "5 minutes 30
|
||||
seconds" or any combination of above. Shorthand: "1d", "2h30m", "5m30s\""""
|
||||
|
||||
|
@ -1,17 +1,44 @@
|
||||
import click
|
||||
|
||||
from toot.cli.base import Context, cli, pass_context
|
||||
from typing import Optional
|
||||
from toot.cli.base import TUI_COLORS, Context, cli, pass_context
|
||||
from toot.cli.validators import validate_tui_colors
|
||||
from toot.tui.app import TUI, TuiOptions
|
||||
|
||||
COLOR_OPTIONS = ", ".join(TUI_COLORS.keys())
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option(
|
||||
"--relative-datetimes",
|
||||
"-r", "--relative-datetimes",
|
||||
is_flag=True,
|
||||
help="Show relative datetimes in status list"
|
||||
)
|
||||
@click.option(
|
||||
"-m", "--media-viewer",
|
||||
help="Program to invoke with media URLs to display the media files, such as 'feh'"
|
||||
)
|
||||
@click.option(
|
||||
"-c", "--colors",
|
||||
callback=validate_tui_colors,
|
||||
help=f"""Number of colors to use, one of {COLOR_OPTIONS}, defaults to 16 if
|
||||
using --color, and 1 if using --no-color."""
|
||||
)
|
||||
@pass_context
|
||||
def tui(ctx: Context, relative_datetimes: bool):
|
||||
def tui(
|
||||
ctx: Context,
|
||||
colors: Optional[int],
|
||||
media_viewer: Optional[str],
|
||||
relative_datetimes: bool,
|
||||
):
|
||||
"""Launches the toot terminal user interface"""
|
||||
options = TuiOptions(relative_datetimes, ctx.color)
|
||||
TUI.create(ctx.app, ctx.user, options).run()
|
||||
if colors is None:
|
||||
colors = 16 if ctx.color else 1
|
||||
|
||||
options = TuiOptions(
|
||||
colors=colors,
|
||||
media_viewer=media_viewer,
|
||||
relative_datetimes=relative_datetimes,
|
||||
)
|
||||
tui = TUI.create(ctx.app, ctx.user, options)
|
||||
tui.run()
|
||||
|
@ -4,6 +4,8 @@ import re
|
||||
from click import Context
|
||||
from typing import Optional
|
||||
|
||||
from toot.cli.base import TUI_COLORS
|
||||
|
||||
|
||||
def validate_language(ctx: Context, param: str, value: Optional[str]):
|
||||
if value is None:
|
||||
@ -58,3 +60,16 @@ def validate_instance(ctx: click.Context, param: str, value: Optional[str]):
|
||||
|
||||
value = value.rstrip("/")
|
||||
return value if value.startswith("http") else f"https://{value}"
|
||||
|
||||
|
||||
def validate_tui_colors(ctx, param, value) -> Optional[int]:
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
if value in TUI_COLORS.values():
|
||||
return value
|
||||
|
||||
if value in TUI_COLORS.keys():
|
||||
return TUI_COLORS[value]
|
||||
|
||||
raise click.BadParameter(f"Invalid value: {value}. Expected one of: {', '.join(TUI_COLORS)}")
|
||||
|
@ -25,6 +25,10 @@ def get_width() -> int:
|
||||
return min(get_terminal_width(), get_max_width())
|
||||
|
||||
|
||||
def print_warning(text: str):
|
||||
click.secho(f"Warning: {text}", fg="yellow", err=True)
|
||||
|
||||
|
||||
def print_instance(instance: Instance):
|
||||
width = get_width()
|
||||
click.echo(instance_to_text(instance, width))
|
||||
|
@ -3,7 +3,7 @@ import subprocess
|
||||
import urwid
|
||||
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from typing import NamedTuple
|
||||
from typing import NamedTuple, Optional
|
||||
|
||||
from toot import api, config, __version__, settings
|
||||
from toot import App, User
|
||||
@ -28,8 +28,9 @@ DEFAULT_MAX_TOOT_CHARS = 500
|
||||
|
||||
|
||||
class TuiOptions(NamedTuple):
|
||||
colors: int
|
||||
media_viewer: Optional[str]
|
||||
relative_datetimes: bool
|
||||
color: bool
|
||||
|
||||
|
||||
class Header(urwid.WidgetWrap):
|
||||
@ -89,7 +90,9 @@ class TUI(urwid.Frame):
|
||||
@staticmethod
|
||||
def create(app: App, user: User, args: TuiOptions):
|
||||
"""Factory method, sets up TUI and an event loop."""
|
||||
screen = TUI.create_screen(args)
|
||||
screen = urwid.raw_display.Screen()
|
||||
screen.set_terminal_properties(args.colors)
|
||||
|
||||
tui = TUI(app, user, screen, args)
|
||||
|
||||
palette = PALETTE.copy()
|
||||
@ -108,23 +111,11 @@ class TUI(urwid.Frame):
|
||||
|
||||
return tui
|
||||
|
||||
@staticmethod
|
||||
def create_screen(args: TuiOptions):
|
||||
screen = urwid.raw_display.Screen()
|
||||
|
||||
# Determine how many colors to use
|
||||
default_colors = 16 if args.color else 1
|
||||
colors = settings.get_setting("tui.colors", int, default_colors)
|
||||
logger.debug(f"Setting colors to {colors}")
|
||||
screen.set_terminal_properties(colors)
|
||||
|
||||
return screen
|
||||
|
||||
def __init__(self, app, user, screen, args: TuiOptions):
|
||||
def __init__(self, app, user, screen, options: TuiOptions):
|
||||
self.app = app
|
||||
self.user = user
|
||||
self.args = args
|
||||
self.config = config.load_config()
|
||||
self.options = options
|
||||
|
||||
self.loop = None # late init, set in `create`
|
||||
self.screen = screen
|
||||
@ -146,7 +137,6 @@ class TUI(urwid.Frame):
|
||||
self.can_translate = False
|
||||
self.account = None
|
||||
self.followed_accounts = []
|
||||
self.media_viewer = settings.get_setting("tui.media_viewer", str)
|
||||
|
||||
super().__init__(self.body, header=self.header, footer=self.footer)
|
||||
|
||||
@ -510,8 +500,15 @@ class TUI(urwid.Frame):
|
||||
if not urls:
|
||||
return
|
||||
|
||||
if self.media_viewer:
|
||||
subprocess.run([self.media_viewer] + urls)
|
||||
media_viewer = self.options.media_viewer
|
||||
if media_viewer:
|
||||
try:
|
||||
subprocess.run([media_viewer] + urls)
|
||||
except FileNotFoundError:
|
||||
self.footer.set_error_message(f"Media viewer not found: '{media_viewer}'")
|
||||
except Exception as ex:
|
||||
self.exception = ex
|
||||
self.footer.set_error_message("Failed invoking media viewer. Press X to see exception.")
|
||||
else:
|
||||
self.footer.set_error_message("Media viewer not configured")
|
||||
|
||||
|
@ -79,7 +79,7 @@ class Timeline(urwid.Columns):
|
||||
return urwid.ListBox(walker)
|
||||
|
||||
def build_list_item(self, status):
|
||||
item = StatusListItem(status, self.tui.args.relative_datetimes)
|
||||
item = StatusListItem(status, self.tui.options.relative_datetimes)
|
||||
urwid.connect_signal(item, "click", lambda *args:
|
||||
self.tui.show_context_menu(status))
|
||||
return urwid.AttrMap(item, None, focus_map={
|
||||
@ -95,7 +95,7 @@ class Timeline(urwid.Columns):
|
||||
return None
|
||||
|
||||
poll = status.original.data.get("poll")
|
||||
show_media = status.original.data["media_attachments"] and self.tui.media_viewer
|
||||
show_media = status.original.data["media_attachments"] and self.tui.options.media_viewer
|
||||
|
||||
options = [
|
||||
"[A]ccount" if not status.is_mine else "",
|
||||
@ -107,7 +107,6 @@ class Timeline(urwid.Columns):
|
||||
"[T]hread" if not self.is_thread else "",
|
||||
"L[i]nks",
|
||||
"[M]edia" if show_media else "",
|
||||
self.tui.media_viewer,
|
||||
"[R]eply",
|
||||
"[P]oll" if poll and not poll["expired"] else "",
|
||||
"So[u]rce",
|
||||
|
Loading…
x
Reference in New Issue
Block a user