resizing-rails 0.1.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +41 -0
  5. data/app/assets/config/resizing_rails_manifest.js +2 -0
  6. data/app/assets/javascripts/resizing/rails/application.js +15 -0
  7. data/app/assets/javascripts/resizing/rails/clipboard.js +15 -0
  8. data/app/assets/javascripts/resizing/rails/progressbar.js +33 -0
  9. data/app/assets/javascripts/resizing/rails/toast.js +35 -0
  10. data/app/assets/javascripts/resizing/rails/video.js +69 -0
  11. data/app/assets/javascripts/resizing/rails/video_fetcher.js +15 -0
  12. data/app/assets/javascripts/resizing/rails/video_uploader.js +77 -0
  13. data/app/assets/stylesheets/resizing/rails/application.scss +15 -0
  14. data/app/assets/stylesheets/resizing/rails/videos.scss +4 -0
  15. data/app/controllers/resizing/rails/application_controller.rb +7 -0
  16. data/app/controllers/resizing/rails/videos_controller.rb +26 -0
  17. data/app/helpers/resizing/rails/application_helper.rb +6 -0
  18. data/app/helpers/resizing/rails/videos_helper.rb +4 -0
  19. data/app/helpers/resizing/rails/webpack_bundle_helper.rb +21 -0
  20. data/app/javascript/packs/resizing.js +1 -0
  21. data/app/javascript/src/video.js +42 -0
  22. data/app/jobs/resizing/rails/application_job.rb +6 -0
  23. data/app/mailers/resizing/rails/application_mailer.rb +8 -0
  24. data/app/models/resizing/rails/application_record.rb +7 -0
  25. data/app/models/resizing/rails/video.rb +37 -0
  26. data/app/views/kaminari/_first_page.html.slim +2 -0
  27. data/app/views/kaminari/_gap.html.slim +2 -0
  28. data/app/views/kaminari/_last_page.html.slim +2 -0
  29. data/app/views/kaminari/_next_page.html.slim +2 -0
  30. data/app/views/kaminari/_page.html.slim +6 -0
  31. data/app/views/kaminari/_paginator.html.slim +12 -0
  32. data/app/views/kaminari/_prev_page.html.slim +2 -0
  33. data/app/views/layouts/resizing/rails/application.html.slim +20 -0
  34. data/app/views/resizing/rails/common/_clipboard.html.slim +1 -0
  35. data/app/views/resizing/rails/common/_toast.html.slim +10 -0
  36. data/app/views/resizing/rails/videos/_upload_form.html.slim +35 -0
  37. data/app/views/resizing/rails/videos/index.html.slim +53 -0
  38. data/app/views/resizing/rails/videos/show.html.slim +75 -0
  39. data/config/routes.rb +7 -0
  40. data/db/migrate/20210122043613_create_resizing_rails_videos.rb +9 -0
  41. data/lib/resizing/rails.rb +7 -0
  42. data/lib/resizing/rails/engine.rb +25 -0
  43. data/lib/resizing/rails/version.rb +5 -0
  44. data/lib/tasks/resizing/rails_tasks.rake +4 -0
  45. metadata +204 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8e0b8f97f32819b39ebb857fea3e47d87a24dde886efeafa5b27311a91f2fc83
4
+ data.tar.gz: 2bc13646968446e0903d4f7e29af1c7aa7a4b441a161ddbed11f10a83f721004
5
+ SHA512:
6
+ metadata.gz: 7a05f15665f5d6dea1451c95e0c78090bda0bffdfc89fbc80b3ec2e60a9bd8e3c13f25aed7e7b8906a01acc26e5eb3297259da219d93d4428d80a9fd3d8c3392
7
+ data.tar.gz: ca25a67ff560dad4aa4b48b6f5ab36abfbc97045b7719e86075307185ef1d8f5e98d461924a73eaba02f52c67eabed364861170baeaac6ffe057acd5b7e90e32
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2021 Junichiro Kasuya
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Resizing::Rails
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'resizing-rails'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install resizing-rails
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+ require 'github_changelog_generator/task'
9
+
10
+ RDoc::Task.new(:rdoc) do |rdoc|
11
+ rdoc.rdoc_dir = 'rdoc'
12
+ rdoc.title = 'Resizing::Rails'
13
+ rdoc.options << '--line-numbers'
14
+ rdoc.rdoc_files.include('README.md')
15
+ rdoc.rdoc_files.include('lib/**/*.rb')
16
+ end
17
+
18
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
19
+ load 'rails/tasks/engine.rake'
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+ require 'bundler/gem_tasks'
24
+
25
+ require 'rake/testtask'
26
+
27
+ Rake::TestTask.new(:test) do |t|
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+ task default: :test
34
+
35
+
36
+ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
37
+ config.user = 'jksy'
38
+ config.project = 'resizing-rails'
39
+ # config.since_tag = '0.0.1'
40
+ config.future_release = 'add-changelog'
41
+ end
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/resizing/rails .js
2
+ //= link_directory ../stylesheets/resizing/rails .css
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require rails-ujs
14
+ //= require bootstrap
15
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ window.addEventListener('click', (e) => {
2
+ src = e.srcElement
3
+ if(src.hasAttribute('data-copy-url')) {
4
+ url = src.getAttribute('data-copy-url')
5
+ if(url !== null) {
6
+ elem = document.getElementById('clipboard')
7
+ elem.value = url
8
+ elem.select()
9
+ document.execCommand("copy")
10
+ toast = new Resizing.Rails.Toast()
11
+ index = url.lastIndexOf('/')
12
+ toast.show("コピーしました", '...' + url.substr(index, url.length))
13
+ }
14
+ }
15
+ })
@@ -0,0 +1,33 @@
1
+ window.Resizing ||= {}
2
+ window.Resizing.Rails ||= {}
3
+
4
+ // Usage
5
+ // min = 0
6
+ // max = 100
7
+ // bar = new Resizing.Rails.ProgressBar(document.querySelector('...'), min, max)
8
+ // bar.setCurrent(20)
9
+ //
10
+
11
+ class ProgressBar {
12
+ constructor(element, min, max) {
13
+ this.element = element
14
+ this.current = this.min = min
15
+ this.max = max
16
+ }
17
+
18
+ setCurrent(value) {
19
+ this.current = value
20
+ this.applyStyle()
21
+ }
22
+
23
+ applyStyle() {
24
+ let percentage = Math.floor(this.current / (this.max - this.min) * 100)
25
+ this.element.style = `width: ${percentage}%;`
26
+ this.element.setAttribute('aria-valuenow', this.current)
27
+ this.element.setAttribute('aria-valuemin', this.min)
28
+ this.element.setAttribute('aria-valuemax', this.max)
29
+ this.element.textContent = `${percentage}%`
30
+ }
31
+ }
32
+
33
+ window.Resizing.Rails.ProgressBar = ProgressBar
@@ -0,0 +1,35 @@
1
+ window.Resizing ||= {}
2
+ window.Resizing.Rails ||= {}
3
+
4
+ // Usage
5
+ // toast = new Resizing.Rails.Toast()
6
+ // toast.show('title', 'body-text')
7
+ //
8
+ class Toast {
9
+ constructor() {
10
+ this.container = document.getElementById('toast-container')
11
+ this.template = document.getElementById('toast-template').content
12
+ }
13
+
14
+ show(title, text) {
15
+ let $node = document.importNode(this.template, true)
16
+ let $toast = $node.querySelector('.toast')
17
+ let id = $toast.id = `toast-${this.generateUniqueId()}`
18
+ $node.querySelector('.toast-title').textContent = title
19
+ $node.querySelector('.toast-body').textContent = text
20
+ this.container.appendChild($node)
21
+
22
+ let $elem = document.getElementById(id)
23
+ let t = new bootstrap.Toast($elem)
24
+ t.show()
25
+ $elem.addEventListener('hidden.bs.toast',() => {
26
+ $elem.remove()
27
+ })
28
+ }
29
+
30
+ generateUniqueId() {
31
+ return (new Date).getTime().toString(16)
32
+ }
33
+ }
34
+
35
+ window.Resizing.Rails.Toast = Toast
@@ -0,0 +1,69 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
3
+
4
+ window.Resizing ||= {}
5
+ window.Resizing.Rails ||= {}
6
+
7
+ class Video {
8
+ constructor(self_url, parentElement) {
9
+ this.self_url = self_url
10
+ this.parentElement = parentElement
11
+ this.listener = null
12
+ let video = this.buildVideoTag()
13
+ this.video = videojs(video.id, {fluid: true})
14
+ this.record = null
15
+ }
16
+
17
+ fetch() {
18
+ let fetcher = new Resizing.Rails.VideoFetcher(this.self_url)
19
+ fetcher.fetch().then(record => {
20
+ this.record = record
21
+ this.call('video_fetched', record)
22
+ if(record.thumbnail_url) {
23
+ this.renderVideo(record)
24
+ }
25
+ if(record.state != 'ready') {
26
+ setTimeout(this.fetch.bind(this), 5_000)
27
+ }
28
+ })
29
+ }
30
+
31
+ renderVideo(record) {
32
+ this.video.poster(record.thumbnail_url)
33
+ if(record.m3u8_url) {
34
+ this.video.src({type: 'application/x-mpegURL', src: record.m3u8_url})
35
+ }
36
+ if(record.avc_url) {
37
+ this.video.src({type: 'video/mp4', src: record.avc_url})
38
+ }
39
+ }
40
+
41
+ buildVideoTag() {
42
+ let video = document.createElement('video')
43
+ video.setAttribute('class', 'video-js')
44
+ video.setAttribute('muted', 'true')
45
+ video.setAttribute('controls', '')
46
+ video.setAttribute('preload', 'metadata')
47
+ video.setAttribute('data-setup', '{}')
48
+ video.setAttribute('poster', '')
49
+ video.id = `video-${this.generateUniqueId()}`
50
+ this.parentElement.appendChild(video)
51
+ return video
52
+ }
53
+
54
+ generateUniqueId() {
55
+ return (new Date).getTime().toString(16)
56
+ }
57
+
58
+ addEventListener(listener) {
59
+ this.listener = listener
60
+ }
61
+
62
+ call(...args) {
63
+ if(this.listener !== null) {
64
+ this.listener(...args)
65
+ }
66
+ }
67
+ }
68
+
69
+ window.Resizing.Rails.Video = Video
@@ -0,0 +1,15 @@
1
+ window.Resizing ||= {}
2
+ window.Resizing.Rails ||= {}
3
+
4
+ class VideoFetcher {
5
+ constructor(self_url) {
6
+ this.self_url = self_url
7
+ }
8
+
9
+ fetch() {
10
+ return fetch(this.self_url, {method: 'GET', credentials: 'same-origin', headers: {'Content-Type': 'application/json'}})
11
+ .then(response => response.json())
12
+ }
13
+ }
14
+
15
+ window.Resizing.Rails.VideoFetcher = VideoFetcher
@@ -0,0 +1,77 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
3
+
4
+ window.Resizing ||= {}
5
+ window.Resizing.Rails ||= {}
6
+
7
+ class VideoUploader {
8
+ constructor(file_field, prepare_url) {
9
+ this.file_field = file_field
10
+ this.prepare_url = prepare_url
11
+ this.callback = null
12
+ }
13
+
14
+ upload() {
15
+ let file = this.file_field.files[0]
16
+ if(file === undefined) {
17
+ this.call('no_file_found')
18
+ return
19
+ }
20
+ this.prepare(file.name)
21
+ .catch(error => {
22
+ this.call('upload_failed')
23
+ })
24
+ }
25
+
26
+ prepare(filename) {
27
+ let body = JSON.stringify({filename: filename})
28
+ return fetch(this.prepare_url, {method: 'POST', credentials: 'same-origin', headers: {'Content-Type': 'application/json'}, body: body})
29
+ .then(response => {
30
+ if(!response.ok) {
31
+ return Promise.reject(response)
32
+ }
33
+ return response.json()
34
+ }).then(record => {
35
+ return this.uploadFile(record)
36
+ })
37
+ }
38
+
39
+ uploadFile(record) {
40
+ let file = this.file_field.files[0]
41
+ let data = record.data
42
+ return fetch(data.s3_presigned_url, {method: 'PUT', credentials: 'same-origin', headers: {'Content-Type': file.type}, body: file})
43
+ .then(response => {
44
+ if(!response.ok) {
45
+ return Promise.reject(response)
46
+ }
47
+ // ignore response body
48
+ }).then(data => {
49
+ return this.uploadDone(record)
50
+ })
51
+ }
52
+
53
+ uploadDone(record) {
54
+ let data = record.data
55
+ return fetch(data.upload_completed_url, {method: 'PUT', credentials: 'same-origin', headers:{'Content-Type': 'application/json'}})
56
+ .then(response => {
57
+ if(!response.ok) {
58
+ return Promise.reject(response)
59
+ }
60
+ return response.json()
61
+ }).then(data => {
62
+ window.location.pathname = record.self_path
63
+ })
64
+ }
65
+
66
+ addEventListener(callback) {
67
+ this.callback = callback
68
+ }
69
+
70
+ call(state) {
71
+ if(this.callback !== undefined) {
72
+ this.callback(state)
73
+ }
74
+ }
75
+ }
76
+
77
+ window.Resizing.Rails.VideoUploader = VideoUploader
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ */
14
+ @import 'bootstrap';
15
+ @import 'videos';
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,7 @@
1
+ module Resizing
2
+ module Rails
3
+ class ApplicationController < ActionController::Base
4
+ protect_from_forgery with: :exception
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ require_dependency "resizing/rails/application_controller"
2
+
3
+ module Resizing::Rails
4
+ class VideosController < ApplicationController
5
+ skip_before_action :verify_authenticity_token, only: [:prepare]
6
+
7
+ def index
8
+ @videos = Resizing::Rails::Video.order('created_at desc').page(params[:page]).per(20)
9
+ render text: 'index'
10
+ end
11
+
12
+ def prepare
13
+ response = client.prepare
14
+ video = Resizing::Rails::Video.create!(data: response)
15
+ render json: video
16
+ end
17
+
18
+ def client
19
+ @client ||= Resizing::Video::Client.new
20
+ end
21
+
22
+ def show
23
+ @video = Resizing::Rails::Video.find(params[:id])
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,6 @@
1
+ module Resizing
2
+ module Rails
3
+ module ApplicationHelper
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ module Resizing::Rails
2
+ module VideosHelper
3
+ end
4
+ end
@@ -0,0 +1,21 @@
1
+ # ref. https://qiita.com/Tak-Iwamoto/items/efce14f67eb572d8742e
2
+ module Resizing::Rails::WebpackBundleHelper
3
+ class BundleNotFound < StandardError; end
4
+
5
+ def asset_bundle_path(file)
6
+ valid_file?(file)
7
+ return "/assets" + manifest.fetch(file)
8
+ end
9
+
10
+ private
11
+
12
+ def manifest
13
+ return @manifest ||= JSON.parse(File.read("app/javascript/dist/manifest.json"))
14
+ end
15
+
16
+ def valid_file?(entry)
17
+ return true if manifest.key?(entry)
18
+ raise BundleNotFound, "Could not find bundle with name #{entry}"
19
+ end
20
+
21
+ end
@@ -0,0 +1 @@
1
+ import { Video } from '../src/video'
@@ -0,0 +1,42 @@
1
+ class Video {
2
+ constructor(element) {
3
+ this.element = element
4
+ this.element
5
+ }
6
+
7
+ upload() {
8
+ file = this.element.files[0]
9
+ prepare(file.name)
10
+ }
11
+
12
+ prepare(filename) {
13
+ body = JSON.stringify({filename: filename})
14
+ fetch(prepare_url, {method: 'POST', credentials: 'same-origin', headers: {'Content-Type': 'application/json'}, body: body})
15
+ .then(response => response.json())
16
+ .then(data => console.log(data))
17
+ }
18
+
19
+ file_upload(record) {
20
+ file = this.element.files[0]
21
+ fetch(record.s3_presigned_url, {method: 'PUT', credentials: 'same-origin', headers: {'Content-Type': file.type}, body: file})
22
+ .then(response => console.log(response))
23
+ .then(data => done_upload(record))
24
+ }
25
+
26
+ done_upload(record) {
27
+ fetch(record.upload_completed_url, {method: 'PUT', credentials: 'same-origin', headers:{'Content-Type': 'application/json'}})
28
+ .then(response => response.json())
29
+ .then(data => monitor_state(data))
30
+ }
31
+
32
+ monitor_state(record) {
33
+ alert('uploaded')
34
+ }
35
+
36
+ // monitor_state(record) {
37
+ // _record = record
38
+ // intervalID = setInternal(() => fetch(_record.self_url, method: 'GET', credentials: 'same-origin', headers:{'Content-Type': 'application/json'})
39
+ // }
40
+ }
41
+
42
+ export { Video }
@@ -0,0 +1,6 @@
1
+ module Resizing
2
+ module Rails
3
+ class ApplicationJob < ActiveJob::Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ module Resizing
2
+ module Rails
3
+ class ApplicationMailer < ActionMailer::Base
4
+ default from: 'from@example.com'
5
+ layout 'mailer'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ module Resizing
2
+ module Rails
3
+ class ApplicationRecord < ActiveRecord::Base
4
+ self.abstract_class = true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,37 @@
1
+ module Resizing::Rails
2
+ class Video < ApplicationRecord
3
+ serialize :data, JSON
4
+
5
+ %w(
6
+ id
7
+ project_id
8
+ state
9
+ source_uri
10
+ deleted_at
11
+ s3_presigned_url
12
+ converted_uri
13
+ created_at
14
+ updated_at
15
+ upload_completed_url
16
+ self_url
17
+ m3u8_url
18
+ hevc_url
19
+ avc_url
20
+ thumbnail_url
21
+ job_state
22
+ ).each do |name|
23
+ define_method "data_#{name}" do
24
+ self.data[name]
25
+ end
26
+ end
27
+
28
+ def self_path
29
+ Resizing::Rails.railtie_routes_url_helpers.video_path(self)
30
+ end
31
+
32
+ def as_json *args
33
+ hash = super(*args)
34
+ hash.merge(self_path: self_path)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,2 @@
1
+ li.page-item
2
+ = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote, class: 'page-link'
@@ -0,0 +1,2 @@
1
+ li.page-item.disabled
2
+ = link_to raw(t 'views.pagination.truncate'), '#', class: 'page-link'
@@ -0,0 +1,2 @@
1
+ li.page-item
2
+ = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, remote: remote, class: 'page-link'
@@ -0,0 +1,2 @@
1
+ li.page-item
2
+ = link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote, class: 'page-link'
@@ -0,0 +1,6 @@
1
+ - if page.current?
2
+ li.page-item.active
3
+ = content_tag :a, page, data: { remote: remote }, rel: page.rel, class: 'page-link'
4
+ - else
5
+ li.page-item
6
+ = link_to page, url, remote: remote, rel: page.rel, class: 'page-link'
@@ -0,0 +1,12 @@
1
+ = paginator.render do
2
+ nav
3
+ ul.pagination.justify-content-center
4
+ == first_page_tag unless current_page.first?
5
+ == prev_page_tag unless current_page.first?
6
+ - each_page do |page|
7
+ - if page.left_outer? || page.right_outer? || page.inside_window?
8
+ == page_tag page
9
+ - elsif !page.was_truncated?
10
+ == gap_tag
11
+ == next_page_tag unless current_page.last?
12
+ == last_page_tag unless current_page.last?
@@ -0,0 +1,2 @@
1
+ li.page-item
2
+ = link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote, class: 'page-link'
@@ -0,0 +1,20 @@
1
+ doctype html
2
+ html
3
+ head
4
+ meta charset='utf-8'
5
+ title Resizing rails
6
+ = csrf_meta_tags
7
+ = csp_meta_tag
8
+
9
+ link href="//vjs.zencdn.net/7.8.2/video-js.min.css" rel="stylesheet"
10
+ script src="//vjs.zencdn.net/7.8.2/video.min.js"
11
+
12
+ = stylesheet_link_tag "resizing/rails/application", media: "all"
13
+ = javascript_include_tag "resizing/rails/application"
14
+
15
+ body
16
+ .container
17
+ = yield
18
+
19
+ = render 'resizing/rails/common/toast'
20
+ = render 'resizing/rails/common/clipboard'
@@ -0,0 +1 @@
1
+ input#clipboard type='hidden' value=''
@@ -0,0 +1,10 @@
1
+ #toast-container.toast-container.position-fixed.top-0.end-0.p-3 style=("z-index: 5")
2
+ template#toast-template
3
+ .toast aria-atomic="true" aria-live="assertive" id="" role="alert"
4
+ .toast-header
5
+ /! img src="..." class="rounded me-2" alt="..."
6
+ strong.me-auto.toast-title Bootstrap
7
+ small.text-muted 2 seconds ago
8
+ button.btn-close aria-label="Close" data-bs-dismiss="toast" type="button"
9
+ .toast-body
10
+ | Heads up, toasts will stack automatically
@@ -0,0 +1,35 @@
1
+ form
2
+ .mb-3.row
3
+ label.form-label.col-sm-3.col-form-label for='video' File(MP4/MOV/AVI/WMV/ASF/WebM)
4
+ .col-sm-10
5
+ input.form-control#video type='file'
6
+ button.btn.btn-primary.mb-3#submit type='submit' upload
7
+
8
+ javascript:
9
+ document.addEventListener('DOMContentLoaded', (event)=> {
10
+ video = new Resizing.Rails.VideoUploader(
11
+ document.getElementById('video'),
12
+ #{raw Resizing::Rails.railtie_routes_url_helpers.prepare_videos_url(only_path: true).to_json}
13
+ );
14
+
15
+ document.getElementById('submit').addEventListener(
16
+ 'click',
17
+ (e) => {
18
+ e.preventDefault()
19
+ e.target.setAttribute('disabled', 'true')
20
+ video.upload()
21
+ }
22
+ )
23
+
24
+ video.addEventListener(e => {
25
+ switch(e) {
26
+ case 'no_file_found':
27
+ (new Resizing.Rails.Toast()).show('Error', 'ファイルを指定してください')
28
+ break;
29
+ case 'upload_failed':
30
+ (new Resizing.Rails.Toast()).show('Error', 'アップロードに失敗しました')
31
+ break;
32
+ }
33
+ document.getElementById('submit').removeAttribute('disabled')
34
+ })
35
+ })
@@ -0,0 +1,53 @@
1
+ h1 動画アップロード
2
+
3
+ = render 'resizing/rails/videos/upload_form'
4
+
5
+ = paginate(@videos)
6
+
7
+ .row.row-cols-1.row-cols-md-4.g-3
8
+ - @videos.each do |video|
9
+ .col
10
+ .card.h-100 data-video-url=video.data_self_url
11
+ img.js-video-thumbnail.card-img-top
12
+ .card-body
13
+ h5.card-title = "#{video.id}:#{video.data_id}"
14
+ ul.list-group.list-group-flush
15
+ li.list-group-item
16
+ | State:
17
+ span.video-state = video.data_state
18
+ li.list-group-item
19
+ | AVC
20
+ a.card-link.avc-url.data-copy-url href='#'
21
+ | Copy URL
22
+ li.list-group-item
23
+ | HEVC
24
+ a.card-link.hevc-url.data-copy-url href='#'
25
+ | Copy URL
26
+ .card-footer
27
+ small.text-muted = 'asfadf'
28
+ .card-body
29
+ = link_to 'Show video details', video, class: 'btn btn-primary'
30
+
31
+ = paginate(@videos)
32
+
33
+ javascript:
34
+ document.addEventListener('DOMContentLoaded', ()=> {
35
+ let setDataCopyURLOrRemoveElement = (elem, value) => {
36
+ if(value) {
37
+ elem.setAttribute('data-copy-url', value)
38
+ } else {
39
+ elem.remove()
40
+ }
41
+ }
42
+ elements = document.querySelectorAll('[data-video-url]')
43
+ elements.forEach(elem => {
44
+ url = elem.getAttribute('data-video-url')
45
+ fetcher = new Resizing.Rails.VideoFetcher(url)
46
+ fetcher.fetch().then(data => {
47
+ elem.querySelector('.js-video-thumbnail').setAttribute('src', data.thumbnail_url)
48
+ elem.querySelector('.video-state').textContent = data.state
49
+ setDataCopyURLOrRemoveElement(elem.querySelector('.avc-url'), data.avc_url)
50
+ setDataCopyURLOrRemoveElement(elem.querySelector('.hevc-url'), data.hevc_url)
51
+ })
52
+ })
53
+ })
@@ -0,0 +1,75 @@
1
+
2
+ .card
3
+ .card-img-top
4
+ #video
5
+ .card-body
6
+ .card-title = "Video##{@video.id}"
7
+ ul.list-group.list-group-flush
8
+ li.list-group-item
9
+ | 進捗
10
+ .progress
11
+ .progress-bar.progress-bar-striped.progress-bar-animated role='progressbar' style="width: 0%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100" 25%
12
+ li.list-group-item
13
+ | AVC
14
+ a.card-link.avc-url.data-copy-url href='#'
15
+ | Copy URL
16
+ li.list-group-item
17
+ | HEVC
18
+ a.card-link.hevc-url.data-copy-url href='#'
19
+ | Copy URL
20
+ li.list-group-item
21
+ label.form-label for='copy-tag' コピー用のタグ(このサイト内だけで有効です)
22
+ textarea#copy-tag class='form-control' rows='10'
23
+ | <div id='video-#{@video.id}'></div>
24
+ <script>
25
+ document.addEventListner('DOMContentLoaded', function () {
26
+ video = new Resizing.Rails.Video("#{@video.data_self_url}", document.querySelector('video-#{@video.id}'))
27
+ video.fetch()
28
+ })
29
+ </script>
30
+
31
+ p
32
+ | ※Resizing.Rails.Video classの読み込みが必要です。
33
+ b 例:
34
+ pre
35
+ code
36
+ | javascript_include_tag "resizing/rails/video"
37
+
38
+ javascript:
39
+ document.addEventListener('DOMContentLoaded', function() {
40
+ progress = new Resizing.Rails.ProgressBar(document.querySelector('.progress-bar'), 0, 100)
41
+
42
+ let setDataCopyURLOrRemoveElement = (elem, value) => {
43
+ if(!elem) {
44
+ return
45
+ }
46
+
47
+ if(value) {
48
+ elem.setAttribute('data-copy-url', value)
49
+ elem.textContent = 'Copy URL'
50
+ } else {
51
+ elem.textContent = ''
52
+ }
53
+ }
54
+
55
+ video_root = document.querySelector('#video')
56
+ video = new Resizing.Rails.Video("#{@video.data_self_url}", video_root)
57
+ video.fetch()
58
+ video.addEventListener((state, data) => {
59
+ console.log('eventListener')
60
+ console.log(data)
61
+ switch(state) {
62
+ case 'video_fetched':
63
+ if(data.job_state?.job_percent_complete !== undefined) {
64
+ progress.setCurrent(data.job_state?.job_percent_complete)
65
+ }
66
+ setDataCopyURLOrRemoveElement(document.querySelector('.avc-url'), data.avc_url)
67
+ setDataCopyURLOrRemoveElement(document.querySelector('.hevc-url'), data.hevc_url)
68
+ break
69
+ default:
70
+ break
71
+ }
72
+ })
73
+
74
+ })
75
+
data/config/routes.rb ADDED
@@ -0,0 +1,7 @@
1
+ Resizing::Rails::Engine.routes.draw do
2
+ resources :videos do
3
+ collection do
4
+ post :prepare
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ class CreateResizingRailsVideos < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :resizing_rails_videos do |t|
4
+ t.text :data
5
+
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ require "resizing/rails/engine"
2
+
3
+ module Resizing
4
+ module Rails
5
+ # Your code goes here...
6
+ end
7
+ end
@@ -0,0 +1,25 @@
1
+ Gem.loaded_specs['resizing-rails'].dependencies.each do |d|
2
+ require d.name
3
+ rescue LoadError
4
+ require d.name.gsub('-', '/')
5
+ end
6
+
7
+ module Resizing
8
+ module Rails
9
+ class Engine < ::Rails::Engine
10
+ isolate_namespace Resizing::Rails
11
+
12
+ # initializer 'ResizingRails precompile hook', group: :all do |app|
13
+ # puts app.config.assets.precompile
14
+ # app.config.assets.precompile += %w(
15
+ # resizing/rails/videos.js
16
+ # )
17
+ # end
18
+
19
+ # rake_tasks do
20
+ # Dir[File.join(File.dirname(__FILE__), '../tasks/*.rake')].each { |f| load f }
21
+ # end
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,5 @@
1
+ module Resizing
2
+ module Rails
3
+ VERSION = '0.1.0.pre'
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :resizing_rails do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,204 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: resizing-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre
5
+ platform: ruby
6
+ authors:
7
+ - Junichiro Kasuya
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-02-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.2.4
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 5.2.4.4
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 5.2.4
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 5.2.4.4
33
+ - !ruby/object:Gem::Dependency
34
+ name: resizing
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 0.8.0
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.8.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: slim-rails
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: kaminari
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: bootstrap
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 5.0.0.beta1
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 5.0.0.beta1
89
+ - !ruby/object:Gem::Dependency
90
+ name: sassc
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: sqlite3
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: github_changelog_generator
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ description: Resizing mountable module for Rails application.
132
+ email:
133
+ - junichiro.kasuya@gmail.com
134
+ executables: []
135
+ extensions: []
136
+ extra_rdoc_files: []
137
+ files:
138
+ - MIT-LICENSE
139
+ - README.md
140
+ - Rakefile
141
+ - app/assets/config/resizing_rails_manifest.js
142
+ - app/assets/javascripts/resizing/rails/application.js
143
+ - app/assets/javascripts/resizing/rails/clipboard.js
144
+ - app/assets/javascripts/resizing/rails/progressbar.js
145
+ - app/assets/javascripts/resizing/rails/toast.js
146
+ - app/assets/javascripts/resizing/rails/video.js
147
+ - app/assets/javascripts/resizing/rails/video_fetcher.js
148
+ - app/assets/javascripts/resizing/rails/video_uploader.js
149
+ - app/assets/stylesheets/resizing/rails/application.scss
150
+ - app/assets/stylesheets/resizing/rails/videos.scss
151
+ - app/controllers/resizing/rails/application_controller.rb
152
+ - app/controllers/resizing/rails/videos_controller.rb
153
+ - app/helpers/resizing/rails/application_helper.rb
154
+ - app/helpers/resizing/rails/videos_helper.rb
155
+ - app/helpers/resizing/rails/webpack_bundle_helper.rb
156
+ - app/javascript/packs/resizing.js
157
+ - app/javascript/src/video.js
158
+ - app/jobs/resizing/rails/application_job.rb
159
+ - app/mailers/resizing/rails/application_mailer.rb
160
+ - app/models/resizing/rails/application_record.rb
161
+ - app/models/resizing/rails/video.rb
162
+ - app/views/kaminari/_first_page.html.slim
163
+ - app/views/kaminari/_gap.html.slim
164
+ - app/views/kaminari/_last_page.html.slim
165
+ - app/views/kaminari/_next_page.html.slim
166
+ - app/views/kaminari/_page.html.slim
167
+ - app/views/kaminari/_paginator.html.slim
168
+ - app/views/kaminari/_prev_page.html.slim
169
+ - app/views/layouts/resizing/rails/application.html.slim
170
+ - app/views/resizing/rails/common/_clipboard.html.slim
171
+ - app/views/resizing/rails/common/_toast.html.slim
172
+ - app/views/resizing/rails/videos/_upload_form.html.slim
173
+ - app/views/resizing/rails/videos/index.html.slim
174
+ - app/views/resizing/rails/videos/show.html.slim
175
+ - config/routes.rb
176
+ - db/migrate/20210122043613_create_resizing_rails_videos.rb
177
+ - lib/resizing/rails.rb
178
+ - lib/resizing/rails/engine.rb
179
+ - lib/resizing/rails/version.rb
180
+ - lib/tasks/resizing/rails_tasks.rake
181
+ homepage: https://github.com/jksy/resizing-rails/
182
+ licenses:
183
+ - MIT
184
+ metadata: {}
185
+ post_install_message:
186
+ rdoc_options: []
187
+ require_paths:
188
+ - lib
189
+ required_ruby_version: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ required_rubygems_version: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ">"
197
+ - !ruby/object:Gem::Version
198
+ version: 1.3.1
199
+ requirements: []
200
+ rubygems_version: 3.0.3
201
+ signing_key:
202
+ specification_version: 4
203
+ summary: Resizing mountable module for Rails application.
204
+ test_files: []