forked from nikita/muzika-gromche
83 lines
2.7 KiB
C#
83 lines
2.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace MuzikaGromche;
|
|
|
|
public delegate bool SeasonalContentPredicate(DateTime dateTime);
|
|
|
|
// I'm not really sure what to do with seasonal content yet.
|
|
//
|
|
// There could be two approaches:
|
|
// - Force seasonal content tracks to be the only available tracks during their season.
|
|
// Then seasons must be short, so they don't cut off too much content for too long.
|
|
// - Exclude seasonal content tracks from the pool when their season is not active.
|
|
// Considering how many tracks are there in the playlist permanently already,
|
|
// this might not give the seasonal content enough visibility.
|
|
//
|
|
// Either way, seasonal content tracks would be listed in the config UI at all times,
|
|
// which makes it confusing if you try to select only seasonal tracks outside of their season.
|
|
|
|
// Seasons may NOT overlap. There is at most ONE active season at any given date.
|
|
public readonly record struct Season(string Name, string Description, SeasonalContentPredicate IsActive)
|
|
{
|
|
public override string ToString() => Name;
|
|
|
|
public static readonly Season NewYear = new("New Year", "New Year and Christmas holiday season", dateTime =>
|
|
{
|
|
// December 10 - February 29
|
|
var month = dateTime.Month;
|
|
var day = dateTime.Day;
|
|
return (month == 12 && day >= 10) || (month == 1) || (month == 2 && day <= 29);
|
|
});
|
|
|
|
// Note: it is important that this property goes last
|
|
public static readonly Season[] All = [NewYear];
|
|
}
|
|
|
|
public interface ISeasonalContent
|
|
{
|
|
public Season? Season { get; init; }
|
|
}
|
|
|
|
public static class SeasonalContentManager
|
|
{
|
|
public static Season? CurrentSeason(DateTime dateTime)
|
|
{
|
|
foreach (var season in Season.All)
|
|
{
|
|
if (season.IsActive(dateTime))
|
|
{
|
|
return season;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static Season? CurrentSeason() => CurrentSeason(DateTime.Today);
|
|
|
|
// Take second approach: filter out seasonal content that is not in the current season.
|
|
public static IEnumerable<T> Filter<T>(this IEnumerable<T> items, Season? season) where T : ISeasonalContent
|
|
{
|
|
return items.Where(item =>
|
|
{
|
|
if (item.Season == null)
|
|
{
|
|
return true; // always available
|
|
}
|
|
return item.Season == season;
|
|
});
|
|
}
|
|
|
|
public static IEnumerable<T> Filter<T>(this IEnumerable<T> items, DateTime dateTime) where T : ISeasonalContent
|
|
{
|
|
var season = CurrentSeason(dateTime);
|
|
return Filter(items, season);
|
|
}
|
|
|
|
public static IEnumerable<T> Filter<T>(this IEnumerable<T> items) where T : ISeasonalContent
|
|
{
|
|
return Filter(items, DateTime.Today);
|
|
}
|
|
}
|