mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-23 03:25:07 +03:00
Implement legal terms, Android client compatibility and more
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
"""In-memory user presence derived from WebSocket connections only."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from fastapi import WebSocket
|
||||
|
||||
|
||||
class PresenceService:
|
||||
def __init__(self) -> None:
|
||||
self._connections: dict[int, set[WebSocket]] = {}
|
||||
self._last_seen: dict[int, datetime] = {}
|
||||
|
||||
def register_connection(self, user_id: int, websocket: WebSocket) -> bool:
|
||||
"""Track a live connection. Returns True if the user became online."""
|
||||
connections = self._connections.setdefault(user_id, set())
|
||||
was_online = bool(connections)
|
||||
connections.add(websocket)
|
||||
return not was_online
|
||||
|
||||
def unregister_connection(self, user_id: int, websocket: WebSocket) -> tuple[bool, datetime | None]:
|
||||
"""Remove a connection. Returns (became_offline, last_seen) when the last conn drops."""
|
||||
connections = self._connections.get(user_id)
|
||||
if not connections:
|
||||
return False, self._last_seen.get(user_id)
|
||||
|
||||
connections.discard(websocket)
|
||||
if connections:
|
||||
return False, None
|
||||
|
||||
del self._connections[user_id]
|
||||
last_seen = datetime.now()
|
||||
self._last_seen[user_id] = last_seen
|
||||
return True, last_seen
|
||||
|
||||
def touch(self, user_id: int) -> None:
|
||||
"""Refresh activity timestamp while online."""
|
||||
if self.is_online(user_id):
|
||||
self._last_seen[user_id] = datetime.now()
|
||||
|
||||
def is_online(self, user_id: int) -> bool:
|
||||
connections = self._connections.get(user_id)
|
||||
return bool(connections)
|
||||
|
||||
def get_last_seen(self, user_id: int) -> datetime | None:
|
||||
if self.is_online(user_id):
|
||||
return self._last_seen.get(user_id) or datetime.now()
|
||||
return self._last_seen.get(user_id)
|
||||
|
||||
def get_presence(self, user_id: int) -> tuple[bool, datetime | None]:
|
||||
online = self.is_online(user_id)
|
||||
if online:
|
||||
return True, self.get_last_seen(user_id)
|
||||
last_seen = self._last_seen.get(user_id)
|
||||
return False, last_seen
|
||||
|
||||
def remove_user(self, user_id: int) -> None:
|
||||
"""Drop all presence state for a deleted user."""
|
||||
self._connections.pop(user_id, None)
|
||||
self._last_seen.pop(user_id, None)
|
||||
|
||||
|
||||
presence_service = PresenceService()
|
||||
Reference in New Issue
Block a user