From 18cd8fb08fd5954b17f36a2f796cfe57f7f1c785 Mon Sep 17 00:00:00 2001 From: xdavidwu Date: Sun, 8 Aug 2021 00:26:52 +0800 Subject: [PATCH] add matrix commenting based on cactus instead of using an appservice, we use a bot user to provision rooms for us. --- _config.yml | 8 +- _includes/comments-providers/matrix.html | 10 ++ _includes/comments-providers/scripts.html | 2 + _includes/comments.html | 3 + _includes/head.html | 4 + _plugins/matrix-room-provision.rb | 60 +++++++++ _sass/minimal-mistakes/_buttons.scss | 2 +- _sass/minimal-mistakes/_colors.scss | 12 ++ _sass/minimal-mistakes/_forms.scss | 151 +++++++++++++--------- 9 files changed, 190 insertions(+), 62 deletions(-) create mode 100644 _includes/comments-providers/matrix.html create mode 100644 _plugins/matrix-room-provision.rb diff --git a/_config.yml b/_config.yml index 8fbdb2e..4afe682 100644 --- a/_config.yml +++ b/_config.yml @@ -33,7 +33,7 @@ masthead_title: # overrides the website title displayed in the masthead, use " " # breadcrumbs: false # true, false (default) words_per_minute: 200 comments: - provider: "disqus" # false (default), "disqus", "discourse", "facebook", "google-plus", "staticman", "staticman_v2" "custom" + provider: "matrix" # false (default), "disqus", "discourse", "facebook", "google-plus", "staticman", "staticman_v2" "custom" disqus: shortname: "parto-blog" # https://help.disqus.com/customer/portal/articles/466208-what-s-a-shortname- discourse: @@ -49,6 +49,12 @@ comments: staticman: branch: # "master" endpoint: # "https://{your Staticman v3 API}/v3/entry/github/" + matrix: + homeserver_url: "https://eglo.ga" + homeserver: "eglo.ga" + site: "xdavidwu.eglo.ga" + admin: "@xdavidwu:eglo.ga" + bot: "@xdavidwu.eglo.ga-comment-bot:eglo.ga" reCaptcha: siteKey: secret: diff --git a/_includes/comments-providers/matrix.html b/_includes/comments-providers/matrix.html new file mode 100644 index 0000000..76c38d2 --- /dev/null +++ b/_includes/comments-providers/matrix.html @@ -0,0 +1,10 @@ + diff --git a/_includes/comments-providers/scripts.html b/_includes/comments-providers/scripts.html index c550618..2268efa 100644 --- a/_includes/comments-providers/scripts.html +++ b/_includes/comments-providers/scripts.html @@ -12,6 +12,8 @@ {% include /comments-providers/staticman_v2.html %} {% when "utterances" %} {% include /comments-providers/utterances.html %} + {% when "matrix" %} + {% include /comments-providers/matrix.html %} {% when "custom" %} {% include /comments-providers/custom_scripts.html %} {% endcase %} diff --git a/_includes/comments.html b/_includes/comments.html index 81178e7..983cfdd 100644 --- a/_includes/comments.html +++ b/_includes/comments.html @@ -155,6 +155,9 @@ {% when "utterances" %}

{{ comments_label }}

+ {% when "matrix" %} +

Comments on Matrix #comments_{{ site.comments.matrix.site }}_{{ page.url }}:{{ site.comments.matrix.homeserver }}

+
{% when "custom" %} {% include /comments-providers/custom.html %} {% endcase %} diff --git a/_includes/head.html b/_includes/head.html index 235ddd4..4fc1a7d 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -7,6 +7,10 @@ +{% if site.comments.provider == "matrix" and page.comments %} + + +{% endif %} diff --git a/_plugins/matrix-room-provision.rb b/_plugins/matrix-room-provision.rb new file mode 100644 index 0000000..832c702 --- /dev/null +++ b/_plugins/matrix-room-provision.rb @@ -0,0 +1,60 @@ +require 'net/http' +require 'json' + +Jekyll::Hooks.register :site, :after_init do |site| + $config = site.config +end + +Jekyll::Hooks.register :posts, :post_write do |page| + if $config['comments']['provider'] != 'matrix' + return + end + + Jekyll.logger.info 'Checking Matrix room for post:', page.data['title'] + hs_url = $config['comments']['matrix']['homeserver_url'] + hs = $config['comments']['matrix']['homeserver'] + site = $config['comments']['matrix']['site'] + room_alias_local = "comments_#{site}_#{page.url}" + room_alias = "##{room_alias_local}:#{hs}" + + alias_encoded = ERB::Util.url_encode room_alias + alias_resolve_uri = URI hs_url + "/_matrix/client/r0/directory/room/#{alias_encoded}" + res = Net::HTTP.get_response alias_resolve_uri + + if res.is_a? Net::HTTPNotFound + Jekyll.logger.info 'Creating Matrix room:', room_alias + create_room_uri = URI hs_url + '/_matrix/client/r0/createRoom' + req = Net::HTTP::Post.new create_room_uri, 'Content-Type' => 'application/json', 'Authorization' => "Bearer #{ENV['MATRIX_ACCESS_TOKEN']}" + req.body = { + visibility: 'private', + room_alias_name: room_alias_local, + name: "#{page.data['title']}", + topic: "Comments of \"#{page.data['title']}\" in #{site} at #{$config['url'] + page.url}", + invite: [$config['comments']['matrix']['admin']], + creation_content: { + 'm.federate': true, + }, + preset: 'public_chat', + initial_state: [ + { + type: 'm.room.history_visibility', + content: { + history_visibility: 'world_readable', + }, + }, + ], + power_level_content_override: { + users: { + $config['comments']['matrix']['admin'] => 100, + $config['comments']['matrix']['bot'] => 100, + }, + }, + }.to_json + res = Net::HTTP.start create_room_uri.hostname, create_room_uri.port, use_ssl: true do |http| + http.request req + end + Jekyll.logger.info "createRoom returns:", res.body + end + + Jekyll.logger.info "" +end diff --git a/_sass/minimal-mistakes/_buttons.scss b/_sass/minimal-mistakes/_buttons.scss index cf2fb0e..fb28f7c 100644 --- a/_sass/minimal-mistakes/_buttons.scss +++ b/_sass/minimal-mistakes/_buttons.scss @@ -6,7 +6,7 @@ Default button ========================================================================== */ -.btn { +.btn, .cactus-button { /* default */ display: inline-block; margin-bottom: 0.25em; diff --git a/_sass/minimal-mistakes/_colors.scss b/_sass/minimal-mistakes/_colors.scss index 66ed6eb..d96090a 100644 --- a/_sass/minimal-mistakes/_colors.scss +++ b/_sass/minimal-mistakes/_colors.scss @@ -597,3 +597,15 @@ a.reversefootnote { .required { color: $danger-color; } + +@if $comments-provider == matrix { + .cactus-login-form { + background-color: $background-color; + } + .cactus-login-field { + > input { + border-color: $border-color; + color: $text-color; + } + } +} diff --git a/_sass/minimal-mistakes/_forms.scss b/_sass/minimal-mistakes/_forms.scss index abe0fde..7cfa17c 100644 --- a/_sass/minimal-mistakes/_forms.scss +++ b/_sass/minimal-mistakes/_forms.scss @@ -2,18 +2,18 @@ /* ========================================================================== Forms ========================================================================== */ - + form { margin: 0 0 5px 0; padding: 1em; background-color: $form-background-color; - + fieldset { margin-bottom: 5px; padding: 0; border-width: 0; } - + legend { display: block; width: 100%; @@ -23,22 +23,22 @@ border: 0; white-space: normal; } - + p { margin-bottom: (5px / 2); } - + ul { list-style-type: none; margin: 0 0 5px 0; padding: 0; } - + br { display: none; } } - + label, input, button, @@ -46,31 +46,31 @@ textarea { vertical-align: baseline; } - + input, button, select, textarea { box-sizing: border-box; } - + label { display: block; margin-bottom: 0.25em; color: $text-color; cursor: pointer; - + small { font-size: $type-size-6; } - + input, textarea, select { display: block; } } - + input, textarea, select { @@ -84,15 +84,15 @@ border-radius: $border-radius; box-shadow: $box-shadow; } - + .input-mini { width: 60px; } - + .input-small { width: 90px; } - + input[type="image"], input[type="checkbox"], input[type="radio"] { @@ -105,17 +105,17 @@ border-radius: 0; box-shadow: none; } - + input[type="checkbox"], input[type="radio"] { box-sizing: border-box; padding: 0; } - + input[type="image"] { border: 0; } - + input[type="file"] { width: auto; padding: initial; @@ -125,7 +125,7 @@ background-color: initial; box-shadow: none; } - + input[type="button"], input[type="reset"], input[type="submit"] { @@ -133,44 +133,44 @@ height: auto; cursor: pointer; } - + select { width: auto; background-color: #fff; } - + select[multiple], select[size] { height: auto; } - + textarea { resize: vertical; height: auto; overflow: auto; vertical-align: top; } - + input[type="hidden"] { display: none; } - + .form { position: relative; } - + .radio, .checkbox { padding-left: 18px; font-weight: normal; } - + .radio input[type="radio"], .checkbox input[type="checkbox"] { float: left; margin-left: -18px; } - + .radio.inline, .checkbox.inline { display: inline-block; @@ -178,16 +178,16 @@ margin-bottom: 0; vertical-align: middle; } - + .radio.inline + .radio.inline, .checkbox.inline + .checkbox.inline { margin-left: 10px; } - + /* Disabled state ========================================================================== */ - + input[disabled], select[disabled], textarea[disabled], @@ -197,11 +197,11 @@ opacity: 0.5; cursor: not-allowed; } - + /* Focus & active state ========================================================================== */ - + input:focus, textarea:focus { border-color: $primary-color; @@ -209,60 +209,60 @@ box-shadow: inset 0 1px 3px rgba($text-color, 0.06), 0 0 5px rgba($primary-color, 0.7); } - + input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus, select:focus { box-shadow: none; } - + /* Help text ========================================================================== */ - + .help-block, .help-inline { color: $muted-text-color; } - + .help-block { display: block; margin-bottom: 1em; line-height: 1em; } - + .help-inline { display: inline-block; vertical-align: middle; padding-left: 5px; } - + /* .form-group ========================================================================== */ - + .form-group { margin-bottom: 5px; padding: 0; border-width: 0; } - + /* .form-inline ========================================================================== */ - + .form-inline input, .form-inline textarea, .form-inline select { display: inline-block; margin-bottom: 0; } - + .form-inline label { display: inline-block; } - + .form-inline .radio, .form-inline .checkbox, .form-inline .radio { @@ -270,36 +270,36 @@ margin-bottom: 0; vertical-align: middle; } - + .form-inline .radio input[type="radio"], .form-inline .checkbox input[type="checkbox"] { float: left; margin-left: 0; margin-right: 3px; } - + /* .form-search ========================================================================== */ - + .form-search input, .form-search textarea, .form-search select { display: inline-block; margin-bottom: 0; } - + .form-search .search-query { padding-left: 14px; padding-right: 14px; margin-bottom: 0; border-radius: 14px; } - + .form-search label { display: inline-block; } - + .form-search .radio, .form-search .checkbox, .form-inline .radio { @@ -307,26 +307,26 @@ margin-bottom: 0; vertical-align: middle; } - + .form-search .radio input[type="radio"], .form-search .checkbox input[type="checkbox"] { float: left; margin-left: 0; margin-right: 3px; } - + /* .form--loading ========================================================================== */ - + .form--loading:before { content: ""; } - + .form--loading .form__spinner { display: block; } - + .form:before { position: absolute; top: 0; @@ -336,7 +336,7 @@ background-color: rgba(255, 255, 255, 0.7); z-index: 10; } - + .form__spinner { display: none; position: absolute; @@ -344,11 +344,11 @@ left: 50%; z-index: 11; } - + /* Google search form ========================================================================== */ - + #goog-fixurl { ul { list-style: none; @@ -359,7 +359,7 @@ } } } - + #goog-wm-qt { width: auto; margin-right: 10px; @@ -374,9 +374,40 @@ border-color: $border-color; border-radius: $border-radius; } - + #goog-wm-sb { @extend .btn; } - + +} +@if $comments-provider == matrix { + .cactus-editor-textarea { + border-radius: $border-radius; + height: 120px; + + &::placeholder { + line-height: 100px; + font-size: 1em; + } + } + + // matrix.to fails with slash in localpart + .cactus-matrixdotto-button { + display: none !important; + } + + .cactus-login-form { + box-shadow: 0 2px 4px 0 rgba(#000, 0.16), 0 2px 10px 0 rgba(#000, 0.12); + padding: 32px; + border-radius: $border-radius; + } + + .cactus-login-field { + > input { + border: 0; + border-bottom: 1px solid; + background: transparent; + outline: none; + } + } } -- 2.43.0