Add contact blocking

This commit is contained in:
Jack Kingsman
2026-03-04 18:54:21 -08:00
parent 145609faf9
commit d5fe9c677f
18 changed files with 693 additions and 48 deletions
+11 -1
View File
@@ -14,7 +14,7 @@ from app.models import (
SendDirectMessageRequest,
)
from app.radio import radio_manager
from app.repository import AmbiguousPublicKeyPrefixError, MessageRepository
from app.repository import AmbiguousPublicKeyPrefixError, AppSettingsRepository, MessageRepository
from app.websocket import broadcast_event
logger = logging.getLogger(__name__)
@@ -29,11 +29,16 @@ async def get_messages_around(
context: int = Query(default=100, ge=1, le=500, description="Number of messages before/after"),
) -> MessagesAroundResponse:
"""Get messages around a specific message for jump-to-message navigation."""
settings = await AppSettingsRepository.get()
blocked_keys = settings.blocked_keys or None
blocked_names = settings.blocked_names or None
messages, has_older, has_newer = await MessageRepository.get_around(
message_id=message_id,
msg_type=type,
conversation_key=conversation_key,
context_size=context,
blocked_keys=blocked_keys,
blocked_names=blocked_names,
)
return MessagesAroundResponse(messages=messages, has_older=has_older, has_newer=has_newer)
@@ -59,6 +64,9 @@ async def list_messages(
q: str | None = Query(default=None, description="Full-text search query"),
) -> list[Message]:
"""List messages from the database."""
settings = await AppSettingsRepository.get()
blocked_keys = settings.blocked_keys or None
blocked_names = settings.blocked_names or None
return await MessageRepository.get_all(
limit=limit,
offset=offset,
@@ -69,6 +77,8 @@ async def list_messages(
after=after,
after_id=after_id,
q=q,
blocked_keys=blocked_keys,
blocked_names=blocked_names,
)
+36
View File
@@ -125,6 +125,22 @@ class AppSettingsUpdate(BaseModel):
default=None,
description="Outbound flood scope / region name (empty = disabled)",
)
blocked_keys: list[str] | None = Field(
default=None,
description="Public keys whose messages are hidden from the UI",
)
blocked_names: list[str] | None = Field(
default=None,
description="Display names whose messages are hidden from the UI",
)
class BlockKeyRequest(BaseModel):
key: str = Field(description="Public key to toggle block status")
class BlockNameRequest(BaseModel):
name: str = Field(description="Display name to toggle block status")
class FavoriteRequest(BaseModel):
@@ -241,6 +257,12 @@ async def update_settings(update: AppSettingsUpdate) -> AppSettings:
kwargs["community_mqtt_email"] = update.community_mqtt_email
community_mqtt_changed = True
# Block lists
if update.blocked_keys is not None:
kwargs["blocked_keys"] = [k.lower() for k in update.blocked_keys]
if update.blocked_names is not None:
kwargs["blocked_names"] = update.blocked_names
# Flood scope
flood_scope_changed = False
if update.flood_scope is not None:
@@ -317,6 +339,20 @@ async def toggle_favorite(request: FavoriteRequest) -> AppSettings:
return result
@router.post("/blocked-keys/toggle", response_model=AppSettings)
async def toggle_blocked_key(request: BlockKeyRequest) -> AppSettings:
"""Toggle a public key's blocked status."""
logger.info("Toggling blocked key: %s", request.key[:12])
return await AppSettingsRepository.toggle_blocked_key(request.key)
@router.post("/blocked-names/toggle", response_model=AppSettings)
async def toggle_blocked_name(request: BlockNameRequest) -> AppSettings:
"""Toggle a display name's blocked status."""
logger.info("Toggling blocked name: %s", request.name)
return await AppSettingsRepository.toggle_blocked_name(request.name)
@router.post("/migrate", response_model=MigratePreferencesResponse)
async def migrate_preferences(request: MigratePreferencesRequest) -> MigratePreferencesResponse:
"""Migrate all preferences from frontend localStorage to database.