Refactor desktop client codebase
This commit is contained in:
175
desktop-client/lobby_widget.py
Normal file
175
desktop-client/lobby_widget.py
Normal file
@@ -0,0 +1,175 @@
|
||||
import os
|
||||
from PyQt6.QtWidgets import (
|
||||
QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton,
|
||||
QFileDialog, QFrame
|
||||
)
|
||||
from PyQt6.QtCore import Qt, pyqtSignal
|
||||
|
||||
class LobbyWidget(QWidget):
|
||||
# Signals to communicate to VlcSyncApp
|
||||
create_requested = pyqtSignal(str, str, str, object) # username, path, filename, size
|
||||
join_requested = pyqtSignal(str, str) # username, room_code
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setAcceptDrops(True)
|
||||
|
||||
self.local_file_path = None
|
||||
self.local_file_name = None
|
||||
self.local_file_size = 0
|
||||
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
# Container for centering
|
||||
container = QFrame()
|
||||
container.setObjectName("lobbyCard")
|
||||
container.setFixedWidth(500)
|
||||
container_layout = QVBoxLayout(container)
|
||||
container_layout.setContentsMargins(30, 30, 30, 30)
|
||||
container_layout.setSpacing(15)
|
||||
|
||||
# Brand
|
||||
title = QLabel("VideoSync")
|
||||
title.setObjectName("brandTitle")
|
||||
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
tagline = QLabel("Watch together, anywhere")
|
||||
tagline.setObjectName("brandTagline")
|
||||
tagline.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
container_layout.addWidget(title)
|
||||
container_layout.addWidget(tagline)
|
||||
container_layout.addSpacing(20)
|
||||
|
||||
# Username
|
||||
self.username_input = QLineEdit()
|
||||
self.username_input.setPlaceholderText("Enter a display name")
|
||||
container_layout.addWidget(QLabel("YOUR NAME"))
|
||||
container_layout.addWidget(self.username_input)
|
||||
|
||||
container_layout.addSpacing(20)
|
||||
|
||||
# Actions Layout (Create vs Join)
|
||||
actions_layout = QHBoxLayout()
|
||||
actions_layout.setSpacing(20)
|
||||
|
||||
# Create Room Panel
|
||||
create_panel = QVBoxLayout()
|
||||
create_panel.addWidget(QLabel("Create a Room"))
|
||||
self.create_file_btn = QPushButton("Choose Video File")
|
||||
self.create_file_btn.setObjectName("secondaryBtn")
|
||||
self.create_file_btn.clicked.connect(self.select_file)
|
||||
|
||||
self.create_file_info = QLabel("")
|
||||
self.create_file_info.setObjectName("fileInfo")
|
||||
self.create_file_info.setWordWrap(True)
|
||||
self.create_file_info.hide()
|
||||
|
||||
self.create_room_btn = QPushButton("Create Room")
|
||||
self.create_room_btn.setObjectName("primaryBtn")
|
||||
self.create_room_btn.setEnabled(False)
|
||||
self.create_room_btn.clicked.connect(self.create_room)
|
||||
|
||||
create_panel.addWidget(self.create_file_btn)
|
||||
create_panel.addWidget(self.create_file_info)
|
||||
create_panel.addWidget(self.create_room_btn)
|
||||
|
||||
# Join Room Panel
|
||||
join_panel = QVBoxLayout()
|
||||
join_panel.addWidget(QLabel("Join a Room"))
|
||||
self.room_code_input = QLineEdit()
|
||||
self.room_code_input.setPlaceholderText("e.g. ABC123")
|
||||
self.join_room_btn = QPushButton("Join Room")
|
||||
self.join_room_btn.setObjectName("secondaryBtn")
|
||||
self.join_room_btn.setEnabled(False)
|
||||
self.join_room_btn.clicked.connect(self.join_room)
|
||||
|
||||
join_panel.addWidget(self.room_code_input)
|
||||
join_panel.addWidget(self.join_room_btn)
|
||||
|
||||
actions_layout.addLayout(create_panel)
|
||||
|
||||
# Divider
|
||||
divider = QLabel("OR")
|
||||
divider.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
divider.setObjectName("divider")
|
||||
actions_layout.addWidget(divider)
|
||||
|
||||
actions_layout.addLayout(join_panel)
|
||||
|
||||
container_layout.addLayout(actions_layout)
|
||||
layout.addWidget(container)
|
||||
|
||||
# Signals to enable/disable buttons
|
||||
self.username_input.textChanged.connect(self.check_inputs)
|
||||
self.room_code_input.textChanged.connect(self.check_inputs)
|
||||
|
||||
def _set_local_file(self, file_path: str):
|
||||
self.local_file_path = file_path
|
||||
self.local_file_name = os.path.basename(file_path)
|
||||
self.local_file_size = os.path.getsize(file_path)
|
||||
|
||||
size_mb = self.local_file_size / (1024 * 1024)
|
||||
self.create_file_info.setText(f"{self.local_file_name}\n{size_mb:.1f} MB")
|
||||
self.create_file_info.show()
|
||||
self.check_inputs()
|
||||
|
||||
def select_file(self):
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
self, "Select Video File", "", "Video Files (*.mp4 *.mkv *.avi *.mov *.webm);;All Files (*)"
|
||||
)
|
||||
if file_path:
|
||||
self._set_local_file(file_path)
|
||||
|
||||
def dragEnterEvent(self, event):
|
||||
if event.mimeData().hasUrls():
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def dropEvent(self, event):
|
||||
for url in event.mimeData().urls():
|
||||
file_path = url.toLocalFile()
|
||||
if os.path.isfile(file_path):
|
||||
ext = os.path.splitext(file_path)[1].lower()
|
||||
if ext in ['.mp4', '.mkv', '.avi', '.mov', '.webm']:
|
||||
self._set_local_file(file_path)
|
||||
break
|
||||
|
||||
def check_inputs(self):
|
||||
has_name = len(self.username_input.text().strip()) > 0
|
||||
has_file = self.local_file_path is not None
|
||||
has_code = len(self.room_code_input.text().strip()) >= 4
|
||||
|
||||
self.create_room_btn.setEnabled(has_name and has_file)
|
||||
self.join_room_btn.setEnabled(has_name and has_code)
|
||||
|
||||
def create_room(self):
|
||||
username = self.username_input.text().strip()
|
||||
self.create_room_btn.setText("Connecting...")
|
||||
self.create_room_btn.setEnabled(False)
|
||||
self.join_room_btn.setEnabled(False)
|
||||
self.create_requested.emit(username, self.local_file_path, self.local_file_name, self.local_file_size)
|
||||
|
||||
def join_room(self):
|
||||
username = self.username_input.text().strip()
|
||||
room_code = self.room_code_input.text().strip().upper()
|
||||
self.join_room_btn.setText("Connecting...")
|
||||
self.join_room_btn.setEnabled(False)
|
||||
self.create_room_btn.setEnabled(False)
|
||||
self.join_requested.emit(username, room_code)
|
||||
|
||||
def reset_ui(self):
|
||||
self.create_room_btn.setText("Create Room")
|
||||
self.join_room_btn.setText("Join Room")
|
||||
self.check_inputs()
|
||||
|
||||
def clear_file(self):
|
||||
self.local_file_path = None
|
||||
self.local_file_name = None
|
||||
self.local_file_size = 0
|
||||
self.create_file_info.hide()
|
||||
self.check_inputs()
|
||||
Reference in New Issue
Block a user