From 65532e9d0bf7dd8bdc09e07f9ac539f46b163ca8 Mon Sep 17 00:00:00 2001 From: Scott Rohrer Date: Wed, 25 Mar 2020 22:43:50 -0400 Subject: [PATCH 1/5] Fixed search and video recording --- .../javascripts/components/Book.es6.jsx | 2 +- .../javascripts/components/Video.es6.jsx | 2 +- app/controllers/searches_controller.rb | 67 +------------------ 3 files changed, 5 insertions(+), 66 deletions(-) diff --git a/app/assets/javascripts/components/Book.es6.jsx b/app/assets/javascripts/components/Book.es6.jsx index 1ae20719..789edde5 100644 --- a/app/assets/javascripts/components/Book.es6.jsx +++ b/app/assets/javascripts/components/Book.es6.jsx @@ -486,7 +486,7 @@ class Book extends React.Component { .then((stream) => { self.onSaveStream(stream); video.controls = false; - video.src = window.URL.createObjectURL(stream); + video.srcObject = stream; }) .catch((err) => { console.log(err.name + ": " + err.message); diff --git a/app/assets/javascripts/components/Video.es6.jsx b/app/assets/javascripts/components/Video.es6.jsx index 967a59f6..04976d4a 100644 --- a/app/assets/javascripts/components/Video.es6.jsx +++ b/app/assets/javascripts/components/Video.es6.jsx @@ -59,7 +59,7 @@ Video = React.createClass( { const video = document.getElementById('camera-stream'); const stream = this.props.stream; - video.src = window.URL.createObjectURL(stream); + video.srcObject = stream; const options = { mimeType: 'video/webm', diff --git a/app/controllers/searches_controller.rb b/app/controllers/searches_controller.rb index b6c9054a..c7058f02 100644 --- a/app/controllers/searches_controller.rb +++ b/app/controllers/searches_controller.rb @@ -4,14 +4,14 @@ def search @query = params[:q] if params[:q].length > 0 - q = params[:q].downcase - @language = Book.all.select{ |book| book if are_close?(q, book.source_language.downcase) || are_close?(q, book.target_language.downcase) || are_close?(q, book.title.downcase)}.sort_by{|book| book.created_at} + q = "%#{params[:q].downcase}%" + @language = Book.where("source_language || target_language || title ilike ?", q).sort_by{|book| book.created_at} .reverse .map do |book| BookSerializer.new(book) end - @user = User.all.select{ |user| user if are_close?(q, user.username.downcase) }.sort_by{|user| user.created_at} + @user = User.where("username ilike ?", q).sort_by{|user| user.created_at} .reverse .map do |user| UserSerializer.new(user) @@ -30,65 +30,4 @@ def search end end - - private - #Damerau–Levenshtein distance algorithm (https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance) - def are_close?(q, target) - - # Initialization for the algorithm - query_length = q.length - target_length = target.length - - char_dictionary = {} - - distance_2d_array = Array.new(query_length+1){Array.new(target_length+1){0}} - - for i in 0..query_length do - distance_2d_array[i][0] = i - end - - for j in 0..target_length do - distance_2d_array[0][j] = j - end - - # Populate a dictionary with alphapets of the two strings - q.each_char{ |char| char_dictionary[char] = 0 } - target.each_char{ |char| char_dictionary[char] = 0 } - - #Determine substring distances - for i in 1..query_length do - db = 0 - for j in 1..target_length do - i1 = char_dictionary[target[j-1]] - j1 = db - cost = 0 - - if q[i-1] == target[j-1] - db = j - else - cost = 1 - end - - distance_2d_array[i][j] = [ - distance_2d_array[i][j-1] + 1, #insertion - distance_2d_array[i-1][j] + 1, #deletion - distance_2d_array[i-1][j-1] + cost #substitution - ].min - - if i1 > 0 && j1 > 0 - distance_2d_array[i][j] = [ - distance_2d_array[i][j], - distance_2d_array[i1-1][j1-1] + (i-i1-1) + (j-j1-1) + 1 - ].min #transposition - end - end - - char_dictionary[q[i-1]] = i - end - - # You can change 'desired_distance' value so that catching more results will happen - desired_distance = 4 - - return distance_2d_array[query_length][target_length] <= desired_distance - end end From c57cec939e151fd8439e4c2067b795ef03805d40 Mon Sep 17 00:00:00 2001 From: Scott Rohrer Date: Mon, 20 Jul 2020 21:58:52 -0400 Subject: [PATCH 2/5] Video fixes --- app/assets/javascripts/components/Book.es6.jsx | 7 +++++-- app/assets/javascripts/components/Dictionary.es6.jsx | 5 ++++- app/assets/javascripts/components/NewBook.es6.jsx | 2 +- app/assets/javascripts/components/PhrasePair.es6.jsx | 9 +++++---- .../javascripts/components/PhraseSearchResult.es6.jsx | 6 +++--- app/assets/javascripts/components/Video.es6.jsx | 2 +- app/assets/stylesheets/book-video.styl | 1 - app/assets/stylesheets/book.styl | 11 +++++++++++ app/views/books/show.html.erb | 3 ++- config/initializers/aws.rb | 2 +- 10 files changed, 33 insertions(+), 15 deletions(-) diff --git a/app/assets/javascripts/components/Book.es6.jsx b/app/assets/javascripts/components/Book.es6.jsx index 789edde5..63b00d1e 100644 --- a/app/assets/javascripts/components/Book.es6.jsx +++ b/app/assets/javascripts/components/Book.es6.jsx @@ -366,7 +366,7 @@ class Book extends React.Component { return (
- +
{this.renderPlayButton()}
) } else { - return
{this.renderPlayButton()}
+ return
{this.renderPlayButton()}
} } else { if (this.state.isEditingBook) { @@ -411,6 +411,7 @@ class Book extends React.Component { author={this.props.currentUser.username} width={600} videoPhrase={false} + awsBucket={this.props.awsBucket} />
) @@ -688,6 +689,7 @@ class Book extends React.Component { targetLanguage={this.state.book.target_language} author={this.state.book.user_id} isNewPhrase={this.state.isNewPhrase} + awsBucket={this.props.awsBucket} />
@@ -746,4 +748,5 @@ Book.propTypes = { delete: React.PropTypes.string, edit: React.PropTypes.string, close: React.PropTypes.string, + awsBucket: React.PropTypes.string }; diff --git a/app/assets/javascripts/components/Dictionary.es6.jsx b/app/assets/javascripts/components/Dictionary.es6.jsx index 6c34ea42..234d3720 100644 --- a/app/assets/javascripts/components/Dictionary.es6.jsx +++ b/app/assets/javascripts/components/Dictionary.es6.jsx @@ -302,7 +302,8 @@ class Dictionary extends React.Component { delete={this.props.delete} edit={this.props.edit} close={this.props.close} - newPhrase="newPhrase" /> + newPhrase="newPhrase" + awsBucket={this.props.awsBucket} /> ); } return ( @@ -320,6 +321,7 @@ class Dictionary extends React.Component { delete={this.props.delete} edit={this.props.edit} close={this.props.close} + awsBucket={this.props.awsBucket} /> ); }); @@ -500,4 +502,5 @@ Dictionary.propTypes = { delete: React.PropTypes.string, edit: React.PropTypes.string, close: React.PropTypes.string, + awsBucket: React.PropTypes.string }; diff --git a/app/assets/javascripts/components/NewBook.es6.jsx b/app/assets/javascripts/components/NewBook.es6.jsx index 8b3bd574..e635b560 100644 --- a/app/assets/javascripts/components/NewBook.es6.jsx +++ b/app/assets/javascripts/components/NewBook.es6.jsx @@ -146,7 +146,7 @@ class NewBook extends React.Component { renderVideoDescription() { if(this.state.isInputVideo == false) { if(this.state.hasVideoDescription) { - return
{this.renderPlayButton()}
+ return
{this.renderPlayButton()}
} else { return } diff --git a/app/assets/javascripts/components/PhrasePair.es6.jsx b/app/assets/javascripts/components/PhrasePair.es6.jsx index 6ed27718..68239ec0 100644 --- a/app/assets/javascripts/components/PhrasePair.es6.jsx +++ b/app/assets/javascripts/components/PhrasePair.es6.jsx @@ -238,7 +238,7 @@ class PhrasePair extends React.Component {
  • { - this.state.sourcePhrase.startsWith('https://s3.amazonaws.com/poly-video-uploads-dev/') ? + this.state.sourcePhrase.startsWith(`https://${this.props.awsBucket}.s3.amazonaws.com/`) ? this.renderSourceInput(true) : this.renderSourceInput(false) @@ -246,7 +246,7 @@ class PhrasePair extends React.Component {
  • { - this.state.targetPhrase && this.state.targetPhrase.startsWith('https://s3.amazonaws.com/poly-video-uploads-dev/') ? + this.state.targetPhrase && this.state.targetPhrase.startsWith(`https://${this.props.awsBucket}.s3.amazonaws.com/`) ? this.renderTargetInput(true) : this.renderTargetInput(false) @@ -262,7 +262,7 @@ class PhrasePair extends React.Component {
    • { - this.state.sourcePhrase.startsWith('https://s3.amazonaws.com/poly-video-uploads-dev/') ? + this.state.sourcePhrase.startsWith(`https://${this.props.awsBucket}.s3.amazonaws.com/`) ? this.renderSourceVideo(this.state.sourcePhrase) : this.renderParagraph(this.state.sourcePhrase) @@ -270,7 +270,7 @@ class PhrasePair extends React.Component {
    • { - this.state.targetPhrase && this.state.targetPhrase.startsWith('https://s3.amazonaws.com/poly-video-uploads-dev/') ? + this.state.targetPhrase && this.state.targetPhrase.startsWith(`https://${this.props.awsBucket}.s3.amazonaws.com/`) ? this.renderTargetVideo(this.state.targetPhrase) : this.renderParagraph(this.state.targetPhrase) @@ -303,4 +303,5 @@ PhrasePair.propTypes = { menu: React.PropTypes.string, edit: React.PropTypes.string, delete: React.PropTypes.string, + awsBucket: React.PropTypes.string }; diff --git a/app/assets/javascripts/components/PhraseSearchResult.es6.jsx b/app/assets/javascripts/components/PhraseSearchResult.es6.jsx index 9cfd7f0a..8e566261 100644 --- a/app/assets/javascripts/components/PhraseSearchResult.es6.jsx +++ b/app/assets/javascripts/components/PhraseSearchResult.es6.jsx @@ -4,7 +4,7 @@ class PhraseSearchResult extends React.Component {
      • { - this.props.phrase.source_phrase.startsWith('https://s3.amazonaws.com/poly-video-uploads-dev/') ? + this.props.phrase.source_phrase.startsWith(`https://${this.props.awsBucket}.s3.amazonaws.com/`) ? this.renderSourceVideo(this.props.phrase.source_phrase) : this.renderParagraph(this.props.phrase.source_phrase) @@ -12,7 +12,7 @@ class PhraseSearchResult extends React.Component {
      • { - this.props.phrase.target_phrase && this.props.phrase.target_phrase.startsWith('https://s3.amazonaws.com/poly-video-uploads-dev/') ? + this.props.phrase.target_phrase && this.props.phrase.target_phrase.startsWith(`https://${this.props.awsBucket}.s3.amazonaws.com/`) ? this.renderTargetVideo(this.props.phrase.target_phrase) : this.renderParagraph(this.props.phrase.target_phrase) @@ -76,5 +76,5 @@ class PhraseSearchResult extends React.Component { } BookEntry.propTypes = { - + awsBucket: React.PropTypes.string }; diff --git a/app/assets/javascripts/components/Video.es6.jsx b/app/assets/javascripts/components/Video.es6.jsx index 04976d4a..cf7ff61d 100644 --- a/app/assets/javascripts/components/Video.es6.jsx +++ b/app/assets/javascripts/components/Video.es6.jsx @@ -143,7 +143,7 @@ Video = React.createClass( { this.onPresignedUrlFetchSuccess = function (file, response) { - const objectUrl = `https://s3.amazonaws.com/poly-video-uploads-dev/${response.object_key}`; + const objectUrl = `https://${this.props.awsBucket}.s3.amazonaws.com/${response.object_key}`; self.setState({currentVideoUploadUrl: objectUrl}); diff --git a/app/assets/stylesheets/book-video.styl b/app/assets/stylesheets/book-video.styl index 8499ecda..8bdafeb6 100644 --- a/app/assets/stylesheets/book-video.styl +++ b/app/assets/stylesheets/book-video.styl @@ -11,7 +11,6 @@ background black margin auto display block - min-height 450px transition height $time ease-in-out .videoControls diff --git a/app/assets/stylesheets/book.styl b/app/assets/stylesheets/book.styl index 1d9b7e7e..b16688b6 100644 --- a/app/assets/stylesheets/book.styl +++ b/app/assets/stylesheets/book.styl @@ -146,6 +146,9 @@ margin 0 position relative + video + width 600px + button &.play width 45px @@ -190,3 +193,11 @@ p.author.new color $grey + +@media (max-width:720px) + .videoDescription + width 100% !important + margin 0 !important + + video + width 100% !important \ No newline at end of file diff --git a/app/views/books/show.html.erb b/app/views/books/show.html.erb index 89ab1e6a..e8d91130 100644 --- a/app/views/books/show.html.erb +++ b/app/views/books/show.html.erb @@ -27,5 +27,6 @@ videoAlt: asset_path('icons/icon-camera-white-outline-blue.svg'), closeAlt: asset_path('icons/icon-cross-white.svg'), pause: asset_path('icons/icon-pause-white.svg'), - play: asset_path('icons/icon-rightArrow-white.svg') + play: asset_path('icons/icon-rightArrow-white.svg'), + awsBucket: ENV['RECORDED_VIDEOS_S3_BUCKET'] ) %> diff --git a/config/initializers/aws.rb b/config/initializers/aws.rb index b4d417f2..0819a32a 100644 --- a/config/initializers/aws.rb +++ b/config/initializers/aws.rb @@ -1,5 +1,5 @@ Aws.config.update({ - region: 'us-east-1', + region: ENV['AWS_REGION'], credentials: Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY']), }) From 93fe6203678e1cc6b8c9bf285738eada47083e96 Mon Sep 17 00:00:00 2001 From: Scott Rohrer Date: Tue, 21 Jul 2020 21:08:48 -0400 Subject: [PATCH 3/5] Fixed errors --- app/assets/javascripts/components/Dictionary.es6.jsx | 1 + app/assets/javascripts/components/NewBook.es6.jsx | 1 + app/assets/javascripts/components/Video.es6.jsx | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/components/Dictionary.es6.jsx b/app/assets/javascripts/components/Dictionary.es6.jsx index 234d3720..92c954d8 100644 --- a/app/assets/javascripts/components/Dictionary.es6.jsx +++ b/app/assets/javascripts/components/Dictionary.es6.jsx @@ -452,6 +452,7 @@ class Dictionary extends React.Component { author={this.props.author} width={600} videoPhrase={true} + awsBucket={this.props.awsBucket} /> ); diff --git a/app/assets/javascripts/components/NewBook.es6.jsx b/app/assets/javascripts/components/NewBook.es6.jsx index e635b560..f064ad91 100644 --- a/app/assets/javascripts/components/NewBook.es6.jsx +++ b/app/assets/javascripts/components/NewBook.es6.jsx @@ -177,6 +177,7 @@ class NewBook extends React.Component { author={this.props.currentUser.username} width={600} videoPhrase={false} + awsBucket={this.props.awsBucket} /> ) diff --git a/app/assets/javascripts/components/Video.es6.jsx b/app/assets/javascripts/components/Video.es6.jsx index cf7ff61d..02f87594 100644 --- a/app/assets/javascripts/components/Video.es6.jsx +++ b/app/assets/javascripts/components/Video.es6.jsx @@ -143,7 +143,7 @@ Video = React.createClass( { this.onPresignedUrlFetchSuccess = function (file, response) { - const objectUrl = `https://${this.props.awsBucket}.s3.amazonaws.com/${response.object_key}`; + const objectUrl = `https://${self.props.awsBucket}.s3.amazonaws.com/${response.object_key}`; self.setState({currentVideoUploadUrl: objectUrl}); From a669d0e5a231d58ec38190e64b51937faaaf4168 Mon Sep 17 00:00:00 2001 From: Scott Rohrer Date: Wed, 22 Jul 2020 13:28:22 -0400 Subject: [PATCH 4/5] Fix for recording phrase videos --- app/assets/javascripts/components/Dictionary.es6.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/components/Dictionary.es6.jsx b/app/assets/javascripts/components/Dictionary.es6.jsx index 92c954d8..89ed4350 100644 --- a/app/assets/javascripts/components/Dictionary.es6.jsx +++ b/app/assets/javascripts/components/Dictionary.es6.jsx @@ -262,7 +262,7 @@ class Dictionary extends React.Component { .then((stream) => { self.onSaveStream(stream); video.controls = false; - video.src = window.URL.createObjectURL(stream); + video.srcObject = stream; }) .catch((err) => { console.log(err.name + ": " + err.message); From 27d732fe30a870349ad7a14c02a85902ba2afc03 Mon Sep 17 00:00:00 2001 From: Scott Rohrer Date: Sat, 15 Aug 2020 15:47:57 -0400 Subject: [PATCH 5/5] Fixed video recording for new book --- app/assets/javascripts/components/NewBook.es6.jsx | 1 + app/views/books/new.html.erb | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/components/NewBook.es6.jsx b/app/assets/javascripts/components/NewBook.es6.jsx index f064ad91..04f47b13 100644 --- a/app/assets/javascripts/components/NewBook.es6.jsx +++ b/app/assets/javascripts/components/NewBook.es6.jsx @@ -328,4 +328,5 @@ NewBook.propTypes = { unstar: React.PropTypes.string, cardinality: React.PropTypes.string, menuAlt: React.PropTypes.string, + awsBucket: React.PropTypes.string }; diff --git a/app/views/books/new.html.erb b/app/views/books/new.html.erb index d047a612..8a4049ba 100644 --- a/app/views/books/new.html.erb +++ b/app/views/books/new.html.erb @@ -13,5 +13,6 @@ pause: asset_path('icons/icon-pause-white.svg'), play: asset_path('icons/icon-rightArrow-white.svg'), deleteAlt: asset_path('icons/icon-trash-white.svg'), - menu: asset_path('icons/icon-menuDots-blue.svg') + menu: asset_path('icons/icon-menuDots-blue.svg'), + awsBucket: ENV['RECORDED_VIDEOS_S3_BUCKET'] ) %>