From 0ff5397290cdfc2f2ae4dcfb460b3b589be74c38 Mon Sep 17 00:00:00 2001 From: George Drak Date: Wed, 8 Sep 2021 13:55:10 +0500 Subject: [PATCH] feat(blocks): move block priority and max count out of descriptor and into metadata --- src/Sitko.Blockly.Blazor/Forms/BlocklyForm.cs | 4 +- src/Sitko.Blockly/BlockDescriptor.cs | 4 -- src/Sitko.Blockly/Blockly.cs | 15 ++++++++ src/Sitko.Blockly/BlocklyFormOptions.cs | 8 ++-- src/Sitko.Blockly/Blocks/CutBlock.cs | 3 +- src/Sitko.Blockly/Blocks/FilesBlock.cs | 3 +- src/Sitko.Blockly/Blocks/GalleryBlock.cs | 3 +- src/Sitko.Blockly/Blocks/IframeBlock.cs | 3 +- src/Sitko.Blockly/Blocks/QuoteBlock.cs | 3 +- src/Sitko.Blockly/Blocks/TextBlock.cs | 3 +- src/Sitko.Blockly/Blocks/TwitchBlock.cs | 3 +- src/Sitko.Blockly/Blocks/TwitterBlock.cs | 3 +- src/Sitko.Blockly/Blocks/YoutubeBlock.cs | 3 +- src/Sitko.Blockly/ContentBlockMetadata.cs | 38 +++++++++++++++++++ 14 files changed, 68 insertions(+), 28 deletions(-) create mode 100644 src/Sitko.Blockly/ContentBlockMetadata.cs diff --git a/src/Sitko.Blockly.Blazor/Forms/BlocklyForm.cs b/src/Sitko.Blockly.Blazor/Forms/BlocklyForm.cs index c339c87..4db831c 100644 --- a/src/Sitko.Blockly.Blazor/Forms/BlocklyForm.cs +++ b/src/Sitko.Blockly.Blazor/Forms/BlocklyForm.cs @@ -77,7 +77,7 @@ protected override void OnInitialized() base.OnInitialized(); BlockDescriptors = Blockly.Descriptors .Where(d => FormOptions.AllowedBlocks.Any() == false || FormOptions.AllowedBlocks.Contains(d.Type)) - .OrderBy(d => FormOptions.BlockPriority(d) ?? d.Priority).ThenBy(d => d.Type.FullName).ToArray(); + .OrderBy(d => FormOptions.BlockPriority(d)).ThenBy(d => d.Type.FullName).ToArray(); OrderedBlocks.SetItems(CurrentValue?.OrderBy(b => b.Position) ?? new List().AsEnumerable()); Blocks.AddRange(CurrentValue ?? new List()); BlocklyFormService.AddForm(this); @@ -100,7 +100,7 @@ protected bool CanAdd(IBlazorBlockDescriptor blockDescriptor) return false; } - var blockMaxCount = FormOptions.MaxBlockCount(blockDescriptor) ?? blockDescriptor.MaxCount; + var blockMaxCount = FormOptions.MaxBlockCount(blockDescriptor); if (blockMaxCount > 0) { var blocksCount = CurrentValue?.Count(b => b.GetType() == blockDescriptor.Type); diff --git a/src/Sitko.Blockly/BlockDescriptor.cs b/src/Sitko.Blockly/BlockDescriptor.cs index f2782f8..9d5caba 100644 --- a/src/Sitko.Blockly/BlockDescriptor.cs +++ b/src/Sitko.Blockly/BlockDescriptor.cs @@ -8,8 +8,6 @@ public interface IBlockDescriptor { string Title { get; } Type Type { get; } - int MaxCount { get; } - int Priority { get; } string Key { get; } bool ShouldRender(BlockListContext context, ContentBlock block) => true; bool ShouldRenderNext(BlockListContext context, ContentBlock block) => true; @@ -25,8 +23,6 @@ public abstract record BlockDescriptor : IBlockDescriptor public abstract string Title { get; } public abstract Type Type { get; } public abstract string Key { get; } - public virtual int MaxCount { get; } = 0; - public virtual int Priority { get; } = int.MaxValue; } public abstract record BlockDescriptor : BlockDescriptor, IBlockDescriptor diff --git a/src/Sitko.Blockly/Blockly.cs b/src/Sitko.Blockly/Blockly.cs index d51e3db..3e70a34 100644 --- a/src/Sitko.Blockly/Blockly.cs +++ b/src/Sitko.Blockly/Blockly.cs @@ -7,6 +7,7 @@ namespace Sitko.Blockly { using System.Collections.Concurrent; + using System.Reflection; public interface IBlockly where TBlockDescriptor : IBlockDescriptor { @@ -23,6 +24,7 @@ public interface IBlockly where TBlockDescriptor : IBlockDescr public class Blockly { protected static readonly ConcurrentDictionary StaticDescriptors = new(); + protected static readonly ConcurrentDictionary StaticMetadata = new(); public static IBlockDescriptor[] GetDescriptors() => StaticDescriptors.Values.ToArray(); @@ -32,12 +34,16 @@ public static IBlockDescriptor[] GetDescriptors() => public static IBlockDescriptor? GetDescriptor(Type type) => StaticDescriptors.Values.FirstOrDefault(d => d.Type == type); + + public static IContentBlockMetadata GetMetadata(IBlockDescriptor descriptor) => + StaticMetadata.Values.First(d => d.BlockType == descriptor.Type); } public class Blockly : Blockly, IBlockly where TBlockDescriptor : IBlockDescriptor { private readonly List blockDescriptors; + private readonly List blocksMetadata = new(); private readonly ILogger> logger; public Blockly(IEnumerable blockDescriptors, ILogger> logger) @@ -88,6 +94,15 @@ public Task InitAsync() foreach (var blockDescriptor in blockDescriptors.Cast()) { StaticDescriptors.TryAdd(blockDescriptor.Type, blockDescriptor); + var metadataAttribute = blockDescriptor.Type.GetCustomAttribute() ?? + new ContentBlockMetadataAttribute(); + blocksMetadata.Add(new ContentBlockMetadata(blockDescriptor.Type, metadataAttribute.Priority, + metadataAttribute.MaxCount)); + } + + foreach (var blockMetadata in blocksMetadata) + { + StaticMetadata.TryAdd(blockMetadata.BlockType, blockMetadata); } return Task.CompletedTask; diff --git a/src/Sitko.Blockly/BlocklyFormOptions.cs b/src/Sitko.Blockly/BlocklyFormOptions.cs index a479e0b..78fbafe 100644 --- a/src/Sitko.Blockly/BlocklyFormOptions.cs +++ b/src/Sitko.Blockly/BlocklyFormOptions.cs @@ -14,24 +14,24 @@ public class BlocklyFormOptions public IStorage? Storage { get; set; } - public int? MaxBlockCount(IBlockDescriptor descriptor) + public int MaxBlockCount(IBlockDescriptor descriptor) { if (maxBlockCounts.ContainsKey(descriptor.Type)) { return maxBlockCounts[descriptor.Type]; } - return null; + return Blockly.GetMetadata(descriptor).MaxCount; } - public int? BlockPriority(IBlockDescriptor descriptor) + public int BlockPriority(IBlockDescriptor descriptor) { if (blockPriorities.ContainsKey(descriptor.Type)) { return blockPriorities[descriptor.Type]; } - return null; + return Blockly.GetMetadata(descriptor).Priority; } public BlocklyFormOptions ClearBlockMaxCounts() diff --git a/src/Sitko.Blockly/Blocks/CutBlock.cs b/src/Sitko.Blockly/Blocks/CutBlock.cs index d54a435..7e0b751 100644 --- a/src/Sitko.Blockly/Blocks/CutBlock.cs +++ b/src/Sitko.Blockly/Blocks/CutBlock.cs @@ -2,6 +2,7 @@ namespace Sitko.Blockly.Blocks { + [ContentBlockMetadata(2, 1)] public record CutBlock : ContentBlock { @@ -15,7 +16,5 @@ public record CutBlockDescriptor : BlockDescriptor public CutBlockDescriptor(ILocalizationProvider localizationProvider) : base(localizationProvider) { } - public override int Priority => 2; - public override int MaxCount => 1; } } diff --git a/src/Sitko.Blockly/Blocks/FilesBlock.cs b/src/Sitko.Blockly/Blocks/FilesBlock.cs index 691a670..402b762 100644 --- a/src/Sitko.Blockly/Blocks/FilesBlock.cs +++ b/src/Sitko.Blockly/Blocks/FilesBlock.cs @@ -5,6 +5,7 @@ namespace Sitko.Blockly.Blocks { + [ContentBlockMetadata(5)] public record FilesBlock : ContentBlock { public override string ToString() => $"Files: {string.Join(", ", Files.Select(p => p.FileName))}"; @@ -14,8 +15,6 @@ public record FilesBlock : ContentBlock public record FilesBlockDescriptor : BlockDescriptor { - public override int Priority => 5; - public FilesBlockDescriptor(ILocalizationProvider localizationProvider) : base(localizationProvider) { } diff --git a/src/Sitko.Blockly/Blocks/GalleryBlock.cs b/src/Sitko.Blockly/Blocks/GalleryBlock.cs index 98d6dcf..08f2567 100644 --- a/src/Sitko.Blockly/Blocks/GalleryBlock.cs +++ b/src/Sitko.Blockly/Blocks/GalleryBlock.cs @@ -5,6 +5,7 @@ namespace Sitko.Blockly.Blocks { + [ContentBlockMetadata(3)] public record GalleryBlock : ContentBlock { public override string ToString() => $"Gallery: {string.Join(", ", Pictures.Select(p => p.FileName))}"; @@ -14,8 +15,6 @@ public record GalleryBlock : ContentBlock public record GalleryBlockDescriptor : BlockDescriptor { - public override int Priority => 3; - public GalleryBlockDescriptor(ILocalizationProvider localizationProvider) : base( localizationProvider) { diff --git a/src/Sitko.Blockly/Blocks/IframeBlock.cs b/src/Sitko.Blockly/Blocks/IframeBlock.cs index 7754fd2..8b66ced 100644 --- a/src/Sitko.Blockly/Blocks/IframeBlock.cs +++ b/src/Sitko.Blockly/Blocks/IframeBlock.cs @@ -2,6 +2,7 @@ namespace Sitko.Blockly.Blocks { + [ContentBlockMetadata(9)] public record IframeBlock : ContentBlock { public override string ToString() => $"Frame: {Src}"; @@ -11,8 +12,6 @@ public record IframeBlock : ContentBlock public record IframeBlockDescriptor : BlockDescriptor { - public override int Priority => 9; - public IframeBlockDescriptor(ILocalizationProvider localizationProvider) : base( localizationProvider) { diff --git a/src/Sitko.Blockly/Blocks/QuoteBlock.cs b/src/Sitko.Blockly/Blocks/QuoteBlock.cs index cfafce3..e7adcd1 100644 --- a/src/Sitko.Blockly/Blocks/QuoteBlock.cs +++ b/src/Sitko.Blockly/Blocks/QuoteBlock.cs @@ -3,6 +3,7 @@ namespace Sitko.Blockly.Blocks { + [ContentBlockMetadata(4)] public record QuoteBlock : ContentBlock { public override string ToString() => $"{Author}: {Text} ({Link})"; @@ -15,8 +16,6 @@ public record QuoteBlock : ContentBlock public record QuoteBlockDescriptor : BlockDescriptor { - public override int Priority => 4; - public QuoteBlockDescriptor(ILocalizationProvider localizationProvider) : base(localizationProvider) { } diff --git a/src/Sitko.Blockly/Blocks/TextBlock.cs b/src/Sitko.Blockly/Blocks/TextBlock.cs index ecbd6a9..6e19c08 100644 --- a/src/Sitko.Blockly/Blocks/TextBlock.cs +++ b/src/Sitko.Blockly/Blocks/TextBlock.cs @@ -2,6 +2,7 @@ namespace Sitko.Blockly.Blocks { + [ContentBlockMetadata(1)] public record TextBlock : ContentBlock { public override string ToString() => Text; @@ -11,8 +12,6 @@ public record TextBlock : ContentBlock public record TextBlockDescriptor : BlockDescriptor { - public override int Priority => 1; - public TextBlockDescriptor(ILocalizationProvider localizationProvider) : base(localizationProvider) { } diff --git a/src/Sitko.Blockly/Blocks/TwitchBlock.cs b/src/Sitko.Blockly/Blocks/TwitchBlock.cs index e747d9a..e0bc016 100644 --- a/src/Sitko.Blockly/Blocks/TwitchBlock.cs +++ b/src/Sitko.Blockly/Blocks/TwitchBlock.cs @@ -4,6 +4,7 @@ namespace Sitko.Blockly.Blocks { + [ContentBlockMetadata(8)] public record TwitchBlock : UrlContentBlock { protected override bool IsEmpty => string.IsNullOrEmpty(VideoId) && string.IsNullOrEmpty(ChannelId) && @@ -124,8 +125,6 @@ protected override void ParseUrl(string? url) public record TwitchBlockDescriptor : BlockDescriptor { - public override int Priority => 8; - public TwitchBlockDescriptor(ILocalizationProvider localizationProvider) : base( localizationProvider) { diff --git a/src/Sitko.Blockly/Blocks/TwitterBlock.cs b/src/Sitko.Blockly/Blocks/TwitterBlock.cs index d89059a..60597e6 100644 --- a/src/Sitko.Blockly/Blocks/TwitterBlock.cs +++ b/src/Sitko.Blockly/Blocks/TwitterBlock.cs @@ -4,6 +4,7 @@ namespace Sitko.Blockly.Blocks { + [ContentBlockMetadata(7)] public record TwitterBlock : UrlContentBlock { protected override bool IsEmpty => string.IsNullOrEmpty(TweetId); @@ -41,8 +42,6 @@ protected override void ParseUrl(string? url) public record TwitterBlockDescriptor : BlockDescriptor { - public override int Priority => 7; - public TwitterBlockDescriptor(ILocalizationProvider localizationProvider) : base( localizationProvider) { diff --git a/src/Sitko.Blockly/Blocks/YoutubeBlock.cs b/src/Sitko.Blockly/Blocks/YoutubeBlock.cs index 36dbeb1..8fde471 100644 --- a/src/Sitko.Blockly/Blocks/YoutubeBlock.cs +++ b/src/Sitko.Blockly/Blocks/YoutubeBlock.cs @@ -4,6 +4,7 @@ namespace Sitko.Blockly.Blocks { + [ContentBlockMetadata(6)] public record YoutubeBlock : UrlContentBlock { protected override bool IsEmpty => string.IsNullOrEmpty(YoutubeId); @@ -32,8 +33,6 @@ protected override void ParseUrl(string? url) public record YoutubeBlockDescriptor : BlockDescriptor { - public override int Priority => 6; - public YoutubeBlockDescriptor(ILocalizationProvider localizationProvider) : base( localizationProvider) { diff --git a/src/Sitko.Blockly/ContentBlockMetadata.cs b/src/Sitko.Blockly/ContentBlockMetadata.cs new file mode 100644 index 0000000..afd53d9 --- /dev/null +++ b/src/Sitko.Blockly/ContentBlockMetadata.cs @@ -0,0 +1,38 @@ +namespace Sitko.Blockly +{ + using System; + + public interface IContentBlockMetadata + { + int Priority { get; } + int MaxCount { get; } + Type BlockType { get; } + } + + public class ContentBlockMetadata : IContentBlockMetadata + { + public int Priority { get; } + public int MaxCount { get; } + + public Type BlockType { get; } + + public ContentBlockMetadata(Type blockType, int priority = int.MaxValue, int maxCount = 0) + { + Priority = priority; + MaxCount = maxCount; + BlockType = blockType; + } + } + + public class ContentBlockMetadataAttribute : Attribute + { + public int Priority { get; } + public int MaxCount { get; } + + public ContentBlockMetadataAttribute(int priority = int.MaxValue, int maxCount = 0) + { + Priority = priority; + MaxCount = maxCount; + } + } +}