Rename Splat to Bubble

This commit is contained in:
Jeffrey Hardy
2024-09-04 14:49:25 -04:00
parent 6dc2c2ba73
commit 5aae70298b
42 changed files with 294 additions and 285 deletions
@@ -1,5 +1,5 @@
:root {
--splat-size: 30vw;
--bubble-size: 30vw;
}
.windshield {
@@ -10,14 +10,14 @@
}
}
.splat {
.bubble {
--hover-size: 0;
--splat-color: var(--color-ink);
--splat-rotate: 20deg;
--bubble-color: var(--color-ink);
--bubble-rotate: 20deg;
aspect-ratio: 1;
block-size: var(--splat-size);
color: var(--splat-color, currentColor);
block-size: var(--bubble-size);
color: var(--bubble-color, currentColor);
container-type: inline-size;
display: grid;
max-inline-size: 100%;
@@ -50,8 +50,8 @@
scale: 1.1;
z-index: 999;
.splat__svg {
transform: rotate(calc(var(--splat-rotate) + 10deg));
.bubble__svg {
transform: rotate(calc(var(--bubble-rotate) + 10deg));
}
}
}
@@ -60,23 +60,23 @@
grid-area: 1/1;
}
.splat__perma & {
--splat-size: 40vh !important;
.bubble__perma & {
--bubble-size: 40vh !important;
}
}
.splat__bubble {
.bubble__bubble {
background-color: var(--color-bg);
border: 0.3em solid var(--splat-color);
border: 0.3em solid var(--bubble-color);
border-radius: 50%;
position: absolute;
z-index: -1;
a {
color: var(--splat-color);
color: var(--bubble-color);
}
&:is(.splat__boosts) {
&:is(.bubble__boosts) {
aspect-ratio: 1;
display: grid;
min-inline-size: 6ch;
@@ -89,7 +89,7 @@
text-decoration: none;
}
.windshield .splat:hover & {
.windshield .bubble:hover & {
transform: translate(0, 1rem) !important;
}
@@ -98,7 +98,7 @@
}
}
&.splat__category {
&.bubble__category {
inset: auto auto 10cqi -3cqi;
+ & {
@@ -109,20 +109,20 @@
}
}
.windshield &:has(.splat__category--new) {
.windshield &:has(.bubble__category--new) {
display: none;
}
}
&.splat__date {
&.bubble__date {
aspect-ratio: 1;
inset: 2cqi 2cqi auto auto;
}
&:where(.splat__meta) {
&:where(.bubble__meta) {
background-color: var(--color-bg);
block-size: auto;
color: var(--splat-color);
color: var(--bubble-color);
display: flex;
font-size: 5cqi;
font-weight: 800;
@@ -143,27 +143,27 @@
padding: 0.2em 0.5em;
.input {
color: var(--splat-color);
color: var(--bubble-color);
}
}
}
@media (hover: hover) {
.windshield .splat:hover & {
.windshield .bubble:hover & {
transform: translate(1rem, 1rem);
}
.windshield .splat:hover & + & {
.windshield .bubble:hover & + & {
transform: translate(0, -1rem);
}
.windshield .splat:hover & + & + & {
.windshield .bubble:hover & + & + & {
transform: translate(-1rem, -1rem);
}
}
}
.splat__image {
.bubble__image {
-webkit-mask-image: url(blob.svg);
-webkit-mask-size: contain;
-webkit-mask-repeat: no-repeat;
@@ -176,44 +176,44 @@
mask-size: contain;
place-items: center;
pointer-events: none;
transform: rotate(var(--splat-rotate));
transform: rotate(var(--bubble-rotate));
@media (hover: hover) {
.windshield .splat:hover & {
transform: rotate(calc(var(--splat-rotate) + 10deg));
.windshield .bubble:hover & {
transform: rotate(calc(var(--bubble-rotate) + 10deg));
}
}
img {
block-size: 100%;
object-fit: cover;
transform: rotate(calc(var(--splat-rotate) * -1));
transform: rotate(calc(var(--bubble-rotate) * -1));
}
}
.splat__link {
.bubble__link {
content: "";
inset: 0;
position: absolute;
z-index: -1;
}
.splat__notes {
.bubble__notes {
position: relative;
}
.splat__svg {
.bubble__svg {
fill: var(--color-bg);
pointer-events: none;
position: relative;
scale: 1.1;
stroke: var(--splat-color);
stroke: var(--bubble-color);
stroke-width: 1.1rem;
transition: all 200ms ease-out;
z-index: -1;
}
.splat__title {
.bubble__title {
-webkit-line-clamp: var(--lines, 5);
-webkit-box-orient: vertical;
display: -webkit-box;
@@ -229,19 +229,19 @@
white-space: normal;
@media (hover: hover) {
.splat:has(.splat__image):hover & {
.bubble:has(.bubble__image):hover & {
color: var(--color-ink-reversed);
text-shadow: 0 0 0.2em var(--splat-color), 0 0 0.2em var(--splat-color), 0 0 0.2em var(--splat-color);
text-shadow: 0 0 0.2em var(--bubble-color), 0 0 0.2em var(--bubble-color), 0 0 0.2em var(--bubble-color);
position: relative;
z-index: 1;
}
}
}
.splats-list {
.bubbles-list {
--hover-size: 0;
.splat__title-link {
.bubble__title-link {
color: var(--color-txt);
text-decoration: none;
}
+6 -6
View File
@@ -1,12 +1,12 @@
class BoostsController < ApplicationController
before_action :set_splat
before_action :set_bubble
def new
@boost = @splat.boosts.build
@boost = @bubble.boosts.build
end
def create
@boost = @splat.boosts.new
@boost = @bubble.boosts.new
@boost.save
respond_to do |format|
@@ -16,11 +16,11 @@ class BoostsController < ApplicationController
end
def index
@boosts = @splat.boosts
@boosts = @bubble.boosts
end
private
def set_splat
@splat = Splat.find(params[:splat_id])
def set_bubble
@bubble = Bubble.find(params[:bubble_id])
end
end
+43
View File
@@ -0,0 +1,43 @@
class BubblesController < ApplicationController
before_action :set_bubble, only: %i[ show edit update ]
def index
if params[:category_id]
@category = Category.find(params[:category_id])
@bubbles = @category.bubbles
else
@bubbles = Bubble.all
end
end
def new
@bubble = Bubble.new
end
def edit
end
def update
@bubble.update(bubble_params)
redirect_to bubble_path(@bubble)
end
def create
Bubble.create! bubble_params
redirect_to bubbles_path
end
def show
end
private
def set_bubble
@bubble = Bubble.find(params[:id])
end
def bubble_params
params.require(:bubble).permit(:title, :body, :color, :image, category_ids: [])
end
end
+5 -5
View File
@@ -1,6 +1,6 @@
class CategoriesController < ApplicationController
before_action :set_category, only: :destroy
before_action :set_splat, only: %i[ new create ]
before_action :set_bubble, only: %i[ new create ]
def index
@categories = Category.all
@@ -14,8 +14,8 @@ class CategoriesController < ApplicationController
@category = Category.find_or_create_by(category_params)
@category.save
@category.splats << @splat
redirect_to splat_path(@splat)
@category.bubbles << @bubble
redirect_to bubble_path(@bubble)
end
def destroy
@@ -33,7 +33,7 @@ class CategoriesController < ApplicationController
@category = Category.find(params[:id])
end
def set_splat
@splat = Splat.find(params[:splat_id])
def set_bubble
@bubble = Bubble.find(params[:bubble_id])
end
end
+5 -5
View File
@@ -1,11 +1,11 @@
class CommentsController < ApplicationController
before_action :set_splat
before_action :set_bubble
def create
@comment = @splat.comments.create(comment_params)
@comment = @bubble.comments.create(comment_params)
@comment.save
redirect_to splat_path(@splat, anchor: "comment_#{@comment.id}")
redirect_to bubble_path(@bubble, anchor: "comment_#{@comment.id}")
end
private
@@ -13,7 +13,7 @@ class CommentsController < ApplicationController
params.require(:comment).permit(:body)
end
def set_splat
@splat = Splat.find(params[:splat_id])
def set_bubble
@bubble = Bubble.find(params[:bubble_id])
end
end
-43
View File
@@ -1,43 +0,0 @@
class SplatsController < ApplicationController
before_action :set_splat, only: %i[ show edit update ]
def index
if params[:category_id]
@category = Category.find(params[:category_id])
@splats = @category.splats
else
@splats = Splat.all
end
end
def new
@splat = Splat.new
end
def edit
end
def update
@splat.update(splat_params)
redirect_to splat_path(@splat)
end
def create
Splat.create! splat_params
redirect_to splats_path
end
def show
end
private
def set_splat
@splat = Splat.find(params[:id])
end
def splat_params
params.require(:splat).permit(:title, :body, :color, :image, category_ids: [])
end
end
+13
View File
@@ -0,0 +1,13 @@
module BubblesHelper
BUBBLE_ROTATION = %w[ 90 80 75 60 45 35 25 5 -45 -40 -75 ]
BUBBLE_SIZE = [ 14, 16, 18, 20, 22 ]
MIN_THRESHOLD = 7
def bubble_rotation(bubble)
BUBBLE_ROTATION[Zlib.crc32(bubble.to_param) % BUBBLE_ROTATION.size]
end
def bubble_size(bubble)
"--bubble-size: #{ BUBBLE_SIZE.min_by { |size| (size - (bubble.boosts.size + bubble.comments.size + MIN_THRESHOLD)).abs } }cqi;"
end
end
-13
View File
@@ -1,13 +0,0 @@
module SplatsHelper
SPLAT_ROTATION = %w[ 90 80 75 60 45 35 25 5 -45 -40 -75 ]
SPLAT_SIZE = [ 14, 16, 18, 20, 22 ]
MIN_THRESHOLD = 7
def splat_rotation(splat)
SPLAT_ROTATION[Zlib.crc32(splat.to_param) % SPLAT_ROTATION.size]
end
def splat_size(splat)
"--splat-size: #{ SPLAT_SIZE.min_by { |size| (size - (splat.boosts.size + splat.comments.size + MIN_THRESHOLD)).abs } }cqi;"
end
end
+1 -1
View File
@@ -1,4 +1,4 @@
class Boost < ApplicationRecord
belongs_to :splat
belongs_to :bubble
belongs_to :creator, class_name: "User", default: -> { Current.user }
end
+1 -1
View File
@@ -1,4 +1,4 @@
class Splat < ApplicationRecord
class Bubble < ApplicationRecord
belongs_to :creator, class_name: "User", default: -> { Current.user }
has_many :comments, dependent: :destroy
+1 -1
View File
@@ -1,4 +1,4 @@
class Categorization < ApplicationRecord
belongs_to :splat
belongs_to :bubble
belongs_to :category
end
+1 -1
View File
@@ -1,4 +1,4 @@
class Category < ApplicationRecord
has_many :categorizations, dependent: :destroy
has_many :splats, through: :categorizations
has_many :bubbles, through: :categorizations
end
+1 -1
View File
@@ -1,4 +1,4 @@
class Comment < ApplicationRecord
belongs_to :splat
belongs_to :bubble
belongs_to :creator, class_name: "User", default: -> { Current.user }
end
+1 -1
View File
@@ -1 +1 @@
<%= link_to splat.boosts.any? ? "+ #{splat.boosts.size}" : "+", new_splat_boost_path(splat), data: { action: "toggle-class#toggle" } %>
<%= link_to bubble.boosts.any? ? "+ #{bubble.boosts.size}" : "+", new_bubble_boost_path(bubble), data: { action: "toggle-class#toggle" } %>
+2 -2
View File
@@ -1,3 +1,3 @@
<%= turbo_stream.update dom_id(@splat, "boosts") do %>
<%= render "/boosts/boost", splat: @splat %>
<%= turbo_stream.update dom_id(@bubble, "boosts") do %>
<%= render "/boosts/boost", bubble: @bubble %>
<% end %>
+2 -2
View File
@@ -1,3 +1,3 @@
<turbo-frame id="<%= dom_id(@splat, "boosts") %>">
<%= render "/boosts/boost", splat: @splat %>
<turbo-frame id="<%= dom_id(@bubble, "boosts") %>">
<%= render "/boosts/boost", bubble: @bubble %>
</turbo-frame>
+2 -2
View File
@@ -1,5 +1,5 @@
<turbo-frame id="<%= dom_id(@splat, "boosts") %>">
<%= form_with model: [@splat, @boost], data: { controller: "auto-submit" } do |form| %>
<turbo-frame id="<%= dom_id(@bubble, "boosts") %>">
<%= form_with model: [@bubble, @boost], data: { controller: "auto-submit" } do |form| %>
<%= form.submit "Boost this", hidden: true %>
<% end %>
</turbo-frame>
+34
View File
@@ -0,0 +1,34 @@
<div class="bubble" style="view-transition-name: bubble-<%= bubble.id -%>; --bubble-color: <%= bubble.color %>; --bubble-rotate: <%= bubble_rotation(bubble) -%>deg; <%= bubble_size(bubble) %>">
<h1 class="bubble__title"><%= bubble.title %></h1>
<svg class="bubble__svg" viewBox="0 0 990 990" xmlns="http://www.w3.org/2000/svg" transform="rotate(<%= bubble_rotation(bubble) -%>)"><path d="m0 0h990v990h-990z" fill="none" stroke="none" /><path d="m391.65 879.47c-110.52-15.95-212.21-91.86-255.92-191.23-66.78-143.65-41.62-347.61 48.08-481.17 368.33-516.3 1252.97 520.2 451.03 660.78-44.07 8.84-88.98 13.49-133.01 15.68-36.69 2-73.37 1.91-109.99-4.03z"/></svg>
<%= link_to bubble, class: "bubble__link" do %>
<span class="for-screen-reader"><%= bubble.title %></span>
<% end %>
<% if bubble.image.attached? %>
<div class="bubble__image">
<%= image_tag bubble.image %>
</div>
<% end %>
<time class="bubble__bubble bubble__meta bubble__date"><%= bubble.created_at.strftime("%b <br> %d").html_safe %></time>
<% bubble.categories.each do | category | %>
<%= link_to "##{category.title}", bubbles_path(category_id: category.id), class: "bubble__bubble bubble__meta bubble__category" %>
<% end %>
<% if bubble.categories.count < 3 %>
<span class="bubble__bubble bubble__meta bubble__category">
<turbo-frame id="new_category">
<%= link_to "#", new_bubble_category_path(bubble), class: "bubble__category--new" %>
</turbo-frame>
</span>
<% end %>
<%= tag.div class: "bubble__bubble bubble__meta bubble__boosts",
data: { controller: "animation toggle-class", animation_play_class: "boosting", toggle_class_toggle_class: "boosting", action: "animationend->toggle-class#toggle" } do %>
<turbo-frame id="<%= dom_id(bubble, "boosts") %>" src="<%= bubble_boosts_path(bubble) %>" />
<% end %>
</div>
@@ -1,4 +1,4 @@
<%= form_with model: splat, class: "flex flex-column gap full-width" do | form | %>
<%= form_with model: bubble, class: "flex flex-column gap full-width" do | form | %>
<%= form.label :title, class: "flex flex-column justify-start align-start" do %>
<%= form.text_field :title, class: "input full-width", required: true, placeholder: "Name it…" %>
<% end %>
@@ -7,7 +7,7 @@
<legend class="for-screen-reader">Color</legend>
<div class="flex align-center gap">
<% Splat.colors.keys.each do | color | %>
<% Bubble.colors.keys.each do | color | %>
<label class="btn btn--circle txt-medium" style="--btn-background: <%= color -%>" >
<%= form.radio_button :color, color %>
<%= image_tag "check.svg", aria: { hidden: "true" }, size: 24, class: "checked" %>
@@ -21,7 +21,7 @@
<legend class="for-screen-reader">Category</legend>
<div class="flex align-center gap flex-wrap">
<%= collection_check_boxes(:splat, :category_ids, Category.all, :id, :title) do | category | %>
<%= collection_check_boxes(:bubble, :category_ids, Category.all, :id, :title) do | category | %>
<%= category.label(class: "btn txt-medium") { category.check_box + tag.span(category.text) } %>
<% end %>
@@ -35,7 +35,7 @@
<fieldset class="flex flex-column unpad margin-block-end borderless justify-space-between">
<legend class="for-screen-reader">Attachment</legend>
<label class="input input--file input--picture unpad" data-controller="upload-preview">
<%= image_tag splat.image.attached? ? splat.image : "default-picture.webp", alt: "Picture",
<%= image_tag bubble.image.attached? ? bubble.image : "default-picture.webp", alt: "Picture",
data: { upload_preview_target: "image" } %>
<%= form.file_field :image, class: "input", accept: "image/png, image/jpeg, image/jpg, image/webp",
data: { upload_preview_target: "input", action: "upload-preview#previewImage" } %>
+3
View File
@@ -0,0 +1,3 @@
<%= turbo_frame_tag @bubble, :edit do %>
<%= render "bubbles/form", bubble: @bubble %>
<% end %>
+51
View File
@@ -0,0 +1,51 @@
<% content_for :header do %>
<nav>
<%= button_to session_path, method: :delete, class: "btn", form_class: "flex-item-justify-start" do %>
<%= image_tag "logout.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Sign out</span>
<% end %>
<h1 class="txt-xx-large margin-none flex align-center gap-half">
Bubbled up
<% if @category %>
in <%= @category.title %>
<%= link_to bubbles_path, class: "btn txt-small" do %>
<%= image_tag "remove.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Clear</span>
<% end %>
<% end %>
</h1>
<%= link_to new_bubble_path, class: "btn btn--plain flex-item-justify-end" do %>
<%= image_tag "bubble-add.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Create a new bubble</span>
<% end %>
</nav>
<% end %>
<section class="windshield flex-inline flex-wrap gap-half justify-center align-end">
<%= render @bubbles.last(10) %>
</section>
<section class="bubbles-list unpad-inline center margin-block-start">
<ul class="unpad margin-none flex flex-column txt-align-start center">
<% @bubbles.each do | bubble | %>
<li class="flex align-center gap margin-none">
<div class="bubble" style="--bubble-color: <%= bubble.color %>; --bubble-size: 2cqi; <%= bubble_rotation(bubble) %>">
<svg class="bubble__svg" style="fill: <%= bubble.color %>;" viewBox="0 0 990 990" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h990v990h-990z" fill="none" stroke="none" /><path d="m391.65 879.47c-110.52-15.95-212.21-91.86-255.92-191.23-66.78-143.65-41.62-347.61 48.08-481.17 368.33-516.3 1252.97 520.2 451.03 660.78-44.07 8.84-88.98 13.49-133.01 15.68-36.69 2-73.37 1.91-109.99-4.03z"/></svg>
</div>
<%= link_to bubble, class: "bubble__title-link flex align-center gap flex-item-grow" do %>
<strong><%= bubble.title %></strong>
<% end %>
<small class="flex align-center gap flex-item-no-shrink">
<% bubble.categories.each do |category| %>
<%= link_to "# #{ category.title }", bubbles_path(category_id: category.id), style: "color: #{ bubble.color }" %>
<% end %>
<time class="txt-nowrap flex-item-justify-end"><%= bubble.created_at.strftime("%b %d").html_safe %></time>
</small>
</li>
<% end %>
</ul>
</section>
+15
View File
@@ -0,0 +1,15 @@
<div class="bubble__perma flex justify-center center">
<div class="bubble" style="view-transition-name: bubble-<%= @bubble.id -%>; --bubble-color: <%= @bubble.color %>; <%= bubble_size(@bubble) %> <%= bubble_rotation(@bubble) %>">
<%= form_with model: @bubble, class: "flex flex-column gap full-width" do | form | %>
<h1 class="bubble__title">
<%= form.text_area :title, class: "input full-width borderless", required: true, placeholder: "Name it…", rows: 4, autofocus: true %>
</h1>
<%= form.button class: "btn btn--reversed center" do %>
<%= image_tag "check.svg", aria: { hidden: "true" }, size: 24%>
<span class="for-screen-reader">Save</span>
<% end %>
<% end %>
<svg class="bubble__svg" viewBox="0 0 990 990" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h990v990h-990z" fill="none" stroke="none" /><path d="m391.65 879.47c-110.52-15.95-212.21-91.86-255.92-191.23-66.78-143.65-41.62-347.61 48.08-481.17 368.33-516.3 1252.97 520.2 451.03 660.78-44.07 8.84-88.98 13.49-133.01 15.68-36.69 2-73.37 1.91-109.99-4.03z"/></svg>
</div>
</div>
@@ -1,31 +1,31 @@
<% content_for :header do %>
<nav>
<%= link_to splats_path, class: "btn flex-item-justify-start" do %>
<%= link_to bubbles_path, class: "btn flex-item-justify-start" do %>
<%= image_tag "arrow-left.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">All Splats</span>
<span class="for-screen-reader">All Bubbles</span>
<% end %>
<div class="flex-item-justify-end" data-controller="dialog">
<%= tag.button class: "btn flex-item-justify-end", popovertarget: "splat-edit-panel" do %>
<%= tag.button class: "btn flex-item-justify-end", popovertarget: "bubble-edit-panel" do %>
<%= image_tag "pencil.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Edit <%= @splat.title %></span>
<span class="for-screen-reader">Edit <%= @bubble.title %></span>
<% end %>
<dialog class="panel" id="splat-edit-panel" data-dialog-target="dialog" popover>
<dialog class="panel" id="bubble-edit-panel" data-dialog-target="dialog" popover>
<div class="flex pad">
<%= turbo_frame_tag @splat, :edit, src: edit_splat_path(@splat), target: "_top" %>
<%= turbo_frame_tag @bubble, :edit, src: edit_bubble_path(@bubble), target: "_top" %>
</div>
</dialog>
</div>
</nav>
<% end %>
<div class="splat__perma flex justify-center center margin-block-end-double">
<%= render @splat %>
<div class="bubble__perma flex justify-center center margin-block-end-double">
<%= render @bubble %>
</div>
<section class="comments align-center panel center borderless margin-block flex flex-wrap gap-half" style="--splat-color: <%= @splat.color %>;">
<% comments = (@splat.comments + @splat.boosts).sort_by(&:updated_at) %>
<section class="comments align-center panel center borderless margin-block flex flex-wrap gap-half" style="--bubble-color: <%= @bubble.color %>;">
<% comments = (@bubble.comments + @bubble.boosts).sort_by(&:updated_at) %>
<% boosts = [] %>
<% comments.each_with_index do |comment, index| %>
+1 -1
View File
@@ -7,7 +7,7 @@
<strong class="txt-nowrap"><%= category.title %></strong>
<span class="txt-nowrap"><%= category.id %></span>
</span>
<span><%= category.splats.collect { |splat| splat.title }.to_sentence%></span>
<span><%= category.bubbles.collect { |bubble| bubble.title }.to_sentence%></span>
<%= button_to category_path(category),
method: :delete, data: { turbo_confirm: "Are you sure you want to delete this category?" },
class: "btn txt-small" do %>
+1 -1
View File
@@ -1,5 +1,5 @@
<turbo-frame id="new_category">
<%= form_with model: [@splat, @category], data: { turbo_frame: "_top" } do |form| %>
<%= form_with model: [@bubble, @category], data: { turbo_frame: "_top" } do |form| %>
<%= form.text_field :title, class: "input borderless", autofocus: "on", list: "categories-list" %>
<%= form.submit "Create Category", hidden: true %>
+1 -1
View File
@@ -3,7 +3,7 @@
<div class="flex flex-column full-width">
<div class="comment__author flex align-center gap-half">
<strong><%= comment.creator.name %></strong>
<%= link_to splat_path(@splat, anchor: "comment_#{comment.id}"), class: "txt-undecorated" do %>
<%= link_to bubble_path(@bubble, anchor: "comment_#{comment.id}"), class: "txt-undecorated" do %>
<time class="txt-subtle"><%= comment.created_at.strftime("%b %d").html_safe %></time>
<% end %>
</div>
+2 -2
View File
@@ -5,8 +5,8 @@
<strong><%= Current.user.name %></strong>
</div>
<div class="comment__body txt-align-start">
<%= form_with model: [@splat, @splat.comments.build], class: "flex flex-column gap full-width" do | form | %>
<%= form.text_area :body, class: "input", required: true, placeholder: Current.user == @splat.creator && @splat.comments.size == 1 ? "Add some notes…" : "Type your comment…", rows: 4 %>
<%= form_with model: [@bubble, @bubble.comments.build], class: "flex flex-column gap full-width" do | form | %>
<%= form.text_area :body, class: "input", required: true, placeholder: Current.user == @bubble.creator && @bubble.comments.size == 1 ? "Add some notes…" : "Type your comment…", rows: 4 %>
<%= form.button class: "btn btn--reversed center" do %>
<%= image_tag "check.svg", aria: { hidden: "true" }, size: 24 %>
+5 -5
View File
@@ -2,11 +2,11 @@
<div class="panel shadow center margin-block-double <%= "shake" if flash[:alert] %>" style="--panel-size: 40ch;">
<%#= image_tag "blob.svg", class: "product__logo center colorize--black", size: 130 %>
<div class="splat center" style="--splat-color: #000; --splat-rotate: -75deg; --splat-size: 12cqi;">
<svg class="splat__svg" style="stroke-width: 2rem;" viewBox="0 0 990 990" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h990v990h-990z" fill="none" stroke="none" /><path d="m391.65 879.47c-110.52-15.95-212.21-91.86-255.92-191.23-66.78-143.65-41.62-347.61 48.08-481.17 368.33-516.3 1252.97 520.2 451.03 660.78-44.07 8.84-88.98 13.49-133.01 15.68-36.69 2-73.37 1.91-109.99-4.03z"/></svg>
<span class="splat__bubble splat__meta splat__date" style="border-width: 0.2rem;"></span>
<span class="splat__bubble splat__meta splat__category" style="border-width: 0.2rem;">&nbsp; &nbsp; &nbsp; &nbsp;</span>
<span class="splat__bubble splat__meta splat__category" style="border-width: 0.2rem;">&nbsp; &nbsp;</span>
<div class="bubble center" style="--bubble-color: #000; --bubble-rotate: -75deg; --bubble-size: 12cqi;">
<svg class="bubble__svg" style="stroke-width: 2rem;" viewBox="0 0 990 990" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h990v990h-990z" fill="none" stroke="none" /><path d="m391.65 879.47c-110.52-15.95-212.21-91.86-255.92-191.23-66.78-143.65-41.62-347.61 48.08-481.17 368.33-516.3 1252.97 520.2 451.03 660.78-44.07 8.84-88.98 13.49-133.01 15.68-36.69 2-73.37 1.91-109.99-4.03z"/></svg>
<span class="bubble__bubble bubble__meta bubble__date" style="border-width: 0.2rem;"></span>
<span class="bubble__bubble bubble__meta bubble__category" style="border-width: 0.2rem;">&nbsp; &nbsp; &nbsp; &nbsp;</span>
<span class="bubble__bubble bubble__meta bubble__category" style="border-width: 0.2rem;">&nbsp; &nbsp;</span>
</div>
<h1 class="margin-none-block-start margin-block-end-double">Fizzy</h1>
-34
View File
@@ -1,34 +0,0 @@
<div class="splat" style="view-transition-name: splat-<%= splat.id -%>; --splat-color: <%= splat.color %>; --splat-rotate: <%= splat_rotation(splat) -%>deg; <%= splat_size(splat) %>">
<h1 class="splat__title"><%= splat.title %></h1>
<svg class="splat__svg" viewBox="0 0 990 990" xmlns="http://www.w3.org/2000/svg" transform="rotate(<%= splat_rotation(splat) -%>)"><path d="m0 0h990v990h-990z" fill="none" stroke="none" /><path d="m391.65 879.47c-110.52-15.95-212.21-91.86-255.92-191.23-66.78-143.65-41.62-347.61 48.08-481.17 368.33-516.3 1252.97 520.2 451.03 660.78-44.07 8.84-88.98 13.49-133.01 15.68-36.69 2-73.37 1.91-109.99-4.03z"/></svg>
<%= link_to splat, class: "splat__link" do %>
<span class="for-screen-reader"><%= splat.title %></span>
<% end %>
<% if splat.image.attached? %>
<div class="splat__image">
<%= image_tag splat.image %>
</div>
<% end %>
<time class="splat__bubble splat__meta splat__date"><%= splat.created_at.strftime("%b <br> %d").html_safe %></time>
<% splat.categories.each do | category | %>
<%= link_to "##{category.title}", splats_path(category_id: category.id), class: "splat__bubble splat__meta splat__category" %>
<% end %>
<% if splat.categories.count < 3 %>
<span class="splat__bubble splat__meta splat__category">
<turbo-frame id="new_category">
<%= link_to "#", new_splat_category_path(splat), class: "splat__category--new" %>
</turbo-frame>
</span>
<% end %>
<%= tag.div class: "splat__bubble splat__meta splat__boosts",
data: { controller: "animation toggle-class", animation_play_class: "boosting", toggle_class_toggle_class: "boosting", action: "animationend->toggle-class#toggle" } do %>
<turbo-frame id="<%= dom_id(splat, "boosts") %>" src="<%= splat_boosts_path(splat) %>" />
<% end %>
</div>
-3
View File
@@ -1,3 +0,0 @@
<%= turbo_frame_tag @splat, :edit do %>
<%= render "splats/form", splat: @splat %>
<% end %>
-51
View File
@@ -1,51 +0,0 @@
<% content_for :header do %>
<nav>
<%= button_to session_path, method: :delete, class: "btn", form_class: "flex-item-justify-start" do %>
<%= image_tag "logout.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Sign out</span>
<% end %>
<h1 class="txt-xx-large margin-none flex align-center gap-half">
Bubbled up
<% if @category %>
in <%= @category.title %>
<%= link_to splats_path, class: "btn txt-small" do %>
<%= image_tag "remove.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Clear</span>
<% end %>
<% end %>
</h1>
<%= link_to new_splat_path, class: "btn btn--plain flex-item-justify-end" do %>
<%= image_tag "bubble-add.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Create a new splat</span>
<% end %>
</nav>
<% end %>
<section class="windshield flex-inline flex-wrap gap-half justify-center align-end">
<%= render @splats.last(10) %>
</section>
<section class="splats-list unpad-inline center margin-block-start">
<ul class="unpad margin-none flex flex-column txt-align-start center">
<% @splats.each do | splat | %>
<li class="flex align-center gap margin-none">
<div class="splat" style="--splat-color: <%= splat.color %>; --splat-size: 2cqi; <%= splat_rotation(splat) %>">
<svg class="splat__svg" style="fill: <%= splat.color %>;" viewBox="0 0 990 990" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h990v990h-990z" fill="none" stroke="none" /><path d="m391.65 879.47c-110.52-15.95-212.21-91.86-255.92-191.23-66.78-143.65-41.62-347.61 48.08-481.17 368.33-516.3 1252.97 520.2 451.03 660.78-44.07 8.84-88.98 13.49-133.01 15.68-36.69 2-73.37 1.91-109.99-4.03z"/></svg>
</div>
<%= link_to splat, class: "splat__title-link flex align-center gap flex-item-grow" do %>
<strong><%= splat.title %></strong>
<% end %>
<small class="flex align-center gap flex-item-no-shrink">
<% splat.categories.each do |category| %>
<%= link_to "# #{ category.title }", splats_path(category_id: category.id), style: "color: #{ splat.color }" %>
<% end %>
<time class="txt-nowrap flex-item-justify-end"><%= splat.created_at.strftime("%b %d").html_safe %></time>
</small>
</li>
<% end %>
</ul>
</section>
-15
View File
@@ -1,15 +0,0 @@
<div class="splat__perma flex justify-center center">
<div class="splat" style="view-transition-name: splat-<%= @splat.id -%>; --splat-color: <%= @splat.color %>; <%= splat_size(@splat) %> <%= splat_rotation(@splat) %>">
<%= form_with model: @splat, class: "flex flex-column gap full-width" do | form | %>
<h1 class="splat__title">
<%= form.text_area :title, class: "input full-width borderless", required: true, placeholder: "Name it…", rows: 4, autofocus: true %>
</h1>
<%= form.button class: "btn btn--reversed center" do %>
<%= image_tag "check.svg", aria: { hidden: "true" }, size: 24%>
<span class="for-screen-reader">Save</span>
<% end %>
<% end %>
<svg class="splat__svg" viewBox="0 0 990 990" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h990v990h-990z" fill="none" stroke="none" /><path d="m391.65 879.47c-110.52-15.95-212.21-91.86-255.92-191.23-66.78-143.65-41.62-347.61 48.08-481.17 368.33-516.3 1252.97 520.2 451.03 660.78-44.07 8.84-88.98 13.49-133.01 15.68-36.69 2-73.37 1.91-109.99-4.03z"/></svg>
</div>
</div>
+2 -2
View File
@@ -1,9 +1,9 @@
Rails.application.routes.draw do
root "splats#index"
root "bubbles#index"
resource :session
resources :splats do
resources :bubbles do
resources :boosts
resources :categories, shallow: true
resources :comments
@@ -0,0 +1,9 @@
class RenameSplatsToBubbles < ActiveRecord::Migration[8.0]
def change
rename_table :splats, :bubbles
rename_column :categorizations, :splat_id, :bubble_id
rename_column :boosts, :splat_id, :bubble_id
rename_column :comments, :splat_id, :bubble_id
end
end
Generated
+16 -16
View File
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2024_08_28_215240) do
ActiveRecord::Schema[8.0].define(version: 2024_09_04_180510) do
create_table "accounts", force: :cascade do |t|
t.string "name", null: false
t.datetime "created_at", null: false
@@ -49,10 +49,19 @@ ActiveRecord::Schema[8.0].define(version: 2024_08_28_215240) do
create_table "boosts", force: :cascade do |t|
t.string "body"
t.integer "creator_id", null: false
t.integer "splat_id", null: false
t.integer "bubble_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["splat_id"], name: "index_boosts_on_splat_id"
t.index ["bubble_id"], name: "index_boosts_on_bubble_id"
end
create_table "bubbles", force: :cascade do |t|
t.string "title"
t.text "body"
t.string "color"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "creator_id", null: false
end
create_table "categories", force: :cascade do |t|
@@ -62,18 +71,18 @@ ActiveRecord::Schema[8.0].define(version: 2024_08_28_215240) do
end
create_table "categorizations", force: :cascade do |t|
t.integer "splat_id", null: false
t.integer "bubble_id", null: false
t.integer "category_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["bubble_id"], name: "index_categorizations_on_bubble_id"
t.index ["category_id"], name: "index_categorizations_on_category_id"
t.index ["splat_id"], name: "index_categorizations_on_splat_id"
end
create_table "comments", force: :cascade do |t|
t.text "body"
t.integer "creator_id", null: false
t.integer "splat_id", null: false
t.integer "bubble_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
@@ -87,15 +96,6 @@ ActiveRecord::Schema[8.0].define(version: 2024_08_28_215240) do
t.index ["user_id"], name: "index_sessions_on_user_id"
end
create_table "splats", force: :cascade do |t|
t.string "title"
t.text "body"
t.string "color"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "creator_id", null: false
end
create_table "users", force: :cascade do |t|
t.integer "account_id", null: false
t.string "name", null: false
@@ -110,8 +110,8 @@ ActiveRecord::Schema[8.0].define(version: 2024_08_28_215240) do
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "categorizations", "bubbles"
add_foreign_key "categorizations", "categories"
add_foreign_key "categorizations", "splats"
add_foreign_key "sessions", "users"
add_foreign_key "users", "accounts"
end
+6 -6
View File
@@ -143,12 +143,12 @@
<span class="for-screen-reader">Go back</span>
</a>
<div>
<p>🇺🇸 Upgrade to a supported web browser. Splat requires a modern web browser. Please use one of the browsers listed below and make sure auto-updates are enabled.</p>
<p>🇪🇸 Actualiza a un navegador web compatible. Splat requiere un navegador web moderno. Utiliza uno de los navegadores listados a continuación y asegúrate de que las actualizaciones automáticas estén habilitadas.</p>
<p>🇫🇷 Mettez à jour vers un navigateur web pris en charge. Splat nécessite un navigateur web moderne. Veuillez utiliser l'un des navigateurs répertoriés ci-dessous et assurez-vous que les mises à jour automatiques sont activées.</p>
<p>🇮🇳 समर्थित वेब ब्राउज़र में अपग्रेड करें। Splat को एक आधुनिक वेब ब्राउज़र की आवश्यकता है। कृपया नीचे सूचीबद्ध ब्राउज़रों में से कोई एक का उपयोग करें और सुनिश्चित करें कि स्वचालित अपडेट्स सक्षम हैं।</p>
<p>🇩🇪 Aktualisieren Sie auf einen unterstützten Webbrowser. Splat erfordert einen modernen Webbrowser. Verwenden Sie bitte einen der unten aufgeführten Browser und stellen Sie sicher, dass automatische Updates aktiviert sind.</p>
<p>🇧🇷 Atualize para um navegador compatível. O Splat requer um navegador moderno. Por favor, use um dos navegadores listados abaixo e certifique-se de que as atualizações automáticas estão ativadas.</p>
<p>🇺🇸 Upgrade to a supported web browser. Fizzy requires a modern web browser. Please use one of the browsers listed below and make sure auto-updates are enabled.</p>
<p>🇪🇸 Actualiza a un navegador web compatible. Fizzy requiere un navegador web moderno. Utiliza uno de los navegadores listados a continuación y asegúrate de que las actualizaciones automáticas estén habilitadas.</p>
<p>🇫🇷 Mettez à jour vers un navigateur web pris en charge. Fizzy nécessite un navigateur web moderne. Veuillez utiliser l'un des navigateurs répertoriés ci-dessous et assurez-vous que les mises à jour automatiques sont activées.</p>
<p>🇮🇳 समर्थित वेब ब्राउज़र में अपग्रेड करें। Fizzy को एक आधुनिक वेब ब्राउज़र की आवश्यकता है। कृपया नीचे सूचीबद्ध ब्राउज़रों में से कोई एक का उपयोग करें और सुनिश्चित करें कि स्वचालित अपडेट्स सक्षम हैं।</p>
<p>🇩🇪 Aktualisieren Sie auf einen unterstützten Webbrowser. Fizzy erfordert einen modernen Webbrowser. Verwenden Sie bitte einen der unten aufgeführten Browser und stellen Sie sicher, dass automatische Updates aktiviert sind.</p>
<p>🇧🇷 Atualize para um navegador compatível. O Fizzy requer um navegador moderno. Por favor, use um dos navegadores listados abaixo e certifique-se de que as atualizações automáticas estão ativadas.</p>
<p><strong>Safari 17.2+, Chrome 119+, Firefox 121+, Opera 104+</strong></p>
</div>
</div>
@@ -1,6 +1,6 @@
require "test_helper"
class SplatsControllerTest < ActionDispatch::IntegrationTest
class BubblesControllerTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end
+4 -4
View File
@@ -3,19 +3,19 @@
one:
body: ""
creator: :jz
splat: one
bubble: one
two:
body: ""
creator: :kevin
splat: two
bubble: two
three:
body: ""
creator: :kevin
splat: one
bubble: one
four:
body: ""
creator: :jz
splat: one
bubble: one
+4 -4
View File
@@ -1,17 +1,17 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
splat: one
bubble: one
category: one
two:
splat: two
bubble: two
category: two
three:
splat: three
bubble: three
category: one
four:
splat: three
bubble: three
category: two
+2 -2
View File
@@ -3,9 +3,9 @@
one:
body: I agree.
creator: :jz
splat: :one
bubble: :one
two:
body: Same, lets do it.
creator: :kevin
splat: :one
bubble: :one
@@ -1,6 +1,6 @@
require "test_helper"
class SplatTest < ActiveSupport::TestCase
class BubbleTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end