diff --git a/app/assets/stylesheets/bubbles.css b/app/assets/stylesheets/bubbles.css index 932efb262..25b014300 100644 --- a/app/assets/stylesheets/bubbles.css +++ b/app/assets/stylesheets/bubbles.css @@ -78,6 +78,7 @@ --rotation: 45deg; aspect-ratio: 6/9; + border-radius: var(--bubble-shape); display: flex; font-size: 6cqi; inset: 70cqi 7cqi auto auto; @@ -86,22 +87,27 @@ place-items: center; transform: rotate(var(--rotation)); - span { + + .boost__form { transform: rotate(calc(var(--rotation) * -1)); } - form { - block-size: 100%; - display: grid; - inline-size: 100%; + .boost__btn { + --btn-background: var(--bubble-color); + --btn-border-radius: 50%; + --btn-color: var(--color-ink-reversed); + --btn-size: 0.5em; + --btn-padding: 0.3em 0.5em; + + font-weight: 800; } - .btn { - --btn-background: transparent; - --btn-color: var(--bubble-color); - - appearance: none; + .boost__input { + color: var(--bubble-color); + field-sizing: content; font-weight: 800; + padding: 0; + text-align: center; } &.boosting { @@ -210,15 +216,6 @@ transition: transform 200ms ease-out; white-space: nowrap; z-index: 1; - - &:has(.input:not([type="file"], [type="date"], select)) { - border-radius: 2em; - padding: 0.2em 0.5em; - - .input { - color: var(--bubble-color); - } - } } @media (hover: hover) { diff --git a/app/assets/stylesheets/toggles.css b/app/assets/stylesheets/toggles.css new file mode 100644 index 000000000..d37f6a21b --- /dev/null +++ b/app/assets/stylesheets/toggles.css @@ -0,0 +1,13 @@ +.toggler--toggled { + .toggler__visible-when-off { + display: none; + } + + .toggler__visible-when-on { + display: unset; + } +} + +.toggler__visible-when-on { + display: none; +} diff --git a/app/controllers/boosts_controller.rb b/app/controllers/boosts_controller.rb index 5f5c95e93..0a6f34f78 100644 --- a/app/controllers/boosts_controller.rb +++ b/app/controllers/boosts_controller.rb @@ -2,6 +2,15 @@ class BoostsController < ApplicationController include BubbleScoped, BucketScoped def create - @bubble.boost! + count = if params[:boost_count].to_i == @bubble.boosts_count + @bubble.boosts_count + 1 + else + params[:boost_count].to_i + end + @bubble.boost!(count) + + respond_to do |format| + format.turbo_stream + end end end diff --git a/app/controllers/buckets_controller.rb b/app/controllers/buckets_controller.rb index 320882381..b6cbe66dc 100644 --- a/app/controllers/buckets_controller.rb +++ b/app/controllers/buckets_controller.rb @@ -38,7 +38,7 @@ class BucketsController < ApplicationController end def bucket_params - params.expect(bucket: [ :name ]) + params.expect(bucket: [ :name, :all_access ]).with_defaults(all_access: false) end def grantees diff --git a/app/helpers/accesses_helper.rb b/app/helpers/accesses_helper.rb new file mode 100644 index 000000000..e1fb3ad0f --- /dev/null +++ b/app/helpers/accesses_helper.rb @@ -0,0 +1,15 @@ +module AccessesHelper + def access_menu_tag(bucket, &) + tag.menu class: [ "flex flex-column gap margin-none pad txt-medium", { "toggler--toggled": bucket.all_access? } ], data: { + controller: "filter toggle-class", + filter_active_class: "filter--active", filter_selected_class: "selected", + toggle_class_toggle_class: "toggler--toggled" }, & + end + + def access_toggles_for(users, selected:) + render partial: "buckets/access_toggle", + collection: users, as: :user, + locals: { selected: selected }, + cached: ->(user) { [ user, selected ] } + end +end diff --git a/app/models/bubble/boostable.rb b/app/models/bubble/boostable.rb index 226671803..94a530e8e 100644 --- a/app/models/bubble/boostable.rb +++ b/app/models/bubble/boostable.rb @@ -5,10 +5,13 @@ module Bubble::Boostable scope :ordered_by_boosts, -> { order boosts_count: :desc } end - def boost! + def boost!(count = 1) + count = count.to_i + count = 1 if count < 1 + transaction do - track_event :boosted - increment! :boosts_count + track_event :boosted, count: count + update! boosts_count: count rescore end end diff --git a/app/models/bucket/accessible.rb b/app/models/bucket/accessible.rb index a5b49e94f..4b21c117b 100644 --- a/app/models/bucket/accessible.rb +++ b/app/models/bucket/accessible.rb @@ -15,12 +15,20 @@ module Bucket::Accessible end def revoke_from(users) - destroy_by user: users + destroy_by user: users unless proxy_association.owner.all_access? end end has_many :users, through: :accesses + scope :all_access, -> { where(all_access: true) } + after_create -> { accesses.grant_to creator } + after_save_commit :grant_access_to_everyone end + + private + def grant_access_to_everyone + accesses.grant_to(account.users) if all_access_previously_changed?(to: true) + end end diff --git a/app/models/filter/resources.rb b/app/models/filter/resources.rb index 78c862c9d..bde1a30d1 100644 --- a/app/models/filter/resources.rb +++ b/app/models/filter/resources.rb @@ -12,5 +12,11 @@ module Filter::Resources kind = resource.class.model_name.plural send "#{kind}=", send(kind).without(resource) empty? ? destroy! : save! + rescue ActiveRecord::RecordNotUnique + destroy! + end + + def buckets + creator.buckets.where id: bucket_ids end end diff --git a/app/models/user.rb b/app/models/user.rb index 2baa83876..bfa562008 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -21,6 +21,8 @@ class User < ApplicationRecord validates_presence_of :email_address normalizes :email_address, with: ->(value) { value.strip.downcase } + after_create_commit :grant_access_to_buckets + scope :active, -> { where(active: true) } scope :alphabetically, -> { order("LOWER(name)") } @@ -48,4 +50,8 @@ class User < ApplicationRecord def deactived_email_address 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/views/boosts/_boosts.html.erb b/app/views/boosts/_boosts.html.erb index 975684583..6fdf9271d 100644 --- a/app/views/boosts/_boosts.html.erb +++ b/app/views/boosts/_boosts.html.erb @@ -5,10 +5,10 @@ toggle_class_toggle_class: "boosting", action: "animationend->toggle-class#toggle" }, hidden: !bubble.boosts_count.positive? do %> - <%= button_to bucket_bubble_boosts_path(bubble.bucket, bubble), - class: "btn btn--plain", - data: { action: "toggle-class#toggle" }, - form_class: "full-width" do %> - <%= tag.span("+ #{bubble.boosts_count}") if bubble.boosts_count.positive? %> + <%= form_with url: bucket_bubble_boosts_path(bubble.bucket, bubble), + class: "boost__form", + data: { action: "toggle-class#toggle" } do %> + <%= text_field_tag :boost_count, bubble.boosts_count, min: 1, class: "input borderless boost__input", autocomplete: "off" %> + <%= tag.button "+", class: "btn btn--plain boost__btn", type: :submit %> <% end %> <% end %> diff --git a/app/views/bubbles/_bubble.html.erb b/app/views/bubbles/_bubble.html.erb index 09d680c94..4945e02b6 100644 --- a/app/views/bubbles/_bubble.html.erb +++ b/app/views/bubbles/_bubble.html.erb @@ -8,12 +8,12 @@

<%= turbo_frame_tag bubble, :edit do %> <%= link_to bubble.title, edit_bucket_bubble_path(bubble.bucket, bubble), class: "txt-undecorated" %> + +
+ <%= render "bubbles/tags", bubble: bubble %> +
<% end %>

- -
- <%= render "bubbles/tags", bubble: bubble %> -
diff --git a/app/views/bubbles/_messages.html.erb b/app/views/bubbles/_messages.html.erb index 5320e9eeb..446b424c9 100644 --- a/app/views/bubbles/_messages.html.erb +++ b/app/views/bubbles/_messages.html.erb @@ -5,6 +5,6 @@ data-created-by-current-user-mine-class="comment--mine"> <%# Template Dependency: comments/comment %> <%# Template Dependency: event_summaries/event_summary %> - <%= render bubble.messages, cache: true %> + <%= render bubble.messages, cached: true %> <%= render "comments/new", bubble: bubble %> diff --git a/app/views/bubbles/_tags.html.erb b/app/views/bubbles/_tags.html.erb index c38e63103..bf23f575c 100644 --- a/app/views/bubbles/_tags.html.erb +++ b/app/views/bubbles/_tags.html.erb @@ -1,6 +1,6 @@ <% bubble.tags.each do |tag| %> <%= link_to bubbles_path(@filter.to_params.merge(tag_ids: [ tag.id ])), - class: "bubble__tag btn btn--plain fill-transparent min-width", style: "color: #{bubble.color}" do %> + class: "bubble__tag btn btn--plain fill-transparent min-width", style: "color: #{bubble.color}", data: { turbo_frame: "_top" } do %> <%= tag.hashtag %> <% end %> <% end %> diff --git a/app/views/bubbles/edit.html.erb b/app/views/bubbles/edit.html.erb index 562bc096b..57bbed5c1 100644 --- a/app/views/bubbles/edit.html.erb +++ b/app/views/bubbles/edit.html.erb @@ -1,12 +1,15 @@ <%= turbo_frame_tag @bubble, :edit do %> - <%= form_with model: @bubble, url: bucket_bubble_path(@bubble.bucket, @bubble), class: "flex flex-column gap full-width", data: { controller: "form" } do |form| %> + <%= form_with model: @bubble, url: bucket_bubble_path(@bubble.bucket, @bubble), class: "flex flex-column justify-center gap full-width", data: { controller: "form" } do |form| %> <%= form.label :title, class: "flex flex-column justify-center align-center" do %> <%= form.text_area :title, class: "input input--textara txt-align-center full-width borderless", required: true, rows: 5, autofocus: true, placeholder: "Name it…", data: { action: "keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel focus->form#select" }, style: "color: var(--spat-color); --input-border-radius: 0" %> <% end %> - <%= form.submit "Save", hidden: true %> + <%= form.button "Save", class: "btn btn--reversed txt-small center", type: :submit do %> + <%= image_tag "check.svg", aria: { hidden: true }, size: 24 %> + Save + <% end %> <%= link_to "Close editor and discard changes", bucket_bubble_path(@bubble.bucket, @bubble), data: { form_target: "cancel" }, hidden: true %> <% end %> <% end %> diff --git a/app/views/buckets/_access_toggle.erb b/app/views/buckets/_access_toggle.erb new file mode 100644 index 000000000..1b2482ef4 --- /dev/null +++ b/app/views/buckets/_access_toggle.erb @@ -0,0 +1,21 @@ +
  • +
    + <%= avatar_tag user, loading: :lazy %> +
    + +
    +
    + <%= user.name %> +
    +
    + + + + <%= image_tag "check.svg", size: 20, class: "toggler__visible-when-on colorize--black flex-item-no-shrink", aria: { hidden: "true" } %> + + +
  • diff --git a/app/views/buckets/_user_toggle.html.erb b/app/views/buckets/_user_toggle.html.erb deleted file mode 100644 index 874dc2ed4..000000000 --- a/app/views/buckets/_user_toggle.html.erb +++ /dev/null @@ -1,24 +0,0 @@ -
  • -
    - <%= avatar_tag user, loading: :lazy %> -
    - -
    -
    - <%= user.name %> -
    -
    - - - - <% if user == Current.user %> - <%= hidden_field_tag "user_ids[]", user.id, id: nil %> - <%= image_tag "check.svg", size: 20, class: "colorize--black flex-item-no-shrink", aria: { hidden: "true" } %> - <% else %> - - <% end %> -
  • diff --git a/app/views/buckets/accesses/edit.html.erb b/app/views/buckets/accesses/edit.html.erb deleted file mode 100644 index 4a593b72f..000000000 --- a/app/views/buckets/accesses/edit.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -

    Users on <%= @bucket.name %>

    - -<%= form_with url: bucket_access_path, method: :put do |form| %> - - - <%= form.submit %> -<% end %> diff --git a/app/views/buckets/edit.html.erb b/app/views/buckets/edit.html.erb index 48931ac1c..f5c2dab81 100644 --- a/app/views/buckets/edit.html.erb +++ b/app/views/buckets/edit.html.erb @@ -17,7 +17,7 @@ <% end %>
    - <%= form_with model: @bucket, class: "flex flex-column gap txt-large", controller: "form" do |form| %> + <%= form_with model: @bucket, class: "flex flex-column gap txt-large", data: { controller: "form" } do |form| %>
    <%= translation_button(:bucket_name) %> @@ -29,7 +29,7 @@
    - + <%= access_menu_tag @bucket do %>
  • <%= image_tag "everyone.svg", aria: { hidden: "true" }, class: "colorize--black" %> @@ -42,13 +42,11 @@ - <%= link_to nil, class: "btn--faux flex-inline", tabindex: "-1" do %> - - <% end %> +
  • @@ -58,15 +56,15 @@ <% end %>
    - <%= render partial: "buckets/user_toggle", collection: @selected_users, as: :user, locals: { selected: true } %> + <%= access_toggles_for @selected_users, selected: true %> <% if @selected_users.any? && @unselected_users.any? %>
    <% end %> - <%= render partial: "buckets/user_toggle", collection: @unselected_users, as: :user, locals: { selected: false } %> + <%= access_toggles_for @unselected_users, selected: false %>
    -
    + <% end %>