Files
vue-pult/docs/migration/gameport/GAMEPORT_OVERVIEW.md
2025-10-01 11:54:13 +03:00

6.2 KiB
Raw Permalink Blame History

Документация по переносу компонента GamePort (Общая структура порта игры)

Общая структура в React

  • Файл: client/src/components/GamePort.tsx
  • Тип: React.memo функциональный компонент с props (portNumber, onStartGame, movingGame/Player, onStartMovingGame/Player, onMoveGameTo/PlayerTo).
  • Зависимости: react-redux (useSelector/dispatch), hooks (useWebSocketNew, useAuth, useIsMobile, useDeviceType, useNotifications), icons (Io*, Fa*), components (Button, Card, Badge, BonusProgress, modals: ConfirmationModal, PlayerDeleteModal).
  • State: timer (string), showConfirmation (type, show), showDeleteModal (bool), isDragging (bool), dragType (string), forceDragEffect (bool), showTechConfirm (bool).
  • Template (JSX): Card relative w-full h-full (bg по статусу, border, cursor-pointer), absolute элементы (gun icon, timer, buttons), main div flex-col justify-center, modals (ConfirmationModal, PlayerDeleteModal, tech confirm).
  • Computed: isActive, hasPlayer, canHaveBonus, isPaused, highlight, isMovingDestination/Source, canDropHere, canManageGame/Player, canDragGame/Player, canCloseGame, isLockedForTechnic/Operator.
  • Effects: useEffect for timer (interval 1000 if active), drag events (start/end/over/enter/leave/drop), debug logs.

Элементы

  • Card: class "game-port-card" (bg-slate-700 idle, bg-gray-700 player, bg-blue/green/orange/cyan active), relative, draggable, onClick handlePortClick, onDrag* handlers.
    • Gun icon: absolute top-1 left-1, FaGun green (connected) or gray line-through + FaBan red (disconnected).
    • Timer: absolute top-1 left-8, div bg-black text-white rounded p-2 text-xs monospace.
    • Lock overlay: absolute inset-0 bg-slate-900/70 flex center FaLock (for restricted access).
    • Drag overlay: absolute inset-0 bg-green-500/30 flex center arrow-down text (if canDropHere).
  • Контент:
    • Number: div text-4xl font-bold {portNumber}.
    • Game name: div text-xs font-semibold {getGameName(port.game)} (e.g., "Пристрелка", "Игра 3").
    • Bonus: div text-xs "Бонусная".
    • Player: div text-xs "Игрок #{gamerId}".
    • Stats: div flex space-x-2, badges "🎯 {patrOk}", " {patrAdd}".
    • Patron controls: flex space-x-2, MinusButton/PlusButton (custom icons), div {patr} text-2xl, disabled if paused/0.
    • Buttons (absolute top-1 right-1 flex gap-2, z-10):
      • Move game: Button bg-gray-600 hover:bg-gray-700, IoSwapHorizontalOutline, title "Перенести игру", disabled paused, onClick handleStartMovingGame.
      • Cancel: Button bg-orange-600 hover:bg-orange-700, IoClose, title "Отменить игру", disabled paused, onClick handleCancelGame.
      • Delete player: Button bg-red-600 hover:bg-red-700, IoTrashOutline, title "Удалить", disabled paused, onClick handleRemovePlayer.
    • For empty port: "Свободен", "Нажмите для создания" green if smena open.
    • For player port: "Игрок", "Игр: {gameCounter}", pause badge if paused.
    • For active: game name, bonus, player, patron controls, stats.
  • Modals:
    • Tech confirm: fixed inset-0 bg-black/60 flex center, content bg-slate-800 p-8, h2 "Техническая пристрелка", buttons "Запустить пристрелку" green, "Отмена" gray.
    • ConfirmationModal: isOpen=showConfirmation.show, type (endGame/cancel/forceEnd), portNumber, onConfirm.
    • PlayerDeleteModal: isOpen=showDeleteModal, gamerId, portNumber, gameCounter, onConfirm.
  • Drag&Drop: draggable=true, data-port={portNumber}, classes (port-dragging, drag-over, can-drop), effects (scale, opacity).

Стили (Tailwind примеры)

  • Card: relative border-2 cursor-pointer w-full h-full min-h-[160px] mobile, [220px] desktop, flex flex-col justify-between, bg-slate-700 border-slate-600 (idle), bg-gray-700 (player), bg-blue-600 (game), bg-orange-600 (tech shot), bg-cyan-500 (shot), transition-all hover:border-white hover:shadow-xl.
  • Absolute buttons: top-1 right-1 flex gap-2 z-10, Button size="sm" variant="ghost" bg-gray-600 hover:bg-gray-700 rounded text-white.
  • Patron: flex justify-center space-x-2, Button size="sm" variant="ghost" rounded text-white hover:bg-opacity-60 text-xs.
  • Responsive: @media min-width 769px — min-h-[300px], desktop-port-card; mobile — min-h-[120px], game-port-card; tablet — game-port-card-tablet min-h-[180px].
  • Drag: .port-dragging opacity-50 scale-98, .drag-over ring-4 ring-green-400 bg-green-500/20 scale-101, .can-drop border-yellow-400 bg-yellow-600.
  • Animations: animate-pulse for highlight (ring-4 ring-*-400), grayscale opacity-50 for paused/locked.

Взаимодействие

  • onClick port: handlePortClick — check role/pause/smena/ESP, open modal or start game, drag if moving.
  • Buttons: handleStartMovingGame/Player (dispatch movingStarted), handlePatronChange (+/-1 via WebSocket 'addp'), handleStopGame/Cancel/ForceEnd (set showConfirmation), handleRemovePlayer (set showDeleteModal).
  • Drag: handleDragStart (set data, class dragging), handleDrop (send 'move'/'moveGamer' via WebSocket, animation with createFlyingPortAnimation), handleDragOver/Enter/Leave (preventDefault, set isDragOver).
  • Modals: Confirmation for end/cancel/forceEnd (onConfirm send 'endGame'/'cancelGame'/'forceEndGame'), PlayerDelete (send 'deleteGamer'), TechConfirm for tech shot (send 'start' game=2).
  • Effects: timer interval if active, drag end cancel moving, logs for debug.
  • In Dashboard: <GamePort v-for portNumber=1 to 6, :props, @start-game, @start-moving />.

Vue маппинг

  • : <Card :class="portClass" @click="handlePortClick" draggable="!paused && canDrag" @dragstart="handleDragStart" @drop="handleDrop" :data-port="portNumber"> absolute gun/timer/buttons, main div flex-col, v-if status elements, v-for badges.
  • Props: portNumber, onStartGame, movingGame/Player, onStartMovingGame/Player.
  • Emits: start-moving-game/player, move-game/player-to.
  • Composables: useGameStore (computed status), useWebSocket (sendMessage), useNotifications (show*), useAuth (role).
  • v-model for modals, @drag* handlers, style for bg/shadow based on computed.
  • Teleport for modals, v-if for lock overlay/drag overlay.