diff --git a/src/ModelPublisher.Core/Models/ReleaseManifest.cs b/src/ModelPublisher.Core/Models/ReleaseManifest.cs index ab93190..0853a45 100644 --- a/src/ModelPublisher.Core/Models/ReleaseManifest.cs +++ b/src/ModelPublisher.Core/Models/ReleaseManifest.cs @@ -38,10 +38,28 @@ public string ResolveFilePath(string relativePath) return Path.GetFullPath(Path.Combine(ManifestDirectory, relativePath)); } + /// + /// Returns the description with the platform's disclaimer appended, formatted for the platform + /// (markdown if supported, plain text otherwise). + /// public string GetDescription(IPlatformPublisher publisher) - => publisher.SupportsMarkdown - ? Description - : MarkdownHelper.ToPlainText(Description); + { + var markdown = AppendDisclaimer(Description, publisher.Disclaimer); + return publisher.SupportsMarkdown ? markdown : MarkdownHelper.ToPlainText(markdown); + } + + /// + /// Returns the description with the platform's disclaimer appended, always as markdown. + /// Use this when the caller handles its own format conversion (e.g. TipTap HTML injection). + /// + public string GetDescriptionMarkdown(IPlatformPublisher publisher) + => AppendDisclaimer(Description, publisher.Disclaimer); + + private static string AppendDisclaimer(string description, string disclaimer) + { + if (string.IsNullOrWhiteSpace(disclaimer)) return description; + return $"{description}\n\n---\n\n{disclaimer}"; + } } public class ManifestFiles diff --git a/src/ModelPublisher.Core/Platforms/Cults3DPublisher.cs b/src/ModelPublisher.Core/Platforms/Cults3DPublisher.cs index 6d80552..cc1565e 100644 --- a/src/ModelPublisher.Core/Platforms/Cults3DPublisher.cs +++ b/src/ModelPublisher.Core/Platforms/Cults3DPublisher.cs @@ -22,6 +22,8 @@ public class Cults3DPublisher : IPlatformPublisher public bool IsFreeOnly => true; public bool SupportsMarkdown => true; + public string Disclaimer => ""; + public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default) { try diff --git a/src/ModelPublisher.Core/Platforms/IPlatformPublisher.cs b/src/ModelPublisher.Core/Platforms/IPlatformPublisher.cs index f93721f..76d9bc9 100644 --- a/src/ModelPublisher.Core/Platforms/IPlatformPublisher.cs +++ b/src/ModelPublisher.Core/Platforms/IPlatformPublisher.cs @@ -17,6 +17,12 @@ public interface IPlatformPublisher bool SupportsMarkdown => false; + /// + /// Platform-specific disclaimer appended to the bottom of every description (markdown format). + /// Return empty string to omit. + /// + string Disclaimer => ""; + Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default); Task PublishPremiumAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default); diff --git a/src/ModelPublisher.Core/Platforms/MakerOnlinePublisher.cs b/src/ModelPublisher.Core/Platforms/MakerOnlinePublisher.cs index 8f8447c..fc3da35 100644 --- a/src/ModelPublisher.Core/Platforms/MakerOnlinePublisher.cs +++ b/src/ModelPublisher.Core/Platforms/MakerOnlinePublisher.cs @@ -21,6 +21,8 @@ public class MakerOnlinePublisher : IPlatformPublisher public bool IsFreeOnly => true; public bool SupportsMarkdown => true; + public string Disclaimer => ""; + public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default) { try diff --git a/src/ModelPublisher.Core/Platforms/MakerWorldPublisher.cs b/src/ModelPublisher.Core/Platforms/MakerWorldPublisher.cs index 61dc88f..7aafee5 100644 --- a/src/ModelPublisher.Core/Platforms/MakerWorldPublisher.cs +++ b/src/ModelPublisher.Core/Platforms/MakerWorldPublisher.cs @@ -21,6 +21,8 @@ public class MakerWorldPublisher : IPlatformPublisher public bool IsFreeOnly => true; public bool SupportsMarkdown => true; + public string Disclaimer => ""; + public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default) { try diff --git a/src/ModelPublisher.Core/Platforms/PatreonPublisher.cs b/src/ModelPublisher.Core/Platforms/PatreonPublisher.cs index 56531e2..cae236a 100644 --- a/src/ModelPublisher.Core/Platforms/PatreonPublisher.cs +++ b/src/ModelPublisher.Core/Platforms/PatreonPublisher.cs @@ -32,6 +32,8 @@ public class PatreonPublisher : IPlatformPublisher public bool IsFreeOnly => true; // Patreon posts aren't free, but we do not have both free and premium tiers public bool SupportsMarkdown => false; + public string Disclaimer => ""; + public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default) { try diff --git a/src/ModelPublisher.Core/Platforms/PrintablesPublisher.cs b/src/ModelPublisher.Core/Platforms/PrintablesPublisher.cs index aa62fa3..9a64d9b 100644 --- a/src/ModelPublisher.Core/Platforms/PrintablesPublisher.cs +++ b/src/ModelPublisher.Core/Platforms/PrintablesPublisher.cs @@ -16,6 +16,8 @@ public class PrintablesPublisher : IPlatformPublisher public bool IsFreeOnly => false; public bool SupportsMarkdown => false; + public string Disclaimer => ""; + public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default) { @@ -93,7 +95,7 @@ await page .CheckAsync(); // Step 8: Description — inject HTML directly into TipTap's ProseMirror div - var descHtml = MarkdownHelper.ToTipTapHtml(manifest.Description); + var descHtml = MarkdownHelper.ToTipTapHtml(manifest.GetDescriptionMarkdown(this)); var descEditor = page.Locator("section") .Filter(new() { HasText = "Description" }) .GetByRole(AriaRole.Textbox); diff --git a/src/ModelPublisher.Core/Platforms/ThangsPublisher.cs b/src/ModelPublisher.Core/Platforms/ThangsPublisher.cs index 124c812..3bdc96d 100644 --- a/src/ModelPublisher.Core/Platforms/ThangsPublisher.cs +++ b/src/ModelPublisher.Core/Platforms/ThangsPublisher.cs @@ -20,6 +20,8 @@ public class ThangsPublisher : IPlatformPublisher public bool IsFreeOnly => false; public bool SupportsMarkdown => true; + + public string Disclaimer => ""; public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default) {