diff --git a/app/assets/images/default-picture.webp b/app/assets/images/default-picture.webp new file mode 100644 index 000000000..9696faeb3 Binary files /dev/null and b/app/assets/images/default-picture.webp differ diff --git a/app/controllers/splats_controller.rb b/app/controllers/splats_controller.rb index cfe056b28..471006d19 100644 --- a/app/controllers/splats_controller.rb +++ b/app/controllers/splats_controller.rb @@ -38,6 +38,6 @@ class SplatsController < ApplicationController end def splat_params - params.require(:splat).permit(:title, :body, :color, category_ids: []) + params.require(:splat).permit(:title, :body, :color, :image, category_ids: []) end end diff --git a/app/javascript/controllers/upload_preview_controller.js b/app/javascript/controllers/upload_preview_controller.js new file mode 100644 index 000000000..4ce38ae9a --- /dev/null +++ b/app/javascript/controllers/upload_preview_controller.js @@ -0,0 +1,20 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static values = { defaultImage: String } + static targets = [ "image", "input", "button" ] + + previewImage() { + const file = this.inputTarget.files[0] + + if (file) { + this.imageTarget.src = URL.createObjectURL(this.inputTarget.files[0]); + this.imageTarget.onload = () => { URL.revokeObjectURL(this.imageTarget.src) } + } + } + + clear() { + this.imageTarget.src = this.defaultImageValue + this.buttonTarget.style.visibility = "hidden" + } +} diff --git a/app/models/splat.rb b/app/models/splat.rb index 342f392d3..c721475f8 100644 --- a/app/models/splat.rb +++ b/app/models/splat.rb @@ -4,6 +4,8 @@ class Splat < ApplicationRecord has_many :categories, through: :categorizations, dependent: :destroy has_many :comments, dependent: :destroy + has_one_attached :image, dependent: :purge_later + belongs_to :creator, class_name: "User", default: -> { Current.user } enum :color, %w[ diff --git a/app/views/splats/_form.html.erb b/app/views/splats/_form.html.erb index a4bc3df66..4c695df63 100644 --- a/app/views/splats/_form.html.erb +++ b/app/views/splats/_form.html.erb @@ -26,12 +26,22 @@ <% end %> +
+ Attachment + +
+ <%= form.label :body, class: "flex flex-column justify-start align-start" do %> <%= form.text_area :body, class: "input full-width", rows: 10, placeholder: "Details…" %> <% end %> diff --git a/db/migrate/20240828215240_create_active_storage_tables.active_storage.rb b/db/migrate/20240828215240_create_active_storage_tables.active_storage.rb new file mode 100644 index 000000000..6bd8bd082 --- /dev/null +++ b/db/migrate/20240828215240_create_active_storage_tables.active_storage.rb @@ -0,0 +1,57 @@ +# This migration comes from active_storage (originally 20170806125915) +class CreateActiveStorageTables < ActiveRecord::Migration[7.0] + def change + # Use Active Record's configured type for primary and foreign keys + primary_key_type, foreign_key_type = primary_and_foreign_key_types + + create_table :active_storage_blobs, id: primary_key_type do |t| + t.string :key, null: false + t.string :filename, null: false + t.string :content_type + t.text :metadata + t.string :service_name, null: false + t.bigint :byte_size, null: false + t.string :checksum + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :key ], unique: true + end + + create_table :active_storage_attachments, id: primary_key_type do |t| + t.string :name, null: false + t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type + t.references :blob, null: false, type: foreign_key_type + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :record_type, :record_id, :name, :blob_id ], name: :index_active_storage_attachments_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + + create_table :active_storage_variant_records, id: primary_key_type do |t| + t.belongs_to :blob, null: false, index: false, type: foreign_key_type + t.string :variation_digest, null: false + + t.index [ :blob_id, :variation_digest ], name: :index_active_storage_variant_records_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end + + private + def primary_and_foreign_key_types + config = Rails.configuration.generators + setting = config.options[config.orm][:primary_key_type] + primary_key_type = setting || :primary_key + foreign_key_type = setting || :bigint + [ primary_key_type, foreign_key_type ] + end +end diff --git a/db/schema.rb b/db/schema.rb index 2a337ad4b..72426805f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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_26_201811) do +ActiveRecord::Schema[8.0].define(version: 2024_08_28_215240) do create_table "accounts", force: :cascade do |t| t.string "name", null: false t.datetime "created_at", null: false @@ -18,6 +18,34 @@ ActiveRecord::Schema[8.0].define(version: 2024_08_26_201811) do t.index ["name"], name: "index_accounts_on_name", unique: true end + create_table "active_storage_attachments", force: :cascade do |t| + t.string "name", null: false + t.string "record_type", null: false + t.bigint "record_id", null: false + t.bigint "blob_id", null: false + t.datetime "created_at", null: false + t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" + t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true + end + + create_table "active_storage_blobs", force: :cascade do |t| + t.string "key", null: false + t.string "filename", null: false + t.string "content_type" + t.text "metadata" + t.string "service_name", null: false + t.bigint "byte_size", null: false + t.string "checksum" + t.datetime "created_at", null: false + t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true + end + + create_table "active_storage_variant_records", force: :cascade do |t| + t.bigint "blob_id", null: false + t.string "variation_digest", null: false + t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true + end + create_table "boosts", force: :cascade do |t| t.string "body" t.integer "creator_id", null: false @@ -80,6 +108,8 @@ ActiveRecord::Schema[8.0].define(version: 2024_08_26_201811) do t.index ["email_address"], name: "index_users_on_email_address", unique: true end + 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", "categories" add_foreign_key "categorizations", "splats" add_foreign_key "sessions", "users"