From 4ecb5db6a9520d6c253504dd031f0615cbf0a692 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 4 Apr 2025 15:17:48 -0500 Subject: [PATCH 001/104] Fix misalignment --- app/assets/stylesheets/cards.css | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 64cc87118..92d0369fa 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -350,7 +350,6 @@ margin-inline-start: var(--inline-space-double); strong { - font-size: 1.1em; font-weight: 900; } From a4cccb70a77074a3ae0590f267f1847899e2eb11 Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Fri, 4 Apr 2025 15:21:33 -0500 Subject: [PATCH 002/104] Make sure the picture-add icon is square so it doesn't get clipped --- app/assets/images/picture-add.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/images/picture-add.svg b/app/assets/images/picture-add.svg index 610d32901..a64cf38d6 100644 --- a/app/assets/images/picture-add.svg +++ b/app/assets/images/picture-add.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 0a7c7e7889f294ba80f95558124c6c758b63c9ad Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 4 Apr 2025 16:06:13 -0500 Subject: [PATCH 003/104] Use a variant of the bubble color for the perma surround --- app/assets/stylesheets/cards.css | 2 +- app/views/bubbles/show.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 92d0369fa..32b69c7c8 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -205,7 +205,7 @@ --padding-inline: calc(var(--block-space-double) + var(--block-space)); --padding-block: var(--block-space-double) calc(var(--block-space-double) + var(--block-space-half)); - background-color: var(--color-container); + background-color: color-mix(in lch, var(--bubble-color) 33%, var(--color-bg)); border-radius: 0.2em; display: inline-flex; padding-block: var(--padding-block); diff --git a/app/views/bubbles/show.html.erb b/app/views/bubbles/show.html.erb index 1d83162c9..9b54be37e 100644 --- a/app/views/bubbles/show.html.erb +++ b/app/views/bubbles/show.html.erb @@ -33,7 +33,7 @@ <% end %>
-
"> +
" style="--bubble-color: <%= @bubble.color %>;"> <%= render "bubbles/cards/perma", bubble: @bubble %>
From d2d8c2121ffa5868b972a66ee8c62e0688c4817c Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 4 Apr 2025 16:14:38 -0500 Subject: [PATCH 004/104] Crisp edges --- app/assets/stylesheets/cards.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 32b69c7c8..e678e2085 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -72,7 +72,9 @@ } .card { + --border-color: transparent; --border-radius: 0.2em; + --border-size: 0; aspect-ratio: 2/0.95; background-color: color-mix(in srgb, var(--bubble-color) 4%, var(--color-bg)); @@ -83,6 +85,11 @@ .card__container & { inline-size: calc(100dvw - var(--actions-inline-inset) * 2 - var(--btn-size) * 2); } + + @media (prefers-color-scheme: dark) { + --border-color: var(--color-subtle-dark); + --border-size: 1px; + } } .card__actions { From 90d67654ead41f4ea98031e8ca264ae4826bf8a3 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 4 Apr 2025 16:16:47 -0500 Subject: [PATCH 005/104] This is a bit narrow --- app/assets/stylesheets/comments.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/comments.css b/app/assets/stylesheets/comments.css index 75cf2012d..8fb6f5bb4 100644 --- a/app/assets/stylesheets/comments.css +++ b/app/assets/stylesheets/comments.css @@ -10,7 +10,7 @@ place-items: center; text-align: center; - @media (min-width: 150ch) { + @media (min-width: 160ch) { padding-inline: calc(var(--tray-size) + var(--inline-space) * 1.5); } } From 1f31ca597f27493b2be7b01c39eb242dc9330596 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 4 Apr 2025 16:19:04 -0500 Subject: [PATCH 006/104] Reset value here --- app/assets/stylesheets/cards.css | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index e678e2085..445f28503 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -352,6 +352,7 @@ .card__meta { --border-color: var(--bubble-color); + --border-size: 1px; --row-gap: 0.25em; margin-inline-start: var(--inline-space-double); From 0d6b9b751910c41df4108b9224ac388993d0a441 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 4 Apr 2025 16:34:25 -0500 Subject: [PATCH 007/104] Stub star feature --- app/assets/images/star.svg | 1 + app/assets/stylesheets/cards.css | 6 ++++++ app/assets/stylesheets/icons.css | 1 + app/views/bubbles/show.html.erb | 6 ++++++ 4 files changed, 14 insertions(+) create mode 100644 app/assets/images/star.svg diff --git a/app/assets/images/star.svg b/app/assets/images/star.svg new file mode 100644 index 000000000..281a18051 --- /dev/null +++ b/app/assets/images/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 445f28503..7fc52c6e2 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -217,6 +217,12 @@ display: inline-flex; padding-block: var(--padding-block); padding-inline: var(--padding-inline); + + &:has(.card__star-input:checked) { + .card { + outline: 4px solid var(--color-negative); + } + } } .card__container--pointing { diff --git a/app/assets/stylesheets/icons.css b/app/assets/stylesheets/icons.css index 3b2d8467e..5f8052bff 100644 --- a/app/assets/stylesheets/icons.css +++ b/app/assets/stylesheets/icons.css @@ -75,6 +75,7 @@ img.icon { .icon--share { --svg: url("share.svg "); } .icon--sort-ascending { --svg: url("sort-ascending.svg "); } .icon--sort-descending { --svg: url("sort-descending.svg "); } +.icon--star { --svg: url("star.svg "); } .icon--tag { --svg: url("tag.svg "); } .icon--temperature { --svg: url("temperature.svg "); } .icon--thumb-up { --svg: url("thumb-up.svg "); } diff --git a/app/views/bubbles/show.html.erb b/app/views/bubbles/show.html.erb index 9b54be37e..580635528 100644 --- a/app/views/bubbles/show.html.erb +++ b/app/views/bubbles/show.html.erb @@ -37,6 +37,12 @@ <%= render "bubbles/cards/perma", bubble: @bubble %>
+ + <%= render "bubbles/color", bubble: @bubble %> <%= render "bubbles/image", bubble: @bubble %> <%= button_to bucket_bubble_path(@bubble.bucket, @bubble), From 43c4ff55b4c46d7a92f86fcf61ecddfc6eaeac5d Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 4 Apr 2025 17:20:22 -0500 Subject: [PATCH 008/104] Try a switch control for considering||doing --- app/assets/stylesheets/cards.css | 15 +++++++++++++++ app/views/bubbles/_pop_toggle.html.erb | 7 ------- app/views/bubbles/cards/_perma.html.erb | 7 ------- app/views/bubbles/show.html.erb | 23 +++++++++++++++++++++++ 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 7fc52c6e2..78f01f192 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -133,6 +133,21 @@ } } +.card__actions-container--top { + margin: var(--block-space-half) auto calc(var(--block-space) * -2); + padding: var(--block-space) 3ch; + + #header:has(&) { + position: relative; + z-index: 1; + } + + .switch__input:checked + .switch__btn { + background-color: var(--bubble-color) !important; + } +} + + .cards .card__assignees:not(:has(.avatar)) { .txt-uppercase { display: none; diff --git a/app/views/bubbles/_pop_toggle.html.erb b/app/views/bubbles/_pop_toggle.html.erb index d55fbbdab..bf1ab0b2d 100644 --- a/app/views/bubbles/_pop_toggle.html.erb +++ b/app/views/bubbles/_pop_toggle.html.erb @@ -20,13 +20,6 @@ <%= label %> <% end %> <% end %> - - <% if bubble.doing? %> - - <%= button_to bucket_bubble_engagement_path(bubble.bucket, bubble), method: :delete, class: "btn popup__item full-width" do %> - Move back to Considering - <% end %> - <% end %>
diff --git a/app/views/bubbles/cards/_perma.html.erb b/app/views/bubbles/cards/_perma.html.erb index 830e48c87..996eeab03 100644 --- a/app/views/bubbles/cards/_perma.html.erb +++ b/app/views/bubbles/cards/_perma.html.erb @@ -32,13 +32,6 @@ <%= render "bubbles/stagings/stages", bubble: bubble %> <% end %> <% end %> - - <% if bubble.considering? %> - <%= button_to bucket_bubble_engagement_path(bubble.bucket, bubble), method: :post, class: "card__move-button card__hide-on-index btn btn--reversed" do %> - Move to Doing - <%= icon_tag "assigned" %> - <% end %> - <% end %>
diff --git a/app/views/bubbles/show.html.erb b/app/views/bubbles/show.html.erb index 580635528..c88a0f625 100644 --- a/app/views/bubbles/show.html.erb +++ b/app/views/bubbles/show.html.erb @@ -27,6 +27,29 @@ Go Back <% end %> + +
+ Considering + <% if @bubble.doing? %> + <%= form_with url: bucket_bubble_engagement_path(@bubble.bucket, @bubble), method: :delete, data: { controller: "form" }, class: "flex" do %> + + <% end %> + <% else %> + <%= form_with url: bucket_bubble_engagement_path(@bubble.bucket, @bubble), method: :post, data: { controller: "form" }, class: "flex" do %> + + <% end %> + <% end %> + Doing +
+
From adb04bf4dfc2e2e5c8abc3df2041ccb847bade26 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 4 Apr 2025 17:20:32 -0500 Subject: [PATCH 009/104] No need for special case here --- app/assets/stylesheets/layout.css | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/stylesheets/layout.css b/app/assets/stylesheets/layout.css index cd27f6305..b2b3c2356 100644 --- a/app/assets/stylesheets/layout.css +++ b/app/assets/stylesheets/layout.css @@ -36,7 +36,6 @@ body { view-transition-name: header; > nav { - font-size: var(--text-small); view-transition-name: nav; header { From 9cae6bb75af130c2d54878ac5942ba0ae51db4fc Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 4 Apr 2025 17:22:01 -0500 Subject: [PATCH 010/104] Some browsers can't do this --- app/assets/stylesheets/cards.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 78f01f192..83d137151 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -227,7 +227,7 @@ --padding-inline: calc(var(--block-space-double) + var(--block-space)); --padding-block: var(--block-space-double) calc(var(--block-space-double) + var(--block-space-half)); - background-color: color-mix(in lch, var(--bubble-color) 33%, var(--color-bg)); + background-color: color-mix(in srgb, var(--bubble-color) 33%, var(--color-bg)); border-radius: 0.2em; display: inline-flex; padding-block: var(--padding-block); From 4c344d2c3603ef64264eed34858ac433ead75513 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 12:34:02 +0200 Subject: [PATCH 011/104] Use Rails 8.1 defaults Avoids deprecation warnings during test runs --- config/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/application.rb b/config/application.rb index 2f544b5a0..ae36b65d4 100644 --- a/config/application.rb +++ b/config/application.rb @@ -9,7 +9,7 @@ Bundler.require(*Rails.groups) module Fizzy class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 8.0 + config.load_defaults 8.1 # Include the `lib` directory in autoload paths. Use the `ignore:` option # to list subdirectories that don't contain `.rb` files or that shouldn't From 92ce80cc327e2df5838ae1c331a98a0701030d8f Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 12:34:39 +0200 Subject: [PATCH 012/104] Extract User::Accessor concern Our User model is getting overloaded --- app/models/user.rb | 11 +---------- app/models/user/accessor.rb | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 app/models/user/accessor.rb diff --git a/app/models/user.rb b/app/models/user.rb index 2eb87913f..0fec0faed 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,15 +1,11 @@ class User < ApplicationRecord - include Avatar, Role, Transferable + include Accessor, Avatar, Role, Transferable belongs_to :account has_many :sessions, dependent: :destroy has_secure_password validations: false - has_many :accesses, dependent: :destroy - has_many :buckets, through: :accesses - has_many :accessible_bubbles, through: :buckets, source: :bubbles - has_many :filters, foreign_key: :creator_id, inverse_of: :creator, dependent: :destroy has_many :pops, dependent: :nullify @@ -27,8 +23,6 @@ class User < ApplicationRecord normalizes :email_address, with: ->(value) { value.strip.downcase } - after_create_commit :grant_access_to_buckets - scope :alphabetically, -> { order("lower(name)") } scope :sorted_with_user_first, ->(user) { order(Arel.sql("users.id != ?, lower(name)", user.id)) } @@ -53,7 +47,4 @@ class User < ApplicationRecord email_address.sub(/@/, "-deactivated-#{SecureRandom.uuid}@") end - def grant_access_to_buckets - Access.insert_all account.buckets.all_access.pluck(:id).collect { |bucket_id| { bucket_id: bucket_id, user_id: id } } - end end diff --git a/app/models/user/accessor.rb b/app/models/user/accessor.rb new file mode 100644 index 000000000..5615f9976 --- /dev/null +++ b/app/models/user/accessor.rb @@ -0,0 +1,16 @@ +module User::Accessor + extend ActiveSupport::Concern + + included do + has_many :accesses, dependent: :destroy + has_many :buckets, through: :accesses + has_many :accessible_bubbles, through: :buckets, source: :bubbles + + after_create_commit :grant_access_to_buckets + end + + private + def grant_access_to_buckets + Access.insert_all account.buckets.all_access.pluck(:id).collect { |bucket_id| { bucket_id: bucket_id, user_id: id } } + end +end From 17bdfb5df534a0befdbc6523308c6c23e92213ea Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 12:35:41 +0200 Subject: [PATCH 013/104] Already included in the Avatar concern --- app/models/user.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 0fec0faed..6dae4820f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -16,8 +16,6 @@ class User < ApplicationRecord has_many :notifications, dependent: :destroy - has_one_attached :avatar - has_many :pins, dependent: :destroy has_many :pinned_bubbles, through: :pins, source: :bubble From d237885bd45a8ebc999adb654090187ba79fea65 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 12:37:18 +0200 Subject: [PATCH 014/104] Extract User::Assignee role Keep slimming down that User --- app/models/user.rb | 6 +----- app/models/user/assignee.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 app/models/user/assignee.rb diff --git a/app/models/user.rb b/app/models/user.rb index 6dae4820f..e16518bee 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,5 @@ class User < ApplicationRecord - include Accessor, Avatar, Role, Transferable + include Accessor, Assignee, Avatar, Role, Transferable belongs_to :account @@ -10,10 +10,6 @@ class User < ApplicationRecord has_many :pops, dependent: :nullify - has_many :assignments, foreign_key: :assignee_id, dependent: :destroy - has_many :assignings, foreign_key: :assigner_id, class_name: "Assignment" - has_many :assigned_bubbles, through: :assignments, source: :bubble - has_many :notifications, dependent: :destroy has_many :pins, dependent: :destroy diff --git a/app/models/user/assignee.rb b/app/models/user/assignee.rb new file mode 100644 index 000000000..730158164 --- /dev/null +++ b/app/models/user/assignee.rb @@ -0,0 +1,9 @@ +module User::Assignee + extend ActiveSupport::Concern + + included do + has_many :assignments, foreign_key: :assignee_id, dependent: :destroy + has_many :assignings, foreign_key: :assigner_id, class_name: "Assignment" + has_many :assigned_bubbles, through: :assignments, source: :bubble + end +end From 8ff017fc5b20034adb595ddcb36ede8663e3d147 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 12:40:08 +0200 Subject: [PATCH 015/104] Only one invocation of this, not carrying the worth of its indirection Generally I am wary of including global state checks in the belly of models. It is one thing to do it as a default parameter, but I think it is too far to do it inside an actual method. --- app/controllers/comments_controller.rb | 2 +- app/models/user.rb | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index c0a9c9d34..d8b0231ac 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -38,6 +38,6 @@ class CommentsController < ApplicationController end def require_own_comment - head :forbidden unless @comment.creator.current? + head :forbidden unless Current.user == @comment.creator end end diff --git a/app/models/user.rb b/app/models/user.rb index e16518bee..5661afe8e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -32,10 +32,6 @@ class User < ApplicationRecord end end - def current? - Current.user == self - end - private def deactived_email_address email_address.sub(/@/, "-deactivated-#{SecureRandom.uuid}@") From 1463fa68f4b57542aaa6cb43ae61d6c2c215f8b9 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 12:48:52 +0200 Subject: [PATCH 016/104] Sessions only depend on user and have no callback, so use the faster delete_all --- app/models/user.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/user.rb b/app/models/user.rb index 5661afe8e..de0fba814 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -26,7 +26,7 @@ class User < ApplicationRecord def deactivate transaction do - sessions.destroy_all + sessions.delete_all accesses.destroy_all update! active: false, email_address: deactived_email_address end From 821f4c43d808c48a95ebee5a131de8afa6c1e969 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 12:49:19 +0200 Subject: [PATCH 017/104] Excess CR --- app/models/user.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/user.rb b/app/models/user.rb index de0fba814..b4d36c032 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -36,5 +36,4 @@ class User < ApplicationRecord def deactived_email_address email_address.sub(/@/, "-deactivated-#{SecureRandom.uuid}@") end - end From 61dfa5eccea4503efc5f16012d6c8b7bf7370466 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 12:58:56 +0200 Subject: [PATCH 018/104] Spacing --- app/views/bubbles/_messages.html.erb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/views/bubbles/_messages.html.erb b/app/views/bubbles/_messages.html.erb index c28e26eae..3bc0610d0 100644 --- a/app/views/bubbles/_messages.html.erb +++ b/app/views/bubbles/_messages.html.erb @@ -3,9 +3,14 @@ <%# Template Dependency: event_summaries/event_summary %> <%= render bubble.messages, cached: true %> <%= render "comments/new", bubble: bubble, cached: true %> +
Subscribers -

<%= pluralize(@bubble.watchers.count, "person") %> will be notified when someone comments on this.

+ +

+ <%= pluralize(@bubble.watchers.count, "person") %> will be notified when someone comments on this. +

+
<%= render partial: "bubbles/watches/watcher", collection: @bubble.watchers.sorted_with_user_first(Current.user) %>
From aefbac9c142e6bfefb81e4c7d1a69e9a60a536ab Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 13:17:42 +0200 Subject: [PATCH 019/104] Get rid of single-use and slight awkward model scope Really dont like that raw Arel.sql wrapping that is required. --- app/helpers/users_helper.rb | 5 +++++ app/models/user.rb | 1 - app/views/bubbles/_messages.html.erb | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 app/helpers/users_helper.rb diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 000000000..58b3e12d6 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,5 @@ +module UsersHelper + def prepend_current_user_to(users_scope) + users_scope.to_a.prepend(Current.user).uniq + end +end diff --git a/app/models/user.rb b/app/models/user.rb index b4d36c032..5b5137ae1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -18,7 +18,6 @@ class User < ApplicationRecord normalizes :email_address, with: ->(value) { value.strip.downcase } scope :alphabetically, -> { order("lower(name)") } - scope :sorted_with_user_first, ->(user) { order(Arel.sql("users.id != ?, lower(name)", user.id)) } def initials name.to_s.scan(/\b\p{L}/).join.upcase diff --git a/app/views/bubbles/_messages.html.erb b/app/views/bubbles/_messages.html.erb index 3bc0610d0..85ea86c05 100644 --- a/app/views/bubbles/_messages.html.erb +++ b/app/views/bubbles/_messages.html.erb @@ -12,7 +12,7 @@

- <%= render partial: "bubbles/watches/watcher", collection: @bubble.watchers.sorted_with_user_first(Current.user) %> + <%= render partial: "bubbles/watches/watcher", collection: prepend_current_user_to(@bubble.watchers.alphabetically) %>
<% end %> From f063116df41d3ea360b000c141aa48b12f74ce7e Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 13:19:30 +0200 Subject: [PATCH 020/104] Group related associations together --- app/models/user.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 5b5137ae1..88bf2b8ec 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -6,12 +6,10 @@ class User < ApplicationRecord has_many :sessions, dependent: :destroy has_secure_password validations: false - has_many :filters, foreign_key: :creator_id, inverse_of: :creator, dependent: :destroy - - has_many :pops, dependent: :nullify - has_many :notifications, dependent: :destroy + has_many :filters, foreign_key: :creator_id, inverse_of: :creator, dependent: :destroy + has_many :pops, dependent: :nullify has_many :pins, dependent: :destroy has_many :pinned_bubbles, through: :pins, source: :bubble From 384de241328b04dec5e14bcdf225a4598aef52e9 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 14:16:04 +0200 Subject: [PATCH 021/104] Get rid of odd toggles concept This is just assignments. --- ...ontroller.rb => assignments_controller.rb} | 2 +- app/views/bubbles/_assignment.html.erb | 2 +- .../bubbles/cards/perma/_assignees.html.erb | 2 +- config/routes.rb | 4 +-- .../assignments/toggles_controller_test.rb | 25 ------------------- .../assignments_controller_test.rb | 25 +++++++++++++++++++ 6 files changed, 29 insertions(+), 31 deletions(-) rename app/controllers/{assignments/toggles_controller.rb => assignments_controller.rb} (93%) delete mode 100644 test/controllers/assignments/toggles_controller_test.rb create mode 100644 test/controllers/assignments_controller_test.rb diff --git a/app/controllers/assignments/toggles_controller.rb b/app/controllers/assignments_controller.rb similarity index 93% rename from app/controllers/assignments/toggles_controller.rb rename to app/controllers/assignments_controller.rb index 96d510baa..554d86850 100644 --- a/app/controllers/assignments/toggles_controller.rb +++ b/app/controllers/assignments_controller.rb @@ -1,4 +1,4 @@ -class Assignments::TogglesController < ApplicationController +class AssignmentsController < ApplicationController include BubbleScoped, BucketScoped def new diff --git a/app/views/bubbles/_assignment.html.erb b/app/views/bubbles/_assignment.html.erb index 2d6914591..7c6071a25 100644 --- a/app/views/bubbles/_assignment.html.erb +++ b/app/views/bubbles/_assignment.html.erb @@ -3,7 +3,7 @@ Assign this to… - <%= form_with url: bucket_bubble_assignment_toggles_path(bubble.bucket, bubble), class: "flex flex-column full-width popup__list", data: { controller: "form" } do |form| %> + <%= form_with url: bucket_bubble_assignments_path(bubble.bucket, bubble), class: "flex flex-column full-width popup__list", data: { controller: "form" } do |form| %> <% bubble.bucket.users.active.sort_by(&:name).each do |user| %> <% end %> diff --git a/config/routes.rb b/config/routes.rb index bd3e3b4d3..b4099406f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -58,10 +58,7 @@ Rails.application.routes.draw do end resources :assignments - - namespace :taggings, as: :tagging do - resources :toggles - end + resources :taggings end end diff --git a/test/controllers/taggings/toggles_controller_test.rb b/test/controllers/taggings_controller_test.rb similarity index 53% rename from test/controllers/taggings/toggles_controller_test.rb rename to test/controllers/taggings_controller_test.rb index 4d54086ad..547a137be 100644 --- a/test/controllers/taggings/toggles_controller_test.rb +++ b/test/controllers/taggings_controller_test.rb @@ -1,25 +1,24 @@ require "test_helper" -class Taggings::TogglesControllerTest < ActionDispatch::IntegrationTest +class TaggingsControllerTest < ActionDispatch::IntegrationTest setup do sign_in_as :kevin end test "new" do - get new_bucket_bubble_tagging_toggle_url(buckets(:writebook), bubbles(:logo)) - + get new_bucket_bubble_tagging_url(buckets(:writebook), bubbles(:logo)) assert_response :success end test "create" do assert_changes "bubbles(:logo).tagged_with?(tags(:mobile))", from: false, to: true do - post bucket_bubble_tagging_toggles_url(buckets(:writebook), bubbles(:logo)), params: { tag_id: tags(:mobile).id }, as: :turbo_stream + post bucket_bubble_taggings_url(buckets(:writebook), bubbles(:logo)), params: { tag_id: tags(:mobile).id }, as: :turbo_stream end assert_response :success assert_changes "bubbles(:logo).tagged_with?(tags(:web))", from: false, to: true do assert_changes "bubbles(:logo).tagged_with?(tags(:mobile))", from: true, to: false do - post bucket_bubble_tagging_toggles_url(buckets(:writebook), bubbles(:logo)), params: { tag_id: tags(:web).id }, as: :turbo_stream + post bucket_bubble_taggings_url(buckets(:writebook), bubbles(:logo)), params: { tag_id: tags(:web).id }, as: :turbo_stream end end assert_response :success From bfb7ed1216464f9f757b4eae0b4089f600c305e1 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 14:57:24 +0200 Subject: [PATCH 023/104] Move pins to my space We used the my/ space in HEY to reflect anything that was primarily hinged off Current.user. Good to use here too. --- .../trays_controller.rb => my/pins_controller.rb} | 4 ++-- app/views/bubbles/pins/trays/show.html.erb | 3 --- app/views/bubbles/pins_trays/show.html.erb | 3 --- app/views/layouts/application.html.erb | 2 +- app/views/{bubbles => my}/pins/_pin.html.erb | 0 app/views/{bubbles => my}/pins/_tray.html.erb | 4 ++-- app/views/my/pins/index.html.erb | 3 +++ config/routes.rb | 7 ++----- test/controllers/my/pins_controller_test.rb | 15 +++++++++++++++ 9 files changed, 25 insertions(+), 16 deletions(-) rename app/controllers/{bubbles/pins/trays_controller.rb => my/pins_controller.rb} (51%) delete mode 100644 app/views/bubbles/pins/trays/show.html.erb delete mode 100644 app/views/bubbles/pins_trays/show.html.erb rename app/views/{bubbles => my}/pins/_pin.html.erb (100%) rename app/views/{bubbles => my}/pins/_tray.html.erb (89%) create mode 100644 app/views/my/pins/index.html.erb create mode 100644 test/controllers/my/pins_controller_test.rb diff --git a/app/controllers/bubbles/pins/trays_controller.rb b/app/controllers/my/pins_controller.rb similarity index 51% rename from app/controllers/bubbles/pins/trays_controller.rb rename to app/controllers/my/pins_controller.rb index ef79beae2..c7f222d33 100644 --- a/app/controllers/bubbles/pins/trays_controller.rb +++ b/app/controllers/my/pins_controller.rb @@ -1,5 +1,5 @@ -class Bubbles::Pins::TraysController < ApplicationController - def show +class My::PinsController < ApplicationController + def index @pins = Current.user.pins.includes(:bubble).ordered.limit(20) end end diff --git a/app/views/bubbles/pins/trays/show.html.erb b/app/views/bubbles/pins/trays/show.html.erb deleted file mode 100644 index 1e155e3c5..000000000 --- a/app/views/bubbles/pins/trays/show.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= turbo_frame_tag "pins" do %> - <%= render collection: @pins, partial: "bubbles/pins/pin" %> -<% end %> \ No newline at end of file diff --git a/app/views/bubbles/pins_trays/show.html.erb b/app/views/bubbles/pins_trays/show.html.erb deleted file mode 100644 index 1e155e3c5..000000000 --- a/app/views/bubbles/pins_trays/show.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= turbo_frame_tag "pins" do %> - <%= render collection: @pins, partial: "bubbles/pins/pin" %> -<% end %> \ No newline at end of file diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 57f76180a..1e6afa890 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -48,7 +48,7 @@ <% if Current.user %> <%= render "notifications/tray" %> - <%= render "bubbles/pins/tray" %> + <%= render "my/pins/tray" %> <%= turbo_frame_tag "terminal", src: terminal_path, data: { turbo_permanent: true } %> <% end %>
diff --git a/app/views/bubbles/pins/_pin.html.erb b/app/views/my/pins/_pin.html.erb similarity index 100% rename from app/views/bubbles/pins/_pin.html.erb rename to app/views/my/pins/_pin.html.erb diff --git a/app/views/bubbles/pins/_tray.html.erb b/app/views/my/pins/_tray.html.erb similarity index 89% rename from app/views/bubbles/pins/_tray.html.erb rename to app/views/my/pins/_tray.html.erb index 7551f3781..70c1d5a16 100644 --- a/app/views/bubbles/pins/_tray.html.erb +++ b/app/views/my/pins/_tray.html.erb @@ -2,7 +2,7 @@ <%= tag.dialog id: "pin-tray", class: "tray pin-tray", data: { controller: "dialog", turbo_permanent: true, dialog_modal_value: false, dialog_target: "dialog", action: "keydown.esc->dialog#close:stop click@document->dialog#closeOnClickOutside" } do %> - <%= turbo_frame_tag "pins", src: bubbles_pins_tray_path %> + <%= turbo_frame_tag "pins", src: my_pins_path %>
@@ -10,4 +10,4 @@ -<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/my/pins/index.html.erb b/app/views/my/pins/index.html.erb new file mode 100644 index 000000000..d4c176587 --- /dev/null +++ b/app/views/my/pins/index.html.erb @@ -0,0 +1,3 @@ +<%= turbo_frame_tag "pins" do %> + <%= render collection: @pins, partial: "my/pins/pin" %> +<% end %> diff --git a/config/routes.rb b/config/routes.rb index b4099406f..2b9b15d91 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -95,11 +95,8 @@ Rails.application.routes.draw do get "up", to: "rails/health#show", as: :rails_health_check get "manifest" => "rails/pwa#manifest", as: :pwa_manifest - namespace :bubbles do - namespace :pins do - resource :tray, only: :show - end - resources :pins, only: :index + namespace :my do + resources :pins end resource :terminal, only: [ :show, :edit ] diff --git a/test/controllers/my/pins_controller_test.rb b/test/controllers/my/pins_controller_test.rb new file mode 100644 index 000000000..cb6b9f9c0 --- /dev/null +++ b/test/controllers/my/pins_controller_test.rb @@ -0,0 +1,15 @@ +require "test_helper" + +class My::PinsControllerTest < ActionDispatch::IntegrationTest + setup do + sign_in_as :kevin + end + + test "index" do + get my_pins_url + + assert_response :success + assert_select "div", text: /#{users(:kevin).pins.first.bubble.title}/ + end +end + From e4c6fe4b559a07873f533cad0e0e00839f94b13f Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 15:15:48 +0200 Subject: [PATCH 024/104] Shape up pinning API and broadcast in the controller --- app/controllers/bubbles/pins_controller.rb | 17 +++++++++++++++-- app/models/bubble/pinnable.rb | 12 ++++++------ app/models/pin.rb | 6 ------ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/app/controllers/bubbles/pins_controller.rb b/app/controllers/bubbles/pins_controller.rb index a28526dea..d93eba759 100644 --- a/app/controllers/bubbles/pins_controller.rb +++ b/app/controllers/bubbles/pins_controller.rb @@ -5,12 +5,25 @@ class Bubbles::PinsController < ApplicationController end def create - @bubble.set_pinned(Current.user, true) + pin = @bubble.pin_by Current.user + + broadcast_new pin redirect_to bucket_bubble_pin_path(@bucket, @bubble) end def destroy - @bubble.set_pinned(Current.user, false) + pin = @bubble.unpin_by Current.user + + broadcast_removed pin redirect_to bucket_bubble_pin_path(@bucket, @bubble) end + + private + def broadcast_new(pin) + pin.broadcast_prepend_later_to [ Current.user, :pins ], target: "pins", partial: "my/pins/pin" + end + + def broadcast_removed(pin) + pin.broadcast_remove_to [ Current.user, :pins ] + end end diff --git a/app/models/bubble/pinnable.rb b/app/models/bubble/pinnable.rb index 2452fadfe..044125eae 100644 --- a/app/models/bubble/pinnable.rb +++ b/app/models/bubble/pinnable.rb @@ -9,11 +9,11 @@ module Bubble::Pinnable pins.exists?(user: user) end - def set_pinned(user, pinned) - if pinned - pins.find_or_create_by!(user: user) - else - pins.find_by(user: user)&.destroy - end + def pin_by(user) + pins.find_or_create_by!(user: user) + end + + def unpin_by(user) + pins.find_by(user: user).tap { it.destroy } end end diff --git a/app/models/pin.rb b/app/models/pin.rb index 5bf4635c8..86913023c 100644 --- a/app/models/pin.rb +++ b/app/models/pin.rb @@ -3,10 +3,4 @@ class Pin < ApplicationRecord belongs_to :user scope :ordered, -> { order(created_at: :desc) } - - after_create_commit -> { broadcast_prepend_later_to [ user, :pins ], - target: "pins", - partial: "bubbles/pins/pin" - } - after_destroy_commit -> { broadcast_remove_to [ user, :pins ] } end From 866a80e133d8ba3464fc95d0f146e6f94ebbe361 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 15:26:49 +0200 Subject: [PATCH 025/104] Fix up the tests --- test/controllers/bubbles/pins_controller_test.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/test/controllers/bubbles/pins_controller_test.rb b/test/controllers/bubbles/pins_controller_test.rb index 7deee667e..cdde4e7f2 100644 --- a/test/controllers/bubbles/pins_controller_test.rb +++ b/test/controllers/bubbles/pins_controller_test.rb @@ -7,17 +7,25 @@ class Bubbles::PinsControllerTest < ActionDispatch::IntegrationTest test "create" do assert_changes -> { bubbles(:layout).pinned_by?(users(:kevin)) }, from: false, to: true do - post bucket_bubble_pin_url(buckets(:writebook), bubbles(:layout)) + perform_enqueued_jobs do + assert_turbo_stream_broadcasts([ users(:kevin), :pins ], count: 1) do + post bucket_bubble_pin_path(buckets(:writebook), bubbles(:layout)) + end + end end - assert_redirected_to bucket_bubble_pin_url(buckets(:writebook), bubbles(:layout)) + assert_redirected_to bucket_bubble_pin_path(buckets(:writebook), bubbles(:layout)) end test "destroy" do assert_changes -> { bubbles(:shipping).pinned_by?(users(:kevin)) }, from: true, to: false do - delete bucket_bubble_pin_url(buckets(:writebook), bubbles(:shipping)) + perform_enqueued_jobs do + assert_turbo_stream_broadcasts([ users(:kevin), :pins ], count: 1) do + delete bucket_bubble_pin_path(buckets(:writebook), bubbles(:shipping)) + end + end end - assert_redirected_to bucket_bubble_pin_url(buckets(:writebook), bubbles(:shipping)) + assert_redirected_to bucket_bubble_pin_path(buckets(:writebook), bubbles(:shipping)) end end From 8708ff04c1e0836bea73dc0d3365cbfca8e91038 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 15:27:40 +0200 Subject: [PATCH 026/104] Fix indention --- app/views/bubbles/pins/show.html.erb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/bubbles/pins/show.html.erb b/app/views/bubbles/pins/show.html.erb index 9039cc92f..cbd2b75a0 100644 --- a/app/views/bubbles/pins/show.html.erb +++ b/app/views/bubbles/pins/show.html.erb @@ -1,13 +1,13 @@ <%= turbo_frame_tag dom_id(@bubble, :pin) do %> <% if @bubble.pinned_by? Current.user %> - <%= button_to bucket_bubble_pin_path(@bubble.bucket, @bubble), method: :delete, class: "btn btn--reversed" do %> - <%= icon_tag "pinned" %> - Un-pin this card - <% end %> + <%= button_to bucket_bubble_pin_path(@bubble.bucket, @bubble), method: :delete, class: "btn btn--reversed" do %> + <%= icon_tag "pinned" %> + Un-pin this card + <% end %> <% else %> - <%= button_to bucket_bubble_pin_path(@bubble.bucket, @bubble), class: "btn" do %> - <%= icon_tag "unpinned" %> - Pin this card - <% end %> + <%= button_to bucket_bubble_pin_path(@bubble.bucket, @bubble), class: "btn" do %> + <%= icon_tag "unpinned" %> + Pin this card + <% end %> <% end %> <% end %> From f725a69dee3a3b1c1d6bdc5afbe12ade44166e75 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 15:43:58 +0200 Subject: [PATCH 027/104] Let BubbleScoped find its own bucket Then it will be easier to break things that are double nested out of that nesting. --- app/controllers/assignments_controller.rb | 2 +- app/controllers/boosts_controller.rb | 2 +- app/controllers/bubbles/engagements_controller.rb | 2 +- app/controllers/bubbles/images_controller.rb | 2 +- app/controllers/bubbles/pins_controller.rb | 2 +- app/controllers/bubbles/pops_controller.rb | 2 +- app/controllers/bubbles/publishes_controller.rb | 2 +- app/controllers/bubbles/recovers_controller.rb | 2 +- app/controllers/bubbles/stagings_controller.rb | 2 +- app/controllers/bubbles/watches_controller.rb | 2 +- app/controllers/comments_controller.rb | 2 +- app/controllers/concerns/bubble_scoped.rb | 8 ++++++-- app/controllers/readings_controller.rb | 2 +- app/controllers/taggings_controller.rb | 2 +- 14 files changed, 19 insertions(+), 15 deletions(-) diff --git a/app/controllers/assignments_controller.rb b/app/controllers/assignments_controller.rb index 554d86850..eb9c4e74f 100644 --- a/app/controllers/assignments_controller.rb +++ b/app/controllers/assignments_controller.rb @@ -1,5 +1,5 @@ class AssignmentsController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def new render partial: "bubbles/assignment", locals: { bubble: @bubble } diff --git a/app/controllers/boosts_controller.rb b/app/controllers/boosts_controller.rb index 0a6f34f78..48400cc10 100644 --- a/app/controllers/boosts_controller.rb +++ b/app/controllers/boosts_controller.rb @@ -1,5 +1,5 @@ class BoostsController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def create count = if params[:boost_count].to_i == @bubble.boosts_count diff --git a/app/controllers/bubbles/engagements_controller.rb b/app/controllers/bubbles/engagements_controller.rb index e13d6679c..5599b7381 100644 --- a/app/controllers/bubbles/engagements_controller.rb +++ b/app/controllers/bubbles/engagements_controller.rb @@ -1,5 +1,5 @@ class Bubbles::EngagementsController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def create @bubble.engage diff --git a/app/controllers/bubbles/images_controller.rb b/app/controllers/bubbles/images_controller.rb index 005eb967d..b7dc7da97 100644 --- a/app/controllers/bubbles/images_controller.rb +++ b/app/controllers/bubbles/images_controller.rb @@ -1,5 +1,5 @@ class Bubbles::ImagesController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def destroy @bubble.image.purge_later diff --git a/app/controllers/bubbles/pins_controller.rb b/app/controllers/bubbles/pins_controller.rb index d93eba759..fda94c937 100644 --- a/app/controllers/bubbles/pins_controller.rb +++ b/app/controllers/bubbles/pins_controller.rb @@ -1,5 +1,5 @@ class Bubbles::PinsController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def show end diff --git a/app/controllers/bubbles/pops_controller.rb b/app/controllers/bubbles/pops_controller.rb index 395f241e2..5421428ca 100644 --- a/app/controllers/bubbles/pops_controller.rb +++ b/app/controllers/bubbles/pops_controller.rb @@ -1,5 +1,5 @@ class Bubbles::PopsController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def create @bubble.pop!(user: Current.user, reason: params[:reason]) diff --git a/app/controllers/bubbles/publishes_controller.rb b/app/controllers/bubbles/publishes_controller.rb index 8064e7c68..bcc75eb27 100644 --- a/app/controllers/bubbles/publishes_controller.rb +++ b/app/controllers/bubbles/publishes_controller.rb @@ -1,5 +1,5 @@ class Bubbles::PublishesController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def create @bubble.publish diff --git a/app/controllers/bubbles/recovers_controller.rb b/app/controllers/bubbles/recovers_controller.rb index 530592762..c94fd6ccf 100644 --- a/app/controllers/bubbles/recovers_controller.rb +++ b/app/controllers/bubbles/recovers_controller.rb @@ -1,5 +1,5 @@ class Bubbles::RecoversController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def create redirect_to @bubble.recover_abandoned_creation diff --git a/app/controllers/bubbles/stagings_controller.rb b/app/controllers/bubbles/stagings_controller.rb index 2f2ea68cc..28f7af26e 100644 --- a/app/controllers/bubbles/stagings_controller.rb +++ b/app/controllers/bubbles/stagings_controller.rb @@ -1,5 +1,5 @@ class Bubbles::StagingsController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def create if params[:stage_id].present? diff --git a/app/controllers/bubbles/watches_controller.rb b/app/controllers/bubbles/watches_controller.rb index cecd292b5..221f51405 100644 --- a/app/controllers/bubbles/watches_controller.rb +++ b/app/controllers/bubbles/watches_controller.rb @@ -1,5 +1,5 @@ class Bubbles::WatchesController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def create set_watching_and_redirect(true) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index d8b0231ac..4708af0e1 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -1,5 +1,5 @@ class CommentsController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped before_action :set_comment, only: [ :show, :edit, :update, :destroy ] before_action :require_own_comment, only: [ :edit, :update, :destroy ] diff --git a/app/controllers/concerns/bubble_scoped.rb b/app/controllers/concerns/bubble_scoped.rb index bf123910c..5805b58ec 100644 --- a/app/controllers/concerns/bubble_scoped.rb +++ b/app/controllers/concerns/bubble_scoped.rb @@ -2,11 +2,15 @@ module BubbleScoped extend ActiveSupport::Concern included do - before_action :set_bubble + before_action :set_bubble, :set_bucket end private def set_bubble - @bubble = @bucket.bubbles.find(params[:bubble_id]) + @bubble = Bubble.find(params[:bubble_id]) + end + + def set_bucket + @bucket = Current.user.buckets.find(@bubble.bucket_id) end end diff --git a/app/controllers/readings_controller.rb b/app/controllers/readings_controller.rb index 6482cd7c9..fe0761831 100644 --- a/app/controllers/readings_controller.rb +++ b/app/controllers/readings_controller.rb @@ -1,5 +1,5 @@ class ReadingsController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def create mark_bubble_notifications_read diff --git a/app/controllers/taggings_controller.rb b/app/controllers/taggings_controller.rb index 629f4fb7a..e35db0b2f 100644 --- a/app/controllers/taggings_controller.rb +++ b/app/controllers/taggings_controller.rb @@ -1,5 +1,5 @@ class TaggingsController < ApplicationController - include BubbleScoped, BucketScoped + include BubbleScoped def new render partial: "bubbles/tagging", locals: { bubble: @bubble, tags: Current.account.tags } From e69c1bd0a1d0859217021bc05e4e1e260e67f1f1 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 15:45:16 +0200 Subject: [PATCH 028/104] Break pins out of the double nesting Its cumbersome and needless --- app/controllers/bubbles/pins_controller.rb | 4 ++-- app/views/bubbles/pins/show.html.erb | 4 ++-- app/views/bubbles/show.html.erb | 2 +- config/routes.rb | 8 ++++++-- test/controllers/bubbles/pins_controller_test.rb | 8 ++++---- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/app/controllers/bubbles/pins_controller.rb b/app/controllers/bubbles/pins_controller.rb index fda94c937..09ac6b9c1 100644 --- a/app/controllers/bubbles/pins_controller.rb +++ b/app/controllers/bubbles/pins_controller.rb @@ -8,14 +8,14 @@ class Bubbles::PinsController < ApplicationController pin = @bubble.pin_by Current.user broadcast_new pin - redirect_to bucket_bubble_pin_path(@bucket, @bubble) + redirect_to bubble_pin_path(@bubble) end def destroy pin = @bubble.unpin_by Current.user broadcast_removed pin - redirect_to bucket_bubble_pin_path(@bucket, @bubble) + redirect_to bubble_pin_path(@bubble) end private diff --git a/app/views/bubbles/pins/show.html.erb b/app/views/bubbles/pins/show.html.erb index cbd2b75a0..5a8852a03 100644 --- a/app/views/bubbles/pins/show.html.erb +++ b/app/views/bubbles/pins/show.html.erb @@ -1,11 +1,11 @@ <%= turbo_frame_tag dom_id(@bubble, :pin) do %> <% if @bubble.pinned_by? Current.user %> - <%= button_to bucket_bubble_pin_path(@bubble.bucket, @bubble), method: :delete, class: "btn btn--reversed" do %> + <%= button_to bubble_pin_path(@bubble), method: :delete, class: "btn btn--reversed" do %> <%= icon_tag "pinned" %> Un-pin this card <% end %> <% else %> - <%= button_to bucket_bubble_pin_path(@bubble.bucket, @bubble), class: "btn" do %> + <%= button_to bubble_pin_path(@bubble), class: "btn" do %> <%= icon_tag "unpinned" %> Pin this card <% end %> diff --git a/app/views/bubbles/show.html.erb b/app/views/bubbles/show.html.erb index c88a0f625..b7d62b740 100644 --- a/app/views/bubbles/show.html.erb +++ b/app/views/bubbles/show.html.erb @@ -81,7 +81,7 @@ <% if @bubble.published? %>
<%= turbo_frame_tag dom_id(@bubble, :watch), src: bucket_bubble_watch_path(@bubble.bucket, @bubble), refresh: :morph %> - <%= turbo_frame_tag dom_id(@bubble, :pin), src: bucket_bubble_pin_path(@bubble.bucket, @bubble), refresh: :morph %> + <%= turbo_frame_tag dom_id(@bubble, :pin), src: bubble_pin_path(@bubble), refresh: :morph %>
<% end %>
diff --git a/config/routes.rb b/config/routes.rb index 2b9b15d91..3433bc802 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -17,7 +17,12 @@ Rails.application.routes.draw do route_for :bucket_bubble, comment.bubble.bucket, comment.bubble, options end - resources :bubbles + resources :bubbles do + scope module: :bubbles do + resource :pin + end + end + resources :notifications, only: :index namespace :notifications do resource :tray, only: :show @@ -54,7 +59,6 @@ Rails.application.routes.draw do resource :recover resources :stagings resource :watch - resource :pin, only: [ :show, :create, :destroy ] end resources :assignments diff --git a/test/controllers/bubbles/pins_controller_test.rb b/test/controllers/bubbles/pins_controller_test.rb index cdde4e7f2..c4a6c3c0e 100644 --- a/test/controllers/bubbles/pins_controller_test.rb +++ b/test/controllers/bubbles/pins_controller_test.rb @@ -9,23 +9,23 @@ class Bubbles::PinsControllerTest < ActionDispatch::IntegrationTest assert_changes -> { bubbles(:layout).pinned_by?(users(:kevin)) }, from: false, to: true do perform_enqueued_jobs do assert_turbo_stream_broadcasts([ users(:kevin), :pins ], count: 1) do - post bucket_bubble_pin_path(buckets(:writebook), bubbles(:layout)) + post bubble_pin_path(bubbles(:layout)) end end end - assert_redirected_to bucket_bubble_pin_path(buckets(:writebook), bubbles(:layout)) + assert_redirected_to bubble_pin_path(bubbles(:layout)) end test "destroy" do assert_changes -> { bubbles(:shipping).pinned_by?(users(:kevin)) }, from: true, to: false do perform_enqueued_jobs do assert_turbo_stream_broadcasts([ users(:kevin), :pins ], count: 1) do - delete bucket_bubble_pin_path(buckets(:writebook), bubbles(:shipping)) + delete bubble_pin_path(bubbles(:shipping)) end end end - assert_redirected_to bucket_bubble_pin_path(buckets(:writebook), bubbles(:shipping)) + assert_redirected_to bubble_pin_path(bubbles(:shipping)) end end From b4c0fec7a6980fbaf7fb8f73ccbcc803f4fa2d01 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 15:51:53 +0200 Subject: [PATCH 029/104] Move Assignments under Bubble Since that what we are assigning --- app/controllers/{ => bubbles}/assignments_controller.rb | 2 +- config/routes.rb | 2 +- test/controllers/{ => bubbles}/assignments_controller_test.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename app/controllers/{ => bubbles}/assignments_controller.rb (93%) rename test/controllers/{ => bubbles}/assignments_controller_test.rb (90%) diff --git a/app/controllers/assignments_controller.rb b/app/controllers/bubbles/assignments_controller.rb similarity index 93% rename from app/controllers/assignments_controller.rb rename to app/controllers/bubbles/assignments_controller.rb index eb9c4e74f..f7cada259 100644 --- a/app/controllers/assignments_controller.rb +++ b/app/controllers/bubbles/assignments_controller.rb @@ -1,4 +1,4 @@ -class AssignmentsController < ApplicationController +class Bubbles::AssignmentsController < ApplicationController include BubbleScoped def new diff --git a/config/routes.rb b/config/routes.rb index 3433bc802..a3ac2ee4a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -59,9 +59,9 @@ Rails.application.routes.draw do resource :recover resources :stagings resource :watch + resources :assignments end - resources :assignments resources :taggings end end diff --git a/test/controllers/assignments_controller_test.rb b/test/controllers/bubbles/assignments_controller_test.rb similarity index 90% rename from test/controllers/assignments_controller_test.rb rename to test/controllers/bubbles/assignments_controller_test.rb index 4bec58298..81156b23e 100644 --- a/test/controllers/assignments_controller_test.rb +++ b/test/controllers/bubbles/assignments_controller_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class AssignmentsControllerTest < ActionDispatch::IntegrationTest +class Bubbles::AssignmentsControllerTest < ActionDispatch::IntegrationTest setup do sign_in_as :kevin end From ec36e52b251836485f507f16a024f01abeddb10b Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 15:52:15 +0200 Subject: [PATCH 030/104] No longer used --- app/views/bubbles/_bubble.html.erb | 48 ------------------------------ 1 file changed, 48 deletions(-) delete mode 100644 app/views/bubbles/_bubble.html.erb diff --git a/app/views/bubbles/_bubble.html.erb b/app/views/bubbles/_bubble.html.erb deleted file mode 100644 index d22a7f701..000000000 --- a/app/views/bubbles/_bubble.html.erb +++ /dev/null @@ -1,48 +0,0 @@ -<% cache bubble do %> - <%= tag.div class: [ "bubble", drafted: bubble.drafted?, popped: bubble.popped? ], - style: "view-transition-name: bubble-#{bubble.id}; --bubble-color: #{bubble.color}; #{bubble_rotation(bubble)}", - role: "group", aria: { label: bubble_title(bubble) }, - data: { - bubble_size_target: "bubble", - activity_score: bubble.activity_score, - activity_score_at: bubble.activity_score_at.to_i, - controller: "animation upload-preview", - animation_play_class: "bubble--wobble", - animation_play_on_load_value: true, - action: "mouseover->animation#play" } do %> -
-

- <% if bubble.published? %> - <%= turbo_frame_tag bubble, :edit do %> - <%= link_to bubble_title(bubble), edit_bucket_bubble_path(bubble.bucket, bubble), - class: "txt-undecorated bubble__title-rendered", - role: "button", aria: { label: "Edit name: #{bubble_title(bubble)}" } %> - <% end %> - <% else %> - <%= form_with model: bubble, url: bucket_bubble_path(bubble.bucket, bubble), id: "bubble_form", data: { controller: "auto-save" } do |form| %> - <%= form.text_area :title, placeholder: "Name it…", class: "input full-width borderless txt-align-start card__title-field", autofocus: bubble.title.blank?, data: { action: "auto-save#change blur->auto-save#submit keydown.enter->auto-save#submit:prevent keydown.ctrl+enter->auto-save#submit:prevent" } %> - <% end %> - <% end %> - -
- <%= render "bubbles/tags", bubble: bubble %> -
-

-
- -
- - -

- <%= link_to bucket_bubble_path(bubble.bucket, bubble), class: "bubble__link" do %> - <%= bubble_title(bubble) %> - <% end %> -

- - <%= render "bubbles/assignments", bubble: bubble %> - <%= render "bubbles/boosts", bubble: bubble %> - <%= render "bubbles/comments", bubble: bubble %> - <%= render "bubbles/date", bubble: bubble %> - <%= render "bubbles/image", bubble: bubble %> - <% end %> -<% end %> From 851be126aba76cd450148a541e84d7d91697e4c1 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 15:55:11 +0200 Subject: [PATCH 031/104] Emphasize where this pin is showing up --- app/controllers/bubbles/pins_controller.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/bubbles/pins_controller.rb b/app/controllers/bubbles/pins_controller.rb index 09ac6b9c1..d75d2b10d 100644 --- a/app/controllers/bubbles/pins_controller.rb +++ b/app/controllers/bubbles/pins_controller.rb @@ -7,23 +7,23 @@ class Bubbles::PinsController < ApplicationController def create pin = @bubble.pin_by Current.user - broadcast_new pin + broadcast_my_new pin redirect_to bubble_pin_path(@bubble) end def destroy pin = @bubble.unpin_by Current.user - broadcast_removed pin + broadcast_my_removed pin redirect_to bubble_pin_path(@bubble) end private - def broadcast_new(pin) + def broadcast_my_new(pin) pin.broadcast_prepend_later_to [ Current.user, :pins ], target: "pins", partial: "my/pins/pin" end - def broadcast_removed(pin) + def broadcast_my_removed(pin) pin.broadcast_remove_to [ Current.user, :pins ] end end From 3b5f8c2e6aeaeccdce12e91eb152fac15818f4b1 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 15:56:12 +0200 Subject: [PATCH 032/104] Note the security oddity of finding straight off root --- app/controllers/concerns/bubble_scoped.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/concerns/bubble_scoped.rb b/app/controllers/concerns/bubble_scoped.rb index 5805b58ec..2f422727c 100644 --- a/app/controllers/concerns/bubble_scoped.rb +++ b/app/controllers/concerns/bubble_scoped.rb @@ -7,6 +7,7 @@ module BubbleScoped private def set_bubble + # Finding the bubble on the root depends on checking permission by finding its bucket via Current.user @bubble = Bubble.find(params[:bubble_id]) end From d0953d6f8778067e3db7bbf5f31fc9f0b7efe7b1 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 5 Apr 2025 15:59:51 +0200 Subject: [PATCH 033/104] Pull assignments out of the double nesting --- app/views/bubbles/_assignment.html.erb | 2 +- app/views/bubbles/cards/perma/_assignees.html.erb | 2 +- config/routes.rb | 2 +- test/controllers/bubbles/assignments_controller_test.rb | 7 +++---- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/views/bubbles/_assignment.html.erb b/app/views/bubbles/_assignment.html.erb index 7c6071a25..d28298c02 100644 --- a/app/views/bubbles/_assignment.html.erb +++ b/app/views/bubbles/_assignment.html.erb @@ -3,7 +3,7 @@ Assign this to… - <%= form_with url: bucket_bubble_assignments_path(bubble.bucket, bubble), class: "flex flex-column full-width popup__list", data: { controller: "form" } do |form| %> + <%= form_with url: bubble_assignments_path(bubble), class: "flex flex-column full-width popup__list", data: { controller: "form" } do |form| %> <% bubble.bucket.users.active.sort_by(&:name).each do |user| %>