Allows you to use Mastodon and Bluesky comments on your Lustre blog hexdocs.pm/chilp/
blog gleam lustre indieweb mastodon bluesky comments
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make styling optional

+41 -22
+1 -1
examples/lustre_chilp_app/src/lustre_chilp_app.gleam
··· 54 54 fn view(model: Model) -> Element(Msg) { 55 55 html.div([], [ 56 56 element.text(model.string), 57 - // Let's render comments under https://pony.social/@strawmelonjuice/115911235653686237 and nothing else 57 + // Let's render comments under https://pony.social/@strawmelonjuice/115911235653686237 58 58 chilp.widget(instance: "pony.social", post_id: "115911235653686237"), 59 59 ]) 60 60 }
+5 -1
src/chilp.gleam
··· 1 1 import chilp/widget 2 2 3 + /// Widget component! 4 + /// Before adding this component make sure to call `widget.register()` to register it! 5 + /// 6 + /// This component adds in inline CSS, to not do this, use `widget.element("bla", "111", False)` instead. 3 7 pub fn widget(instance instance: String, post_id post: String) { 4 - widget.element(instance:, post_id: post) 8 + widget.element(instance:, post_id: post, with_styles: True) 5 9 }
+35 -20
src/chilp/widget.gleam
··· 1 1 // IMPORTS --------------------------------------------------------------------- 2 2 3 3 import chilp/widget/base as widget 4 + import gleam/bool 4 5 import gleam/result 5 6 import gleam/string 6 7 import lustre ··· 13 14 // MAIN ------------------------------------------------------------------------ 14 15 15 16 pub fn register() -> Result(Nil, lustre.Error) { 17 + // I went along with the examples at https://github.com/lustre-labs/lustre/tree/main/examples/05-components! 18 + // If you're looking for good examples, look there! 16 19 let component = 17 20 lustre.component(init, update, view, [ 18 - // Attributes are string values that are set on the component's HTML element. 19 - // We can set up listeners for any attributes we care about and decode them 20 - // into a message for our update function. Any time the parent app changes 21 - // the attribute, this function will run and if it is `Ok` the message will 22 - // be sent to the component's update function. 23 21 component.on_attribute_change("postpointer", fn(value) { 24 22 value 25 23 |> string.split_once(":") ··· 30 28 lustre.register(component, "comment-widget") 31 29 } 32 30 33 - pub fn element(instance instance: String, post_id post: String) -> Element(msg) { 31 + pub fn element( 32 + instance instance: String, 33 + post_id post: String, 34 + with_styles styles: Bool, 35 + ) -> Element(msg) { 34 36 element.element( 35 37 "comment-widget", 36 - [attribute.attribute("postpointer", instance <> ":" <> post)], 38 + [ 39 + attribute.attribute("postpointer", instance <> ":" <> post), 40 + attribute.attribute("styles-enabled", styles |> bool.to_string), 41 + ], 37 42 [], 38 43 ) 39 44 } ··· 43 48 type WrappingModel { 44 49 WrappingModelSet( 45 50 chilp_model: widget.ChilpDataInYourModel(Msg), 51 + styles: Bool, 46 52 widget: widget.CommentWidget(Msg), 47 53 ) 48 - WrappingModelUnset(chilp_model: widget.ChilpDataInYourModel(Msg)) 54 + WrappingModelUnset( 55 + chilp_model: widget.ChilpDataInYourModel(Msg), 56 + styles: Bool, 57 + ) 49 58 } 50 59 51 60 fn init(_) -> #(WrappingModel, Effect(Msg)) { 52 - #(WrappingModelUnset(widget.init(ChilpMsgWrapper)), effect.none()) 61 + #(WrappingModelUnset(widget.init(ChilpMsgWrapper), True), effect.none()) 53 62 } 54 63 55 64 // UPDATE ---------------------------------------------------------------------- ··· 65 74 let chilp_model = model.chilp_model 66 75 let widget = widget.new(instance, post, chilp_model) 67 76 #( 68 - WrappingModelSet(widget:, chilp_model:), 77 + WrappingModelSet(widget:, chilp_model:, styles: model.styles), 69 78 widget.force(widget, chilp_model:), 70 79 ) 71 80 } ··· 73 82 let #(chilp_model, effects) = 74 83 widget.update(message, model.chilp_model, browse) 75 84 let new_model = case model { 76 - WrappingModelSet(_, widget) -> WrappingModelSet(chilp_model:, widget:) 77 - WrappingModelUnset(_) -> WrappingModelUnset(chilp_model:) 85 + WrappingModelSet(_, styles, widget) -> 86 + WrappingModelSet(chilp_model:, styles:, widget:) 87 + WrappingModelUnset(_, styles:) -> 88 + WrappingModelUnset(chilp_model:, styles:) 78 89 } 79 90 #(new_model, effects) 80 91 } ··· 99 110 // VIEW ------------------------------------------------------------------------ 100 111 101 112 fn view(model: WrappingModel) -> Element(Msg) { 102 - html.div([attribute.class("chilp-widget-component")], [ 103 - html.style([], js_inline_styles()), 104 - case model { 105 - WrappingModelSet(chilp_model:, widget:) -> 106 - widget.show(from: widget, data: chilp_model) 107 - WrappingModelUnset(chilp_model: _) -> element.none() 108 - }, 109 - ]) 113 + case model { 114 + WrappingModelSet(chilp_model:, widget:, styles: True) -> 115 + html.div([attribute.class("chilp-widget-component")], [ 116 + html.style([], js_inline_styles()), 117 + widget.show(from: widget, data: chilp_model), 118 + ]) 119 + WrappingModelSet(chilp_model:, widget:, styles: False) -> 120 + html.div([attribute.class("chilp-widget-component")], [ 121 + widget.show(from: widget, data: chilp_model), 122 + ]) 123 + WrappingModelUnset(..) -> element.none() 124 + } 110 125 }