tag autocomplete and better browsing

This commit is contained in:
Kyle Drake 2014-07-31 15:25:08 -07:00
parent 581398f826
commit 1ac9cdf606
9 changed files with 1956 additions and 96 deletions

4
app.rb
View file

@ -266,6 +266,10 @@ post '/tags/remove' do
redirect request.referer
end
get '/tags/suggestions/:name.json' do |name|
Tag.suggestions(name).collect {|t| t.name}.to_json
end
get '/browse' do
@current_page = params[:current_page]
@current_page = @current_page.to_i

View file

@ -11,4 +11,15 @@ class Tag < Sequel::Model
def self.create_unless_exists(name)
dataset.filter(name: name).first || create(name: name)
end
def self.suggestions(name, limit=3)
Tag.filter(name: /^#{name}/).
order(:name).
limit(limit).
all
end
def self.popular_names(limit=10)
DB["select tags.name,count(*) as c from sites_tags inner join tags on tags.id=sites_tags.tag_id where tags.name != '' group by tags.name having count(*) > 1 order by c desc LIMIT ?", limit].all
end
end

View file

@ -771,4 +771,14 @@ a.tag:hover {
}
.selected {
font-weight: bold;
}
.modal-body {
max-height: 800px;
overflow-y: visible;
}
.tt-dropdown-menu {
padding: 0px 10px 0px 10px;
background: #FFFFFF;
}

View file

@ -2009,6 +2009,14 @@ a.tag:hover {
.selected {
font-weight: bold; }
.modal-body {
max-height: 800px;
overflow-y: visible; }
.tt-dropdown-menu {
padding: 0px 10px 0px 10px;
background: #FFFFFF; }
.footer-Base {
color: #5e5b56;
float: left;

View file

@ -841,6 +841,10 @@ a.tag:hover { text-decoration: none; background: #FFEE8A; }
.selected { font-weight: bold; }
.modal-body { max-height: 800px; overflow-y: visible; }
.tt-dropdown-menu { padding: 0px 10px 0px 10px; background: #FFFFFF; }
.footer-Base { color: #5e5b56; float: left; width: 100%; }
.footer-Base h1, .footer-Base h2, .footer-Base h3, .footer-Base h4 { color: #8b9a7a; }

File diff suppressed because it is too large Load diff

View file

@ -29,7 +29,7 @@
A tag can only be a single word, and can only contain letters and numbers.
</p>
<p>Tag:</p>
<input type="text" name="tags">
<input type="text" name="tags" class="typeahead">
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>

View file

@ -4,102 +4,123 @@
}
</script>
<div class="header-Outro">
<div class="row content">
<% if params[:tag] %>
<h1>Sites tagged <%= params[:tag] %>
<% else %>
<h1>Sites on Neocities</h1>
<% end %>
<h3 class="subtitle"></h3>
</div>
<div class="header-Outro">
<div class="row content">
<% if params[:tag] %>
<h1>Sites tagged <%= params[:tag] %>
<% else %>
<h1>Sites on Neocities</h1>
<% end %>
<h3 class="subtitle"></h3>
</div>
</div>
<div class="row content">
<div class="col col-50">
<form id="search_criteria" action="/browse" method="GET">
<fieldset class="grouping">
<% if params[:tag] %>
<input name="tag" type="hidden" value="<%= params[:tag] %>">
<% end %>
<label class="text-Label" for="sort_by">Sort By:</label>
<div class="select-Container">
<select name="sort_by" id="sort_by" class="input-Select">
<option value="last_updated" <%= params[:sort_by] == 'last_updated' ? 'selected' : '' %>>Last Updated</option>
<option value="views" <%= params[:sort_by] == 'views' ? 'selected' : '' %>>Most Views</option>
<option value="hits" <%= params[:sort_by] == 'hits' ? 'selected' : '' %>>Most Hits</option>
<option value="newest" <%= params[:sort_by] == 'newest' ? 'selected' : '' %>>Newest</option>
<option value="oldest" <%= params[:sort_by] == 'oldest' ? 'selected' : '' %>>Oldest</option>
<option value="random" <%= params[:sort_by] == 'random' ? 'selected' : '' %>>Random</option>
</select>
</div>
<!--
<div>
<input name="is_nsfw" type="checkbox" value="true" <%= params[:is_nsfw].to_s == 'true' ? 'checked' : '' %>> Show 18+ content
</div>
-->
<div style="margin-top: 10px">
<input class="btn-Action" type="submit" value="Update">
</div>
</fieldset>
</form>
</div>
<div class="row content">
<div class="col col-50">
<form id="search_criteria" action="/browse" method="GET">
<fieldset class="grouping">
<% if params[:tag] %>
<input name="tag" type="hidden" value="<%= params[:tag] %>">
<% end %>
<label class="text-Label" for="sort_by">Sort By:</label>
<div class="select-Container">
<select name="sort_by" id="sort_by" class="input-Select">
<option value="last_updated" <%= params[:sort_by] == 'last_updated' ? 'selected' : '' %>>Last Updated</option>
<option value="hits" <%= params[:sort_by] == 'hits' ? 'selected' : '' %>>Most Hits</option>
<option value="newest" <%= params[:sort_by] == 'newest' ? 'selected' : '' %>>Newest</option>
<option value="oldest" <%= params[:sort_by] == 'oldest' ? 'selected' : '' %>>Oldest</option>
<option value="random" <%= params[:sort_by] == 'random' ? 'selected' : '' %>>Random</option>
</select>
</div>
<!--
<div>
<input name="is_nsfw" type="checkbox" value="true" <%= params[:is_nsfw].to_s == 'true' ? 'checked' : '' %>> Show 18+ content
</div>
-->
<div style="margin-top: 10px">
<input class="btn-Action" type="submit" value="Update">
</div>
</fieldset>
</form>
</div>
<div class="col col-50">
<p>If you like a site, don't forget to follow it!<br>Visitor counts are updated hourly.</p>
<% unless signed_in? %>
<a class="btn-Action" href="/new" title="create a Neocities.org site today!">Create your Neocities site now</a>
<% end %>
</div>
</div> <!-- end .row.content -->
<br />
<% if @sites.length == 0 %>
<div class="row content single-Col">
<h2>No active sites found.<br>Try another search!</h2>
</div>
<% else %>
<ul class="row website-Gallery content int-Gall">
<% @sites.each do |site| %>
<li>
<a href="//<%= site.host %>" class="neo-Screen-Shot" target="_blank" title="<%= site.title %>">
<span class="img-Holder" style="background:url(<%= site.screenshot_url('index.html', '270x162') %>) no-repeat;">
<img src="/img/placeholder.png" alt="<%= site.title %>" />
</span>
</a>
<div>
<span>
<center><a href="//<%= site.host %>" title="<%= site.title %>"><%= site.title.shorten(35) %></a>
</span>
</div>
<div>
<span style="float: left">
<a href="/site/<%= site.username %>">Profile</a>
</span>
<span style="float: right">
<a href="/site/<%= site.username %>">
<%= site.hits %> hit<%= site.hits == 1 ? '' : 's' %>
</a>
</span>
</div>
</li>
<% end %>
</ul>
<% end %>
<% if params[:sort_by] != 'random' %>
<% if @page_count > 1 %>
<div class="txt-Center content eps">
<% if @current_page != 1 %>
<a href="#" onclick="getPage(<%= @current_page - 1 %>); return false"><i class="icon-arrow-left" style="text-decoration: none"></i></a>&nbsp;
<% end %>
<% 1.upto(@page_count) do |num| %>
<a href="#" onclick="getPage(<%= num %>); return false" style="<%= num == @current_page ? 'text-decoration: none' : '' %>"><%= num %></a>&nbsp;
<% end %>
<% if @current_page != @page_count %>
<a href="#" onclick="getPage(<%= @current_page + 1 %>); return false"><i class="icon-arrow-right" style="text-decoration: none"></i></a>
<% end %>
</div>
<div class="col col-50">
<p>If you like a site, don't forget to follow it!<br>Visitor counts are updated hourly.</p>
<% unless signed_in? %>
<a class="btn-Action" href="/new" title="create a Neocities.org site today!">Create your Neocities site now</a>
<% end %>
</div>
</div> <!-- end .row.content -->
<br />
<% if @sites.length == 0 %>
<div class="row content single-Col">
<h2>No active sites found.<br>Try another search!</h2>
</div>
<% else %>
<ul class="row website-Gallery content int-Gall">
<% @sites.each do |site| %>
<li>
<a href="//<%= site.host %>" class="neo-Screen-Shot" target="_blank" title="<%= site.title %>">
<span class="img-Holder" style="background:url(<%= site.screenshot_url('index.html', '270x162') %>) no-repeat;">
<img src="/img/placeholder.png" alt="<%= site.title %>" />
</span>
</a>
<div>
<span>
<center><a href="//<%= site.host %>" title="<%= site.title %>"><%= site.title.shorten(35) %></a>
</span>
</div>
<div>
<span style="float: left">
<a href="/site/<%= site.username %>">Profile</a>
</span>
<span style="float: right">
<a href="/site/<%= site.username %>">
<%= site.hits %> hit<%= site.hits == 1 ? '' : 's' %>
</a>
</span>
</div>
</li>
<% end %>
</ul>
<% end %>
<% if params[:sort_by] != 'random' %>
<% if @page_count > 1 %>
<div class="txt-Center content eps">
<% if @current_page != 1 %>
<a href="#" onclick="getPage(<%= @current_page - 1 %>); return false"><i class="icon-arrow-left" style="text-decoration: none"></i></a>&nbsp;
<% end %>
<% 1.upto(@page_count) do |num| %>
<a href="#" onclick="getPage(<%= num %>); return false" style="<%= num == @current_page ? 'text-decoration: none' : '' %>"><%= num %></a>&nbsp;
<% end %>
<% if @current_page != @page_count %>
<a href="#" onclick="getPage(<%= @current_page + 1 %>); return false"><i class="icon-arrow-right" style="text-decoration: none"></i></a>
<% end %>
</div>
<% end %>
<% end %>
<div class="row content">
<div class="col col-100">
<h3>
<% Tag.popular_names.each do |tag| %>
<a href="/browse?tag=<%= Rack::Utils.escape tag[:name] %>"><%= tag[:name] %></a>&nbsp;&nbsp;
<% end %>
</h3>
</div>
</div>
<div class="row content">
<div class="col col-20">
<h4>Search by tag:</h4>
<form method="GET" action="browse">
<input class="input-Area typeahead" name="tag" placeholder="pokemon">
<input type="submit" class="btn-Action" value="Search" style="width: 100px">
</form>
</div>
</div>

View file

@ -54,11 +54,31 @@
<script src="/assets/scripts/underscore-min.js"></script>
<script src="/assets/scripts/nav.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
<script src="/js/typeahead.bundle.js"></script>
<script>
$("a#like").tooltip({html: true})
$("a.comment_like").tooltip({html: true})
$('#shareButton').popover({html: true})
$('.typeahead').typeahead({
minLength: 3,
highlight: true
}, {
name: 'tags',
source: function(query, callback) {
$.get('/tags/suggestions/'+query+'.json', function(data) {
console.log(data)
var suggestions = JSON.parse(data)
var suggestionObjects = []
for(var i=0; i<suggestions.length; i++)
suggestionObjects.push({value: suggestions[i]})
callback(suggestionObjects)
})
}
})
</script>
</body>
</html>