|  | @@ -1,68 +1,65 @@
 | 
	
		
			
				|  |  |  using System;
 | 
	
		
			
				|  |  |  using System.Collections.Generic;
 | 
	
		
			
				|  |  |  using System.Linq;
 | 
	
		
			
				|  |  | +using System.Threading;
 | 
	
		
			
				|  |  | +using System.Threading.Tasks;
 | 
	
		
			
				|  |  |  using Jellyfin.Data.Enums;
 | 
	
		
			
				|  |  |  using MediaBrowser.Controller.Drawing;
 | 
	
		
			
				|  |  |  using MediaBrowser.Controller.Dto;
 | 
	
		
			
				|  |  |  using MediaBrowser.Controller.Entities;
 | 
	
		
			
				|  |  | +using MediaBrowser.Controller.Library;
 | 
	
		
			
				|  |  |  using MediaBrowser.Controller.Persistence;
 | 
	
		
			
				|  |  |  using MediaBrowser.Model.Entities;
 | 
	
		
			
				|  |  |  using MediaBrowser.Model.Querying;
 | 
	
		
			
				|  |  |  using Microsoft.Extensions.Logging;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -namespace Jellyfin.Drawing.Skia;
 | 
	
		
			
				|  |  | +namespace Emby.Server.Implementations.Library;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /// <summary>
 | 
	
		
			
				|  |  | -/// The default image generator.
 | 
	
		
			
				|  |  | +/// The splashscreen post scan task.
 | 
	
		
			
				|  |  |  /// </summary>
 | 
	
		
			
				|  |  | -public class DefaultImageGenerator : IImageGenerator
 | 
	
		
			
				|  |  | +public class SplashscreenPostScanTask : ILibraryPostScanTask
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    private readonly IImageEncoder _imageEncoder;
 | 
	
		
			
				|  |  |      private readonly IItemRepository _itemRepository;
 | 
	
		
			
				|  |  | -    private readonly ILogger _logger;
 | 
	
		
			
				|  |  | +    private readonly IImageEncoder _imageEncoder;
 | 
	
		
			
				|  |  | +    private readonly ILogger<SplashscreenPostScanTask> _logger;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// <summary>
 | 
	
		
			
				|  |  | -    /// Initializes a new instance of the <see cref="DefaultImageGenerator"/> class.
 | 
	
		
			
				|  |  | +    /// Initializes a new instance of the <see cref="SplashscreenPostScanTask"/> class.
 | 
	
		
			
				|  |  |      /// </summary>
 | 
	
		
			
				|  |  | -    /// <param name="imageEncoder">Instance of the <see cref="IImageEncoder"/> interface.</param>
 | 
	
		
			
				|  |  |      /// <param name="itemRepository">Instance of the <see cref="IItemRepository"/> interface.</param>
 | 
	
		
			
				|  |  | -    /// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
 | 
	
		
			
				|  |  | -    public DefaultImageGenerator(
 | 
	
		
			
				|  |  | -        IImageEncoder imageEncoder,
 | 
	
		
			
				|  |  | +    /// <param name="imageEncoder">Instance of the <see cref="IImageEncoder"/> interface.</param>
 | 
	
		
			
				|  |  | +    /// <param name="logger">Instance of the <see cref="ILogger{SplashscreenPostScanTask"/> interface.</param>
 | 
	
		
			
				|  |  | +    public SplashscreenPostScanTask(
 | 
	
		
			
				|  |  |          IItemRepository itemRepository,
 | 
	
		
			
				|  |  | -        ILogger<DefaultImageGenerator> logger)
 | 
	
		
			
				|  |  | +        IImageEncoder imageEncoder,
 | 
	
		
			
				|  |  | +        ILogger<SplashscreenPostScanTask> logger)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        _imageEncoder = imageEncoder;
 | 
	
		
			
				|  |  |          _itemRepository = itemRepository;
 | 
	
		
			
				|  |  | +        _imageEncoder = imageEncoder;
 | 
	
		
			
				|  |  |          _logger = logger;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /// <inheritdoc/>
 | 
	
		
			
				|  |  | -    public IReadOnlyList<GeneratedImageType> GetSupportedImages()
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        return new[] { GeneratedImageType.Splashscreen };
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /// <inheritdoc/>
 | 
	
		
			
				|  |  | -    public void Generate(GeneratedImageType imageTypeType, string outputPath)
 | 
	
		
			
				|  |  | +    /// <inheritdoc />
 | 
	
		
			
				|  |  | +    public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          var posters = GetItemsWithImageType(ImageType.Primary).Select(x => x.GetImages(ImageType.Primary).First().Path).ToList();
 | 
	
		
			
				|  |  | -        var landscape = GetItemsWithImageType(ImageType.Thumb).Select(x => x.GetImages(ImageType.Thumb).First().Path).ToList();
 | 
	
		
			
				|  |  | -        if (landscape.Count == 0)
 | 
	
		
			
				|  |  | +        var backdrops = GetItemsWithImageType(ImageType.Thumb).Select(x => x.GetImages(ImageType.Thumb).First().Path).ToList();
 | 
	
		
			
				|  |  | +        if (backdrops.Count == 0)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              // Thumb images fit better because they include the title in the image but are not provided with TMDb.
 | 
	
		
			
				|  |  |              // Using backdrops as a fallback to generate an image at all
 | 
	
		
			
				|  |  |              _logger.LogDebug("No thumb images found. Using backdrops to generate splashscreen");
 | 
	
		
			
				|  |  | -            landscape = GetItemsWithImageType(ImageType.Backdrop).Select(x => x.GetImages(ImageType.Backdrop).First().Path).ToList();
 | 
	
		
			
				|  |  | +            backdrops = GetItemsWithImageType(ImageType.Backdrop).Select(x => x.GetImages(ImageType.Backdrop).First().Path).ToList();
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        var splashBuilder = new SplashscreenBuilder((SkiaEncoder)_imageEncoder);
 | 
	
		
			
				|  |  | -        splashBuilder.GenerateSplash(posters, landscape, outputPath);
 | 
	
		
			
				|  |  | +        _imageEncoder.CreateSplashscreen(posters, backdrops);
 | 
	
		
			
				|  |  | +        return Task.CompletedTask;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private IReadOnlyList<BaseItem> GetItemsWithImageType(ImageType imageType)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        // todo make included libraries configurable
 | 
	
		
			
				|  |  | +        // TODO make included libraries configurable
 | 
	
		
			
				|  |  |          return _itemRepository.GetItemList(new InternalItemsQuery
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              CollapseBoxSetItems = false,
 | 
	
	
		
			
				|  | @@ -70,7 +67,7 @@ public class DefaultImageGenerator : IImageGenerator
 | 
	
		
			
				|  |  |              DtoOptions = new DtoOptions(false),
 | 
	
		
			
				|  |  |              ImageTypes = new[] { imageType },
 | 
	
		
			
				|  |  |              Limit = 30,
 | 
	
		
			
				|  |  | -            // todo max parental rating configurable
 | 
	
		
			
				|  |  | +            // TODO max parental rating configurable
 | 
	
		
			
				|  |  |              MaxParentalRating = 10,
 | 
	
		
			
				|  |  |              OrderBy = new ValueTuple<string, SortOrder>[]
 | 
	
		
			
				|  |  |              {
 |