mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2026-03-06 09:27:33 +01:00
Esqueleto esquelético de chats. No funcionan todavía... Pero se pueden enviar y recibir de forma extraña.
This commit is contained in:
@@ -954,8 +954,9 @@ class BaseBuffer(base.Buffer):
|
|||||||
return post.get("uri")
|
return post.get("uri")
|
||||||
if it.get("uri"):
|
if it.get("uri"):
|
||||||
return it.get("uri")
|
return it.get("uri")
|
||||||
if it.get("id"):
|
for key in ("id", "convoId", "convo_id", "messageId", "message_id", "msgId", "msg_id"):
|
||||||
return it.get("id")
|
if it.get(key):
|
||||||
|
return it.get(key)
|
||||||
if it.get("did"):
|
if it.get("did"):
|
||||||
return it.get("did")
|
return it.get("did")
|
||||||
if it.get("handle"):
|
if it.get("handle"):
|
||||||
@@ -963,17 +964,30 @@ class BaseBuffer(base.Buffer):
|
|||||||
author = it.get("author")
|
author = it.get("author")
|
||||||
if isinstance(author, dict):
|
if isinstance(author, dict):
|
||||||
return author.get("did") or author.get("handle")
|
return author.get("did") or author.get("handle")
|
||||||
|
# Chat message fallback
|
||||||
|
sent_at = it.get("sentAt") or it.get("sent_at")
|
||||||
|
sender = it.get("sender") or {}
|
||||||
|
sender_did = sender.get("did") if isinstance(sender, dict) else None
|
||||||
|
text = it.get("text")
|
||||||
|
if sent_at or sender_did or text:
|
||||||
|
return (sent_at, sender_did, text)
|
||||||
return None
|
return None
|
||||||
post = getattr(it, "post", None)
|
post = getattr(it, "post", None)
|
||||||
if post is not None:
|
if post is not None:
|
||||||
return getattr(post, "uri", None)
|
return getattr(post, "uri", None)
|
||||||
for attr in ("uri", "id", "did", "handle"):
|
for attr in ("uri", "id", "convoId", "convo_id", "messageId", "message_id", "msgId", "msg_id", "did", "handle"):
|
||||||
val = getattr(it, attr, None)
|
val = getattr(it, attr, None)
|
||||||
if val:
|
if val:
|
||||||
return val
|
return val
|
||||||
author = getattr(it, "author", None)
|
author = getattr(it, "author", None)
|
||||||
if author is not None:
|
if author is not None:
|
||||||
return getattr(author, "did", None) or getattr(author, "handle", None)
|
return getattr(author, "did", None) or getattr(author, "handle", None)
|
||||||
|
sent_at = getattr(it, "sentAt", None) or getattr(it, "sent_at", None)
|
||||||
|
sender = getattr(it, "sender", None)
|
||||||
|
sender_did = getattr(sender, "did", None) if sender is not None else None
|
||||||
|
text = getattr(it, "text", None)
|
||||||
|
if sent_at or sender_did or text:
|
||||||
|
return (sent_at, sender_did, text)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
for item in self.session.db[self.name]:
|
for item in self.session.db[self.name]:
|
||||||
|
|||||||
@@ -68,6 +68,70 @@ class ConversationListBuffer(BaseBuffer):
|
|||||||
return conversation[attr]
|
return conversation[attr]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _get_members_key(self, conversation):
|
||||||
|
"""Fallback key when convo id is missing: stable member DID list."""
|
||||||
|
members = getattr(conversation, "members", None) or (conversation.get("members") if isinstance(conversation, dict) else None) or []
|
||||||
|
dids = []
|
||||||
|
for m in members:
|
||||||
|
did = getattr(m, "did", None) or (m.get("did") if isinstance(m, dict) else None)
|
||||||
|
if did:
|
||||||
|
dids.append(did)
|
||||||
|
if not dids:
|
||||||
|
return None
|
||||||
|
dids.sort()
|
||||||
|
return tuple(dids)
|
||||||
|
|
||||||
|
def _get_last_message_key(self, conversation):
|
||||||
|
"""Key for detecting conversation updates based on last message."""
|
||||||
|
last_msg = getattr(conversation, "lastMessage", None) or (conversation.get("lastMessage") if isinstance(conversation, dict) else None)
|
||||||
|
if not last_msg:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def g(obj, key, default=None):
|
||||||
|
if isinstance(obj, dict):
|
||||||
|
return obj.get(key, default)
|
||||||
|
return getattr(obj, key, default)
|
||||||
|
|
||||||
|
for attr in ("id", "messageId", "message_id", "msgId", "msg_id"):
|
||||||
|
val = g(last_msg, attr)
|
||||||
|
if val:
|
||||||
|
return val
|
||||||
|
|
||||||
|
sent_at = g(last_msg, "sentAt") or g(last_msg, "sent_at")
|
||||||
|
sender = g(last_msg, "sender") or {}
|
||||||
|
sender_did = g(sender, "did")
|
||||||
|
text = g(last_msg, "text")
|
||||||
|
if sent_at or sender_did or text:
|
||||||
|
return (sent_at, sender_did, text)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_formatted_message(self):
|
||||||
|
"""Return last message text for current conversation."""
|
||||||
|
conversation = self.get_conversation()
|
||||||
|
if not conversation:
|
||||||
|
return None
|
||||||
|
return self.compose_function(
|
||||||
|
conversation,
|
||||||
|
self.session.db,
|
||||||
|
self.session.settings,
|
||||||
|
self.session.settings["general"].get("relative_times", False),
|
||||||
|
self.session.settings["general"].get("show_screen_names", False),
|
||||||
|
)[1]
|
||||||
|
|
||||||
|
def get_message(self):
|
||||||
|
"""Return a readable summary for the selected conversation."""
|
||||||
|
conversation = self.get_conversation()
|
||||||
|
if not conversation:
|
||||||
|
return None
|
||||||
|
composed = self.compose_function(
|
||||||
|
conversation,
|
||||||
|
self.session.db,
|
||||||
|
self.session.settings,
|
||||||
|
self.session.settings["general"].get("relative_times", False),
|
||||||
|
self.session.settings["general"].get("show_screen_names", False),
|
||||||
|
)
|
||||||
|
return " ".join(composed)
|
||||||
|
|
||||||
def on_new_chat(self, *args, **kwargs):
|
def on_new_chat(self, *args, **kwargs):
|
||||||
"""Start a new conversation by entering a handle."""
|
"""Start a new conversation by entering a handle."""
|
||||||
dlg = wx.TextEntryDialog(None, _("Enter the handle of the user (e.g., user.bsky.social):"), _("New Chat"))
|
dlg = wx.TextEntryDialog(None, _("Enter the handle of the user (e.g., user.bsky.social):"), _("New Chat"))
|
||||||
@@ -113,19 +177,80 @@ class ConversationListBuffer(BaseBuffer):
|
|||||||
call_threaded(do_create)
|
call_threaded(do_create)
|
||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
|
|
||||||
def start_stream(self, mandatory=False, play_sound=True):
|
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False):
|
||||||
count = self.get_max_items()
|
count = self.get_max_items()
|
||||||
try:
|
try:
|
||||||
res = self.session.list_convos(limit=count)
|
res = self.session.list_convos(limit=count)
|
||||||
items = res.get("items", [])
|
items = res.get("items", [])
|
||||||
self.session.db[self.name] = []
|
return self._merge_conversations(items, play_sound, avoid_autoreading=avoid_autoreading)
|
||||||
self.buffer.list.clear()
|
|
||||||
return self.process_items(items, play_sound)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
log.exception("Error fetching conversations")
|
log.exception("Error fetching conversations")
|
||||||
output.speak(_("Error loading conversations."), True)
|
output.speak(_("Error loading conversations."), True)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def _merge_conversations(self, items, play_sound=True, avoid_autoreading=False):
|
||||||
|
"""Merge conversation list, updating items without duplicating or re-alerting."""
|
||||||
|
if self.session.db.get(self.name) is None:
|
||||||
|
self.session.db[self.name] = []
|
||||||
|
|
||||||
|
# Track current selection to restore after refresh
|
||||||
|
selected_key = None
|
||||||
|
current_convo = self.get_conversation()
|
||||||
|
if current_convo:
|
||||||
|
selected_key = self.get_convo_id(current_convo) or self._get_members_key(current_convo)
|
||||||
|
|
||||||
|
existing = {}
|
||||||
|
existing_last = {}
|
||||||
|
for convo in self.session.db[self.name]:
|
||||||
|
key = self.get_convo_id(convo) or self._get_members_key(convo)
|
||||||
|
if key is None:
|
||||||
|
continue
|
||||||
|
existing[key] = convo
|
||||||
|
existing_last[key] = self._get_last_message_key(convo)
|
||||||
|
|
||||||
|
new_db = []
|
||||||
|
new_count = 0
|
||||||
|
for convo in items:
|
||||||
|
key = self.get_convo_id(convo) or self._get_members_key(convo)
|
||||||
|
new_db.append(convo)
|
||||||
|
if key is None:
|
||||||
|
new_count += 1
|
||||||
|
continue
|
||||||
|
if key not in existing:
|
||||||
|
new_count += 1
|
||||||
|
continue
|
||||||
|
if self._get_last_message_key(convo) != existing_last.get(key):
|
||||||
|
new_count += 1
|
||||||
|
|
||||||
|
# Replace DB with latest ordered list from API
|
||||||
|
self.session.db[self.name] = new_db
|
||||||
|
|
||||||
|
# Rebuild list UI to keep ordering consistent with API
|
||||||
|
self.buffer.list.clear()
|
||||||
|
safe = True
|
||||||
|
relative_times = self.session.settings["general"].get("relative_times", False)
|
||||||
|
show_screen_names = self.session.settings["general"].get("show_screen_names", False)
|
||||||
|
for convo in new_db:
|
||||||
|
row = self.compose_function(convo, self.session.db, self.session.settings, relative_times, show_screen_names, safe=safe)
|
||||||
|
self.buffer.list.insert_item(False, *row)
|
||||||
|
|
||||||
|
# Restore selection if possible
|
||||||
|
if selected_key is not None:
|
||||||
|
for idx, convo in enumerate(new_db):
|
||||||
|
key = self.get_convo_id(convo) or self._get_members_key(convo)
|
||||||
|
if key == selected_key:
|
||||||
|
self.buffer.list.select_item(idx)
|
||||||
|
break
|
||||||
|
|
||||||
|
# Sound and auto-read only when something actually changed
|
||||||
|
if new_count > 0:
|
||||||
|
if play_sound and self.sound and not self.session.settings["sound"].get("session_mute", False):
|
||||||
|
self.session.sound.play(self.sound)
|
||||||
|
if not avoid_autoreading:
|
||||||
|
self.auto_read(new_count)
|
||||||
|
|
||||||
|
return new_count
|
||||||
|
|
||||||
def fav(self):
|
def fav(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -246,8 +371,6 @@ class ChatBuffer(BaseBuffer):
|
|||||||
try:
|
try:
|
||||||
res = self.session.get_convo_messages(self.convo_id, limit=count)
|
res = self.session.get_convo_messages(self.convo_id, limit=count)
|
||||||
items = res.get("items", [])
|
items = res.get("items", [])
|
||||||
self.session.db[self.name] = []
|
|
||||||
self.buffer.list.clear()
|
|
||||||
items = list(reversed(items))
|
items = list(reversed(items))
|
||||||
return self.process_items(items, play_sound)
|
return self.process_items(items, play_sound)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
Reference in New Issue
Block a user