from utils import format_time_short HELP_TEXT = """ Available Commands:
/play, /pause - Control playback
/seek [time] - Seek (e.g., 1:23, +30s, -1m)
/tag [now|time] [name] - Create a highlight
/time - Show current timestamp
/help - Show this message

Keyboard Shortcuts:
Space: Play/Pause
F: Fullscreen | M: Mute
Left/Right: Seek ±5s
Up/Down: Volume ±5%
Enter: Focus chat | Esc: Clear focus """ def parse_time_arg(arg: str, current_ms: int, length_ms: int): """Parses a time string (absolute time, offset like +30s, or 'now') and returns the target time in MS. Returns None on error.""" if arg == "now": return current_ms try: target_ms = 0 if arg.startswith('+') or arg.startswith('-'): modifier = 1 if arg.startswith('+') else -1 num_str = arg[1:] if num_str.endswith('s'): val = float(num_str[:-1]) * 1000 elif num_str.endswith('m'): val = float(num_str[:-1]) * 60 * 1000 elif num_str.endswith('h'): val = float(num_str[:-1]) * 3600 * 1000 else: val = float(num_str) * 1000 target_ms = current_ms + (val * modifier) elif ":" in arg: parts = arg.split(":") parts.reverse() if len(parts) > 0: target_ms += float(parts[0]) * 1000 if len(parts) > 1: target_ms += float(parts[1]) * 60 * 1000 if len(parts) > 2: target_ms += float(parts[2]) * 3600 * 1000 else: if arg.endswith('s'): target_ms = float(arg[:-1]) * 1000 elif arg.endswith('m'): target_ms = float(arg[:-1]) * 60 * 1000 elif arg.endswith('h'): target_ms = float(arg[:-1]) * 3600 * 1000 else: target_ms = float(arg) * 1000 if length_ms > 0: return max(0, min(target_ms, length_ms)) return max(0, target_ms) except ValueError: return None def handle_chat_command(cmd: str, parts: list, widget): """Handle a slash command. Returns True if the command was handled.""" if cmd == "/play": if not widget.vlc_player.is_playing: widget.toggle_playback() widget.add_system_message(" ".join(parts)) return True elif cmd == "/pause": if widget.vlc_player.is_playing: widget.toggle_playback() widget.add_system_message(" ".join(parts)) return True elif cmd == "/seek": if len(parts) > 1: if widget._handle_seek_command(parts[1]): widget.add_system_message(" ".join(parts)) else: widget.add_system_message("Invalid time format. Use: 1:23, +30s, -1m") else: widget.add_system_message("Usage: /seek [time]") return True elif cmd == "/tag": if len(parts) > 1: time_arg = parts[1].lower() tag_name = " ".join(parts[2:]) current_ms = widget.vlc_player.current_time_ms length_ms = widget.vlc_player.get_length() target_ms = parse_time_arg(time_arg, current_ms, length_ms) if target_ms is not None: time_str = format_time_short(target_ms) msg = f"{time_str} {tag_name}".strip() widget.chat_message_ready.emit(msg) else: widget.add_system_message("Invalid time format. Use: now, 1:23, +30s, -1m") else: widget.add_system_message("Usage: /tag [now|time] [name]") return True elif cmd == "/time": current_ms = widget.vlc_player.current_time_ms time_str = format_time_short(current_ms) widget.add_system_message(f"Current time: {time_str}") return True elif cmd == "/help": widget.add_system_message(HELP_TEXT) return True return False