1+ module ElectricLemur.Muscadine.Site.ItemHelper
2+ open Giraffe
3+
4+ type ItemWrapper =
5+ | Game of Game.Game
6+ | Project of Project.Project
7+ | Book of Book.Book
8+
9+ let tryWrapItem ( item : obj ) =
10+ match item with
11+ | :? Game.Game as g -> Some ( Game g)
12+ | :? Project.Project as p -> Some ( Project p)
13+ | :? Book.Book as b -> Some ( Book b)
14+ | _ -> None
15+
16+ let wrapItem ( item : obj ) =
17+ match tryWrapItem obj with
18+ | Some i -> i
19+ | _ -> failwith $" Unable to unwrap type {item.GetType().FullName}"
20+
21+ let fromJObject obj =
22+ Database.documentTypeField |> JObj.getter< string> obj
23+ |> Option.bind (
24+ function
25+ | s when s = Game.documentType -> Some ( Game.makeModelFromJObject obj |> Game)
26+ | s when s = Project.documentType -> Some ( Project.makeModelFromJObject obj |> Project)
27+ | s when s = Book.documentType -> Some ( Book.makeModelFromJObject obj |> Book)
28+ | s -> None
29+ )
30+
31+ let toJObject item =
32+ match item with
33+ | Game g -> Game.makeJObjectFromModel g
34+ | Project p -> Project.makeJObjectFromModel p
35+ | Book b -> Book.makeJObjectFromModel b
36+
37+ let documentType item =
38+ match item with
39+ | Game _ -> Game.documentType
40+ | Project _ -> Project.documentType
41+ | Book _ -> Book.documentType
42+
43+ let itemId item =
44+ match item with
45+ | Game g -> g.Id
46+ | Project p -> p.Id
47+ | Book b -> b.Id
48+
49+ let name item =
50+ match item with
51+ | Game g -> g.Name
52+ | Project p -> p.Name
53+ | Book b -> b.Title
54+
55+ let description item =
56+ match item with
57+ | Game g -> g.Description
58+ | Project p -> p.Description
59+ | Book b -> b.Description
60+
61+ let dateAdded item =
62+ match item with
63+ | Game g -> g.DateAdded
64+ | Project p -> p.DateAdded
65+ | Book b -> b.DateAdded
66+
67+ let coverImages item =
68+ match item with
69+ | Game g -> g.CoverImagePaths
70+ | Project p -> p.IconImagePaths
71+ | Book b -> b.CoverImagePaths
72+
73+ let icon item =
74+ match coverImages item with
75+ | Some coverImages -> Image.Icon.Image coverImages
76+ | None -> Items.getDefaultIcon ( documentType item)
77+
78+ module Handlers =
79+ let GET_itemPage itemDocumentType slug : HttpHandler =
80+ fun next ctx -> task {
81+ let! item =
82+ Items.tryLookupBySlug slug itemDocumentType id ctx
83+ |> Task.map ( Option.bind fromJObject)
84+
85+ let! content =
86+ item
87+ |> Option.mapAsync ( fun item -> task {
88+ let! microblogEntries = Microblog.loadMicroblogsForDocument ( documentType item) ( itemId item) ctx
89+ return ( microblogEntries, item)
90+ })
91+ |> Task.bind ( Option.mapAsync ( fun ( microblogEntries , item ) -> task {
92+ let! tags = Tag.loadTagsForDocument ( documentType item) ( itemId item) ctx
93+ return ( tags, microblogEntries, item)
94+ }))
95+ |> Task.map ( Option.map ( fun ( tags , microblogEntries , item ) ->
96+ FrontendHelpers.makeItemPage ( name item) ( description item) ( icon item) tags microblogEntries ctx))
97+
98+ match content with
99+ | None -> return ! ( setStatusCode 404 >=> text " Page not found" ) next ctx
100+ | Some content ->
101+ let pageHtml = FrontendHelpers.layout FrontendHelpers.PageDefinitions.Games content [ " frontend/item_page.scss" ] ctx
102+ return ! ( htmlView pageHtml next ctx)
103+ }
0 commit comments