diff --git a/.kamal/secrets.beta b/.kamal/secrets.beta index ef220785d..60d911ced 100644 --- a/.kamal/secrets.beta +++ b/.kamal/secrets.beta @@ -1,6 +1,5 @@ -SECRETS=$(kamal secrets fetch --adapter 1password --account basecamp --from Deploy/Fizzy Deployments/BASECAMP_REGISTRY_PASSWORD Beta/SECRET_KEY_BASE Beta/OPEN_AI_API_KEY) +SECRETS=$(kamal secrets fetch --adapter 1password --account basecamp --from Deploy/Fizzy Deployments/BASECAMP_REGISTRY_PASSWORD Beta/RAILS_MASTER_KEY) GITHUB_TOKEN=$(gh config get -h github.com oauth_token) BASECAMP_REGISTRY_PASSWORD=$(kamal secrets extract BASECAMP_REGISTRY_PASSWORD $SECRETS) -SECRET_KEY_BASE=$(kamal secrets extract SECRET_KEY_BASE $SECRETS) -OPEN_AI_API_KEY=$(kamal secrets extract OPEN_AI_API_KEY $SECRETS) +RAILS_MASTER_KEY=$(kamal secrets extract RAILS_MASTER_KEY $SECRETS) diff --git a/.kamal/secrets.dhh b/.kamal/secrets.dhh index b427fe0c2..60d911ced 100644 --- a/.kamal/secrets.dhh +++ b/.kamal/secrets.dhh @@ -1,5 +1,5 @@ -SECRETS=$(kamal secrets fetch --adapter 1password --account basecamp --from Deploy/Fizzy Deployments/BASECAMP_REGISTRY_PASSWORD Production/SECRET_KEY_BASE) +SECRETS=$(kamal secrets fetch --adapter 1password --account basecamp --from Deploy/Fizzy Deployments/BASECAMP_REGISTRY_PASSWORD Beta/RAILS_MASTER_KEY) GITHUB_TOKEN=$(gh config get -h github.com oauth_token) BASECAMP_REGISTRY_PASSWORD=$(kamal secrets extract BASECAMP_REGISTRY_PASSWORD $SECRETS) -SECRET_KEY_BASE=$(kamal secrets extract SECRET_KEY_BASE $SECRETS) +RAILS_MASTER_KEY=$(kamal secrets extract RAILS_MASTER_KEY $SECRETS) diff --git a/.kamal/secrets.production b/.kamal/secrets.production index 8ac9f1e7c..b6d71edd3 100644 --- a/.kamal/secrets.production +++ b/.kamal/secrets.production @@ -1,6 +1,5 @@ -SECRETS=$(kamal secrets fetch --adapter 1password --account basecamp --from Deploy/Fizzy Deployments/BASECAMP_REGISTRY_PASSWORD Production/SECRET_KEY_BASE Production/OPEN_AI_API_KEY) +SECRETS=$(kamal secrets fetch --adapter 1password --account basecamp --from Deploy/Fizzy Deployments/BASECAMP_REGISTRY_PASSWORD Production/RAILS_MASTER_KEY) GITHUB_TOKEN=$(gh config get -h github.com oauth_token) BASECAMP_REGISTRY_PASSWORD=$(kamal secrets extract BASECAMP_REGISTRY_PASSWORD $SECRETS) -SECRET_KEY_BASE=$(kamal secrets extract SECRET_KEY_BASE $SECRETS) -OPEN_AI_API_KEY=$(kamal secrets extract OPEN_AI_API_KEY $SECRETS) +RAILS_MASTER_KEY=$(kamal secrets extract RAILS_MASTER_KEY $SECRETS) diff --git a/Gemfile b/Gemfile index 8c1219952..1984dc71d 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,6 @@ source "https://rubygems.org" git_source(:bc) { |repo| "https://github.com/basecamp/#{repo}" } gem "rails", github: "rails/rails", branch: "main" -gem "active_record-tenanted", bc: "active_record-tenanted" # Assets & front end gem "importmap-rails" @@ -11,6 +10,7 @@ gem "stimulus-rails" gem "turbo-rails" # Deployment and drivers +gem "active_record-tenanted", bc: "active_record-tenanted" gem "bootsnap", require: false gem "kamal", require: false gem "puma", ">= 5.0" @@ -30,8 +30,10 @@ gem "jbuilder" gem "actiontext-lexical", bc: "actiontext-lexical" gem "image_processing", "~> 1.14" gem "platform_agent" +gem "aws-sdk-s3", require: false -# Telemetry and logging +# Telemetry, logging, and operations +gem "mission_control-jobs" gem "sentry-ruby" gem "sentry-rails" gem "rails_structured_logging", bc: "rails-structured-logging" diff --git a/Gemfile.lock b/Gemfile.lock index 5fcb8b1ef..d761017df 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,13 +1,13 @@ GIT remote: https://github.com/basecamp/actiontext-lexical - revision: 9328297709d532fcb4cb5e47cfbddefda34d7c32 + revision: 7f327ddd60f4902ac60bb426495e85b31b6f0ad2 specs: actiontext-lexical (0.1.0) rails (>= 8.0.2) GIT remote: https://github.com/basecamp/active_record-tenanted - revision: 523947a0f0f49f66a8a62eb93e9ba1a345b3076b + revision: f6fca189655ae6609d10ecad7cceed61592320c4 specs: active_record-tenanted (0.1.0) activerecord (>= 8.1.alpha) @@ -17,28 +17,29 @@ GIT GIT remote: https://github.com/basecamp/rails-structured-logging - revision: fc810cc48ac54a07722013149e104ceb8ec9a7e3 + revision: 76960cb5c15fc2b6b5f7542e05d7dcc031cef9e6 specs: - rails_structured_logging (0.2.0) + rails_structured_logging (0.2.1) json rails (>= 6.0.0) GIT remote: https://github.com/crmne/ruby_llm.git - revision: 8412d51e869f1ee8e5229831a9a0bb5e9b8f3847 + revision: 74305703dcdcdcf8b2adefd8236184bcffc83910 specs: - ruby_llm (1.2.0) + ruby_llm (1.3.0rc1) base64 event_stream_parser (~> 1) - faraday (~> 2) - faraday-multipart (~> 1) - faraday-net_http (~> 3) - faraday-retry (~> 2) + faraday (>= 1.10.0) + faraday-multipart (>= 1) + faraday-net_http (>= 1) + faraday-retry (>= 1) + marcel (~> 1.0) zeitwerk (~> 2) GIT remote: https://github.com/rails/rails.git - revision: c1d7d56e831acf0aff5f3e27a6b384f543f358d0 + revision: 0ac3fba6ee5f7d1680024a4925eee6069095487b branch: main specs: actioncable (8.1.0.alpha) @@ -144,11 +145,29 @@ GEM addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) ast (2.4.3) - base64 (0.2.0) + aws-eventstream (1.3.2) + aws-partitions (1.1109.0) + aws-sdk-core (3.224.1) + aws-eventstream (~> 1, >= 1.3.0) + aws-partitions (~> 1, >= 1.992.0) + aws-sigv4 (~> 1.9) + base64 + jmespath (~> 1, >= 1.6.1) + logger + aws-sdk-kms (1.101.0) + aws-sdk-core (~> 3, >= 3.216.0) + aws-sigv4 (~> 1.5) + aws-sdk-s3 (1.188.0) + aws-sdk-core (~> 3, >= 3.224.1) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.5) + aws-sigv4 (1.11.0) + aws-eventstream (~> 1, >= 1.0.2) + base64 (0.3.0) bcrypt (3.1.20) bcrypt_pbkdf (1.1.1) - benchmark (0.4.0) - bigdecimal (3.1.9) + benchmark (0.4.1) + bigdecimal (3.2.1) bootsnap (1.18.6) msgpack (~> 1.2) brakeman (7.0.2) @@ -207,7 +226,7 @@ GEM addressable (>= 2.5.0) globalid (1.2.1) activesupport (>= 6.1) - hashdiff (1.1.2) + hashdiff (1.2.0) i18n (1.14.7) concurrent-ruby (~> 1.0) image_processing (1.14.0) @@ -225,7 +244,8 @@ GEM jbuilder (2.13.0) actionview (>= 5.0.0) activesupport (>= 5.0.0) - json (2.11.3) + jmespath (1.6.2) + json (2.12.2) kamal (2.6.1) activesupport (>= 7.0) base64 (~> 0.2) @@ -237,7 +257,7 @@ GEM sshkit (>= 1.23.0, < 2.0) thor (~> 1.3) zeitwerk (>= 2.6.18, < 3.0) - language_server-protocol (3.17.0.4) + language_server-protocol (3.17.0.5) lint_roller (1.1.0) logger (1.7.0) loofah (2.24.1) @@ -256,6 +276,16 @@ GEM mini_mime (1.1.5) mini_portile2 (2.8.9) minitest (5.25.5) + mission_control-jobs (1.0.2) + actioncable (>= 7.1) + actionpack (>= 7.1) + activejob (>= 7.1) + activerecord (>= 7.1) + importmap-rails (>= 1.2.1) + irb (~> 1.13) + railties (>= 7.1) + stimulus-rails + turbo-rails msgpack (1.8.0) multipart-post (2.4.1) net-http (0.6.0) @@ -304,7 +334,7 @@ GEM psych (5.2.6) date stringio - public_suffix (6.0.1) + public_suffix (6.0.2) puma (6.6.0) nio4r (~> 2.0) raabro (1.4.0) @@ -327,7 +357,7 @@ GEM loofah (~> 2.21) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) rainbow (3.1.1) - rake (13.2.1) + rake (13.3.0) rb_sys (0.9.106) rdoc (6.14.0) erb @@ -342,7 +372,7 @@ GEM chunky_png (~> 1.0) rqrcode_core (~> 2.0) rqrcode_core (2.0.0) - rubocop (1.75.4) + rubocop (1.75.8) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -360,12 +390,12 @@ GEM lint_roller (~> 1.1) rubocop (>= 1.75.0, < 2.0) rubocop-ast (>= 1.38.0, < 2.0) - rubocop-rails (2.31.0) + rubocop-rails (2.32.0) activesupport (>= 4.2.0) lint_roller (~> 1.1) rack (>= 1.1) rubocop (>= 1.75.0, < 2.0) - rubocop-ast (>= 1.38.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) rubocop-rails-omakase (1.1.0) rubocop (>= 1.72) rubocop-performance (>= 1.24) @@ -376,7 +406,7 @@ GEM logger rubyzip (2.4.1) securerandom (0.4.1) - selenium-webdriver (4.32.0) + selenium-webdriver (4.33.0) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) @@ -452,7 +482,7 @@ GEM crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) websocket (1.2.11) - websocket-driver (0.7.7) + websocket-driver (0.8.0) base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) @@ -470,6 +500,7 @@ PLATFORMS DEPENDENCIES actiontext-lexical! active_record-tenanted! + aws-sdk-s3 bcrypt (~> 3.1.7) bootsnap brakeman @@ -481,6 +512,7 @@ DEPENDENCIES importmap-rails jbuilder kamal + mission_control-jobs platform_agent propshaft puma (>= 5.0) diff --git a/app/assets/stylesheets/_global.css b/app/assets/stylesheets/_global.css index 5b2a966af..6861d229e 100644 --- a/app/assets/stylesheets/_global.css +++ b/app/assets/stylesheets/_global.css @@ -23,12 +23,10 @@ --border: 1px solid var(--color-ink-lighter); /* Shadows */ - --shadow: 0 0 0 1px oklch(var(--lch-black) / 0.02), - 0 .2em 1.6em -0.8em oklch(var(--lch-black) / 0.2), - 0 .4em 2.4em -1em oklch(var(--lch-black) / 0.3), - 0 .4em .8em -1.2em oklch(var(--lch-black) / 0.4), - 0 .8em 1.2em -1.6em oklch(var(--lch-black) / 0.5), - 0 1.2em 1.6em -2em oklch(var(--lch-black) / 0.6); + --shadow: 0 0 0 1px oklch(var(--lch-black) / 5%), + 0 0.2em 0.2em oklch(var(--lch-black) / 5%), + 0 0.4em 0.4em oklch(var(--lch-black) / 5%), + 0 0.8em 0.8em oklch(var(--lch-black) / 5%); /* Components */ --btn-size: 2.65em; @@ -186,7 +184,7 @@ --color-code-token__punctuation: oklch(var(--lch-ink-dark)); --color-code-token__selector: oklch(var(--lch-green-dark)); --color-code-token__variable: oklch(var(--lch-red-dark)); - + @media (prefers-color-scheme: dark) { --lch-canvas: 20% 0.0195 232.58; diff --git a/app/assets/stylesheets/bubble.css b/app/assets/stylesheets/bubble.css index 0b330b06a..43baf342b 100644 --- a/app/assets/stylesheets/bubble.css +++ b/app/assets/stylesheets/bubble.css @@ -52,12 +52,12 @@ } } -.bubble--closing { +.bubble--considering { inset-inline-start: calc(-1 * var(--bubble-gap)); translate: -100% -50%; } -.bubble--considering { +.bubble--doing { inset-inline-end: calc(-1 * var(--bubble-gap)); translate: 100% -50%; } diff --git a/app/assets/stylesheets/card-columns.css b/app/assets/stylesheets/card-columns.css index 108e7fd19..692efdf5d 100644 --- a/app/assets/stylesheets/card-columns.css +++ b/app/assets/stylesheets/card-columns.css @@ -101,7 +101,6 @@ --text-small: 1.1em; background-color: var(--color-canvas); - box-shadow: 0 0 0 1px var(--color-ink-lighter); line-height: 1.2; .avatar { @@ -122,6 +121,22 @@ display: none; } + .card__collection { + background-color: var(--color-canvas); + color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink)); + padding: 0 0 0 var(--inline-space); + } + + .card__collection-name { + border-inline-start: 1px solid color-mix(in srgb, var(--color-ink) 33%, var(--color-canvas)); + color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink)); + } + + .card__header { + color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink)); + margin: 0 0 calc(-0.5 * var(--card-padding-inline)) 0; + } + .card__title { margin-block-start: 0.1em; min-block-size: 0; diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 2ad8423e6..92e540165 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -25,6 +25,10 @@ .avatar { --avatar-size: 2.75em; } + + @media (prefers-color-scheme: dark) { + box-shadow: 0 0 0 1px var(--color-ink-lighter); + } } /* Children @@ -69,11 +73,6 @@ margin-block-start: calc(-1 * var(--card-padding-block)); margin-inline-start: calc(-1 * var(--card-padding-inline)); min-inline-size: 0; - - .cards--considering & { - color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink)); - margin: 0 0 calc(-0.5 * var(--card-padding-inline)) 0; - } } .card__collection { @@ -211,6 +210,7 @@ box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-link) 20%, var(--color-canvas)); color: var(--btn-color); font-weight: 700; + transition: none; } .card__move-button { diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index a6f4cab39..3a240af09 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -11,7 +11,7 @@ class UploadsController < ApplicationController def show expires_in 5.minutes, public: true - redirect_to @attachment.url + redirect_to @attachment.url, allow_other_host: true end private diff --git a/app/helpers/html_helper.rb b/app/helpers/html_helper.rb new file mode 100644 index 000000000..f61da26c1 --- /dev/null +++ b/app/helpers/html_helper.rb @@ -0,0 +1,46 @@ +module HtmlHelper + def format_html(html) + fragment = Nokogiri::HTML.fragment(html) + + auto_link(fragment) + + fragment.to_html.html_safe + end + + private + EXCLUDED_ELEMENTS = %w[ a figcaption pre code ] + EMAIL_REGEXP = /\b[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\b/ + URL_REGEXP = URI::DEFAULT_PARSER.make_regexp(%w[http https]) + + def auto_link(fragment) + fragment.traverse do |node| + next unless auto_linkable_node?(node) + + content = node.text + linked_content = content.dup + + auto_link_urls(linked_content) + auto_link_emails(linked_content) + + if linked_content != content + node.replace(Nokogiri::HTML.fragment(linked_content)) + end + end + end + + def auto_linkable_node?(node) + node.text? && node.ancestors.none? { |ancestor| EXCLUDED_ELEMENTS.include?(ancestor.name) } + end + + def auto_link_urls(linked_content) + linked_content.gsub!(URL_REGEXP) do |match| + %(#{match}) + end + end + + def auto_link_emails(text) + text.gsub!(EMAIL_REGEXP) do |match| + %(#{match}) + end + end +end diff --git a/app/javascript/controllers/retarget_links_controller.js b/app/javascript/controllers/retarget_links_controller.js new file mode 100644 index 000000000..f0187711e --- /dev/null +++ b/app/javascript/controllers/retarget_links_controller.js @@ -0,0 +1,15 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + connect() { + this.element.querySelectorAll("a").forEach(this.#retargetLink.bind(this)) + } + + #retargetLink(link) { + link.target = this.#targetsSameDomain(link) ? "_top" : "_blank" + } + + #targetsSameDomain(link) { + return link.href.startsWith(window.location.origin) + } +} diff --git a/app/models/card.rb b/app/models/card.rb index ba26a18d7..656a51b12 100644 --- a/app/models/card.rb +++ b/app/models/card.rb @@ -1,7 +1,7 @@ class Card < ApplicationRecord - include Assignable, Colored, Engageable, Eventable, Golden, - Mentions, Pinnable, Closeable, Readable, Searchable, Staged, - Statuses, Taggable, Watchable + include Assignable, Colored, Engageable, Entropy, Eventable, + Golden, Mentions, Pinnable, Closeable, Readable, Searchable, + Staged, Statuses, Taggable, Watchable belongs_to :collection, touch: true belongs_to :creator, class_name: "User", default: -> { Current.user } diff --git a/app/models/card/closeable.rb b/app/models/card/closeable.rb index 46c3a9696..afcdbc53d 100644 --- a/app/models/card/closeable.rb +++ b/app/models/card/closeable.rb @@ -1,8 +1,6 @@ module Card::Closeable extend ActiveSupport::Concern - AUTO_CLOSE_REMINDER_BEFORE = 7.days - included do has_one :closure, dependent: :destroy @@ -10,30 +8,6 @@ module Card::Closeable scope :open, -> { where.missing(:closure) } scope :recently_closed_first, -> { closed.order("closures.created_at": :desc) } - scope :in_auto_closing_collection, -> { joins(:collection).merge(Collection.auto_closing) } - scope :due_to_be_closed, -> { considering.in_auto_closing_collection.where("last_active_at <= DATETIME('now', '-' || auto_close_period || ' seconds')") } - - delegate :auto_closing?, :auto_close_period, to: :collection - end - - class_methods do - def auto_close_all_due - due_to_be_closed.find_each do |card| - card.close(user: User.system, reason: "Closed") - end - end - end - - def auto_close_at - last_active_at + auto_close_period if auto_closing? && last_active_at - end - - def days_until_close - (auto_close_at.to_date - Date.current).to_i if auto_close_at - end - - def closing_soon? - considering? && auto_closing? && Time.current >= auto_close_at - AUTO_CLOSE_REMINDER_BEFORE end def closed? diff --git a/app/models/card/engageable.rb b/app/models/card/engageable.rb index aa5279d64..9db8e6a64 100644 --- a/app/models/card/engageable.rb +++ b/app/models/card/engageable.rb @@ -1,15 +1,11 @@ module Card::Engageable extend ActiveSupport::Concern - STAGNATED_AFTER = 30.days - AUTO_RECONSIDER_REMINDER_BEFORE = 7.days - included do has_one :engagement, dependent: :destroy, class_name: "Card::Engagement" scope :considering, -> { published_or_drafted_by(Current.user).open.where.missing(:engagement) } scope :doing, -> { published.open.joins(:engagement) } - scope :stagnated, -> { doing.where(last_active_at: ..STAGNATED_AFTER.ago) } scope :by_engagement_status, ->(status) do case status.to_s @@ -19,16 +15,6 @@ module Card::Engageable end end - class_methods do - def auto_reconsider_all_stagnated - stagnated.find_each(&:reconsider) - end - end - - def auto_reconsider_at - last_active_at + STAGNATED_AFTER if last_active_at - end - def doing? open? && published? && engagement.present? end @@ -37,6 +23,14 @@ module Card::Engageable open? && published? && engagement.blank? end + def engagement_status + if doing? + "doing" + elsif considering? + "considering" + end + end + def engage unless doing? transaction do diff --git a/app/models/card/entropy.rb b/app/models/card/entropy.rb new file mode 100644 index 000000000..b0eded7a3 --- /dev/null +++ b/app/models/card/entropy.rb @@ -0,0 +1,47 @@ +module Card::Entropy + extend ActiveSupport::Concern + + AUTO_RECONSIDER_PERIOD = 30.days + ENTROPY_REMINDER_BEFORE = 7.days + + included do + scope :in_auto_closing_collection, -> { joins(:collection).merge(Collection.auto_closing) } + + scope :stagnated, -> { doing.where(last_active_at: ..AUTO_RECONSIDER_PERIOD.ago) } + scope :due_to_be_closed, -> { considering.in_auto_closing_collection.where("last_active_at <= DATETIME('now', '-' || auto_close_period || ' seconds')") } + + delegate :auto_closing?, :auto_close_period, to: :collection + end + + class_methods do + def auto_close_all_due + due_to_be_closed.find_each do |card| + card.close(user: User.system, reason: "Closed") + end + end + + def auto_reconsider_all_stagnated + stagnated.find_each(&:reconsider) + end + end + + def subject_to_entropy? + doing? || (auto_closing? && considering?) + end + + def auto_close_at + last_active_at + auto_close_period if auto_closing? && last_active_at + end + + def days_until_close + (auto_close_at.to_date - Date.current).to_i if auto_close_at + end + + def auto_reconsider_at + last_active_at + AUTO_RECONSIDER_PERIOD if last_active_at + end + + def days_until_reconsider + (auto_reconsider_at.to_date - Date.current).to_i if auto_reconsider_at + end +end diff --git a/app/views/cards/comments/_comment.html.erb b/app/views/cards/comments/_comment.html.erb index a1e863bf9..b0eeaee14 100644 --- a/app/views/cards/comments/_comment.html.erb +++ b/app/views/cards/comments/_comment.html.erb @@ -28,7 +28,7 @@ <% end %> -
+
<%= comment.body %>
diff --git a/app/views/cards/container/_title.html.erb b/app/views/cards/container/_title.html.erb index 1767fd854..0a45685e9 100644 --- a/app/views/cards/container/_title.html.erb +++ b/app/views/cards/container/_title.html.erb @@ -4,7 +4,7 @@

<%= link_to card.title, edit_collection_card_path(card.collection, card), class: "card__title-link" %>

-
+
<%= card.description %>
diff --git a/app/views/cards/display/_preview.html.erb b/app/views/cards/display/_preview.html.erb index bc27a29f9..9ccdf3f97 100644 --- a/app/views/cards/display/_preview.html.erb +++ b/app/views/cards/display/_preview.html.erb @@ -29,12 +29,8 @@ <%= render "cards/display/common/background", card: card %> - <% if card.auto_closing? %> - <% if card.considering? %> - <%= render "cards/display/preview/bubble", card: card, style: "closing" %> - <% elsif card.doing? %> - <%= render "cards/display/preview/bubble", card: card, style: "considering" %> - <% end %> + <% if card.subject_to_entropy? %> + <%= render "cards/display/preview/bubble", card: card %> <% end %> <% end %> <% end %> diff --git a/app/views/cards/display/preview/_bubble.html.erb b/app/views/cards/display/preview/_bubble.html.erb index 13faa9920..c05989755 100644 --- a/app/views/cards/display/preview/_bubble.html.erb +++ b/app/views/cards/display/preview/_bubble.html.erb @@ -1,6 +1,6 @@ -