kopia lustrzana https://github.com/ihabunek/toot
Show relative datetimes in status list
Status detail pane now shows the full created_at timestamp.pull/302/head
rodzic
7cada43e2f
commit
deebdf7141
|
@ -10,6 +10,7 @@ from .utils import highlight_hashtags, parse_datetime, highlight_keys
|
||||||
from .widgets import SelectableText, SelectableColumns
|
from .widgets import SelectableText, SelectableColumns
|
||||||
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")
|
||||||
|
|
||||||
|
@ -364,12 +365,13 @@ class StatusDetails(urwid.Pile):
|
||||||
visibility_color = visibility_colors.get(status.visibility, "gray")
|
visibility_color = visibility_colors.get(status.visibility, "gray")
|
||||||
|
|
||||||
yield ("pack", urwid.Text([
|
yield ("pack", urwid.Text([
|
||||||
("red", "🠷 ") if status.bookmarked else "",
|
("blue", f"{status.created_at.strftime('%Y-%m-%d %H:%M')} "),
|
||||||
|
("red" if status.bookmarked else "gray", "🠷 "),
|
||||||
("gray", f"⤶ {status.data['replies_count']} "),
|
("gray", f"⤶ {status.data['replies_count']} "),
|
||||||
("yellow" if status.reblogged else "gray", f"♺ {status.data['reblogs_count']} "),
|
("yellow" if status.reblogged else "gray", f"♺ {status.data['reblogs_count']} "),
|
||||||
("yellow" if status.favourited else "gray", f"★ {status.data['favourites_count']}"),
|
("yellow" if status.favourited else "gray", f"★ {status.data['favourites_count']}"),
|
||||||
(visibility_color, f" · {visibility}"),
|
(visibility_color, f" · {visibility}"),
|
||||||
("yellow", f" · Translated from {translated_from} ") if translated_from else "",
|
("yellow", f" · Translated from {translated_from} " if translated_from else ""),
|
||||||
("gray", f" · {application}" if application else ""),
|
("gray", f" · {application}" if application else ""),
|
||||||
]))
|
]))
|
||||||
|
|
||||||
|
@ -418,7 +420,9 @@ class StatusDetails(urwid.Pile):
|
||||||
|
|
||||||
class StatusListItem(SelectableColumns):
|
class StatusListItem(SelectableColumns):
|
||||||
def __init__(self, status):
|
def __init__(self, status):
|
||||||
created_at = status.created_at.strftime("%Y-%m-%d %H:%M")
|
edited = status.data["edited_at"]
|
||||||
|
created_at = time_ago(status.created_at).ljust(3, " ")
|
||||||
|
edited_flag = "*" if edited else " "
|
||||||
favourited = ("yellow", "★") if status.original.favourited else " "
|
favourited = ("yellow", "★") if status.original.favourited else " "
|
||||||
reblogged = ("yellow", "♺") if status.original.reblogged else " "
|
reblogged = ("yellow", "♺") if status.original.reblogged else " "
|
||||||
is_reblog = ("cyan", "♺") if status.reblog else " "
|
is_reblog = ("cyan", "♺") if status.reblog else " "
|
||||||
|
@ -426,6 +430,7 @@ class StatusListItem(SelectableColumns):
|
||||||
|
|
||||||
return super().__init__([
|
return super().__init__([
|
||||||
("pack", SelectableText(("blue", created_at), wrap="clip")),
|
("pack", SelectableText(("blue", created_at), wrap="clip")),
|
||||||
|
("pack", urwid.Text(("blue", edited_flag))),
|
||||||
("pack", urwid.Text(" ")),
|
("pack", urwid.Text(" ")),
|
||||||
("pack", urwid.Text(favourited)),
|
("pack", urwid.Text(favourited)),
|
||||||
("pack", urwid.Text(" ")),
|
("pack", urwid.Text(" ")),
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from html.parser import HTMLParser
|
from html.parser import HTMLParser
|
||||||
|
import math
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -7,6 +8,11 @@ import subprocess
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
HASHTAG_PATTERN = re.compile(r'(?<!\w)(#\w+)\b')
|
HASHTAG_PATTERN = re.compile(r'(?<!\w)(#\w+)\b')
|
||||||
|
SECOND = 1
|
||||||
|
MINUTE = SECOND * 60
|
||||||
|
HOUR = MINUTE * 60
|
||||||
|
DAY = HOUR * 24
|
||||||
|
WEEK = DAY * 7
|
||||||
|
|
||||||
|
|
||||||
def parse_datetime(value):
|
def parse_datetime(value):
|
||||||
|
@ -27,6 +33,28 @@ def parse_datetime(value):
|
||||||
return dttm.astimezone()
|
return dttm.astimezone()
|
||||||
|
|
||||||
|
|
||||||
|
def time_ago(value: datetime) -> datetime:
|
||||||
|
now = datetime.now().astimezone()
|
||||||
|
delta = now.timestamp() - value.timestamp()
|
||||||
|
|
||||||
|
if (delta < 1):
|
||||||
|
return "now"
|
||||||
|
|
||||||
|
if (delta < 8 * DAY):
|
||||||
|
if (delta < MINUTE):
|
||||||
|
return f"{math.floor(delta / SECOND)}".rjust(2, " ") + "s"
|
||||||
|
if (delta < HOUR):
|
||||||
|
return f"{math.floor(delta / MINUTE)}".rjust(2, " ") + "m"
|
||||||
|
if (delta < DAY):
|
||||||
|
return f"{math.floor(delta / HOUR)}".rjust(2, " ") + "h"
|
||||||
|
return f"{math.floor(delta / DAY)}".rjust(2, " ") + "d"
|
||||||
|
|
||||||
|
if (delta < 53 * WEEK): # not exactly correct but good enough as a boundary
|
||||||
|
return f"{math.floor(delta / WEEK)}".rjust(2, " ") + "w"
|
||||||
|
|
||||||
|
return ">1y"
|
||||||
|
|
||||||
|
|
||||||
def highlight_keys(text, high_attr, low_attr=""):
|
def highlight_keys(text, high_attr, low_attr=""):
|
||||||
"""
|
"""
|
||||||
Takes a string and adds high_attr attribute to parts in square brackets,
|
Takes a string and adds high_attr attribute to parts in square brackets,
|
||||||
|
|
Ładowanie…
Reference in New Issue