using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using SameBeat.Api.Hubs; using SameBeat.Application.Interfejsy; namespace SameBeat.Api.Controllers; /// /// Moderacja czatu przez hosta (ETAP 6). Trasa zaczyna sie od "api/host", wiec jest automatycznie /// chroniona [Authorize] przez KonwencjaAutoryzacjiHosta. Ban/wyciszenie dziala na UczestnikCzatu -- /// to CELOWO osobny mechanizm od bana w poczekalni (HostWaitingRoomController), patrz komentarz w /// UczestnikCzatu.Zbanuj. /// [ApiController] [Route("api/host/chat")] public class HostChatController : ControllerBase { private readonly ISerwisCzatu _serwisCzatu; private readonly IHubContext _hubKontekst; public HostChatController(ISerwisCzatu serwisCzatu, IHubContext hubKontekst) { _serwisCzatu = serwisCzatu; _hubKontekst = hubKontekst; } /// /// Historia z UczestnikCzatuId kazdego nadawcy -- host potrzebuje tego, zeby moc kliknac /// wycisz/odcisz/zbanuj przy konkretnej wiadomosci. Publiczny GET /api/chat/historia celowo /// tego pola nie ma (patrz WiadomoscCzatuDto). /// [HttpGet("historia")] public async Task PobierzHistorieAsync(CancellationToken token) { var wynik = await _serwisCzatu.PobierzHistorieDlaHostaAsync(token); if (!wynik.Sukces || wynik.Dane is null) { return BadRequest(new { blad = wynik.Blad }); } return Ok(wynik.Dane); } /// Soft-delete wiadomosci -- znika z widoku widzow, zostaje w bazie do moderacji/audytu. [HttpDelete("wiadomosc/{id:guid}")] public async Task UsunWiadomoscAsync(Guid id, CancellationToken token) { var wynik = await _serwisCzatu.UsunWiadomoscAsync(id, token); if (!wynik.Sukces) { return NotFound(new { blad = wynik.Blad }); } await _hubKontekst.Clients.All.SendAsync("ChatWiadomoscUsunieta", new { id }, cancellationToken: token); return Ok(new { sukces = true }); } [HttpPost("wycisz/{uczestnikCzatuId:guid}")] public async Task WyciszAsync(Guid uczestnikCzatuId, CancellationToken token) { var wynik = await _serwisCzatu.WyciszAsync(uczestnikCzatuId, token); if (!wynik.Sukces) { return NotFound(new { blad = wynik.Blad }); } return Ok(new { sukces = true }); } [HttpPost("odcisz/{uczestnikCzatuId:guid}")] public async Task OdciszAsync(Guid uczestnikCzatuId, CancellationToken token) { var wynik = await _serwisCzatu.OdciszAsync(uczestnikCzatuId, token); if (!wynik.Sukces) { return NotFound(new { blad = wynik.Blad }); } return Ok(new { sukces = true }); } /// Ban tozsamosci czatu -- NIE jest tym samym co ban w poczekalni z ETAPU 2 (patrz komentarz w UczestnikCzatu.Zbanuj). [HttpPost("zbanuj/{uczestnikCzatuId:guid}")] public async Task ZbanujAsync(Guid uczestnikCzatuId, CancellationToken token) { var wynik = await _serwisCzatu.ZbanujAsync(uczestnikCzatuId, token); if (!wynik.Sukces) { return NotFound(new { blad = wynik.Blad }); } return Ok(new { sukces = true }); } }