mirror of
https://github.com/ihabunek/toot.git
synced 2025-05-18 00:58:30 -04:00
commit
0557a3cd69
@ -180,60 +180,7 @@ class TUI(urwid.Frame):
|
|||||||
return future
|
return future
|
||||||
|
|
||||||
def connect_default_timeline_signals(self, timeline):
|
def connect_default_timeline_signals(self, timeline):
|
||||||
def _account(timeline, account_id):
|
|
||||||
self.show_account(account_id)
|
|
||||||
|
|
||||||
def _compose(*args):
|
|
||||||
self.show_compose()
|
|
||||||
|
|
||||||
def _delete(timeline, status):
|
|
||||||
if status.is_mine:
|
|
||||||
self.show_delete_confirmation(status)
|
|
||||||
|
|
||||||
def _reply(timeline, status):
|
|
||||||
self.show_compose(status)
|
|
||||||
|
|
||||||
def _source(timeline, status):
|
|
||||||
self.show_status_source(status)
|
|
||||||
|
|
||||||
def _links(timeline, status):
|
|
||||||
self.show_links(status)
|
|
||||||
|
|
||||||
def _media(timeline, status):
|
|
||||||
self.show_media(status)
|
|
||||||
|
|
||||||
def _menu(timeline, status):
|
|
||||||
self.show_context_menu(status)
|
|
||||||
|
|
||||||
def _poll(timeline, status):
|
|
||||||
self.show_poll(status)
|
|
||||||
|
|
||||||
def _zoom(timeline, status_details):
|
|
||||||
self.show_status_zoom(status_details)
|
|
||||||
|
|
||||||
def _clear(*args):
|
|
||||||
self.clear_screen()
|
|
||||||
|
|
||||||
def _copy(timeline, status):
|
|
||||||
self.copy_status(status)
|
|
||||||
|
|
||||||
urwid.connect_signal(timeline, "account", _account)
|
|
||||||
urwid.connect_signal(timeline, "bookmark", self.async_toggle_bookmark)
|
|
||||||
urwid.connect_signal(timeline, "compose", _compose)
|
|
||||||
urwid.connect_signal(timeline, "delete", _delete)
|
|
||||||
urwid.connect_signal(timeline, "favourite", self.async_toggle_favourite)
|
|
||||||
urwid.connect_signal(timeline, "focus", self.refresh_footer)
|
urwid.connect_signal(timeline, "focus", self.refresh_footer)
|
||||||
urwid.connect_signal(timeline, "media", _media)
|
|
||||||
urwid.connect_signal(timeline, "menu", _menu)
|
|
||||||
urwid.connect_signal(timeline, "poll", _poll)
|
|
||||||
urwid.connect_signal(timeline, "reblog", self.async_toggle_reblog)
|
|
||||||
urwid.connect_signal(timeline, "reply", _reply)
|
|
||||||
urwid.connect_signal(timeline, "source", _source)
|
|
||||||
urwid.connect_signal(timeline, "links", _links)
|
|
||||||
urwid.connect_signal(timeline, "zoom", _zoom)
|
|
||||||
urwid.connect_signal(timeline, "translate", self.async_translate)
|
|
||||||
urwid.connect_signal(timeline, "clear-screen", _clear)
|
|
||||||
urwid.connect_signal(timeline, "copy-status", _copy)
|
|
||||||
|
|
||||||
def build_timeline(self, name, statuses, local):
|
def build_timeline(self, name, statuses, local):
|
||||||
def _close(*args):
|
def _close(*args):
|
||||||
@ -242,9 +189,6 @@ class TUI(urwid.Frame):
|
|||||||
def _next(*args):
|
def _next(*args):
|
||||||
self.async_load_timeline(is_initial=False)
|
self.async_load_timeline(is_initial=False)
|
||||||
|
|
||||||
def _thread(timeline, status):
|
|
||||||
self.show_thread(status)
|
|
||||||
|
|
||||||
def _toggle_save(timeline, status):
|
def _toggle_save(timeline, status):
|
||||||
if not timeline.name.startswith("#"):
|
if not timeline.name.startswith("#"):
|
||||||
return
|
return
|
||||||
@ -260,12 +204,11 @@ class TUI(urwid.Frame):
|
|||||||
self.loop.set_alarm_in(5, lambda *args: self.footer.clear_message())
|
self.loop.set_alarm_in(5, lambda *args: self.footer.clear_message())
|
||||||
config.save_config(self.config)
|
config.save_config(self.config)
|
||||||
|
|
||||||
timeline = Timeline(name, statuses, self.can_translate, self.followed_tags, self.followed_accounts)
|
timeline = Timeline(self, name, statuses)
|
||||||
|
|
||||||
self.connect_default_timeline_signals(timeline)
|
self.connect_default_timeline_signals(timeline)
|
||||||
urwid.connect_signal(timeline, "next", _next)
|
urwid.connect_signal(timeline, "next", _next)
|
||||||
urwid.connect_signal(timeline, "close", _close)
|
urwid.connect_signal(timeline, "close", _close)
|
||||||
urwid.connect_signal(timeline, "thread", _thread)
|
|
||||||
urwid.connect_signal(timeline, "save", _toggle_save)
|
urwid.connect_signal(timeline, "save", _toggle_save)
|
||||||
|
|
||||||
return timeline
|
return timeline
|
||||||
@ -289,8 +232,7 @@ class TUI(urwid.Frame):
|
|||||||
statuses = ancestors + [status] + descendants
|
statuses = ancestors + [status] + descendants
|
||||||
focus = len(ancestors)
|
focus = len(ancestors)
|
||||||
|
|
||||||
timeline = Timeline("thread", statuses, self.can_translate,
|
timeline = Timeline(self, "thread", statuses, focus=focus, is_thread=True)
|
||||||
self.followed_tags, self.followed_accounts, focus, is_thread=True)
|
|
||||||
|
|
||||||
self.connect_default_timeline_signals(timeline)
|
self.connect_default_timeline_signals(timeline)
|
||||||
urwid.connect_signal(timeline, "close", _close)
|
urwid.connect_signal(timeline, "close", _close)
|
||||||
|
@ -3,15 +3,16 @@ import sys
|
|||||||
import urwid
|
import urwid
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
|
||||||
from typing import Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from .entities import Status
|
from .entities import Status
|
||||||
from .scroll import Scrollable, ScrollBar
|
from .scroll import Scrollable, ScrollBar
|
||||||
from .utils import highlight_hashtags, parse_datetime, highlight_keys
|
from .utils import highlight_hashtags, parse_datetime, highlight_keys
|
||||||
from .widgets import SelectableText, SelectableColumns
|
from .widgets import SelectableText, SelectableColumns
|
||||||
|
from toot.tui import app
|
||||||
|
from toot.tui.utils import time_ago
|
||||||
from toot.utils import format_content
|
from toot.utils import format_content
|
||||||
from toot.utils.language import language_name
|
from toot.utils.language import language_name
|
||||||
from toot.tui.utils import time_ago
|
|
||||||
|
|
||||||
logger = logging.getLogger("toot")
|
logger = logging.getLogger("toot")
|
||||||
|
|
||||||
@ -21,45 +22,25 @@ class Timeline(urwid.Columns):
|
|||||||
Displays a list of statuses to the left, and status details on the right.
|
Displays a list of statuses to the left, and status details on the right.
|
||||||
"""
|
"""
|
||||||
signals = [
|
signals = [
|
||||||
"account", # Display account info and actions
|
"close", # Close thread
|
||||||
"close", # Close thread
|
"focus", # Focus changed
|
||||||
"compose", # Compose a new toot
|
"next", # Fetch more statuses
|
||||||
"delete", # Delete own status
|
"save", # Save current timeline
|
||||||
"favourite", # Favourite status
|
|
||||||
"focus", # Focus changed
|
|
||||||
"bookmark", # Bookmark status
|
|
||||||
"media", # Display media attachments
|
|
||||||
"menu", # Show a context menu
|
|
||||||
"next", # Fetch more statuses
|
|
||||||
"poll", # Vote in a poll
|
|
||||||
"reblog", # Reblog status
|
|
||||||
"reply", # Compose a reply to a status
|
|
||||||
"source", # Show status source
|
|
||||||
"links", # Show status links
|
|
||||||
"thread", # Show thread for status
|
|
||||||
"translate", # Translate status
|
|
||||||
"save", # Save current timeline
|
|
||||||
"zoom", # Open status in scrollable popup window
|
|
||||||
"clear-screen", # Clear the screen (used internally)
|
|
||||||
"copy-status", # Copy status to clipboard
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(
|
||||||
name,
|
self,
|
||||||
statuses,
|
tui: "app.TUI",
|
||||||
can_translate,
|
name: str,
|
||||||
followed_tags=[],
|
statuses: List[Status],
|
||||||
followed_accounts=[],
|
focus: int = 0,
|
||||||
focus=0,
|
is_thread: bool = False
|
||||||
is_thread=False):
|
):
|
||||||
|
self.tui = tui
|
||||||
self.name = name
|
self.name = name
|
||||||
self.is_thread = is_thread
|
self.is_thread = is_thread
|
||||||
self.statuses = statuses
|
self.statuses = statuses
|
||||||
self.can_translate = can_translate
|
|
||||||
self.status_list = self.build_status_list(statuses, focus=focus)
|
self.status_list = self.build_status_list(statuses, focus=focus)
|
||||||
self.followed_tags = followed_tags
|
|
||||||
self.followed_accounts = followed_accounts
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
focused_status = statuses[focus]
|
focused_status = statuses[focus]
|
||||||
@ -100,7 +81,7 @@ class Timeline(urwid.Columns):
|
|||||||
def build_list_item(self, status):
|
def build_list_item(self, status):
|
||||||
item = StatusListItem(status)
|
item = StatusListItem(status)
|
||||||
urwid.connect_signal(item, "click", lambda *args:
|
urwid.connect_signal(item, "click", lambda *args:
|
||||||
self._emit("menu", status))
|
self.tui.show_context_menu(status))
|
||||||
return urwid.AttrMap(item, None, focus_map={
|
return urwid.AttrMap(item, None, focus_map={
|
||||||
"blue": "green_selected",
|
"blue": "green_selected",
|
||||||
"green": "green_selected",
|
"green": "green_selected",
|
||||||
@ -129,7 +110,7 @@ class Timeline(urwid.Columns):
|
|||||||
"[P]oll" if poll and not poll["expired"] else "",
|
"[P]oll" if poll and not poll["expired"] else "",
|
||||||
"So[u]rce",
|
"So[u]rce",
|
||||||
"[Z]oom",
|
"[Z]oom",
|
||||||
"Tra[n]slate" if self.can_translate else "",
|
"Tra[n]slate" if self.tui.can_translate else "",
|
||||||
"Cop[y]",
|
"Cop[y]",
|
||||||
"[H]elp",
|
"[H]elp",
|
||||||
]
|
]
|
||||||
@ -190,27 +171,29 @@ class Timeline(urwid.Columns):
|
|||||||
self._emit("next")
|
self._emit("next")
|
||||||
|
|
||||||
if key in ("a", "A"):
|
if key in ("a", "A"):
|
||||||
self._emit("account", status.original.data['account']['id'])
|
account_id = status.original.data["account"]["id"]
|
||||||
|
self.tui.show_account(account_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("b", "B"):
|
if key in ("b", "B"):
|
||||||
self._emit("reblog", status)
|
self.tui.async_toggle_reblog(self, status)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("c", "C"):
|
if key in ("c", "C"):
|
||||||
self._emit("compose")
|
self.tui.show_compose()
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("d", "D"):
|
if key in ("d", "D"):
|
||||||
self._emit("delete", status)
|
if status.is_mine:
|
||||||
|
self.tui.show_delete_confirmation(status)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("f", "F"):
|
if key in ("f", "F"):
|
||||||
self._emit("favourite", status)
|
self.tui.async_toggle_favourite(self, status)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("m", "M"):
|
if key in ("m", "M"):
|
||||||
self._emit("media", status)
|
self.tui.show_media(status)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("q", "Q"):
|
if key in ("q", "Q"):
|
||||||
@ -222,7 +205,7 @@ class Timeline(urwid.Columns):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if key in ("r", "R"):
|
if key in ("r", "R"):
|
||||||
self._emit("reply", status)
|
self.tui.show_compose(status)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("s", "S"):
|
if key in ("s", "S"):
|
||||||
@ -231,31 +214,31 @@ class Timeline(urwid.Columns):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if key in ("o", "O"):
|
if key in ("o", "O"):
|
||||||
self._emit("bookmark", status)
|
self.tui.async_toggle_bookmark(self, status)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("l", "L"):
|
if key in ("l", "L"):
|
||||||
self._emit("links", status)
|
self.tui.show_links(status)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("n", "N"):
|
if key in ("n", "N"):
|
||||||
if self.can_translate:
|
if self.tui.can_translate:
|
||||||
self._emit("translate", status)
|
self.tui.async_translate(self, status)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("t", "T"):
|
if key in ("t", "T"):
|
||||||
self._emit("thread", status)
|
self.tui.show_thread(status)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("u", "U"):
|
if key in ("u", "U"):
|
||||||
self._emit("source", status)
|
self.tui.show_status_source(status)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("v", "V"):
|
if key in ("v", "V"):
|
||||||
if status.original.url:
|
if status.original.url:
|
||||||
webbrowser.open(status.original.url)
|
webbrowser.open(status.original.url)
|
||||||
# force a screen refresh; necessary with console browsers
|
# force a screen refresh; necessary with console browsers
|
||||||
self._emit("clear-screen")
|
self.tui.clear_screen()
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("e", "E"):
|
if key in ("e", "E"):
|
||||||
@ -263,17 +246,17 @@ class Timeline(urwid.Columns):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if key in ("z", "Z"):
|
if key in ("z", "Z"):
|
||||||
self._emit("zoom", self.status_details)
|
self.tui.show_status_zoom(self.status_details)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("p", "P"):
|
if key in ("p", "P"):
|
||||||
poll = status.original.data.get("poll")
|
poll = status.original.data.get("poll")
|
||||||
if poll and not poll["expired"]:
|
if poll and not poll["expired"]:
|
||||||
self._emit("poll", status)
|
self.tui.show_poll(status)
|
||||||
return
|
return
|
||||||
|
|
||||||
if key in ("y", "Y"):
|
if key in ("y", "Y"):
|
||||||
self._emit("copy-status", status)
|
self.tui.copy_status(status)
|
||||||
return
|
return
|
||||||
|
|
||||||
return super().keypress(size, key)
|
return super().keypress(size, key)
|
||||||
@ -328,8 +311,8 @@ class Timeline(urwid.Columns):
|
|||||||
class StatusDetails(urwid.Pile):
|
class StatusDetails(urwid.Pile):
|
||||||
def __init__(self, timeline: Timeline, status: Optional[Status]):
|
def __init__(self, timeline: Timeline, status: Optional[Status]):
|
||||||
self.status = status
|
self.status = status
|
||||||
self.followed_tags = timeline.followed_tags
|
self.followed_tags = timeline.tui.followed_tags
|
||||||
self.followed_accounts = timeline.followed_accounts
|
self.followed_accounts = timeline.tui.followed_accounts
|
||||||
|
|
||||||
reblogged_by = status.author if status and status.reblog else None
|
reblogged_by = status.author if status and status.reblog else None
|
||||||
widget_list = list(self.content_generator(status.original, reblogged_by)
|
widget_list = list(self.content_generator(status.original, reblogged_by)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user