This repository has been archived on 2026-05-04. You can view files and clone it, but cannot push or open issues or pull requests.
Galaxy-Strike-Online/client/src/components/Console/Console.jsx
2026-03-29 10:28:07 +03:00

140 lines
3.8 KiB
JavaScript

import React, { useState, useEffect, useRef } from "react";
import "./Console.css";
import { useSocket } from "../../hooks/useSocket";
import ConsoleManager from "../../services/ConsoleManager";
import PlayerManager from "../../services/PlayerManager"; // Імпортуємо менеджер гравців
const Console = () => {
const { socket } = useSocket();
const [isOpen, setIsOpen] = useState(false);
const [input, setInput] = useState("");
const [suggestions, setSuggestions] = useState([]);
const [selectedIndex, setSelectedIndex] = useState(0);
const [logs, setLogs] = useState(ConsoleManager.logs);
const [playerNames, setPlayerNames] = useState([]);
const inputRef = useRef(null);
const scrollRef = useRef(null);
useEffect(() => {
ConsoleManager.init(socket, setLogs);
}, [socket]);
useEffect(() => {
const updatePlayers = (data) => {
setPlayerNames([...data.online, ...data.offline]);
};
const unsubscribe = PlayerManager.subscribe(updatePlayers);
setPlayerNames([
...PlayerManager.onlinePlayers,
...PlayerManager.offlinePlayers,
]);
return () => unsubscribe();
}, []);
useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
}
}, [logs]);
useEffect(() => {
const handleGlobalKeyDown = (e) => {
if (e.key === "F9") {
e.preventDefault();
setIsOpen((prev) => !prev);
}
};
window.addEventListener("keydown", handleGlobalKeyDown);
return () => window.removeEventListener("keydown", handleGlobalKeyDown);
}, []);
useEffect(() => {
setSuggestions(ConsoleManager.getSuggestions(input, playerNames));
setSelectedIndex(0);
}, [input, playerNames]);
const handleKeyDown = (e) => {
if (e.key === "Tab" && suggestions.length > 0) {
e.preventDefault();
const parts = input.split(" ");
parts[parts.length - 1] = suggestions[selectedIndex];
setInput(parts.join(" ") + (parts.length < 3 ? " " : ""));
}
if (e.key === "ArrowDown") {
if (suggestions.length > 0) {
setSelectedIndex((prev) => (prev + 1) % suggestions.length);
} else {
const hist = ConsoleManager.getHistory("down");
if (hist !== null) setInput(hist);
}
}
if (e.key === "ArrowUp") {
if (suggestions.length > 0) {
setSelectedIndex(
(prev) => (prev - 1 + suggestions.length) % suggestions.length,
);
} else {
const hist = ConsoleManager.getHistory("up");
if (hist !== null) setInput(hist);
}
}
if (e.key === "Escape") setIsOpen(false);
};
const handleSubmit = (e) => {
e.preventDefault();
if (!input.trim()) return;
ConsoleManager.execute(input);
setInput("");
};
if (!isOpen) return null;
return (
<div className="game-console-bottom">
<div className="console-scroll-area" ref={scrollRef}>
{logs.map((line, i) => (
<div key={i} className="console-line">
{line}
</div>
))}
</div>
{suggestions.length > 0 && (
<div className="console-suggestions-upward">
{suggestions.map((s, i) => (
<div
key={i}
className={`suggestion-item ${i === selectedIndex ? "selected" : ""}`}
>
{s}
</div>
))}
</div>
)}
<form className="console-input-form" onSubmit={handleSubmit}>
<span className="console-prompt">#</span>
<input
ref={inputRef}
autoFocus
value={input}
onKeyDown={handleKeyDown}
onChange={(e) => setInput(e.target.value)}
placeholder="Type /command..."
/>
</form>
</div>
);
};
export default Console;