Add global mini-player and improve configuration

- Add global activeRoom store for persistent WebSocket connection
- Add MiniPlayer component for playback controls across pages
- Add chunked S3 streaming with 64KB chunks and Range support
- Add queue item removal button
- Move DB credentials to environment variables
- Update .env.example with DB configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-12 15:02:02 +03:00
parent 2f1e1f35e3
commit f77a453158
12 changed files with 572 additions and 119 deletions

View File

@@ -75,3 +75,40 @@ def get_file_content(s3_key: str) -> bytes:
client = get_s3_client()
response = client.get_object(Bucket=settings.s3_bucket_name, Key=s3_key)
return response["Body"].read()
def get_file_size(s3_key: str) -> int:
"""Get file size from S3 without downloading"""
client = get_s3_client()
response = client.head_object(Bucket=settings.s3_bucket_name, Key=s3_key)
return response["ContentLength"]
def get_file_range(s3_key: str, start: int, end: int):
"""Get a range of bytes from S3 file"""
client = get_s3_client()
response = client.get_object(
Bucket=settings.s3_bucket_name,
Key=s3_key,
Range=f"bytes={start}-{end}"
)
return response["Body"].read()
def stream_file_chunks(s3_key: str, start: int = 0, end: int = None, chunk_size: int = 64 * 1024):
"""Stream file from S3 in chunks (default 64KB chunks)"""
client = get_s3_client()
if end is None:
range_header = f"bytes={start}-"
else:
range_header = f"bytes={start}-{end}"
response = client.get_object(
Bucket=settings.s3_bucket_name,
Key=s3_key,
Range=range_header
)
for chunk in response["Body"].iter_chunks(chunk_size=chunk_size):
yield chunk