Last active
May 13, 2021 15:25
-
-
Save julianrubisch/e8c10576a368213a4b6713e89ff66eb3 to your computer and use it in GitHub Desktop.
StimulusReflex Patterns - 2 Imports
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- app/views/embed_imports/_form.html.erb --> | |
<%= form_with(model: [board, embed_import]) do |form| %> | |
<%= form.file_field :upload %> | |
<%= form.submit "Upload Links", class: "inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-lime-600 hover:bg-lime-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-lime-500" %> | |
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/embed_import.rb | |
class EmbedImport < ApplicationRecord | |
has_one_attached :upload | |
belongs_to :board | |
after_create_commit :start | |
private | |
def start | |
return if finished_at | |
ImportJob.perform_later self | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/embed_import.rb | |
class EmbedImport < ApplicationRecord | |
# ... | |
# When given a block, yields progress (value between 0 and 100) and embed | |
# for each row of imported CSV file. | |
def process(&block) | |
yield 0, nil if block_given? | |
upload.open do |file| | |
# don't do this if your file is large, i.e. in production! | |
# use this: size = upload.byte_size | |
line_count = file.readlines.size - 1 | |
file.rewind | |
yield 20, nil # arbitrary; download to local disk done | |
import_csv(file) do |embed, index| | |
next unless block | |
# simulate a slow running process | |
sleep 1 | |
# file.pos will not change per row but per chunk of data read from the file | |
# use in connection with size: file.pos.to_d / size | |
progress = ((index.to_d / line_count) * 75).floor + 20 | |
block.call(progress, embed) | |
end | |
end | |
update! finished_at: Time.now | |
yield 100, nil if block_given? | |
end | |
private | |
# ... | |
def import_csv(io) | |
CSV.new(io, headers: true).each.with_index do |row, index| | |
embed = import(row) | |
yield embed, index if block_given? | |
end | |
end | |
def import(params) | |
Embed.create! params.to_h.merge(board_id: board_id) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/jobs/import_job.rb | |
class ImportJob < ApplicationJob | |
include CableReady::Broadcaster | |
queue_as :default | |
def perform(import) | |
cable_ready["import"].dispatch_event( | |
name: "import:start" | |
).broadcast | |
import.process do |progress, imported| | |
cable_ready["import"].dispatch_event( | |
name: "import:progress", | |
detail: {progress: progress, imported: imported} | |
).broadcast | |
yield progress, imported | |
end | |
end | |
end | |
# app/jobs/embed_import_job.rb | |
class EmbedImportJob < ImportJob | |
def perform(import) | |
super do |progress, imported| | |
if imported.present? | |
StreamBoardJob.perform_now(board: imported.board) | |
end | |
end | |
end | |
end | |
# app/models/embed_import.rb | |
class EmbedImport < ApplicationRecord | |
# ... | |
private | |
def start | |
return if finished_at | |
EmbedImportJob.perform_later self | |
end | |
# ... | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="hidden"> | |
<div class="relative pt-1"> | |
<div class="overflow-hidden h-2 mb-4 text-xs flex rounded bg-orange-200"> | |
<div id="progress-bar" style="width:0%" class="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-orange-500 transition-all ease-in-out"></div> | |
</div> | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div data-controller="import" data-action="import:progress@document->import#onProgress" class="hidden"> | |
<div class="relative pt-1"> | |
<div class="overflow-hidden h-2 mb-4 text-xs flex rounded bg-orange-200"> | |
<div style="width:0%" data-import-target="progressBar" class="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-orange-500 transition-all ease-in-out"></div> | |
</div> | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/embed_imports_controller.rb | |
class EmbedImportsController < ApplicationController | |
def create | |
@embed_import = EmbedImport.new(embed_imports_params) | |
@embed_import.board = Board.friendly.find(params[:board_id]) | |
@embed_import.save | |
end | |
private | |
def embed_imports_params | |
params.require(:embed_import).permit(:upload) | |
end | |
end |
We can make this file beautiful and searchable if this error is corrected: No commas found in this CSV file in line 0.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
input | |
https://soundcloud.com/titled/acousmoniumset | |
https://youtu.be/8qeX8WChkdQ | |
https://www.youtube.com/watch?v=KSrNQH_Cdsg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/embed_import.rb | |
class EmbedImport < ApplicationRecord | |
# ... | |
# When given a block, yields progress (value between 0 and 100) and embed | |
# for each row of imported CSV file. | |
def process(&block) | |
yield 0, nil if block_given? | |
upload.open do |file| | |
# don't do this if your file is large, i.e. in production! | |
# use this: size = upload.byte_size | |
line_count = file.readlines.size - 1 | |
file.rewind | |
yield 20, nil # arbitrary; download to local disk done | |
import_csv(file) do |embed, index| | |
next unless block | |
# simulate a slow running process | |
sleep 1 | |
# file.pos will not change per row but per chunk of data read from the file | |
# use in connection with size: file.pos.to_d / size | |
progress = ((index.to_d / line_count) * 75).floor + 20 | |
block.call(progress, embed) | |
end | |
end | |
update! finished_at: Time.now | |
yield 100, nil if block_given? | |
end | |
private | |
# ... | |
def import_csv(io) | |
CSV.new(io, headers: true).each.with_index do |row, index| | |
embed = import(row) | |
yield embed, index if block_given? | |
end | |
end | |
def import(params) | |
Embed.create! params.to_h.merge(board_id: board_id) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ bin/rails g migration AddUserReferenceToEmbedImports user:references |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/channels/import_channel.rb | |
class ImportChannel < ApplicationCable::Channel | |
def subscribed | |
stream_from "import_#{current_user.id}" | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// app/javascript/controllers/import_controller.js | |
import { Controller } from "stimulus"; | |
export default class extends Controller { | |
static targets = ["progressBar"]; | |
onProgress(e) { | |
if (e.detail.progress > 0) { | |
this.element.classList.remove("hidden"); | |
} | |
this.progressBarTarget.setAttribute( | |
"style", | |
`width: ${e.detail.progress}%` | |
); | |
if (e.detail.progress === 100) { | |
this.element.classList.add("hidden"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ImportJob < ApplicationJob | |
include CableReady::Broadcaster | |
queue_as :default | |
def perform(import) | |
import.process do |progress, imported| | |
# TODO | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ImportJob < ApplicationJob | |
include CableReady::Broadcaster | |
queue_as :default | |
def perform(import) | |
import.process do |progress, imported| | |
cable_ready["import"].set_style( # <-- update style here | |
name: "width", | |
selector: "#progress-bar", | |
value: progress | |
).broadcast | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ImportJob < ApplicationJob | |
include CableReady::Broadcaster | |
queue_as :default | |
def perform(import) | |
cable_ready["import"].dispatch_event( | |
name: "import:start" | |
).broadcast | |
import.process do |progress, imported| | |
cable_ready["import"].dispatch_event( | |
name: "import:progress", | |
detail: {progress: progress, imported: imported} | |
).broadcast | |
if imported.present? | |
StreamBoardJob.perform_now(board: imported.board) | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/jobs/import_job.rb | |
class ImportJob < ApplicationJob | |
include CableReady::Broadcaster | |
queue_as :default | |
def perform(import) | |
cable_ready["import_#{import.user_id}"].dispatch_event( | |
name: "import:start" | |
).broadcast | |
import.process do |progress, imported| | |
cable_ready["import_#{import.user_id}"].dispatch_event( | |
name: "import:progress", | |
detail: {progress: progress, imported: imported} | |
).broadcast | |
yield progress, imported | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment