WIP on messages

This commit is contained in:
2022-04-19 16:25:51 -04:00
parent 48e6d3edfa
commit a0573a348a
19 changed files with 372 additions and 264 deletions

View File

@@ -11,4 +11,8 @@
<Compile Include="ViewModels.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.28.1" />
</ItemGroup>
</Project>

View File

@@ -1,6 +1,7 @@
namespace MyWebLog
open System
open Markdig
/// Support functions for domain definition
[<AutoOpen>]
@@ -54,21 +55,38 @@ type CommentStatus =
| Spam
/// The source format for a revision
type RevisionSource =
/// Types of markup text
type MarkupText =
/// Markdown text
| Markdown
/// HTML
| Html
| Markdown of string
/// HTML text
| Html of string
/// Functions to support revision sources
module RevisionSource =
/// Functions to support markup text
module MarkupText =
/// Convert a revision source to a string representation
let toString = function Markdown -> "Markdown" | Html -> "HTML"
/// Pipeline with most extensions enabled
let private _pipeline = MarkdownPipelineBuilder().UseSmartyPants().UseAdvancedExtensions().Build ()
/// Get the source type for the markup text
let sourceType = function Markdown _ -> "Markdown" | Html _ -> "HTML"
/// Convert a string to a revision source
let ofString = function "Markdown" -> Markdown | "HTML" -> Html | x -> invalidArg "string" x
/// Get the raw text, regardless of type
let text = function Markdown text -> text | Html text -> text
/// Get the string representation of the markup text
let toString it = $"{sourceType it}: {text it}"
/// Get the HTML representation of the markup text
let toHtml = function Markdown text -> Markdown.ToHtml (text, _pipeline) | Html text -> text
/// Parse a string into a MarkupText instance
let parse (it : string) =
match it with
| text when text.StartsWith "Markdown: " -> Markdown (text.Substring 10)
| text when text.StartsWith "HTML: " -> Html (text.Substring 6)
| text -> invalidOp $"Cannot derive type of text ({text})"
/// A revision of a page or post
[<CLIMutable; NoComparison; NoEquality>]
@@ -76,11 +94,8 @@ type Revision =
{ /// When this revision was saved
asOf : DateTime
/// The source language (Markdown or HTML)
sourceType : RevisionSource
/// The text of the revision
text : string
text : MarkupText
}
/// Functions to support revisions
@@ -88,9 +103,8 @@ module Revision =
/// An empty revision
let empty =
{ asOf = DateTime.UtcNow
sourceType = Html
text = ""
{ asOf = DateTime.UtcNow
text = Html ""
}

View File

@@ -4,6 +4,7 @@ open MyWebLog
open System
/// Details about a page used to display page lists
[<NoComparison; NoEquality>]
type DisplayPage =
{ /// The ID of this page
id : string
@@ -40,7 +41,7 @@ type DisplayPage =
/// The model to use to allow a user to log on
[<CLIMutable>]
[<CLIMutable; NoComparison; NoEquality>]
type LogOnModel =
{ /// The user's e-mail address
emailAddress : string
@@ -51,6 +52,7 @@ type LogOnModel =
/// The model used to display the admin dashboard
[<NoComparison; NoEquality>]
type DashboardModel =
{ /// The number of published posts
posts : int
@@ -73,7 +75,7 @@ type DashboardModel =
/// View model to edit a page
[<CLIMutable>]
[<CLIMutable; NoComparison; NoEquality>]
type EditPageModel =
{ /// The ID of the page being edited
pageId : string
@@ -84,6 +86,9 @@ type EditPageModel =
/// The permalink for the page
permalink : string
/// The template to use to display the page
template : string
/// Whether this page is shown in the page list
isShownInPageList : bool
@@ -99,17 +104,18 @@ type EditPageModel =
match page.revisions |> List.sortByDescending (fun r -> r.asOf) |> List.tryHead with
| Some rev -> rev
| None -> Revision.empty
{ pageId = PageId.toString page.id
title = page.title
permalink = Permalink.toString page.permalink
{ pageId = PageId.toString page.id
title = page.title
permalink = Permalink.toString page.permalink
template = defaultArg page.template ""
isShownInPageList = page.showInPageList
source = RevisionSource.toString latest.sourceType
text = latest.text
source = MarkupText.sourceType latest.text
text = MarkupText.text latest.text
}
/// View model for editing web log settings
[<CLIMutable>]
[<CLIMutable; NoComparison; NoEquality>]
type SettingsModel =
{ /// The name of the web log
name : string
@@ -126,3 +132,34 @@ type SettingsModel =
/// The time zone in which dates/times should be displayed
timeZone : string
}
[<CLIMutable; NoComparison; NoEquality>]
type UserMessage =
{ /// The level of the message
level : string
/// The message
message : string
/// Further details about the message
detail : string option
}
/// Functions to support user messages
module UserMessage =
/// An empty user message (use one of the others for pre-filled level)
let empty = { level = ""; message = ""; detail = None }
/// A blank success message
let success = { empty with level = "success" }
/// A blank informational message
let info = { empty with level = "primary" }
/// A blank warning message
let warning = { empty with level = "warning" }
/// A blank error message
let error = { empty with level = "danger" }