diff --git a/Gemfile b/Gemfile
index aa8439cd0..c1cc15622 100644
--- a/Gemfile
+++ b/Gemfile
@@ -34,6 +34,10 @@ group :development, :test do
gem "rubocop-rails-omakase", require: false
end
+group :development do
+ gem "hotwire-spark"
+end
+
group :test do
gem "capybara"
gem "selenium-webdriver"
diff --git a/Gemfile.lock b/Gemfile.lock
index d9c50d18c..4cfbbd656 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -151,8 +151,22 @@ GEM
reline (>= 0.3.8)
drb (2.2.1)
erubi (1.13.0)
+ ffi (1.17.0-aarch64-linux-gnu)
+ ffi (1.17.0-aarch64-linux-musl)
+ ffi (1.17.0-arm-linux-gnu)
+ ffi (1.17.0-arm-linux-musl)
+ ffi (1.17.0-arm64-darwin)
+ ffi (1.17.0-x86-linux-gnu)
+ ffi (1.17.0-x86-linux-musl)
+ ffi (1.17.0-x86_64-darwin)
+ ffi (1.17.0-x86_64-linux-gnu)
+ ffi (1.17.0-x86_64-linux-musl)
globalid (1.2.1)
activesupport (>= 6.1)
+ hotwire-spark (0.1.3)
+ listen
+ rails (>= 8.0.0)
+ zeitwerk
i18n (1.14.6)
concurrent-ruby (~> 1.0)
importmap-rails (2.0.3)
@@ -168,6 +182,9 @@ GEM
activesupport (>= 5.0.0)
json (2.9.0)
language_server-protocol (3.17.0.3)
+ listen (3.9.0)
+ rb-fsevent (~> 0.10, >= 0.10.3)
+ rb-inotify (~> 0.9, >= 0.9.10)
logger (1.6.2)
loofah (2.23.1)
crass (~> 1.0.2)
@@ -239,6 +256,9 @@ GEM
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)
+ rb-fsevent (0.11.2)
+ rb-inotify (0.11.1)
+ ffi (~> 1.0)
rdoc (6.8.1)
psych (>= 4.0.0)
regexp_parser (2.9.3)
@@ -353,6 +373,7 @@ DEPENDENCIES
brakeman
capybara
debug
+ hotwire-spark
hotwire_combobox!
house_md!
importmap-rails
diff --git a/app/assets/images/drag.svg b/app/assets/images/drag.svg
new file mode 100644
index 000000000..26b655f04
--- /dev/null
+++ b/app/assets/images/drag.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/assets/images/trash.svg b/app/assets/images/trash.svg
new file mode 100644
index 000000000..fc95dc1a8
--- /dev/null
+++ b/app/assets/images/trash.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/assets/stylesheets/bubbles.css b/app/assets/stylesheets/bubbles.css
index 608a8d2da..91b65091e 100644
--- a/app/assets/stylesheets/bubbles.css
+++ b/app/assets/stylesheets/bubbles.css
@@ -81,6 +81,7 @@
border-radius: var(--bubble-shape);
display: flex;
font-size: 6cqi;
+ inline-size: min-content;
inset: 70cqi 7cqi auto auto;
min-inline-size: 4.5ch;
padding: 0;
@@ -104,10 +105,13 @@
.boost__input {
color: var(--bubble-color);
- field-sizing: content;
font-weight: 800;
padding: 0;
text-align: center;
+
+ @supports (field-sizing: content) {
+ field-sizing: content;
+ }
}
&.boosting {
@@ -369,15 +373,6 @@
position: relative;
transition: background-color 200ms ease-out;
- &:nth-of-type(10)::after {
- border-bottom: 1px dashed var(--color-subtle-dark);
- block-size: 0;
- content: "";
- inline-size: 100%;
- inset: auto 0 0 0;
- position: absolute;
- }
-
@media (hover: hover) {
&:hover {
background-color: color(from var(--bubble-color) srgb r g b / 0.15);
@@ -396,6 +391,27 @@
}
}
+.bubbles-list__divider {
+ --border-color: var(--divider-color);
+ --border-size: 2px;
+ --divider-color: var(--color-subtle-dark);
+
+ font-size: 1rem;
+}
+
+.btn--reversed.bubbles-list__handle {
+ --btn-background: var(--divider-color);
+
+ font-size: 0.9rem;
+ cursor: grab;
+}
+
+.bubbles-list__count {
+ background-color: var(--divider-color);
+ color: var(--color-ink-reversed);
+ padding: 0.1em 0.7em;
+}
+
.bubble__title-text {
font-weight: 600;
flex-grow: 1;
diff --git a/app/assets/stylesheets/utilities.css b/app/assets/stylesheets/utilities.css
index 60de39c8d..6cf59bfed 100644
--- a/app/assets/stylesheets/utilities.css
+++ b/app/assets/stylesheets/utilities.css
@@ -216,7 +216,7 @@
.separator {
border-block: 0;
border-inline-end: 0;
- border-inline-start: 1px var(--border-style, solid) var(--border-color, currentColor);
+ border-inline-start: var(--border-size, 1px) var(--border-style, solid) var(--border-color, currentColor);
display: inline-flex;
inline-size: 0;
}
@@ -224,7 +224,7 @@
.separator--horizontal {
block-size: 0;
border-block-end: 0;
- border-block-start: 1px var(--border-style, solid) var(--border-color, currentColor);
+ border-block-start: var(--border-size, 1px) var(--border-style, solid) var(--border-color, currentColor);
border-inline: 0;
display: flex;
}
diff --git a/app/controllers/bubbles_controller.rb b/app/controllers/bubbles_controller.rb
index 974c9aec9..920b8b181 100644
--- a/app/controllers/bubbles_controller.rb
+++ b/app/controllers/bubbles_controller.rb
@@ -4,7 +4,7 @@ class BubblesController < ApplicationController
skip_before_action :set_bucket, only: :index
before_action :set_filter, only: :index
- before_action :set_bubble, only: %i[ show edit update ]
+ before_action :set_bubble, only: %i[ show edit update destroy ]
def index
@bubbles = @filter.bubbles
@@ -22,6 +22,11 @@ class BubblesController < ApplicationController
def edit
end
+ def destroy
+ @bubble.destroy!
+ redirect_to bubbles_path, notice: "Bubble deleted"
+ end
+
def update
@bubble.update! bubble_params
redirect_to @bubble
diff --git a/app/views/bubbles/index.html.erb b/app/views/bubbles/index.html.erb
index af61d2e44..277f7684a 100644
--- a/app/views/bubbles/index.html.erb
+++ b/app/views/bubbles/index.html.erb
@@ -32,6 +32,18 @@
+ -
+
+
+
+ Top 10
+
+
+
+
<%= render partial: "bubbles/list/bubble", collection: @bubbles, cached: true %>
diff --git a/app/views/bubbles/show.html.erb b/app/views/bubbles/show.html.erb
index 7f0f2793e..1b48b031b 100644
--- a/app/views/bubbles/show.html.erb
+++ b/app/views/bubbles/show.html.erb
@@ -56,6 +56,14 @@
<%= image_tag "picture-double.svg", aria: { hidden: true }, size: 24 %>
I've seen this
+
+ <%= button_to bucket_bubble_path(@bubble.bucket, @bubble),
+ method: :delete,
+ class: "btn full-width justify-start borderless",
+ data: { turbo_confirm: "Are you sure you want to delete this bubble?" } do %>
+ <%= image_tag "trash.svg", aria: { hidden: true }, size: 24 %>
+ Delete bubble
+ <% end %>
diff --git a/app/views/comments/edit.html.erb b/app/views/comments/edit.html.erb
index b68d43122..04d0b5a13 100644
--- a/app/views/comments/edit.html.erb
+++ b/app/views/comments/edit.html.erb
@@ -9,13 +9,13 @@
Save
<% end %>
<%= link_to bucket_bubble_comment_path(@bubble.bucket, @bubble, @comment), class: "btn btn--small", data: { form_target: "cancel" } do %>
- <%= image_tag "close.svg", aria: { hidden: true }, size: 16 %>
+ <%= image_tag "remove-med.svg", aria: { hidden: true }, size: 16 %>
Cancel
<% end %>
<%= tag.button type: :submit, class: "btn btn--small btn--negative flex-item-justify-end", form: dom_id(@comment, :delete_form),
data: { turbo_confirm: "Are you sure you want to delete this comment?" } do %>
- <%= image_tag "remove.svg", aria: { hidden: true }, size: 16 %>
+ <%= image_tag "trash.svg", aria: { hidden: true }, size: 16 %>
Delete
<% end %>