From cda20600b1fb72cee65fc63de80469823b41302a Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Thu, 19 Jun 2025 12:16:32 +0200 Subject: [PATCH] Show mentions in the editor --- Gemfile | 2 +- Gemfile.lock | 13 ++++---- app/assets/stylesheets/actiontext-lexical.css | 32 ++++++++++++++++++- app/assets/stylesheets/rich-text-content.css | 22 +++++++++++-- app/controllers/prompts/users_controller.rb | 6 ++++ app/helpers/rich_text_helper.rb | 5 +++ app/models/user.rb | 6 +++- app/views/cards/edit.html.erb | 4 ++- app/views/prompts/users/_user.html.erb | 10 ++++++ app/views/prompts/users/index.html.erb | 1 + app/views/users/_attachable.html.erb | 2 ++ config/routes.rb | 4 +++ 12 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 app/controllers/prompts/users_controller.rb create mode 100644 app/helpers/rich_text_helper.rb create mode 100644 app/views/prompts/users/_user.html.erb create mode 100644 app/views/prompts/users/index.html.erb create mode 100644 app/views/users/_attachable.html.erb diff --git a/Gemfile b/Gemfile index 8c43ff533..4935a7c87 100644 --- a/Gemfile +++ b/Gemfile @@ -27,7 +27,7 @@ gem "rqrcode" gem "redcarpet" gem "rouge" gem "jbuilder" -gem "actiontext-lexical", bc: "actiontext-lexical" +gem "actiontext-lexical", path: "/Users/jorge/Work/jorgemanrubia/actiontext-lexical" gem "image_processing", "~> 1.14" gem "platform_agent" gem "aws-sdk-s3", require: false diff --git a/Gemfile.lock b/Gemfile.lock index 696e77ae4..27b510c14 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,3 @@ -GIT - remote: https://github.com/basecamp/actiontext-lexical - revision: 3f1ec3916f468ac2bb626091bcb97469c2c52483 - specs: - actiontext-lexical (0.1.0) - rails (>= 8.0.2) - GIT remote: https://github.com/basecamp/active_record-tenanted revision: f6fca189655ae6609d10ecad7cceed61592320c4 @@ -154,6 +147,12 @@ GIT thor (~> 1.0, >= 1.2.2) zeitwerk (~> 2.6) +PATH + remote: /Users/jorge/Work/jorgemanrubia/actiontext-lexical + specs: + actiontext-lexical (0.1.0) + rails (>= 8.0.2) + GEM remote: https://rubygems.org/ specs: diff --git a/app/assets/stylesheets/actiontext-lexical.css b/app/assets/stylesheets/actiontext-lexical.css index a8a3e227a..db03addc8 100644 --- a/app/assets/stylesheets/actiontext-lexical.css +++ b/app/assets/stylesheets/actiontext-lexical.css @@ -1,5 +1,9 @@ lexical-editor { - .node--selected { + display: block; + position: relative; + overflow: visible; + + .node--selected:not(.attachment--custom) { &:not(:has(img)) { box-shadow: 0 0 0 var(--hover-size) var(--hover-color); } @@ -134,3 +138,29 @@ lexical-toolbar { } } } + +/* Debug styles by Jorge */ +.lexical-prompt-menu { + background: white; + border: 2px solid black; + list-style: none; + + margin: 0; + padding: 0; + min-height: 100px; + min-width: 300px; + + visibility: hidden; + + &.lexical-prompt-menu--visible { + visibility: initial; + } + + [aria-selected] { + border: 1px solid red; + } +} + +.attachment--custom.node--selected { + box-shadow: 0 0 0 var(--hover-size) var(--hover-color); +} diff --git a/app/assets/stylesheets/rich-text-content.css b/app/assets/stylesheets/rich-text-content.css index 9b8c91cf6..1652b4cbb 100644 --- a/app/assets/stylesheets/rich-text-content.css +++ b/app/assets/stylesheets/rich-text-content.css @@ -20,7 +20,7 @@ :where(h5) { font-size: 0.83em; } :where(h6) { font-size: 0.67em; } - :where(p, ul, ol, dl, blockquote, figure, .attachment) { + :where(p, ul, ol, dl, blockquote, figure:not(.attachment--custom), .attachment:not(.attachment--custom)) { margin-block: var(--block-margin); overflow-wrap: break-word; text-wrap: pretty; @@ -54,7 +54,7 @@ } /* Attachments */ - .attachment { + .attachment:not(.attachment--custom) { block-size: auto; display: inline-block; inline-size: 100%; @@ -221,7 +221,7 @@ } /* Attachment junk gets wrapped in a paragraph causing unwanted space */ - p:has(action-text-attachment) { + p:has(action-text-attachment[src]) { display: none; + * { @@ -330,4 +330,20 @@ } } } + + /* Debug styles by Jorge */ + /* Custom attachments such as mentions, etc. */ + .attachment--custom { + display: inline; + padding: 0; + margin: 0; + white-space: normal; + } + + .attachment--custom, .lexical-prompt-menu__item, action-text-attachment { + img { + display: inline; + width: 24px; + } + } } diff --git a/app/controllers/prompts/users_controller.rb b/app/controllers/prompts/users_controller.rb new file mode 100644 index 000000000..1aaf995c4 --- /dev/null +++ b/app/controllers/prompts/users_controller.rb @@ -0,0 +1,6 @@ +class Prompts::UsersController < ApplicationController + def index + @users = User.all + render layout: false + end +end diff --git a/app/helpers/rich_text_helper.rb b/app/helpers/rich_text_helper.rb new file mode 100644 index 000000000..e3ac46c83 --- /dev/null +++ b/app/helpers/rich_text_helper.rb @@ -0,0 +1,5 @@ +module RichTextHelper + def mentions_prompt + content_tag "lexical-prompt", "", trigger: "@", src: prompts_users_path, name: "mention" + end +end diff --git a/app/models/user.rb b/app/models/user.rb index d68ccff46..c1dbc8c83 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,5 @@ class User < ApplicationRecord - include Accessor, Assignee, Mentionable, Named, Role, Transferable + include Accessor, ActionText::Attachable, Assignee, Mentionable, Named, Role, Transferable include Timelined # Depends on Accessor has_one_attached :avatar @@ -25,6 +25,10 @@ class User < ApplicationRecord update! active: false, email_address: deactived_email_address end + def to_attachable_partial_path + "users/attachable" + end + private def deactived_email_address email_address.sub(/@/, "-deactivated-#{SecureRandom.uuid}@") diff --git a/app/views/cards/edit.html.erb b/app/views/cards/edit.html.erb index d7cbe9e6c..4a6043125 100644 --- a/app/views/cards/edit.html.erb +++ b/app/views/cards/edit.html.erb @@ -10,7 +10,9 @@ <%= form.rich_textarea :description, class: "card-field__description rich-text-content", placeholder: "Add some notes, context, pictures, or video about this…", - data: { action: "keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop" } %> + data: { action: "keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop" } do %> + <%= mentions_prompt %> + <% end %> <%= form.button "Save changes", type: :submit, class: "btn btn--reversed", style: "--btn-background: #{@card.color}" %> <%= link_to "Close editor and discard changes", collection_card_path(@card.collection, @card), data: { form_target: "cancel" }, hidden: true %> diff --git a/app/views/prompts/users/_user.html.erb b/app/views/prompts/users/_user.html.erb new file mode 100644 index 000000000..7204e5162 --- /dev/null +++ b/app/views/prompts/users/_user.html.erb @@ -0,0 +1,10 @@ +" sgid="<%= user.attachable_sgid %>"> + + + diff --git a/app/views/prompts/users/index.html.erb b/app/views/prompts/users/index.html.erb new file mode 100644 index 000000000..4d78c50f9 --- /dev/null +++ b/app/views/prompts/users/index.html.erb @@ -0,0 +1 @@ +<%= render partial: "prompts/users/user", collection: @users %> diff --git a/app/views/users/_attachable.html.erb b/app/views/users/_attachable.html.erb new file mode 100644 index 000000000..0f973fc6f --- /dev/null +++ b/app/views/users/_attachable.html.erb @@ -0,0 +1,2 @@ +<%= avatar_image_tag user %> +<%= user.name %> diff --git a/config/routes.rb b/config/routes.rb index 3e9761dd4..dc00a8766 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -103,6 +103,10 @@ Rails.application.routes.draw do resources :pins end + namespace :prompts do + resources :users + end + namespace :public do resources :collections do scope module: :collections do