Skip to content

Commit

Permalink
uploader field shared
Browse files Browse the repository at this point in the history
  • Loading branch information
michelson committed Aug 20, 2023
1 parent 486d585 commit db55239
Show file tree
Hide file tree
Showing 23 changed files with 438 additions and 265 deletions.
6 changes: 4 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ gem "aws-sdk-rails"
gem "aws-sdk-s3", "~> 1.48"
gem "friendly_id", "~> 5.4"
gem "standardrb", "~> 1.0"
gem "active_storage_validations", "~> 0.9.8"
# gem "active_storage_validations", "~> 0.9.8"
gem 'activestorage-validator'
gem "socialization", "~> 2.0"
gem "kaminari"
gem "store_attribute", "~> 1.0"
Expand All @@ -90,7 +91,8 @@ gem "ruby-openai", "~> 4.2"
gem "qdrant-ruby", "~> 0.9.2"
# gem "pgvector", "~> 0.2"

gem "plain", github: "chaskiq/plain", branch: "main" #path: "/Users/michelson/Documents/rubyonrails/plain"
# gem "plain", github: "chaskiq/plain", branch: "main" #path: "/Users/michelson/Documents/rubyonrails/plain"
gem "plain", path: "/Users/michelson/Documents/rubyonrails/plain"

# sentry

Expand Down
35 changes: 15 additions & 20 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
GIT
remote: https://github.com/chaskiq/plain.git
revision: 9bb2deca3a7f49bd987ca90dbb23dab7fe2601ca
branch: main
specs:
plain (0.1.0)
coderay (~> 1.1)
front_matter_parser (~> 1.0.1)
langchainrb (~> 0.6.8)
qdrant-ruby (~> 0.9.2)
rails (>= 7.0.6)
redcarpet (~> 2.3.0)
ruby-openai (~> 4.2)

GIT
remote: https://github.com/rspec/rspec-core.git
revision: 81589709e88db1ec2537faee3a7f4a43c7d9aac1
Expand Down Expand Up @@ -59,6 +45,18 @@ GIT
specs:
rspec-support (3.13.0.pre)

PATH
remote: /Users/michelson/Documents/rubyonrails/plain
specs:
plain (0.1.0)
coderay (~> 1.1)
front_matter_parser (~> 1.0.1)
langchainrb (~> 0.6.8)
qdrant-ruby (~> 0.9.2)
rails (>= 7.0.6)
redcarpet (~> 2.3.0)
ruby-openai (~> 4.2)

GEM
remote: https://rubygems.org/
specs:
Expand Down Expand Up @@ -109,11 +107,6 @@ GEM
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
active_storage_validations (0.9.8)
activejob (>= 5.2.0)
activemodel (>= 5.2.0)
activestorage (>= 5.2.0)
activesupport (>= 5.2.0)
activejob (7.0.7)
activesupport (= 7.0.7)
globalid (>= 0.3.6)
Expand All @@ -129,6 +122,8 @@ GEM
activesupport (= 7.0.7)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activestorage-validator (0.4.0)
rails (>= 6.1.0)
activesupport (7.0.7)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
Expand Down Expand Up @@ -582,7 +577,7 @@ PLATFORMS

DEPENDENCIES
aasm (~> 5.2)
active_storage_validations (~> 0.9.8)
activestorage-validator
acts-as-taggable-on (~> 9.0)
aws-sdk-rails
aws-sdk-s3 (~> 1.48)
Expand Down
24 changes: 24 additions & 0 deletions app/controllers/api/v1/audio_direct_uploads_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

class Api::V1::AudioDirectUploadsController < ActiveStorage::DirectUploadsController
protect_from_forgery with: :exception
skip_before_action :verify_authenticity_token

before_action :authenticate_user!

def create
blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_args)
render json: direct_upload_json(blob)
end

private

def direct_upload_json(blob)
blob.as_json(root: false, methods: :signed_id)
.merge(service_url: rails_blob_path(blob))
.merge(direct_upload: {
url: blob.service_url_for_direct_upload,
headers: blob.service_headers_for_direct_upload
})
end
end
1 change: 1 addition & 0 deletions app/controllers/api/v1/direct_uploads_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
class Api::V1::DirectUploadsController < ActiveStorage::DirectUploadsController
protect_from_forgery with: :exception
skip_before_action :verify_authenticity_token
before_action :authenticate_user!

def create
# ActiveStorage::Current.url_options = { host: Chaskiq::Config.fetch("HOST", nil) }
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/user_invitations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ def create
user = User.invite!({email: params[:email]}, current_user)
if user.valid?
# user.update(role: "artist")
current_user.decrement(:invitations_count)
current_user.save
flash[:now] = "User invited"
end
@user = current_user
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class UsersController < ApplicationController

before_action :find_user
before_action :check_user_role

def show
get_tracks
Expand Down Expand Up @@ -99,4 +100,8 @@ def paginated_render
]
end
end

def check_user_role
redirect_to root_url, notice: "The profile you are trying to access is not activated" and return unless @user.is_creator?
end
end
154 changes: 154 additions & 0 deletions app/javascript/controllers/audio_upload_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { Controller } from "@hotwired/stimulus";
import { DirectUpload } from "@rails/activestorage";

export default class extends Controller {
//static targets = ["input", "progress"];
static targets = ["input", "progressContainer", "template", "submit"]; // Renaming target to "progressContainer"

connect(){
this.validFiles = []
}

uploadFile() {
this.totalUploads = this.inputTarget.files.length; // Set the total number of files to be uploaded
this.maxSizeValue = 200 * 1024 * 1024 // 200 MB in bytes

if(this.totalUploads > 5){
alert(`You can only select ${5} files.`);
return
}

this.completedUploads = 0; // Counter for completed uploads

let errors = []

this.validFiles = []

Array.from(this.inputTarget.files).forEach((file, index) => {

// Check the file count
if (index >= this.limitValue) {
errors.push(`You can only select ${this.limitValue} files.`);
return;
}

// Check the file format
if (!file.type.startsWith("audio/")) {
errors.push(`File ${file.name} is not an audio file.`);
return;
}

// Check the file size
if (file.size > this.maxSizeValue) {
errors.push(`File ${file.name} exceeds the size limit of ${this.maxSizeValue / (1024 * 1024)} MB.`);
return;
}

this.validFiles.push({file: file, index: index});
});

if(errors.length > 0) {
alert(JSON.stringify(errors))
}

// hide submit button
this.submitTarget.classList.add("hidden")

this.validFiles.forEach((validFile) => {
const {file, index} = validFile
const identifier = Math.floor(Math.random() * Date.now()).toString(16)
const progressBar = this.add_template(identifier, file) //this.createProgressBar(identifier);

const upload = new DirectUpload(
file,
this.inputTarget.dataset.directUploadUrl,
{
directUploadWillStoreFileWithXHR: (request)=>{
console.log(progressBar)

request.upload.addEventListener("progress", (event) => {
this.progressUpdate(event, identifier);
});
}
}
);

upload.create((error, blob) => {
if (error) {
console.log(error);
} else {
this.createHiddenBlobInput(blob);
// if you're not submitting the form after upload, you need to attach
// uploaded blob to some model here and skip hidden input.

this.completedUploads++;
// Check if all uploads are complete
this.checkAllUploadsComplete();
}
});
});
}

checkAllUploadsComplete() {
if (this.completedUploads === this.totalUploads) {
console.log("All uploads are complete!");
this.submitTarget.classList.remove("hidden")
// Here you can perform any other actions you want when all files are uploaded
}
}

createProgressBar(index) {
const progressBar = document.createElement('div');
progressBar.setAttribute("id", `progress-bar-${index}`);
progressBar.style.width = "0%";
progressBar.style.height = "20px";
progressBar.style.backgroundColor = "green";
progressBar.style.marginTop = "10px";

this.progressContainerTarget.appendChild(progressBar); // Append to the container

return progressBar;
}

// add blob id to be submitted with the form
createHiddenBlobInput(blob) {
const hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("value", blob.signed_id);
hiddenField.name = this.inputTarget.name;
this.element.appendChild(hiddenField);
}

add_template(identifier, file) {
let doc = this.templateTarget
var content = doc.innerHTML.replace(/NEW_RECORD/g, `progress-bar-${identifier}`);
content = content.replace(/FILE/g, `${file.name}`);
this.progressContainerTarget.insertAdjacentHTML('beforebegin', content);
}

progressUpdate(event, index) {
const progress = (event.loaded / event.total) * 100;
const fileIndex = index

// updater(ctx, progress, index)

const progressBar = document.querySelector(`#progress-bar-${fileIndex}`);
if (progressBar) {
progressBar.style.width = `${progress}%`;
}
}

preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}

// When a file is dropped onto the designated area
handleDrop(e) {
this.preventDefaults(e);
let files = e.dataTransfer.files;
this.inputTarget.files = files;
debugger
this.uploadFile();
}
}
2 changes: 2 additions & 0 deletions app/javascript/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Chart from './chart_controller'
import GoogleMaps from './google_maps'
import Scroll from './scroll_controller'
import Upload from './upload_controller'
import AudioUpload from './audio_upload_controller'
import select_controller from "./select_controller"
import animate_controller from "./animate_controller"
import removals_controller from "./removals_controller"
Expand Down Expand Up @@ -50,6 +51,7 @@ application.register("gmaps", GoogleMaps)
application.register("scroll", Scroll)
application.register("hello", HelloController)
application.register("upload", Upload)
application.register("audio-upload", AudioUpload)
application.register("select", select_controller)
application.register("animate", animate_controller)
application.register("removals", removals_controller)
Expand Down
Loading

0 comments on commit db55239

Please sign in to comment.