diff --git a/Umbraco.Community.Skrivlet/Converters/EmbedBlockDataConverter.cs b/Umbraco.Community.Skrivlet/Converters/EmbedBlockDataConverter.cs new file mode 100644 index 0000000..b7390e7 --- /dev/null +++ b/Umbraco.Community.Skrivlet/Converters/EmbedBlockDataConverter.cs @@ -0,0 +1,76 @@ +using System.Text.Json; + +namespace Umbraco.Community.SkrivLet.Converters +{ + public class EmbedBlockDataConverter : IBlockDataConverter + { + public bool CanConvert(string type) + { + return type.Equals("embed"); + } + + public SkrivLetBlockBase Convert(ref Utf8JsonReader reader, string id, string type) + { + if (reader.TokenType != JsonTokenType.StartObject) + { + throw new JsonException(); + } + + var block = new SkrivLetBlock(id, type); + block.Data = new EmbedBlockData(); + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + return block; + } + + // Get the key. + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new JsonException(); + } + + string? propertyName = reader.GetString() ?? ""; + switch (propertyName.ToLower()) + { + case "service": + reader.Read(); + block.Data.Service = reader.GetString() ?? ""; + break; + case "source": + reader.Read(); + block.Data.Source = reader.GetString() ?? ""; + break; + case "embed": + reader.Read(); + block.Data.Embed = reader.GetString() ?? ""; + break; + case "width": + reader.Read(); + block.Data.Width = reader.GetInt16(); + break; + case "height": + reader.Read(); + block.Data.Height = reader.GetInt16(); + break; + case "caption": + reader.Read(); + block.Data.Caption = reader.GetString() ?? ""; + break; + } + } + return block; + } + } + + public class EmbedBlockData + { + public string Service { get; set; } + public string Source { get; set; } + public string Embed { get; set; } + public int Height { get; set; } + public int Width { get; set; } + public string Caption { get; set; } + } +} diff --git a/Umbraco.Community.Skrivlet/SkrivLetComposer.cs b/Umbraco.Community.Skrivlet/SkrivLetComposer.cs index bc73651..24243a4 100644 --- a/Umbraco.Community.Skrivlet/SkrivLetComposer.cs +++ b/Umbraco.Community.Skrivlet/SkrivLetComposer.cs @@ -18,6 +18,7 @@ public void Compose(IUmbracoBuilder builder) builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); + builder.Services.AddTransient(); } } } diff --git a/Umbraco.Community.Skrivlet/Views/Partials/SkrivLet/Embed.cshtml b/Umbraco.Community.Skrivlet/Views/Partials/SkrivLet/Embed.cshtml new file mode 100644 index 0000000..af1c3cf --- /dev/null +++ b/Umbraco.Community.Skrivlet/Views/Partials/SkrivLet/Embed.cshtml @@ -0,0 +1,4 @@ +@model Umbraco.Community.SkrivLet.SkrivLetBlock +
+ +
diff --git a/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/basic-theme.css b/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/basic-theme.css index 7fe2571..a8027cd 100644 --- a/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/basic-theme.css +++ b/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/basic-theme.css @@ -97,3 +97,14 @@ .sl-check__text--checked { text-decoration: line-through; } + +.sl-embed { + margin: 0 0 1.25rem 0; +} + +.sl-embed--youtube iframe, +.sl-embed--vimeo iframe { + aspect-ratio: 16 / 9; + width: 100%; + height: auto; +} diff --git a/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/skrivlet.controller.js b/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/skrivlet.controller.js index b9d7040..04a1481 100644 --- a/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/skrivlet.controller.js +++ b/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/skrivlet.controller.js @@ -213,6 +213,50 @@ angular.module('umbraco').controller('SkrivLetController', function ($scope, edi } + class EmbedWithUI extends Embed { + static get toolbox() { + return { + title: 'Video', + icon: '' + }; + } + + render() { + if (!this.data.service) { + const container = document.createElement('div'); + + this.element = container; + + const label = document.createElement('label'); + label.innerHTML = 'Enter a URL to embed a video from YouTube or Vimeo'; + label.classList.add('cdx-label'); + label.setAttribute('for', 'embed-input'); + container.appendChild(label); + + const input = document.createElement('input'); + input.classList.add('cdx-input'); + input.placeholder = ''; + input.type = 'url'; + input.id = 'embed-input'; + input.addEventListener('paste', (event) => { + const url = event.clipboardData.getData('text'); + const service = Object.keys(Embed.services).find((key) => Embed.services[key].regex.test(url)); + if (service) { + this.onPaste({detail: {key: service, data: url}}); + } + }); + container.appendChild(input); + + return container; + } + return super.render(); + } + + validate(savedData) { + return savedData.service && savedData.source ? true : false; + } + } + const editor = new EditorJS({ holder: 'editorjs', @@ -230,8 +274,13 @@ angular.module('umbraco').controller('SkrivLetController', function ($scope, edi tools: { embed: { - class: Embed, - inlineToolbar: true + class: EmbedWithUI, + config: { + services: { + youtube: true, + vimeo: true + } + } }, header: Header, image: UmbracoImageTool, diff --git a/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/skrivlet.css b/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/skrivlet.css index b176e69..1c2e68c 100644 --- a/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/skrivlet.css +++ b/Umbraco.Community.Skrivlet/wwwroot/App_Plugins/SkrivLet/skrivlet.css @@ -34,6 +34,10 @@ max-width: 800px; } +.cdx-label { + font-weight: 700; +} + /* Image */ .simple-image { padding: 20px 0;