Tightly integrate WhatsApp selectors into existing UIs
This commit is contained in:
@@ -263,6 +263,18 @@ class WhatsAppChatsList(WhatsAppContactsList):
|
||||
|
||||
def get_queryset(self, *args, **kwargs):
|
||||
rows = []
|
||||
seen = set()
|
||||
state = transport.get_runtime_state("whatsapp")
|
||||
runtime_contacts = state.get("contacts") or []
|
||||
runtime_name_map = {}
|
||||
for item in runtime_contacts:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
identifier = str(item.get("identifier") or "").strip()
|
||||
if not identifier:
|
||||
continue
|
||||
runtime_name_map[identifier] = str(item.get("name") or "").strip()
|
||||
|
||||
sessions = (
|
||||
ChatSession.objects.filter(
|
||||
user=self.request.user,
|
||||
@@ -273,8 +285,9 @@ class WhatsAppChatsList(WhatsAppContactsList):
|
||||
)
|
||||
for session in sessions:
|
||||
identifier = str(session.identifier.identifier or "").strip()
|
||||
if not identifier:
|
||||
if not identifier or identifier in seen:
|
||||
continue
|
||||
seen.add(identifier)
|
||||
latest = (
|
||||
Message.objects.filter(user=self.request.user, session=session)
|
||||
.order_by("-ts")
|
||||
@@ -284,15 +297,17 @@ class WhatsAppChatsList(WhatsAppContactsList):
|
||||
preview = str((latest.text if latest else "") or "").strip()
|
||||
if len(preview) > 80:
|
||||
preview = f"{preview[:77]}..."
|
||||
display_name = (
|
||||
preview
|
||||
or runtime_name_map.get(identifier)
|
||||
or session.identifier.person.name
|
||||
or "WhatsApp Chat"
|
||||
)
|
||||
rows.append(
|
||||
{
|
||||
"identifier": identifier,
|
||||
"jid": identifier,
|
||||
"name": (
|
||||
preview
|
||||
or session.identifier.person.name
|
||||
or "WhatsApp Chat"
|
||||
),
|
||||
"name": display_name,
|
||||
"service_icon_class": _service_icon_class("whatsapp"),
|
||||
"person_name": session.identifier.person.name,
|
||||
"compose_page_url": urls["page_url"],
|
||||
@@ -304,6 +319,41 @@ class WhatsAppChatsList(WhatsAppContactsList):
|
||||
"last_ts": int(latest.ts or 0) if latest else 0,
|
||||
}
|
||||
)
|
||||
# Fallback: show synced WhatsApp contacts as chat entries even when no
|
||||
# local message history exists yet.
|
||||
for item in runtime_contacts:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
identifier = str(item.get("identifier") or item.get("jid") or "").strip()
|
||||
if not identifier:
|
||||
continue
|
||||
identifier = identifier.split("@", 1)[0].strip()
|
||||
if not identifier or identifier in seen:
|
||||
continue
|
||||
seen.add(identifier)
|
||||
linked = self._linked_identifier(identifier, str(item.get("jid") or ""))
|
||||
urls = _compose_urls(
|
||||
"whatsapp",
|
||||
identifier,
|
||||
linked.person_id if linked else None,
|
||||
)
|
||||
rows.append(
|
||||
{
|
||||
"identifier": identifier,
|
||||
"jid": str(item.get("jid") or identifier).strip(),
|
||||
"name": str(item.get("name") or "WhatsApp Chat").strip()
|
||||
or "WhatsApp Chat",
|
||||
"service_icon_class": _service_icon_class("whatsapp"),
|
||||
"person_name": linked.person.name if linked else "",
|
||||
"compose_page_url": urls["page_url"],
|
||||
"compose_widget_url": urls["widget_url"],
|
||||
"match_url": (
|
||||
f"{reverse('compose_contact_match')}?"
|
||||
f"{urlencode({'service': 'whatsapp', 'identifier': identifier})}"
|
||||
),
|
||||
"last_ts": 0,
|
||||
}
|
||||
)
|
||||
if rows:
|
||||
rows.sort(key=lambda row: row.get("last_ts", 0), reverse=True)
|
||||
return rows
|
||||
@@ -355,8 +405,16 @@ class WhatsAppAccountAdd(SuperUserRequiredMixin, ObjectRead):
|
||||
|
||||
qr_value = str(state.get("pair_qr") or "")
|
||||
contacts = state.get("contacts") or []
|
||||
history_imported = int(state.get("history_imported_messages") or 0)
|
||||
sqlite_imported = int(state.get("history_sqlite_imported") or 0)
|
||||
sqlite_scanned = int(state.get("history_sqlite_scanned") or 0)
|
||||
on_demand_requested = bool(state.get("history_on_demand_requested"))
|
||||
on_demand_error = str(state.get("history_on_demand_error") or "").strip() or "-"
|
||||
on_demand_anchor = str(state.get("history_on_demand_anchor") or "").strip() or "-"
|
||||
history_running = bool(state.get("history_sync_running"))
|
||||
return [
|
||||
f"connected={bool(state.get('connected'))}",
|
||||
f"runtime_updated={_age('updated_at')}",
|
||||
f"runtime_seen={_age('runtime_seen_at')}",
|
||||
f"pair_requested={_age('pair_requested_at')}",
|
||||
f"qr_received={_age('qr_received_at')}",
|
||||
@@ -370,6 +428,21 @@ class WhatsAppAccountAdd(SuperUserRequiredMixin, ObjectRead):
|
||||
f"contacts_count={len(contacts) if isinstance(contacts, list) else 0}",
|
||||
f"contacts_sync_count={state.get('contacts_sync_count') or 0}",
|
||||
f"contacts_synced={_age('contacts_synced_at')}",
|
||||
f"history_sync_running={history_running}",
|
||||
f"history_started={_age('history_sync_started_at')}",
|
||||
f"history_finished={_age('history_sync_finished_at')}",
|
||||
f"history_duration_ms={state.get('history_sync_duration_ms') or 0}",
|
||||
f"history_imported_messages={history_imported}",
|
||||
f"history_sqlite_imported={sqlite_imported}",
|
||||
f"history_sqlite_scanned={sqlite_scanned}",
|
||||
f"history_sqlite_rows={state.get('history_sqlite_rows') or 0}",
|
||||
f"history_sqlite_table={state.get('history_sqlite_table') or '-'}",
|
||||
f"history_sqlite_error={state.get('history_sqlite_error') or '-'}",
|
||||
f"history_sqlite_ts={_age('history_sqlite_ts')}",
|
||||
f"history_on_demand_requested={on_demand_requested}",
|
||||
f"history_on_demand_at={_age('history_on_demand_at')}",
|
||||
f"history_on_demand_anchor={on_demand_anchor}",
|
||||
f"history_on_demand_error={on_demand_error}",
|
||||
f"pair_qr_present={bool(qr_value)}",
|
||||
f"session_db={state.get('session_db') or '-'}",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user