diff --git a/lib/librarix/application.rb b/lib/librarix/application.rb index 06ab228..c9e55eb 100644 --- a/lib/librarix/application.rb +++ b/lib/librarix/application.rb @@ -17,8 +17,19 @@ module Librarix end get '/search' do - movies = params.key?('search') ? Tmdb::Movie.find(params['search']) : Tmdb::Movie.popular.map { |m| Tmdb::Movie.new(m) } - slim :search, locals: {movies: movies, conf: Tmdb::Configuration.new} + movies = if params['search'].nil? + Tmdb::Movie.popular.map { |m| Tmdb::Movie.new(m) } + elsif params['search'] == '' + [] + else + Tmdb::Movie.find(params['search']) + end + + if request.xhr? + slim :list, layout: false, locals: {movies: movies} + else + slim :search, locals: {movies: movies} + end end post '/add' do @@ -36,7 +47,11 @@ module Librarix post '/remove' do Librarix::Redis::Movie.new(params[:id]).remove - redirect to('/') + if request.xhr? + "" + else + redirect to('/') + end end end end diff --git a/lib/librarix/assets/application.scss b/lib/librarix/assets/application.scss index 9fdbbea..85975c5 100644 --- a/lib/librarix/assets/application.scss +++ b/lib/librarix/assets/application.scss @@ -1,35 +1,56 @@ body { - margin: 0; + margin: 10px; } h2 { margin-top: 0; } +#search { + display: flex; + + input { + border-radius: 0.4em; + border: solid 3px #f4f4f4; + } + + input[type="submit"] { + background-color: #f4f4f4; + } + + input[type="text"] { + flex-grow: 1; + font-size: 1.4em; + padding: 5px; + } +} + ul { list-style-type: none; margin: 0; padding: 0; li { - padding: 10px; - - display: flex; - flex-flow: row wrap; - align-items: center; - justify-content: center; - - .poster { - margin-right: 10px; - } - - .informations { - align-self: flex-start; - flex: 1 1 300px; - } + padding: 10px 0; } li:nth-child(even) { background-color: #f4f4f4; } } + +.movie { + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: center; + + .poster { + margin-right: 10px; + } + + .informations { + align-self: flex-start; + flex: 1 1 300px; + } +} diff --git a/lib/librarix/public/application.css b/lib/librarix/public/application.css index 06fab10..2154dcc 100644 --- a/lib/librarix/public/application.css +++ b/lib/librarix/public/application.css @@ -1 +1 @@ -body{margin:0}h2{margin-top:0}ul{list-style-type:none;margin:0;padding:0}ul li{padding:10px;display:flex;flex-flow:row wrap;align-items:center;justify-content:center}ul li .poster{margin-right:10px}ul li .informations{align-self:flex-start;flex:1 1 300px}ul li:nth-child(even){background-color:#f4f4f4} +body{margin:10px}h2{margin-top:0}#search{display:flex}#search input{border-radius:0.4em;border:solid 3px #f4f4f4}#search input[type="submit"]{background-color:#f4f4f4}#search input[type="text"]{flex-grow:1;font-size:1.4em;padding:5px}ul{list-style-type:none;margin:0;padding:0}ul li{padding:10px 0}ul li:nth-child(even){background-color:#f4f4f4}.movie{display:flex;flex-flow:row wrap;align-items:center;justify-content:center}.movie .poster{margin-right:10px}.movie .informations{align-self:flex-start;flex:1 1 300px} diff --git a/lib/librarix/public/application.js b/lib/librarix/public/application.js index 5ddd9e1..1c88a66 100644 --- a/lib/librarix/public/application.js +++ b/lib/librarix/public/application.js @@ -1,2 +1,65 @@ +function initButtons() { + var buttons = document.querySelectorAll('button[data-action=remove-movie]'); + for (var i = 0; i < buttons.length; i++) { + buttons[i].addEventListener('click', function(event) { + event.preventDefault(); + removeMovie(this.previousElementSibling.value) + }); + } +} + +function initSearch() { + var typing_timer; + var typing_interval = 300; + + document.querySelector('#search > input[type="text"]').addEventListener('input', function(event) { + var value = this.value; + + clearTimeout(typing_timer); + typing_timer = setTimeout(function() { search(value); }, typing_interval); + }); + document.querySelector('#search > input[type="submit"]').style.display = 'none'; + + window.addEventListener('popstate', function(event) { + document.querySelector('#search > input[type="text"]').value = event.state.value; + search(event.state.value); + }); +} + +function search(value) { + var url = '/search?search=' + encodeURIComponent(value) + window.history.pushState({value: value}, "", url); + + var req = new XMLHttpRequest(); + req.open('GET', url); + req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + + req.addEventListener('load', function(e) { + document.getElementById('movies').parentNode.innerHTML = this.responseText; + }); + + req.send() +} + +function removeMovie(id) { + var data = new FormData(); + data.append('id', id); + + var req = new XMLHttpRequest(); + req.open('POST', '/remove'); + req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + + req.addEventListener('load', function(e) { + document.querySelector('.movie[data-id="' + id + '"]').parentNode.remove(); + }); + + req.send(data) +} + document.addEventListener('DOMContentLoaded', function(event) { + initButtons(); + + if(document.querySelector('#search') != null) { + initSearch(); + } }); diff --git a/lib/librarix/views/index.slim b/lib/librarix/views/index.slim index 2584fa6..09a4ffc 100644 --- a/lib/librarix/views/index.slim +++ b/lib/librarix/views/index.slim @@ -1,6 +1,3 @@ - content_for(:title) { 'Index' } -ul - - movies.each do |movie| - li - == slim :movie, locals: {movie: movie} +== slim :list, locals: {movies: movies} diff --git a/lib/librarix/views/layout.slim b/lib/librarix/views/layout.slim index b51492e..f362a2b 100644 --- a/lib/librarix/views/layout.slim +++ b/lib/librarix/views/layout.slim @@ -7,5 +7,4 @@ html link rel="stylesheet" media="all" href="/application.css" script type="text/javascript" src="/application.js" body - div#main - == yield + == yield diff --git a/lib/librarix/views/list.slim b/lib/librarix/views/list.slim new file mode 100644 index 0000000..2062ac1 --- /dev/null +++ b/lib/librarix/views/list.slim @@ -0,0 +1,4 @@ +ul#movies + - movies.each do |movie| + li + == slim :movie, locals: {movie: movie} diff --git a/lib/librarix/views/movie.slim b/lib/librarix/views/movie.slim index af8e1d3..b30decd 100644 --- a/lib/librarix/views/movie.slim +++ b/lib/librarix/views/movie.slim @@ -1,16 +1,17 @@ -.poster - - if movie.poster_path - img src="#{poster_url(movie.poster_path, 'w154')}" -.informations - h2 - a href="https://www.themoviedb.org/movie/#{movie.id}" #{movie.original_title} (#{movie.release_year}) - p = movie.overview -.actions - - if movie.added? - form method="post" action="/remove" - input type="hidden" name="id" value="#{movie.id}" - button type="submit" Remove - - else - form method="post" action="/add" - input type="hidden" name="id" value="#{movie.id}" - button type="submit" Add +.movie data-id="#{movie.id}" + .poster + - if movie.poster_path + img src="#{poster_url(movie.poster_path, 'w154')}" + .informations + h2 + a href="https://www.themoviedb.org/movie/#{movie.id}" #{movie.original_title} (#{movie.release_year}) + p = movie.overview + .actions + - if movie.added? + form method="post" action="/remove" + input type="hidden" name="id" value="#{movie.id}" + button type="submit" data-action="remove-movie" Remove + - else + form method="post" action="/add" + input type="hidden" name="id" value="#{movie.id}" + button type="submit" data-action="add-movie" Add diff --git a/lib/librarix/views/search.slim b/lib/librarix/views/search.slim index 33360a8..23952b3 100644 --- a/lib/librarix/views/search.slim +++ b/lib/librarix/views/search.slim @@ -1,10 +1,8 @@ - content_for(:title) { 'Search' } -form method="get" action="/search" - input type="text" name="search" value="#{params['search']}" - input type="submit" +form method="get" action="/search" id="search" + input type="text" name="search" value="#{params['search']}" autocomplete="off" autofocus="on" + input type="submit" value="Search" -ul - - movies.each do |movie| - li - == slim :movie, locals: {movie: movie} +div + == slim :list, locals: {movies: movies}