fixes #762 - Marking unwatched doesn't update display

This commit is contained in:
Luke Pulverenti
2014-07-03 22:22:57 -04:00
parent 59dc591f66
commit 7fa9b14f56
55 changed files with 706 additions and 438 deletions

View File

@@ -25,13 +25,6 @@ namespace MediaBrowser.Controller.Dto
/// <returns>System.String.</returns>
string GetDtoId(BaseItem item);
/// <summary>
/// Gets the user item data dto.
/// </summary>
/// <param name="data">The data.</param>
/// <returns>UserItemDataDto.</returns>
UserItemDataDto GetUserItemDataDto(UserItemData data);
/// <summary>
/// Attaches the primary image aspect ratio.
/// </summary>

View File

@@ -6,6 +6,7 @@ using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Library;
using MediaBrowser.Model.Logging;
@@ -1571,5 +1572,19 @@ namespace MediaBrowser.Controller.Entities
return path;
}
public virtual void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user)
{
if (RunTimeTicks.HasValue)
{
double pct = RunTimeTicks.Value;
if (pct > 0)
{
pct = userData.PlaybackPositionTicks / pct;
dto.PlayedPercentage = 100 * pct;
}
}
}
}
}

View File

@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MoreLinq;
using System;
@@ -769,6 +770,11 @@ namespace MediaBrowser.Controller.Entities
/// <returns>IEnumerable{BaseItem}.</returns>
/// <exception cref="System.ArgumentNullException"></exception>
public virtual IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{
return GetChildren(user, includeLinkedChildren, false);
}
internal IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren, bool includeHidden)
{
if (user == null)
{
@@ -780,7 +786,7 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem>();
var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, false);
var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, includeHidden, false);
return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list;
}
@@ -796,9 +802,10 @@ namespace MediaBrowser.Controller.Entities
/// <param name="user">The user.</param>
/// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param>
/// <param name="list">The list.</param>
/// <param name="includeHidden">if set to <c>true</c> [include hidden].</param>
/// <param name="recursive">if set to <c>true</c> [recursive].</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
private bool AddChildrenToList(User user, bool includeLinkedChildren, List<BaseItem> list, bool recursive)
private bool AddChildrenToList(User user, bool includeLinkedChildren, List<BaseItem> list, bool includeHidden, bool recursive)
{
var hasLinkedChildren = false;
@@ -806,7 +813,7 @@ namespace MediaBrowser.Controller.Entities
{
if (child.IsVisible(user))
{
if (!child.IsHiddenFromUser(user))
if (includeHidden || !child.IsHiddenFromUser(user))
{
list.Add(child);
}
@@ -815,7 +822,7 @@ namespace MediaBrowser.Controller.Entities
{
var folder = (Folder)child;
if (folder.AddChildrenToList(user, includeLinkedChildren, list, true))
if (folder.AddChildrenToList(user, includeLinkedChildren, list, includeHidden, true))
{
hasLinkedChildren = true;
}
@@ -855,7 +862,7 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem>();
var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, true);
var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, false, true);
return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list;
}
@@ -1069,5 +1076,68 @@ namespace MediaBrowser.Controller.Entities
return GetRecursiveChildren(user).Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual)
.All(i => i.IsUnplayed(user));
}
public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user)
{
var recursiveItemCount = 0;
var unplayed = 0;
double totalPercentPlayed = 0;
IEnumerable<BaseItem> children;
var folder = this;
var season = folder as Season;
if (season != null)
{
children = season.GetEpisodes(user).Where(i => i.LocationType != LocationType.Virtual);
}
else
{
children = folder.GetRecursiveChildren(user)
.Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual);
}
// Loop through each recursive child
foreach (var child in children)
{
recursiveItemCount++;
var isUnplayed = true;
var itemUserData = UserDataManager.GetUserData(user.Id, child.GetUserDataKey());
// Incrememt totalPercentPlayed
if (itemUserData != null)
{
if (itemUserData.Played)
{
totalPercentPlayed += 100;
isUnplayed = false;
}
else if (itemUserData.PlaybackPositionTicks > 0 && child.RunTimeTicks.HasValue && child.RunTimeTicks.Value > 0)
{
double itemPercent = itemUserData.PlaybackPositionTicks;
itemPercent /= child.RunTimeTicks.Value;
totalPercentPlayed += itemPercent;
}
}
if (isUnplayed)
{
unplayed++;
}
}
dto.UnplayedItemCount = unplayed;
if (recursiveItemCount > 0)
{
dto.PlayedPercentage = totalPercentPlayed / recursiveItemCount;
dto.Played = dto.PlayedPercentage.Value >= 100;
}
}
}
}

View File

@@ -1,4 +1,6 @@

using MediaBrowser.Model.Dto;
using System;
namespace MediaBrowser.Controller.Entities
{
/// <summary>
@@ -6,10 +8,24 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public interface IHasUserData
{
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>The identifier.</value>
Guid Id { get; set; }
/// <summary>
/// Gets the user data key.
/// </summary>
/// <returns>System.String.</returns>
string GetUserDataKey();
/// <summary>
/// Fills the user data dto values.
/// </summary>
/// <param name="dto">The dto.</param>
/// <param name="userData">The user data.</param>
/// <param name="user">The user.</param>
void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user);
}
}

View File

@@ -91,7 +91,7 @@ namespace MediaBrowser.Controller.Entities.TV
{
get
{
return FindParent<Season>();
return Season;
}
}

View File

@@ -1,4 +1,5 @@
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -51,5 +52,10 @@ namespace MediaBrowser.Controller.Entities
LibraryManager.RegisterItem(item);
}
}
public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user)
{
// Nothing meaninful here and will only waste resources
}
}
}

View File

@@ -44,7 +44,7 @@ namespace MediaBrowser.Controller.Entities
var excludeFolderIds = user.Configuration.ExcludeFoldersFromGrouping.Select(i => new Guid(i)).ToList();
return user.RootFolder
.GetChildren(user, true)
.GetChildren(user, true, true)
.OfType<Folder>()
.Where(i => !excludeFolderIds.Contains(i.Id) && !IsExcludedFromGrouping(i));
}

View File

@@ -1,4 +1,5 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using System;
using System.Threading;
@@ -34,5 +35,13 @@ namespace MediaBrowser.Controller.Library
/// <param name="key">The key.</param>
/// <returns>Task{UserItemData}.</returns>
UserItemData GetUserData(Guid userId, string key);
/// <summary>
/// Gets the user data dto.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="user">The user.</param>
/// <returns>UserItemDataDto.</returns>
UserItemDataDto GetUserDataDto(IHasUserData item, User user);
}
}

View File

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Controller.LiveTv
{
public interface ILiveTvRecording : IHasImages, IHasMediaSources
public interface ILiveTvRecording : IHasImages, IHasMediaSources, IHasUserData
{
string ServiceName { get; set; }
@@ -20,8 +20,6 @@ namespace MediaBrowser.Controller.LiveTv
string GetClientTypeName();
string GetUserDataKey();
bool IsParentalAllowed(User user);
Task RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken);

View File

@@ -1,6 +1,6 @@
using System;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
@@ -18,6 +18,11 @@ namespace MediaBrowser.Controller.Providers
/// </summary>
[Obsolete]
public bool ForceSave { get; set; }
public MetadataRefreshOptions()
{
MetadataRefreshMode = MetadataRefreshMode.Default;
}
}
public class ImageRefreshOptions
@@ -38,48 +43,54 @@ namespace MediaBrowser.Controller.Providers
public bool IsReplacingImage(ImageType type)
{
return ReplaceAllImages || ReplaceImages.Contains(type);
return ImageRefreshMode == ImageRefreshMode.FullRefresh &&
(ReplaceAllImages || ReplaceImages.Contains(type));
}
}
public enum MetadataRefreshMode
{
/// <summary>
/// Providers will be executed based on default rules
/// The none
/// </summary>
EnsureMetadata = 0,
/// <summary>
/// No providers will be executed
/// </summary>
None = 1,
/// <summary>
/// All providers will be executed to search for new metadata
/// </summary>
FullRefresh = 2,
None = 0,
/// <summary>
/// The validation only
/// </summary>
ValidationOnly = 3
ValidationOnly = 1,
/// <summary>
/// Providers will be executed based on default rules
/// </summary>
Default = 2,
/// <summary>
/// All providers will be executed to search for new metadata
/// </summary>
FullRefresh = 3
}
public enum ImageRefreshMode
{
/// <summary>
/// The none
/// </summary>
None = 0,
/// <summary>
/// The default
/// </summary>
Default = 0,
Default = 1,
/// <summary>
/// Existing images will be validated
/// </summary>
ValidationOnly = 1,
ValidationOnly = 2,
/// <summary>
/// All providers will be executed to search for new metadata
/// </summary>
FullRefresh = 2
FullRefresh = 3
}
}

View File

@@ -219,7 +219,13 @@ namespace MediaBrowser.Controller.Session
/// <param name="deviceName">Name of the device.</param>
/// <param name="remoteEndPoint">The remote end point.</param>
/// <returns>Task{SessionInfo}.</returns>
Task<AuthenticationResult> AuthenticateNewSession(string username, string password, string clientType, string appVersion, string deviceId, string deviceName, string remoteEndPoint);
Task<AuthenticationResult> AuthenticateNewSession(string username,
string password,
string clientType,
string appVersion,
string deviceId,
string deviceName,
string remoteEndPoint);
/// <summary>
/// Reports the capabilities.