aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Barron <barronpm@gmail.com>2020-06-30 21:44:41 -0400
committerPatrick Barron <barronpm@gmail.com>2020-07-17 16:11:53 -0400
commitab396225eaf486932fdb2f23eefa1cbfecbb27f4 (patch)
treeb225cd9617e14ae1f0386f9ff8aa85a8a433e424
parent175e7b45e56fb97b0f9bdddd99c195af3ecabcc6 (diff)
Migrate Display Preferences to EF Core
-rw-r--r--Emby.Dlna/ContentDirectory/ControlHandler.cs1
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs3
-rw-r--r--Emby.Server.Implementations/Channels/ChannelManager.cs1
-rw-r--r--Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs225
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs1
-rw-r--r--Emby.Server.Implementations/Emby.Server.Implementations.csproj2
-rw-r--r--Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs2
-rw-r--r--Emby.Server.Implementations/Images/FolderImageProvider.cs2
-rw-r--r--Emby.Server.Implementations/Images/GenreImageProvider.cs1
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs1
-rw-r--r--Emby.Server.Implementations/Library/MusicManager.cs2
-rw-r--r--Emby.Server.Implementations/Library/SearchEngine.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs1
-rw-r--r--Jellyfin.Data/Entities/DisplayPreferences.cs72
-rw-r--r--Jellyfin.Data/Entities/HomeSection.cs21
-rw-r--r--Jellyfin.Data/Entities/User.cs5
-rw-r--r--Jellyfin.Data/Enums/HomeSectionType.cs53
-rw-r--r--Jellyfin.Data/Enums/IndexingKind.cs20
-rw-r--r--Jellyfin.Data/Enums/ScrollDirection.cs (renamed from MediaBrowser.Model/Entities/ScrollDirection.cs)8
-rw-r--r--Jellyfin.Data/Enums/SortOrder.cs (renamed from MediaBrowser.Model/Entities/SortOrder.cs)8
-rw-r--r--Jellyfin.Data/Enums/ViewType.cs38
-rw-r--r--Jellyfin.Server.Implementations/DisplayPreferencesManager.cs49
-rw-r--r--Jellyfin.Server.Implementations/JellyfinDb.cs2
-rw-r--r--Jellyfin.Server.Implementations/Migrations/20200630170339_AddDisplayPreferences.Designer.cs403
-rw-r--r--Jellyfin.Server.Implementations/Migrations/20200630170339_AddDisplayPreferences.cs92
-rw-r--r--Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs93
-rw-r--r--Jellyfin.Server/CoreAppHost.cs2
-rw-r--r--Jellyfin.Server/Migrations/MigrationRunner.cs3
-rw-r--r--Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs118
-rw-r--r--MediaBrowser.Api/ChannelService.cs2
-rw-r--r--MediaBrowser.Api/DisplayPreferencesService.cs92
-rw-r--r--MediaBrowser.Api/Movies/MoviesService.cs1
-rw-r--r--MediaBrowser.Api/SuggestionsService.cs1
-rw-r--r--MediaBrowser.Api/TvShowsService.cs1
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs5
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs1
-rw-r--r--MediaBrowser.Controller/IDisplayPreferencesManager.cs25
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs1
-rw-r--r--MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs53
-rw-r--r--MediaBrowser.Controller/Playlists/Playlist.cs1
-rw-r--r--MediaBrowser.Model/Dlna/SortCriteria.cs2
-rw-r--r--MediaBrowser.Model/Entities/DisplayPreferencesDto.cs (renamed from MediaBrowser.Model/Entities/DisplayPreferences.cs)12
-rw-r--r--MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs2
-rw-r--r--MediaBrowser.Model/LiveTv/SeriesTimerQuery.cs2
44 files changed, 1101 insertions, 331 deletions
diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs
index 291de5245..00821bf78 100644
--- a/Emby.Dlna/ContentDirectory/ControlHandler.cs
+++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs
@@ -11,6 +11,7 @@ using System.Xml;
using Emby.Dlna.Didl;
using Emby.Dlna.Service;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Drawing;
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index f6077400d..f6f10beb0 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -554,8 +554,6 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton<IUserDataRepository, SqliteUserDataRepository>();
serviceCollection.AddSingleton<IUserDataManager, UserDataManager>();
- serviceCollection.AddSingleton<IDisplayPreferencesRepository, SqliteDisplayPreferencesRepository>();
-
serviceCollection.AddSingleton<IItemRepository, SqliteItemRepository>();
serviceCollection.AddSingleton<IAuthenticationRepository, AuthenticationRepository>();
@@ -650,7 +648,6 @@ namespace Emby.Server.Implementations
_httpServer = Resolve<IHttpServer>();
_httpClient = Resolve<IHttpClient>();
- ((SqliteDisplayPreferencesRepository)Resolve<IDisplayPreferencesRepository>()).Initialize();
((AuthenticationRepository)Resolve<IAuthenticationRepository>()).Initialize();
SetStaticProperties();
diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs
index c803d9d82..2a7cddd87 100644
--- a/Emby.Server.Implementations/Channels/ChannelManager.cs
+++ b/Emby.Server.Implementations/Channels/ChannelManager.cs
@@ -7,6 +7,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Progress;
using MediaBrowser.Controller.Channels;
diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs
deleted file mode 100644
index 5597155a8..000000000
--- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs
+++ /dev/null
@@ -1,225 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Text.Json;
-using System.Threading;
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Json;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.IO;
-using Microsoft.Extensions.Logging;
-using SQLitePCL.pretty;
-
-namespace Emby.Server.Implementations.Data
-{
- /// <summary>
- /// Class SQLiteDisplayPreferencesRepository.
- /// </summary>
- public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository
- {
- private readonly IFileSystem _fileSystem;
-
- private readonly JsonSerializerOptions _jsonOptions;
-
- public SqliteDisplayPreferencesRepository(ILogger<SqliteDisplayPreferencesRepository> logger, IApplicationPaths appPaths, IFileSystem fileSystem)
- : base(logger)
- {
- _fileSystem = fileSystem;
-
- _jsonOptions = JsonDefaults.GetOptions();
-
- DbFilePath = Path.Combine(appPaths.DataPath, "displaypreferences.db");
- }
-
- /// <summary>
- /// Gets the name of the repository.
- /// </summary>
- /// <value>The name.</value>
- public string Name => "SQLite";
-
- public void Initialize()
- {
- try
- {
- InitializeInternal();
- }
- catch (Exception ex)
- {
- Logger.LogError(ex, "Error loading database file. Will reset and retry.");
-
- _fileSystem.DeleteFile(DbFilePath);
-
- InitializeInternal();
- }
- }
-
- /// <summary>
- /// Opens the connection to the database.
- /// </summary>
- /// <returns>Task.</returns>
- private void InitializeInternal()
- {
- string[] queries =
- {
- "create table if not exists userdisplaypreferences (id GUID NOT NULL, userId GUID NOT NULL, client text NOT NULL, data BLOB NOT NULL)",
- "create unique index if not exists userdisplaypreferencesindex on userdisplaypreferences (id, userId, client)"
- };
-
- using (var connection = GetConnection())
- {
- connection.RunQueries(queries);
- }
- }
-
- /// <summary>
- /// Save the display preferences associated with an item in the repo.
- /// </summary>
- /// <param name="displayPreferences">The display preferences.</param>
- /// <param name="userId">The user id.</param>
- /// <param name="client">The client.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <exception cref="ArgumentNullException">item</exception>
- public void SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, CancellationToken cancellationToken)
- {
- if (displayPreferences == null)
- {
- throw new ArgumentNullException(nameof(displayPreferences));
- }
-
- if (string.IsNullOrEmpty(displayPreferences.Id))
- {
- throw new ArgumentException("Display preferences has an invalid Id", nameof(displayPreferences));
- }
-
- cancellationToken.ThrowIfCancellationRequested();
-
- using (var connection = GetConnection())
- {
- connection.RunInTransaction(
- db => SaveDisplayPreferences(displayPreferences, userId, client, db),
- TransactionMode);
- }
- }
-
- private void SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, IDatabaseConnection connection)
- {
- var serialized = JsonSerializer.SerializeToUtf8Bytes(displayPreferences, _jsonOptions);
-
- using (var statement = connection.PrepareStatement("replace into userdisplaypreferences (id, userid, client, data) values (@id, @userId, @client, @data)"))
- {
- statement.TryBind("@id", new Guid(displayPreferences.Id).ToByteArray());
- statement.TryBind("@userId", userId.ToByteArray());
- statement.TryBind("@client", client);
- statement.TryBind("@data", serialized);
-
- statement.MoveNext();
- }
- }
-
- /// <summary>
- /// Save all display preferences associated with a user in the repo.
- /// </summary>
- /// <param name="displayPreferences">The display preferences.</param>
- /// <param name="userId">The user id.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <exception cref="ArgumentNullException">item</exception>
- public void SaveAllDisplayPreferences(IEnumerable<DisplayPreferences> displayPreferences, Guid userId, CancellationToken cancellationToken)
- {
- if (displayPreferences == null)
- {
- throw new ArgumentNullException(nameof(displayPreferences));
- }
-
- cancellationToken.ThrowIfCancellationRequested();
-
- using (var connection = GetConnection())
- {
- connection.RunInTransaction(
- db =>
- {
- foreach (var displayPreference in displayPreferences)
- {
- SaveDisplayPreferences(displayPreference, userId, displayPreference.Client, db);
- }
- },
- TransactionMode);
- }
- }
-
- /// <summary>
- /// Gets the display preferences.
- /// </summary>
- /// <param name="displayPreferencesId">The display preferences id.</param>
- /// <param name="userId">The user id.</param>
- /// <param name="client">The client.</param>
- /// <returns>Task{DisplayPreferences}.</returns>
- /// <exception cref="ArgumentNullException">item</exception>
- public DisplayPreferences GetDisplayPreferences(string displayPreferencesId, Guid userId, string client)
- {
- if (string.IsNullOrEmpty(displayPreferencesId))
- {
- throw new ArgumentNullException(nameof(displayPreferencesId));
- }
-
- var guidId = displayPreferencesId.GetMD5();
-
- using (var connection = GetConnection(true))
- {
- using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where id = @id and userId=@userId and client=@client"))
- {
- statement.TryBind("@id", guidId.ToByteArray());
- statement.TryBind("@userId", userId.ToByteArray());
- statement.TryBind("@client", client);
-
- foreach (var row in statement.ExecuteQuery())
- {
- return Get(row);
- }
- }
- }
-
- return new DisplayPreferences
- {
- Id = guidId.ToString("N", CultureInfo.InvariantCulture)
- };
- }
-
- /// <summary>
- /// Gets all display preferences for the given user.
- /// </summary>
- /// <param name="userId">The user id.</param>
- /// <returns>Task{DisplayPreferences}.</returns>
- /// <exception cref="ArgumentNullException">item</exception>
- public IEnumerable<DisplayPreferences> GetAllDisplayPreferences(Guid userId)
- {
- var list = new List<DisplayPreferences>();
-
- using (var connection = GetConnection(true))
- using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where userId=@userId"))
- {
- statement.TryBind("@userId", userId.ToByteArray());
-
- foreach (var row in statement.ExecuteQuery())
- {
- list.Add(Get(row));
- }
- }
-
- return list;
- }
-
- private DisplayPreferences Get(IReadOnlyList<IResultSetValue> row)
- => JsonSerializer.Deserialize<DisplayPreferences>(row[0].ToBlob(), _jsonOptions);
-
- public void SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client, CancellationToken cancellationToken)
- => SaveDisplayPreferences(displayPreferences, new Guid(userId), client, cancellationToken);
-
- public DisplayPreferences GetDisplayPreferences(string displayPreferencesId, string userId, string client)
- => GetDisplayPreferences(displayPreferencesId, new Guid(userId), client);
- }
-}
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index a6390b1ef..04e5e570f 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -9,6 +9,7 @@ using System.Text;
using System.Text.Json;
using System.Threading;
using Emby.Server.Implementations.Playlists;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Json;
using MediaBrowser.Controller;
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index f7ad59c10..548dc7085 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -54,7 +54,7 @@
<TargetFramework>netstandard2.1</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
- <TreatWarningsAsErrors Condition=" '$(Configuration)' == 'Release'" >true</TreatWarningsAsErrors>
+ <TreatWarningsAsErrors Condition=" '$(Configuration)' == 'Release'">true</TreatWarningsAsErrors>
</PropertyGroup>
<!-- Code Analyzers-->
diff --git a/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs b/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs
index da88b8d8a..161b4c452 100644
--- a/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs
+++ b/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs
@@ -3,7 +3,7 @@
using System;
using System.Collections.Generic;
using System.IO;
-using Emby.Server.Implementations.Images;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
diff --git a/Emby.Server.Implementations/Images/FolderImageProvider.cs b/Emby.Server.Implementations/Images/FolderImageProvider.cs
index e9523386e..0224ab32a 100644
--- a/Emby.Server.Implementations/Images/FolderImageProvider.cs
+++ b/Emby.Server.Implementations/Images/FolderImageProvider.cs
@@ -1,7 +1,7 @@
#pragma warning disable CS1591
using System.Collections.Generic;
-using Emby.Server.Implementations.Images;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
diff --git a/Emby.Server.Implementations/Images/GenreImageProvider.cs b/Emby.Server.Implementations/Images/GenreImageProvider.cs
index d2aeccdb2..1cd4cd66b 100644
--- a/Emby.Server.Implementations/Images/GenreImageProvider.cs
+++ b/Emby.Server.Implementations/Images/GenreImageProvider.cs
@@ -1,6 +1,7 @@
#pragma warning disable CS1591
using System.Collections.Generic;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 77d44e131..4690f2094 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -50,7 +50,6 @@ using Microsoft.Extensions.Logging;
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
using Genre = MediaBrowser.Controller.Entities.Genre;
using Person = MediaBrowser.Controller.Entities.Person;
-using SortOrder = MediaBrowser.Model.Entities.SortOrder;
using VideoResolver = Emby.Naming.Video.VideoResolver;
namespace Emby.Server.Implementations.Library
diff --git a/Emby.Server.Implementations/Library/MusicManager.cs b/Emby.Server.Implementations/Library/MusicManager.cs
index 0bdc59914..877fdec86 100644
--- a/Emby.Server.Implementations/Library/MusicManager.cs
+++ b/Emby.Server.Implementations/Library/MusicManager.cs
@@ -4,12 +4,12 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Playlists;
-using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using MusicAlbum = MediaBrowser.Controller.Entities.Audio.MusicAlbum;
diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs
index 3df9cc06f..e3e554824 100644
--- a/Emby.Server.Implementations/Library/SearchEngine.cs
+++ b/Emby.Server.Implementations/Library/SearchEngine.cs
@@ -4,12 +4,12 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Extensions;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Search;
using Microsoft.Extensions.Logging;
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 7b0fcbc9e..80e09f0a3 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -12,6 +12,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using Emby.Server.Implementations.Library;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
diff --git a/Jellyfin.Data/Entities/DisplayPreferences.cs b/Jellyfin.Data/Entities/DisplayPreferences.cs
new file mode 100644
index 000000000..668030149
--- /dev/null
+++ b/Jellyfin.Data/Entities/DisplayPreferences.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Enums;
+
+namespace Jellyfin.Data.Entities
+{
+ public class DisplayPreferences
+ {
+ public DisplayPreferences(string client, Guid userId)
+ {
+ RememberIndexing = false;
+ ShowBackdrop = true;
+ Client = client;
+ UserId = userId;
+
+ HomeSections = new HashSet<HomeSection>();
+ }
+
+ protected DisplayPreferences()
+ {
+ }
+
+ [Required]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ [Required]
+ public Guid UserId { get; set; }
+
+ /// <summary>
+ /// Gets or sets the id of the associated item.
+ /// </summary>
+ /// <remarks>
+ /// This is currently unused. In the future, this will allow us to have users set
+ /// display preferences per item.
+ /// </remarks>
+ public Guid? ItemId { get; set; }
+
+ [Required]
+ [MaxLength(64)]
+ [StringLength(64)]
+ public string Client { get; set; }
+
+ [Required]
+ public bool RememberIndexing { get; set; }
+
+ [Required]
+ public bool RememberSorting { get; set; }
+
+ [Required]
+ public SortOrder SortOrder { get; set; }
+
+ [Required]
+ public bool ShowSidebar { get; set; }
+
+ [Required]
+ public bool ShowBackdrop { get; set; }
+
+ public string SortBy { get; set; }
+
+ public ViewType? ViewType { get; set; }
+
+ [Required]
+ public ScrollDirection ScrollDirection { get; set; }
+
+ public IndexingKind? IndexBy { get; set; }
+
+ public virtual ICollection<HomeSection> HomeSections { get; protected set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/HomeSection.cs b/Jellyfin.Data/Entities/HomeSection.cs
new file mode 100644
index 000000000..f39956a54
--- /dev/null
+++ b/Jellyfin.Data/Entities/HomeSection.cs
@@ -0,0 +1,21 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Enums;
+
+namespace Jellyfin.Data.Entities
+{
+ public class HomeSection
+ {
+ [Key]
+ [Required]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ public int DisplayPreferencesId { get; set; }
+
+ public int Order { get; set; }
+
+ public HomeSectionType Type { get; set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/User.cs b/Jellyfin.Data/Entities/User.cs
index b89b0a8f4..d93144e3a 100644
--- a/Jellyfin.Data/Entities/User.cs
+++ b/Jellyfin.Data/Entities/User.cs
@@ -349,6 +349,11 @@ namespace Jellyfin.Data.Entities
/// </summary>
public virtual ICollection<AccessSchedule> AccessSchedules { get; protected set; }
+ /// <summary>
+ /// Gets or sets the list of item display preferences.
+ /// </summary>
+ public virtual ICollection<DisplayPreferences> DisplayPreferences { get; protected set; }
+
/*
/// <summary>
/// Gets or sets the list of groups this user is a member of.
diff --git a/Jellyfin.Data/Enums/HomeSectionType.cs b/Jellyfin.Data/Enums/HomeSectionType.cs
new file mode 100644
index 000000000..be764c592
--- /dev/null
+++ b/Jellyfin.Data/Enums/HomeSectionType.cs
@@ -0,0 +1,53 @@
+namespace Jellyfin.Data.Enums
+{
+ /// <summary>
+ /// An enum representing the different options for the home screen sections.
+ /// </summary>
+ public enum HomeSectionType
+ {
+ /// <summary>
+ /// My Media.
+ /// </summary>
+ SmallLibraryTiles = 0,
+
+ /// <summary>
+ /// My Media Small.
+ /// </summary>
+ LibraryButtons = 1,
+
+ /// <summary>
+ /// Active Recordings.
+ /// </summary>
+ ActiveRecordings = 2,
+
+ /// <summary>
+ /// Continue Watching.
+ /// </summary>
+ Resume = 3,
+
+ /// <summary>
+ /// Continue Listening.
+ /// </summary>
+ ResumeAudio = 4,
+
+ /// <summary>
+ /// Latest Media.
+ /// </summary>
+ LatestMedia = 5,
+
+ /// <summary>
+ /// Next Up.
+ /// </summary>
+ NextUp = 6,
+
+ /// <summary>
+ /// Live TV.
+ /// </summary>
+ LiveTv = 7,
+
+ /// <summary>
+ /// None.
+ /// </summary>
+ None = 8
+ }
+}
diff --git a/Jellyfin.Data/Enums/IndexingKind.cs b/Jellyfin.Data/Enums/IndexingKind.cs
new file mode 100644
index 000000000..c4d8e70ca
--- /dev/null
+++ b/Jellyfin.Data/Enums/IndexingKind.cs
@@ -0,0 +1,20 @@
+namespace Jellyfin.Data.Enums
+{
+ public enum IndexingKind
+ {
+ /// <summary>
+ /// Index by the premiere date.
+ /// </summary>
+ PremiereDate,
+
+ /// <summary>
+ /// Index by the production year.
+ /// </summary>
+ ProductionYear,
+
+ /// <summary>
+ /// Index by the community rating.
+ /// </summary>
+ CommunityRating
+ }
+}
diff --git a/MediaBrowser.Model/Entities/ScrollDirection.cs b/Jellyfin.Data/Enums/ScrollDirection.cs
index a1de0edcb..382f585ba 100644
--- a/MediaBrowser.Model/Entities/ScrollDirection.cs
+++ b/Jellyfin.Data/Enums/ScrollDirection.cs
@@ -1,17 +1,17 @@
-namespace MediaBrowser.Model.Entities
+namespace Jellyfin.Data.Enums
{
/// <summary>
- /// Enum ScrollDirection.
+ /// An enum representing the axis that should be scrolled.
/// </summary>
public enum ScrollDirection
{
/// <summary>
- /// The horizontal.
+ /// Horizontal scrolling direction.
/// </summary>
Horizontal,
/// <summary>
- /// The vertical.
+ /// Vertical scrolling direction.
/// </summary>
Vertical
}
diff --git a/MediaBrowser.Model/Entities/SortOrder.cs b/Jellyfin.Data/Enums/SortOrder.cs
index f3abc06f3..309fa7877 100644
--- a/MediaBrowser.Model/Entities/SortOrder.cs
+++ b/Jellyfin.Data/Enums/SortOrder.cs
@@ -1,17 +1,17 @@
-namespace MediaBrowser.Model.Entities
+namespace Jellyfin.Data.Enums
{
/// <summary>
- /// Enum SortOrder.
+ /// An enum representing the sorting order.
/// </summary>
public enum SortOrder
{
/// <summary>
- /// The ascending.
+ /// Sort in increasing order.
/// </summary>
Ascending,
/// <summary>
- /// The descending.
+ /// Sort in decreasing order.
/// </summary>
Descending
}
diff --git a/Jellyfin.Data/Enums/ViewType.cs b/Jellyfin.Data/Enums/ViewType.cs
new file mode 100644
index 000000000..595429ab1
--- /dev/null
+++ b/Jellyfin.Data/Enums/ViewType.cs
@@ -0,0 +1,38 @@
+namespace Jellyfin.Data.Enums
+{
+ /// <summary>
+ /// An enum representing the type of view for a library or collection.
+ /// </summary>
+ public enum ViewType
+ {
+ /// <summary>
+ /// Shows banners.
+ /// </summary>
+ Banner = 0,
+
+ /// <summary>
+ /// Shows a list of content.
+ /// </summary>
+ List = 1,
+
+ /// <summary>
+ /// Shows poster artwork.
+ /// </summary>
+ Poster = 2,
+
+ /// <summary>
+ /// Shows poster artwork with a card containing the name and year.
+ /// </summary>
+ PosterCard = 3,
+
+ /// <summary>
+ /// Shows a thumbnail.
+ /// </summary>
+ Thumb = 4,
+
+ /// <summary>
+ /// Shows a thumbnail with a card containing the name and year.
+ /// </summary>
+ ThumbCard = 5
+ }
+}
diff --git a/Jellyfin.Server.Implementations/DisplayPreferencesManager.cs b/Jellyfin.Server.Implementations/DisplayPreferencesManager.cs
new file mode 100644
index 000000000..132e74c6a
--- /dev/null
+++ b/Jellyfin.Server.Implementations/DisplayPreferencesManager.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Linq;
+using Jellyfin.Data.Entities;
+using MediaBrowser.Controller;
+
+namespace Jellyfin.Server.Implementations
+{
+ /// <summary>
+ /// Manages the storage and retrieval of display preferences through Entity Framework.
+ /// </summary>
+ public class DisplayPreferencesManager : IDisplayPreferencesManager
+ {
+ private readonly JellyfinDbProvider _dbProvider;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DisplayPreferencesManager"/> class.
+ /// </summary>
+ /// <param name="dbProvider">The Jellyfin db provider.</param>
+ public DisplayPreferencesManager(JellyfinDbProvider dbProvider)
+ {
+ _dbProvider = dbProvider;
+ }
+
+ /// <inheritdoc />
+ public DisplayPreferences GetDisplayPreferences(Guid userId, string client)
+ {
+ var dbContext = _dbProvider.CreateContext();
+ var user = dbContext.Users.Find(userId);
+#pragma warning disable CA1307
+ var prefs = user.DisplayPreferences.FirstOrDefault(pref => string.Equals(pref.Client, client));
+
+ if (prefs == null)
+ {
+ prefs = new DisplayPreferences(client, userId);
+ user.DisplayPreferences.Add(prefs);
+ }
+
+ return prefs;
+ }
+
+ /// <inheritdoc />
+ public void SaveChanges(DisplayPreferences preferences)
+ {
+ var dbContext = _dbProvider.CreateContext();
+ dbContext.Update(preferences);
+ dbContext.SaveChanges();
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/JellyfinDb.cs b/Jellyfin.Server.Implementations/JellyfinDb.cs
index 53120a763..774970e94 100644
--- a/Jellyfin.Server.Implementations/JellyfinDb.cs
+++ b/Jellyfin.Server.Implementations/JellyfinDb.cs
@@ -27,6 +27,8 @@ namespace Jellyfin.Server.Implementations
public virtual DbSet<ActivityLog> ActivityLogs { get; set; }
+ public virtual DbSet<DisplayPreferences> DisplayPreferences { get; set; }
+
public virtual DbSet<ImageInfo> ImageInfos { get; set; }
public virtual DbSet<Permission> Permissions { get; set; }
diff --git a/Jellyfin.Server.Implementations/Migrations/20200630170339_AddDisplayPreferences.Designer.cs b/Jellyfin.Server.Implementations/Migrations/20200630170339_AddDisplayPreferences.Designer.cs
new file mode 100644
index 000000000..75f9bb7a3
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/20200630170339_AddDisplayPreferences.Designer.cs
@@ -0,0 +1,403 @@
+#pragma warning disable CS1591
+
+// <auto-generated />
+using System;
+using Jellyfin.Server.Implementations;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ [DbContext(typeof(JellyfinDb))]
+ [Migration("20200630170339_AddDisplayPreferences")]
+ partial class AddDisplayPreferences
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasDefaultSchema("jellyfin")
+ .HasAnnotation("ProductVersion", "3.1.5");
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("DayOfWeek")
+ .HasColumnType("INTEGER");
+
+ b.Property<double>("EndHour")
+ .HasColumnType("REAL");
+
+ b.Property<double>("StartHour")
+ .HasColumnType("REAL");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AccessSchedules");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ActivityLog", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("ItemId")
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property<int>("LogSeverity")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<string>("Overview")
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ShortOverview")
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<string>("Type")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("ActivityLogs");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Client")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(64);
+
+ b.Property<int?>("IndexBy")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid?>("ItemId")
+ .HasColumnType("TEXT");
+
+ b.Property<bool>("RememberIndexing")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("RememberSorting")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("ScrollDirection")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("ShowBackdrop")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("ShowSidebar")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("SortBy")
+ .HasColumnType("TEXT");
+
+ b.Property<int>("SortOrder")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property<int?>("ViewType")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("DisplayPreferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.HomeSection", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("DisplayPreferencesId")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Order")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Type")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DisplayPreferencesId");
+
+ b.ToTable("HomeSection");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ImageInfo", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("LastModified")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Path")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(512);
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("ImageInfos");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid?>("Permission_Permissions_Guid")
+ .HasColumnType("TEXT");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("Value")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Permission_Permissions_Guid");
+
+ b.ToTable("Permissions");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid?>("Preference_Preferences_Guid")
+ .HasColumnType("TEXT");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Value")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.HasKey("Id");
+
+ b.HasIndex("Preference_Preferences_Guid");
+
+ b.ToTable("Preferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.User", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT");
+
+ b.Property<string>("AudioLanguagePreference")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<string>("AuthenticationProviderId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<bool>("DisplayCollectionsView")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("DisplayMissingEpisodes")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("EasyPassword")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<bool>("EnableAutoLogin")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("EnableLocalPassword")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("EnableNextEpisodeAutoPlay")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("EnableUserPreferenceAccess")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("HidePlayedInLatest")
+ .HasColumnType("INTEGER");
+
+ b.Property<long>("InternalId")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("InvalidLoginAttemptCount")
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime?>("LastActivityDate")
+ .HasColumnType("TEXT");
+
+ b.Property<DateTime?>("LastLoginDate")
+ .HasColumnType("TEXT");
+
+ b.Property<int?>("LoginAttemptsBeforeLockout")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("MaxParentalAgeRating")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("MustUpdatePassword")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Password")
+ .HasColumnType("TEXT")
+ .HasMaxLength(65535);
+
+ b.Property<string>("PasswordResetProviderId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<bool>("PlayDefaultAudioTrack")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("RememberAudioSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("RememberSubtitleSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("RemoteClientBitrateLimit")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("SubtitleLanguagePreference")
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.Property<int>("SubtitleMode")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("SyncPlayAccess")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Username")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(255);
+
+ b.HasKey("Id");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("AccessSchedules")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("DisplayPreferences")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.HomeSection", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.DisplayPreferences", null)
+ .WithMany("HomeSections")
+ .HasForeignKey("DisplayPreferencesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ImageInfo", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithOne("ProfileImage")
+ .HasForeignKey("Jellyfin.Data.Entities.ImageInfo", "UserId");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Permissions")
+ .HasForeignKey("Permission_Permissions_Guid");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Preferences")
+ .HasForeignKey("Preference_Preferences_Guid");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/20200630170339_AddDisplayPreferences.cs b/Jellyfin.Server.Implementations/Migrations/20200630170339_AddDisplayPreferences.cs
new file mode 100644
index 000000000..e9a493d9d
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/20200630170339_AddDisplayPreferences.cs
@@ -0,0 +1,92 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1601
+
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ public partial class AddDisplayPreferences : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "DisplayPreferences",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ UserId = table.Column<Guid>(nullable: false),
+ ItemId = table.Column<Guid>(nullable: true),
+ Client = table.Column<string>(maxLength: 64, nullable: false),
+ RememberIndexing = table.Column<bool>(nullable: false),
+ RememberSorting = table.Column<bool>(nullable: false),
+ SortOrder = table.Column<int>(nullable: false),
+ ShowSidebar = table.Column<bool>(nullable: false),
+ ShowBackdrop = table.Column<bool>(nullable: false),
+ SortBy = table.Column<string>(nullable: true),
+ ViewType = table.Column<int>(nullable: true),
+ ScrollDirection = table.Column<int>(nullable: false),
+ IndexBy = table.Column<int>(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_DisplayPreferences", x => x.Id);
+ table.ForeignKey(
+ name: "FK_DisplayPreferences_Users_UserId",
+ column: x => x.UserId,
+ principalSchema: "jellyfin",
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "HomeSection",
+ schema: "jellyfin",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ DisplayPreferencesId = table.Column<int>(nullable: false),
+ Order = table.Column<int>(nullable: false),
+ Type = table.Column<int>(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_HomeSection", x => x.Id);
+ table.ForeignKey(
+ name: "FK_HomeSection_DisplayPreferences_DisplayPreferencesId",
+ column: x => x.DisplayPreferencesId,
+ principalSchema: "jellyfin",
+ principalTable: "DisplayPreferences",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_DisplayPreferences_UserId",
+ schema: "jellyfin",
+ table: "DisplayPreferences",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_HomeSection_DisplayPreferencesId",
+ schema: "jellyfin",
+ table: "HomeSection",
+ column: "DisplayPreferencesId");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "HomeSection",
+ schema: "jellyfin");
+
+ migrationBuilder.DropTable(
+ name: "DisplayPreferences",
+ schema: "jellyfin");
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
index 51fad8224..69b544e5b 100644
--- a/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
+++ b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
@@ -15,7 +15,7 @@ namespace Jellyfin.Server.Implementations.Migrations
#pragma warning disable 612, 618
modelBuilder
.HasDefaultSchema("jellyfin")
- .HasAnnotation("ProductVersion", "3.1.4");
+ .HasAnnotation("ProductVersion", "3.1.5");
modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
{
@@ -88,6 +88,79 @@ namespace Jellyfin.Server.Implementations.Migrations
b.ToTable("ActivityLogs");
});
+ modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Client")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasMaxLength(64);
+
+ b.Property<int?>("IndexBy")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid?>("ItemId")
+ .HasColumnType("TEXT");
+
+ b.Property<bool>("RememberIndexing")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("RememberSorting")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("ScrollDirection")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("ShowBackdrop")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("ShowSidebar")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("SortBy")
+ .HasColumnType("TEXT");
+
+ b.Property<int>("SortOrder")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property<int?>("ViewType")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("DisplayPreferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.HomeSection", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("DisplayPreferencesId")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Order")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Type")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DisplayPreferencesId");
+
+ b.ToTable("HomeSection");
+ });
+
modelBuilder.Entity("Jellyfin.Data.Entities.ImageInfo", b =>
{
b.Property<int>("Id")
@@ -282,6 +355,24 @@ namespace Jellyfin.Server.Implementations.Migrations
.IsRequired();
});
+ modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("DisplayPreferences")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.HomeSection", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.DisplayPreferences", null)
+ .WithMany("HomeSections")
+ .HasForeignKey("DisplayPreferencesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
modelBuilder.Entity("Jellyfin.Data.Entities.ImageInfo", b =>
{
b.HasOne("Jellyfin.Data.Entities.User", null)
diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs
index 207eaa98d..c5a7368aa 100644
--- a/Jellyfin.Server/CoreAppHost.cs
+++ b/Jellyfin.Server/CoreAppHost.cs
@@ -9,6 +9,7 @@ using Jellyfin.Server.Implementations;
using Jellyfin.Server.Implementations.Activity;
using Jellyfin.Server.Implementations.Users;
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Activity;
@@ -73,6 +74,7 @@ namespace Jellyfin.Server
serviceCollection.AddSingleton<IActivityManager, ActivityManager>();
serviceCollection.AddSingleton<IUserManager, UserManager>();
+ serviceCollection.AddSingleton<IDisplayPreferencesManager, DisplayPreferencesManager>();
base.RegisterServices(serviceCollection);
}
diff --git a/Jellyfin.Server/Migrations/MigrationRunner.cs b/Jellyfin.Server/Migrations/MigrationRunner.cs
index d633c554d..7f208952c 100644
--- a/Jellyfin.Server/Migrations/MigrationRunner.cs
+++ b/Jellyfin.Server/Migrations/MigrationRunner.cs
@@ -21,7 +21,8 @@ namespace Jellyfin.Server.Migrations
typeof(Routines.MigrateActivityLogDb),
typeof(Routines.RemoveDuplicateExtras),
typeof(Routines.AddDefaultPluginRepository),
- typeof(Routines.MigrateUserDb)
+ typeof(Routines.MigrateUserDb),
+ typeof(Routines.MigrateDisplayPreferencesDb)
};
/// <summary>
diff --git a/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs
new file mode 100644
index 000000000..1ed23fe8e
--- /dev/null
+++ b/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs
@@ -0,0 +1,118 @@
+using System;
+using System.IO;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
+using Jellyfin.Server.Implementations;
+using MediaBrowser.Controller;
+using MediaBrowser.Model.Entities;
+using Microsoft.Extensions.Logging;
+using SQLitePCL.pretty;
+
+namespace Jellyfin.Server.Migrations.Routines
+{
+ /// <summary>
+ /// The migration routine for migrating the display preferences database to EF Core.
+ /// </summary>
+ public class MigrateDisplayPreferencesDb : IMigrationRoutine
+ {
+ private const string DbFilename = "displaypreferences.db";
+
+ private readonly ILogger<MigrateDisplayPreferencesDb> _logger;
+ private readonly IServerApplicationPaths _paths;
+ private readonly JellyfinDbProvider _provider;
+ private readonly JsonSerializerOptions _jsonOptions;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MigrateDisplayPreferencesDb"/> class.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ /// <param name="paths">The server application paths.</param>
+ /// <param name="provider">The database provider.</param>
+ public MigrateDisplayPreferencesDb(ILogger<MigrateDisplayPreferencesDb> logger, IServerApplicationPaths paths, JellyfinDbProvider provider)
+ {
+ _logger = logger;
+ _paths = paths;
+ _provider = provider;
+ _jsonOptions = new JsonSerializerOptions();
+ _jsonOptions.Converters.Add(new JsonStringEnumConverter());
+ }
+
+ /// <inheritdoc />
+ public Guid Id => Guid.Parse("06387815-C3CC-421F-A888-FB5F9992BEA8");
+
+ /// <inheritdoc />
+ public string Name => "MigrateDisplayPreferencesDatabase";
+
+ /// <inheritdoc />
+ public void Perform()
+ {
+ HomeSectionType[] defaults =
+ {
+ HomeSectionType.SmallLibraryTiles,
+ HomeSectionType.Resume,
+ HomeSectionType.ResumeAudio,
+ HomeSectionType.LiveTv,
+ HomeSectionType.NextUp,
+ HomeSectionType.LatestMedia,
+ HomeSectionType.None,
+ };
+
+ var dbFilePath = Path.Combine(_paths.DataPath, DbFilename);
+ using (var connection = SQLite3.Open(dbFilePath, ConnectionFlags.ReadOnly, null))
+ {
+ var dbContext = _provider.CreateContext();
+
+ var results = connection.Query("SELECT * FROM userdisplaypreferences");
+ foreach (var result in results)
+ {
+ var dto = JsonSerializer.Deserialize<DisplayPreferencesDto>(result[3].ToString(), _jsonOptions);
+
+ var displayPreferences = new DisplayPreferences(result[2].ToString(), new Guid(result[1].ToBlob()))
+ {
+ ViewType = Enum.TryParse<ViewType>(dto.ViewType, true, out var viewType) ? viewType : (ViewType?)null,
+ IndexBy = Enum.TryParse<IndexingKind>(dto.IndexBy, true, out var indexBy) ? indexBy : (IndexingKind?)null,
+ ShowBackdrop = dto.ShowBackdrop,
+ ShowSidebar = dto.ShowSidebar,
+ SortBy = dto.SortBy,
+ SortOrder = dto.SortOrder,
+ RememberIndexing = dto.RememberIndexing,
+ RememberSorting = dto.RememberSorting,
+ ScrollDirection = dto.ScrollDirection
+ };
+
+ for (int i = 0; i < 7; i++)
+ {
+ dto.CustomPrefs.TryGetValue("homesection" + i, out var homeSection);
+
+ displayPreferences.HomeSections.Add(new HomeSection
+ {
+ Order = i,
+ Type = Enum.TryParse<HomeSectionType>(homeSection, true, out var type) ? type : defaults[i]
+ });
+ }
+
+ dbContext.Add(displayPreferences);
+ }
+
+ dbContext.SaveChanges();
+ }
+
+ try
+ {
+ File.Move(dbFilePath, dbFilePath + ".old");
+
+ var journalPath = dbFilePath + "-journal";
+ if (File.Exists(journalPath))
+ {
+ File.Move(journalPath, dbFilePath + ".old-journal");
+ }
+ }
+ catch (IOException e)
+ {
+ _logger.LogError(e, "Error renaming legacy display preferences database to 'displaypreferences.db.old'");
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Api/ChannelService.cs b/MediaBrowser.Api/ChannelService.cs
index 8c336b1c9..8d3a9ee5a 100644
--- a/MediaBrowser.Api/ChannelService.cs
+++ b/MediaBrowser.Api/ChannelService.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using MediaBrowser.Api.UserLibrary;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
@@ -11,7 +12,6 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging;
diff --git a/MediaBrowser.Api/DisplayPreferencesService.cs b/MediaBrowser.Api/DisplayPreferencesService.cs
index c3ed40ad3..e5dd03807 100644
--- a/MediaBrowser.Api/DisplayPreferencesService.cs
+++ b/MediaBrowser.Api/DisplayPreferencesService.cs
@@ -1,9 +1,10 @@
-using System.Threading;
+using System;
+using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
+using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Net;
-using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging;
@@ -13,7 +14,7 @@ namespace MediaBrowser.Api
/// Class UpdateDisplayPreferences.
/// </summary>
[Route("/DisplayPreferences/{DisplayPreferencesId}", "POST", Summary = "Updates a user's display preferences for an item")]
- public class UpdateDisplayPreferences : DisplayPreferences, IReturnVoid
+ public class UpdateDisplayPreferences : DisplayPreferencesDto, IReturnVoid
{
/// <summary>
/// Gets or sets the id.
@@ -27,7 +28,7 @@ namespace MediaBrowser.Api
}
[Route("/DisplayPreferences/{Id}", "GET", Summary = "Gets a user's display preferences for an item")]
- public class GetDisplayPreferences : IReturn<DisplayPreferences>
+ public class GetDisplayPreferences : IReturn<DisplayPreferencesDto>
{
/// <summary>
/// Gets or sets the id.
@@ -50,28 +51,21 @@ namespace MediaBrowser.Api
public class DisplayPreferencesService : BaseApiService
{
/// <summary>
- /// The _display preferences manager.
+ /// The user manager.
/// </summary>
- private readonly IDisplayPreferencesRepository _displayPreferencesManager;
- /// <summary>
- /// The _json serializer.
- /// </summary>
- private readonly IJsonSerializer _jsonSerializer;
+ private readonly IDisplayPreferencesManager _displayPreferencesManager;
/// <summary>
/// Initializes a new instance of the <see cref="DisplayPreferencesService" /> class.
/// </summary>
- /// <param name="jsonSerializer">The json serializer.</param>
/// <param name="displayPreferencesManager">The display preferences manager.</param>
public DisplayPreferencesService(
ILogger<DisplayPreferencesService> logger,
IServerConfigurationManager serverConfigurationManager,
IHttpResultFactory httpResultFactory,
- IJsonSerializer jsonSerializer,
- IDisplayPreferencesRepository displayPreferencesManager)
+ IDisplayPreferencesManager displayPreferencesManager)
: base(logger, serverConfigurationManager, httpResultFactory)
{
- _jsonSerializer = jsonSerializer;
_displayPreferencesManager = displayPreferencesManager;
}
@@ -81,9 +75,34 @@ namespace MediaBrowser.Api
/// <param name="request">The request.</param>
public object Get(GetDisplayPreferences request)
{
- var result = _displayPreferencesManager.GetDisplayPreferences(request.Id, request.UserId, request.Client);
+ var result = _displayPreferencesManager.GetDisplayPreferences(Guid.Parse(request.UserId), request.Client);
+
+ if (result == null)
+ {
+ return null;
+ }
+
+ var dto = new DisplayPreferencesDto
+ {
+ Client = result.Client,
+ Id = result.UserId.ToString(),
+ ViewType = result.ViewType?.ToString(),
+ SortBy = result.SortBy,
+ SortOrder = result.SortOrder,
+ IndexBy = result.IndexBy?.ToString(),
+ RememberIndexing = result.RememberIndexing,
+ RememberSorting = result.RememberSorting,
+ ScrollDirection = result.ScrollDirection,
+ ShowBackdrop = result.ShowBackdrop,
+ ShowSidebar = result.ShowSidebar
+ };
- return ToOptimizedResult(result);
+ foreach (var homeSection in result.HomeSections)
+ {
+ dto.CustomPrefs["homesection" + homeSection.Order] = homeSection.Type.ToString().ToLowerInvariant();
+ }
+
+ return ToOptimizedResult(dto);
}
/// <summary>
@@ -92,10 +111,43 @@ namespace MediaBrowser.Api
/// <param name="request">The request.</param>
public void Post(UpdateDisplayPreferences request)
{
- // Serialize to json and then back so that the core doesn't see the request dto type
- var displayPreferences = _jsonSerializer.DeserializeFromString<DisplayPreferences>(_jsonSerializer.SerializeToString(request));
+ HomeSectionType[] defaults =
+ {
+ HomeSectionType.SmallLibraryTiles,
+ HomeSectionType.Resume,
+ HomeSectionType.ResumeAudio,
+ HomeSectionType.LiveTv,
+ HomeSectionType.NextUp,
+ HomeSectionType.LatestMedia,
+ HomeSectionType.None,
+ };
+
+ var prefs = _displayPreferencesManager.GetDisplayPreferences(Guid.Parse(request.UserId), request.Client);
+
+ prefs.ViewType = Enum.TryParse<ViewType>(request.ViewType, true, out var viewType) ? viewType : (ViewType?)null;
+ prefs.IndexBy = Enum.TryParse<IndexingKind>(request.IndexBy, true, out var indexBy) ? indexBy : (IndexingKind?)null;
+ prefs.ShowBackdrop = request.ShowBackdrop;
+ prefs.ShowSidebar = request.ShowSidebar;
+ prefs.SortBy = request.SortBy;
+ prefs.SortOrder = request.SortOrder;
+ prefs.RememberIndexing = request.RememberIndexing;
+ prefs.RememberSorting = request.RememberSorting;
+ prefs.ScrollDirection = request.ScrollDirection;
+ prefs.HomeSections.Clear();
+
+ for (int i = 0; i < 7; i++)
+ {
+ if (request.CustomPrefs.TryGetValue("homesection" + i, out var homeSection))
+ {
+ prefs.HomeSections.Add(new HomeSection
+ {
+ Order = i,
+ Type = Enum.TryParse<HomeSectionType>(homeSection, true, out var type) ? type : defaults[i]
+ });
+ }
+ }
- _displayPreferencesManager.SaveDisplayPreferences(displayPreferences, request.UserId, request.Client, CancellationToken.None);
+ _displayPreferencesManager.SaveChanges(prefs);
}
}
}
diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs
index 34cccffa3..2ff322d29 100644
--- a/MediaBrowser.Api/Movies/MoviesService.cs
+++ b/MediaBrowser.Api/Movies/MoviesService.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
diff --git a/MediaBrowser.Api/SuggestionsService.cs b/MediaBrowser.Api/SuggestionsService.cs
index 17afa8e79..b42e822e8 100644
--- a/MediaBrowser.Api/SuggestionsService.cs
+++ b/MediaBrowser.Api/SuggestionsService.cs
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs
index 165abd613..799cea648 100644
--- a/MediaBrowser.Api/TvShowsService.cs
+++ b/MediaBrowser.Api/TvShowsService.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
index 344861a49..fc19575b3 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
@@ -1,5 +1,6 @@
using System;
using System.Linq;
+using Jellyfin.Data.Enums;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Services;
@@ -466,8 +467,8 @@ namespace MediaBrowser.Api.UserLibrary
var sortOrderValue = sortOrders.Length > sortOrderIndex ? sortOrders[sortOrderIndex] : null;
var sortOrder = string.Equals(sortOrderValue, "Descending", StringComparison.OrdinalIgnoreCase)
- ? MediaBrowser.Model.Entities.SortOrder.Descending
- : MediaBrowser.Model.Entities.SortOrder.Ascending;
+ ? Jellyfin.Data.Enums.SortOrder.Descending
+ : Jellyfin.Data.Enums.SortOrder.Ascending;
result[i] = new ValueTuple<string, SortOrder>(vals[i], sortOrder);
}
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index cb35d6e32..22bb7fd55 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
diff --git a/MediaBrowser.Controller/IDisplayPreferencesManager.cs b/MediaBrowser.Controller/IDisplayPreferencesManager.cs
new file mode 100644
index 000000000..e27b0ec7c
--- /dev/null
+++ b/MediaBrowser.Controller/IDisplayPreferencesManager.cs
@@ -0,0 +1,25 @@
+using System;
+using Jellyfin.Data.Entities;
+
+namespace MediaBrowser.Controller
+{
+ /// <summary>
+ /// Manages the storage and retrieval of display preferences.
+ /// </summary>
+ public interface IDisplayPreferencesManager
+ {
+ /// <summary>
+ /// Gets the display preferences for the user and client.
+ /// </summary>
+ /// <param name="userId">The user's id.</param>
+ /// <param name="client">The client string.</param>
+ /// <returns>The associated display preferences.</returns>
+ DisplayPreferences GetDisplayPreferences(Guid userId, string client);
+
+ /// <summary>
+ /// Saves changes to the provided display preferences.
+ /// </summary>
+ /// <param name="preferences">The display preferences to save.</param>
+ void SaveChanges(DisplayPreferences preferences);
+ }
+}
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 9d6646857..b5eec1846 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
diff --git a/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs b/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs
deleted file mode 100644
index c2dcb66d7..000000000
--- a/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using MediaBrowser.Model.Entities;
-
-namespace MediaBrowser.Controller.Persistence
-{
- /// <summary>
- /// Interface IDisplayPreferencesRepository.
- /// </summary>
- public interface IDisplayPreferencesRepository : IRepository
- {
- /// <summary>
- /// Saves display preferences for an item.
- /// </summary>
- /// <param name="displayPreferences">The display preferences.</param>
- /// <param name="userId">The user id.</param>
- /// <param name="client">The client.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- void SaveDisplayPreferences(
- DisplayPreferences displayPreferences,
- string userId,
- string client,
- CancellationToken cancellationToken);
-
- /// <summary>
- /// Saves all display preferences for a user.
- /// </summary>
- /// <param name="displayPreferences">The display preferences.</param>
- /// <param name="userId">The user id.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- void SaveAllDisplayPreferences(
- IEnumerable<DisplayPreferences> displayPreferences,
- Guid userId,
- CancellationToken cancellationToken);
-
- /// <summary>
- /// Gets the display preferences.
- /// </summary>
- /// <param name="displayPreferencesId">The display preferences id.</param>
- /// <param name="userId">The user id.</param>
- /// <param name="client">The client.</param>
- /// <returns>Task{DisplayPreferences}.</returns>
- DisplayPreferences GetDisplayPreferences(string displayPreferencesId, string userId, string client);
-
- /// <summary>
- /// Gets all display preferences for the given user.
- /// </summary>
- /// <param name="userId">The user id.</param>
- /// <returns>Task{DisplayPreferences}.</returns>
- IEnumerable<DisplayPreferences> GetAllDisplayPreferences(Guid userId);
- }
-}
diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs
index b1a638883..0fd63770f 100644
--- a/MediaBrowser.Controller/Playlists/Playlist.cs
+++ b/MediaBrowser.Controller/Playlists/Playlist.cs
@@ -6,6 +6,7 @@ using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
diff --git a/MediaBrowser.Model/Dlna/SortCriteria.cs b/MediaBrowser.Model/Dlna/SortCriteria.cs
index 1f7fa76ad..53e4540cb 100644
--- a/MediaBrowser.Model/Dlna/SortCriteria.cs
+++ b/MediaBrowser.Model/Dlna/SortCriteria.cs
@@ -1,6 +1,6 @@
#pragma warning disable CS1591
-using MediaBrowser.Model.Entities;
+using Jellyfin.Data.Enums;
namespace MediaBrowser.Model.Dlna
{
diff --git a/MediaBrowser.Model/Entities/DisplayPreferences.cs b/MediaBrowser.Model/Entities/DisplayPreferencesDto.cs
index 7e5c5be3b..1f7fe3030 100644
--- a/MediaBrowser.Model/Entities/DisplayPreferences.cs
+++ b/MediaBrowser.Model/Entities/DisplayPreferencesDto.cs
@@ -1,22 +1,18 @@
#nullable disable
using System.Collections.Generic;
+using Jellyfin.Data.Enums;
namespace MediaBrowser.Model.Entities
{
/// <summary>
/// Defines the display preferences for any item that supports them (usually Folders).
/// </summary>
- public class DisplayPreferences
+ public class DisplayPreferencesDto
{
/// <summary>
- /// The image scale.
+ /// Initializes a new instance of the <see cref="DisplayPreferencesDto" /> class.
/// </summary>
- private const double ImageScale = .9;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="DisplayPreferences" /> class.
- /// </summary>
- public DisplayPreferences()
+ public DisplayPreferencesDto()
{
RememberIndexing = false;
PrimaryImageHeight = 250;
diff --git a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs
index 2b2377fda..ab74aff28 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs
@@ -2,7 +2,7 @@
#pragma warning disable CS1591
using System;
-using MediaBrowser.Model.Entities;
+using Jellyfin.Data.Enums;
namespace MediaBrowser.Model.LiveTv
{
diff --git a/MediaBrowser.Model/LiveTv/SeriesTimerQuery.cs b/MediaBrowser.Model/LiveTv/SeriesTimerQuery.cs
index b899a464b..dae885775 100644
--- a/MediaBrowser.Model/LiveTv/SeriesTimerQuery.cs
+++ b/MediaBrowser.Model/LiveTv/SeriesTimerQuery.cs
@@ -1,6 +1,6 @@
#pragma warning disable CS1591
-using MediaBrowser.Model.Entities;
+using Jellyfin.Data.Enums;
namespace MediaBrowser.Model.LiveTv
{