using System.Collections.Generic;
using System.Threading.Tasks;
using Kavita.API.Attributes;
using Kavita.API.Database;
using Kavita.API.Services;
using Kavita.Models.Constants;
using Kavita.Models.DTOs.Dashboard;
using Kavita.Models.DTOs.SideNav;
using Kavita.Server.Attributes;
using Microsoft.AspNetCore.Mvc;
namespace Kavita.Server.Controllers;
///
/// Responsible for anything that deals with Streams (SmartFilters, ExternalSource, DashboardStream, SideNavStream)
///
public class StreamController(
IStreamService streamService,
IUnitOfWork unitOfWork)
: BaseApiController
{
///
/// Returns the layout of the user's dashboard
///
///
[HttpGet("dashboard")]
public async Task>> GetDashboardLayout(bool visibleOnly = true)
{
return Ok(await streamService.GetDashboardStreams(UserId, visibleOnly));
}
///
/// Return's the user's side nav
///
[HttpGet("sidenav")]
public async Task>> GetSideNav(bool visibleOnly = true)
{
return Ok(await streamService.GetSidenavStreams(UserId, visibleOnly));
}
///
/// Return's the user's external sources
///
[HttpGet("external-sources")]
public async Task>> GetExternalSources()
{
return Ok(await streamService.GetExternalSources(UserId));
}
///
/// Create an external Source
///
///
///
[HttpPost("create-external-source")]
public async Task> CreateExternalSource(ExternalSourceDto dto)
{
// Check if a host and api key exists for the current user
return Ok(await streamService.CreateExternalSource(UserId, dto));
}
///
/// Updates an existing external source
///
///
///
[HttpPost("update-external-source")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task> UpdateExternalSource(ExternalSourceDto dto)
{
// Check if a host and api key exists for the current user
return Ok(await streamService.UpdateExternalSource(UserId, dto));
}
///
/// Validates the external source by host is unique (for this user)
///
///
///
[HttpPost("external-source-exists")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task> ExternalSourceExists(ExternalSourceDto dto)
{
return Ok(await unitOfWork.AppUserExternalSourceRepository.ExternalSourceExists(UserId, dto.Name, dto.Host, dto.ApiKey));
}
///
/// Delete's the external source
///
///
///
[HttpDelete("delete-external-source")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task ExternalSourceExists(int externalSourceId)
{
await streamService.DeleteExternalSource(UserId, externalSourceId);
return Ok();
}
///
/// Creates a Dashboard Stream from a SmartFilter and adds it to the user's dashboard as visible
///
///
///
[HttpPost("add-dashboard-stream")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task> AddDashboard([FromQuery] int smartFilterId)
{
return Ok(await streamService.CreateDashboardStreamFromSmartFilter(UserId, smartFilterId));
}
///
/// Updates the visibility of a dashboard stream
///
///
///
[HttpPost("update-dashboard-stream")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task UpdateDashboardStream(DashboardStreamDto dto)
{
await streamService.UpdateDashboardStream(UserId, dto);
return Ok();
}
///
/// Updates the position of a dashboard stream
///
///
///
[HttpPost("update-dashboard-position")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task UpdateDashboardStreamPosition(UpdateStreamPositionDto dto)
{
await streamService.UpdateDashboardStreamPosition(UserId, dto);
return Ok();
}
///
/// Creates a SideNav Stream from a SmartFilter and adds it to the user's sidenav as visible
///
///
///
[HttpPost("add-sidenav-stream")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task> AddSideNav([FromQuery] int smartFilterId)
{
return Ok(await streamService.CreateSideNavStreamFromSmartFilter(UserId, smartFilterId));
}
///
/// Creates a SideNav Stream from a SmartFilter and adds it to the user's sidenav as visible
///
///
///
[HttpPost("add-sidenav-stream-from-external-source")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task> AddSideNavFromExternalSource([FromQuery] int externalSourceId)
{
return Ok(await streamService.CreateSideNavStreamFromExternalSource(UserId, externalSourceId));
}
///
/// Updates the visibility of a dashboard stream
///
///
///
[HttpPost("update-sidenav-stream")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task UpdateSideNavStream(SideNavStreamDto dto)
{
await streamService.UpdateSideNavStream(UserId, dto);
return Ok();
}
///
/// Updates the position of a dashboard stream
///
///
///
[HttpPost("update-sidenav-position")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task UpdateSideNavStreamPosition(UpdateStreamPositionDto dto)
{
await streamService.UpdateSideNavStreamPosition(UserId, dto);
return Ok();
}
[HttpPost("bulk-sidenav-stream-visibility")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task BulkUpdateSideNavStream(BulkUpdateSideNavStreamVisibilityDto dto)
{
await streamService.UpdateSideNavStreamBulk(UserId, dto);
return Ok();
}
///
/// Removes a Smart Filter from a user's SideNav Streams
///
///
///
[HttpDelete("smart-filter-side-nav-stream")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task DeleteSmartFilterSideNavStream([FromQuery] int sideNavStreamId)
{
await streamService.DeleteSideNavSmartFilterStream(UserId, sideNavStreamId);
return Ok();
}
///
/// Removes a Smart Filter from a user's Dashboard Streams
///
///
///
[HttpDelete("smart-filter-dashboard-stream")]
[DisallowRole(PolicyConstants.ReadOnlyRole)]
public async Task DeleteSmartFilterDashboardStream([FromQuery] int dashboardStreamId)
{
await streamService.DeleteDashboardSmartFilterStream(UserId, dashboardStreamId);
return Ok();
}
}