Keep folder extras with the item that owns the folder

This commit is contained in:
Shadowghost
2026-08-03 10:50:33 +02:00
parent 33a8cdfc0b
commit 4e2089b6a1
5 changed files with 146 additions and 3 deletions
+19 -1
View File
@@ -771,6 +771,17 @@ namespace MediaBrowser.Controller.Entities
[JsonIgnore]
protected virtual bool SupportsOwnedItems => !ParentId.IsEmpty() && IsFileProtocol;
/// <summary>
/// Gets a value indicating whether this item searches the folder it lives in for its own extras.
/// </summary>
[JsonIgnore]
protected virtual bool SearchesContainingFolderForExtras =>
IsFileProtocol
&& SupportsOwnedItems
&& !IsInMixedFolder
&& this is not (ICollectionFolder or UserRootFolder or AggregateFolder)
&& GetType() != typeof(Folder);
[JsonIgnore]
public virtual bool SupportsPeople => false;
@@ -1528,7 +1539,14 @@ namespace MediaBrowser.Controller.Entities
/// <returns><c>true</c> if any items have changed, else <c>false</c>.</returns>
protected virtual async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, IReadOnlyList<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
if (!IsFileProtocol || !SupportsOwnedItems || IsInMixedFolder || this is ICollectionFolder or UserRootFolder or AggregateFolder || this.GetType() == typeof(Folder))
if (!SearchesContainingFolderForExtras)
{
return false;
}
if (GetParent() is Folder container
&& container.SearchesContainingFolderForExtras
&& string.Equals(container.Path, ContainingFolderPath, StringComparison.OrdinalIgnoreCase))
{
return false;
}
@@ -47,7 +47,7 @@ namespace MediaBrowser.Controller.Entities.TV
public int? IndexNumberEnd { get; set; }
[JsonIgnore]
protected override bool SupportsOwnedItems => IsStacked || MediaSourceCount > 1;
protected override bool SupportsOwnedItems => IsStacked || LocalAlternateVersions.Length > 0 || MediaSourceCount > 1;
[JsonIgnore]
public override bool SupportsInheritedParentImages => true;
+18 -1
View File
@@ -527,7 +527,13 @@ namespace MediaBrowser.Controller.Entities
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, IReadOnlyList<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
var hasChanges = false;
// The extras of a version group are maintained by its primary.
if (!PrimaryVersionId.HasValue)
{
hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
}
// Clean up LocalAlternateVersions - remove paths that no longer exist
if (LocalAlternateVersions.Length > 0)
@@ -588,10 +594,20 @@ namespace MediaBrowser.Controller.Entities
{
altVideo.OwnerId = Id;
altVideo.SetPrimaryVersionId(Id);
altVideo.IsInMixedFolder = IsInMixedFolder;
LibraryManager.CreateItem(altVideo, GetParent());
}
}
// A version is resolved on its own, so it does not learn whether the folder it sits in
// holds other items. It has to share that with the version it belongs to, before the
// refresh below acts on it.
if (LibraryManager.GetItemById(id) is Video resolvedVersion && resolvedVersion.IsInMixedFolder != IsInMixedFolder)
{
resolvedVersion.IsInMixedFolder = IsInMixedFolder;
await resolvedVersion.UpdateToRepositoryAsync(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
}
await RefreshMetadataForOwnedVideo(options, copyTitleMetadata, path, cancellationToken).ConfigureAwait(false);
// Create LinkedChild entry for this local alternate version
@@ -671,6 +687,7 @@ namespace MediaBrowser.Controller.Entities
video.Id = id;
video.OwnerId = Id;
video.IsInMixedFolder = IsInMixedFolder;
LibraryManager.CreateItem(video, parentFolder);
newOptions.ForceSave = true;
}