Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 43 additions & 9 deletions controllers/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,34 +25,68 @@ func NewSearchController(s *myradio.Session, c *structs.Config) *SearchControlle
func (sc *SearchController) Get(w http.ResponseWriter, r *http.Request) {
// Check if they've landed or they've searched
var term = r.URL.Query().Get("term")
var searching = (term != "")
var results []myradio.ShowMeta
var source = r.URL.Query().Get("source")

var errorMsg string
var searching = len(term) != 0
var validSearch = true

if len(term) < 3 {
errorMsg = "Your search term is too short. Try using more keywords."
validSearch = false
}

var showResults []myradio.ShowMeta
var podcastResults []myradio.Podcast
var peopleResults []myradio.UserSearch

var err error

if searching {
if validSearch {
// Contact the DB and get search results
sm := models.NewSearchModel(sc.session)

results, err = sm.Get(term)
switch source {
default:
source = "show"
showResults, err = sm.GetShows(term)
case "podcast":
podcastResults, err = sm.GetPodcasts(term)
case "show":
showResults, err = sm.GetShows(term)
// Sadly the people endpoint doesn't return just public users yet.
//case "people":
// peopleResults, err = sm.GetUsers(term)
}

if err != nil {
log.Println(err)
return
}
}

// TODO Need to filter for unpublished podcasts/shows/people somehow!
var numResults = len(showResults) + len(podcastResults) + len(peopleResults)
data := struct {
Searching bool
Results []myradio.ShowMeta
Searching bool
Source string
ShowResults []myradio.ShowMeta
PodcastResults []myradio.Podcast
//PeopleResults []myradio.UserSearch
NumResults int
BaseURL string
Term string
ErrorMsg string
}{
Searching: searching,
Results: results,
NumResults: len(results),
Searching: searching,
Source: source,
ShowResults: showResults,
PodcastResults: podcastResults,
//PeopleResults: peopleResults,
NumResults: numResults,
BaseURL: r.URL.Path,
Term: term,
ErrorMsg: errorMsg,
}

err = utils.RenderTemplate(w, sc.config.PageContext, data, "search.tmpl")
Expand Down
26 changes: 24 additions & 2 deletions models/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,35 @@ func NewSearchModel(s *myradio.Session) *SearchModel {
return &SearchModel{Model{session: s}}
}

// Get gets the data required for the Search controller from MyRadio.
// GetShows gets the data required for the Search controller from MyRadio.
//
// term is the string term to search for. This is currently a show
// search.
//
// On success, it returns the search results, and nil.
// Otherwise, it returns undefined data and the error causing failure.
func (m *SearchModel) Get(term string) ([]myradio.ShowMeta, error) {
func (m *SearchModel) GetShows(term string) ([]myradio.ShowMeta, error) {
return m.session.GetSearchMeta(term)
}

// GetPodcasts gets the data required for the Search controller from MyRadio.
//
// term is the string term to search for. This is currently a podcast
// search.
//
// On success, it returns the search results, and nil.
// Otherwise, it returns undefined data and the error causing failure.
func (m *SearchModel) GetPodcasts(term string) ([]myradio.Podcast, error) {
return m.session.GetPodcastMeta(term)
}

// GetUsers gets the data required for the Search controller from MyRadio.
//
// term is the string term to search for. This is currently a user
// search.
//
// On success, it returns the search results, and nil.
// Otherwise, it returns undefined data and the error causing failure.
func (m *SearchModel) GetUsers(term string) ([]myradio.UserSearch, error) {
return m.session.GetUserMeta(term)
}
7 changes: 7 additions & 0 deletions public/js/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
let form = document.getElementById("searchForm");
let filters = document.getElementsByClassName("search-filter")
for (var i = 0; i < filters.length; i++) {
filters[i].addEventListener("click", function () {
form.submit();
});
};
23 changes: 23 additions & 0 deletions sass/base/_searchBox.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ $search-background: rgb(255, 255, 255);
margin-top: auto;
width: auto;


input {
background: none;
border: 0;
Expand All @@ -22,6 +23,7 @@ $search-background: rgb(255, 255, 255);
padding-left: 0;
padding-right: .5em;
width: 100%;
float: left;

&:focus {
outline: none;
Expand All @@ -30,6 +32,27 @@ $search-background: rgb(255, 255, 255);
}
}

input[type="radio"] {
display: none;
}
.source-group {
position: absolute;
top: -4px;
right: 1px;
background: $off-white-color;
border-radius: 45px;
padding: 0 15px;
label {
display: inline-block;
padding: 0 5px;
font-size: 0.8em;
vertical-align: text-top;
}
input:checked + label {
color: $blue;
}

}
button {
color: $search-button-color;
border: 0;
Expand Down
143 changes: 125 additions & 18 deletions views/search.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,130 @@
{{define "content"}}
{{with .PageData}}

<div class="container container-padded pt-5 mt-5">
<form action="{{url "/search/"}}" class="form-inline ml-auto search-box" style="font-size:2rem;">
<button type="submit" class="" alt="Submit"><i class="fa fa-search" aria-hidden="true"></i></button>
<div class="col px-0">
<input type="text" name="term" placeholder="Search..." value="{{.Term}}" width="100%">
<div class="container-fluid on-demand">
<div class="container container-padded">
<div class="row align-items-end text-center">
<div class="col">
<h1 class="display-5 header-title">
Past. Present. Future. #Content.
<br>
<span class="display-3">
Find it on {{$.PageContext.ShortName }}.
</span>
</h1>
<form id="searchForm" action="{{url "/search/"}}" class="mt-5 form-inline ml-auto search-box" style="font-size:2rem;">
<button type="submit" class="" alt="Submit"><i class="fa fa-search" aria-hidden="true"></i></button>
<div class="col px-0">
<input type="text" name="term" placeholder="Search..." value="{{.Term}}" width="100%">

<div class="source-group bg-dark">
<input type="radio" id="sourceShows" name="source" class="search-filter" value="show" {{if eq .Source "show"}}checked{{end}}>
<label for="sourceShows">Shows</label>
<input type="radio" id="sourcePodcasts" name="source" class="search-filter" value="podcast" {{if eq .Source "podcast"}}checked{{end}}>
<label for="sourcePodcasts">Podcasts</label>
</div>
</div>
</form>
</div>
</div>
</div>
</div>

{{if .Searching}}
<div class="container-fluid container-padded {{if eq .Source "show"}}bg-primary{{else if eq .Source "podcast"}}bg-podcasts{{end}}">
<div class="container container-padded py-3">
<div class="row">
<div class="col-12 col-sm-8">
<h2>
<span class="text-muted">Searching for...</span>
<br>
{{if eq .Source "show"}}
<span class="display-4">Shows</span>
{{else if eq .Source "podcast"}}
<span class="display-4">Podcasts</span>
{{end}}
</h2>
</div>
<div class="col-12 col-sm-4">
{{if eq .Source "show"}}
<div class="text-right">
<span class="h3 text-muted">Want something new?</span>
<br>
<a href="/ontap" class="btn btn-lg btn-primary mt-3" title="New On-Demand Content">New Shows</a>
</div>
{{else if eq .Source "podcast"}}
<div class="text-right">
<span class="h3 text-muted">Want something new?</span>
<br>
<a href="/podcasts" class="btn btn-lg btn-primary mt-3" title="All/Latest Podcasts">Latest Podcasts</a>
</div>
{{end}}
</div>
</div>
</form>
</div>
</div>
{{end}}

<div class="container container-padded mt-2">
{{if .Searching}}
<div class="pt-3" style="text-align: right;">{{.NumResults}} Results</div>
<span>Top Results</span>
<hr>
{{range .Results}}
<h5>
<a href="/schedule/shows/{{.ShowID}}/">{{.Title}}</a>
</h5>
{{html .Description}}
<hr>
{{else}}
<p>
No Results
</p>
{{end}}
{{if eq .Source "show"}}
{{range .ShowResults}}
<div class="row">
<div class="mobile-hide col-12 col-md-3 col-lg-2">
<img class="img-fluid" src='
{{if .Photo}}
{{$.PageContext.FullURL}}{{.Photo}}
{{else}}
{{url "/images/default_show_profile.png"}}
{{end}}
' alt="{{.Title}} Logo">
</div>
<div class="col-12 col-md-9 col-lg-10">
<h4>
<a href="{{.MicroSiteLink.URL}}/">{{.Title}}</a>
</h4>
<h5>
{{.CreditsString}}
</h5>
<p class="ellipsis">{{html .Description}}</p>
</div>
</div>
<hr>
{{end}}
{{else if eq .Source "podcast"}}
{{range .PodcastResults}}
<div class="row">
<div class="mobile-hide col-12 col-md-3 col-lg-2">
<img class="img-fluid" src='
{{if .Photo}}
{{$.PageContext.FullURL}}{{.Photo}}
{{else}}
{{url "/images/default_show_profile.png"}}
{{end}}
' alt="{{.Title}} Logo">
</div>
<div class="col-12 col-md-9 col-lg-10">
<h4>
<a href="{{.MicrositeLink.URL}}/">{{.Title}}</a>
</h4>
<span class="h4">
{{.Time.Format "Monday, _2 Jan 2006"}}
</span>
<p class="ellipsis">{{html .Description}}</p>
</div>
</div>
<hr>
{{end}}
{{end}}
{{if gt (len .ErrorMsg) 0}}
<div class="alert mt-5 alert-warning">{{.ErrorMsg}}</div>
{{else if eq .NumResults 0}}
<h4 class="display-5 text-center m-5">
No search results. Please try a different search term.
</h4>
{{end}}

{{else}}
{{end}}
Expand All @@ -31,3 +134,7 @@

{{end}}
{{end}}

{{define "footer-scripts"}}
<script src='{{url "/js/search.js"}}?ver={{ .PageContext.CacheBuster }}'></script>
{{end}}