using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using SameBeat.Api.Hubs; using SameBeat.Application.DTO; using SameBeat.Application.Interfejsy; using SameBeat.Application.Komendy; namespace SameBeat.Api.Controllers; /// /// Czat na zywo (ETAP 6) -- dostepny dla kazdego widza, nie tylko uczestnikow na scenie. Wszystkie /// endpointy sa [AllowAnonymous]: widz nie ma konta ani wpisu w poczekalni, tylko lekka tozsamosc /// czatu (UczestnikCzatu) zalozona przez POST /api/chat/dolacz. /// [ApiController] [Route("api/chat")] public class ChatController : ControllerBase { private readonly ISerwisCzatu _serwisCzatu; private readonly IHubContext _hubKontekst; public ChatController(ISerwisCzatu serwisCzatu, IHubContext hubKontekst) { _serwisCzatu = serwisCzatu; _hubKontekst = hubKontekst; } /// Zaklada nowa tozsamosc czatu dla biezacego wydarzenia. Bez sekretu sesji -- czat nie daje praw do audio/wideo. [HttpPost("dolacz")] [AllowAnonymous] public async Task DolaczAsync([FromBody] DolaczDoCzatuKomenda komenda, CancellationToken token) { var wynik = await _serwisCzatu.DolaczAsync(komenda, token); if (!wynik.Sukces || wynik.Dane is null) { return BadRequest(new { blad = wynik.Blad }); } return Ok(wynik.Dane); } /// Wysyla wiadomosc i rozglasza ja przez SignalR do wszystkich klientow. Odrzuca ban/wyciszenie/zbyt szybkie pisanie. [HttpPost("wiadomosc")] [AllowAnonymous] public async Task WyslijWiadomoscAsync([FromBody] WyslijWiadomoscKomenda komenda, CancellationToken token) { var wynik = await _serwisCzatu.WyslijWiadomoscAsync(komenda, token); if (!wynik.Sukces || wynik.Dane is null) { return BadRequest(new { blad = wynik.Blad }); } var pelnaWiadomosc = wynik.Dane; // Publiczny broadcast (wszyscy, rowniez anonimowi widzowie) -- CELOWO bez UczestnikCzatuId, // patrz komentarz w WiadomoscCzatuDto. Host dostaje ten sam JSON PLUS UczestnikCzatuId przez // osobny broadcast tylko do grupy "host" -- bez tego przyciski moderacji (wycisz/zbanuj) nie // mialyby jak wskazac nadawcy. var publicznaWiadomosc = new WiadomoscCzatuDto(pelnaWiadomosc.Id, pelnaWiadomosc.Nick, pelnaWiadomosc.Tresc, pelnaWiadomosc.WyslanoUtc); await _hubKontekst.Clients.All.SendAsync("ChatNowaWiadomosc", publicznaWiadomosc, cancellationToken: token); await _hubKontekst.Clients.Group(StanImprezyHub.GrupaHost).SendAsync("ChatNowaWiadomoscHost", pelnaWiadomosc, cancellationToken: token); return Ok(pelnaWiadomosc); } /// Ostatnie wiadomosci NIE usuniete dla biezacego wydarzenia -- do zaladowania historii zaraz po wejsciu na /party. [HttpGet("historia")] [AllowAnonymous] public async Task PobierzHistorieAsync(CancellationToken token) { var wynik = await _serwisCzatu.PobierzHistorieAsync(token); if (!wynik.Sukces || wynik.Dane is null) { return BadRequest(new { blad = wynik.Blad }); } return Ok(wynik.Dane); } }