Skip to content

Commit

Permalink
Merge branch 'pepf-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Rayman committed Nov 22, 2014
2 parents a09a65f + 2b9ec82 commit a31ecb6
Show file tree
Hide file tree
Showing 4 changed files with 318 additions and 280 deletions.
77 changes: 77 additions & 0 deletions client/components/searchbar/searchbar.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<template name="searchBar">
<div class="row" id="searchArea">
{{#if param 'lovedToggle'}}
<div class="col-md-{{param 'lovedToggleWidth'}}">
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
<span class="glyphicon glyphicon-heart"></span><span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
{{#each lovedSongs}}
<li><a class="loved" href="#">{{this.snippet.title}}</a></li>
{{/each}}
</ul>
</div>
</div>
{{/if}}
<div class="col-md-{{param 'searchBarWidth'}}">
<form class="youtube-search">
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-search"></span></span>
<input type="text" class="form-control youtube-query" placeholder="Search">
<span class="input-group-btn">
<button class="btn btn-default" type="button" data-toggle="clearResults"><span class="glyphicon glyphicon-remove" ></span></button>
</span>
</div>
</form>
</div>
{{#if param 'viewToggle'}}
<div class="col-md-{{param 'viewToggleWidth'}}">
<div class="btn-group">
<button data-action="show-list" type="button" class="btn btn-default {{#if sessionIs 'songView' 'list'}}active{{/if}}"><span class="glyphicon glyphicon-list"></span></button>
<button data-action="show-grid" type="button" class="btn btn-default {{#if sessionIs 'songView' 'grid'}}active{{/if}}"><span class="glyphicon glyphicon-picture"></span></button>
</div>
</div>
{{/if}}
{{> searchResults}}
</div>
{{#if error}}
<div class="alert alert-info alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
{{error}}
</div>
{{/if}}
</template>

<template name="searchResults">
{{#with result}}
<ul class="list-group" id="searchresults">
{{#each items}}
{{> searchResult}}
{{/each}}
</ul>
{{/with}}
</template>

<template name="searchResult">
<li class="youtube-result list-group-item">
<div class="floatleft overlay-container" style="margin-right:20px">
<p class="duration-container">{{formatDuration contentDetails.duration}}</p>
<img src="{{snippet.thumbnails.default.url}}" alt="thumbnail" />
</div>
<div>
<h4 class="list-group-item-heading">{{snippet.title}}</h4>
<button type="submit" id="quickAdd" class="btn btn-primary btn-xs floatright">
<span class="glyphicon glyphicon-plus"></span>
</button>
<button type="submit" id="quickLove" class="btn btn-danger btn-xs floatright">
<span class="glyphicon glyphicon-heart"></span>
</button>
<span class="glyphicon glyphicon-thumbs-up green bold"></span> {{statistics.likeCount}}
<span class="glyphicon glyphicon-thumbs-down red bold"></span> {{statistics.dislikeCount}}
<a rel="external" href="http://youtu.be/{{id}}">
<span class="glyphicon glyphicon-link"></span>
</a>
</div>
</li>
</template>
194 changes: 194 additions & 0 deletions client/components/searchbar/searchbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
// initialize active_tab
Session.set('active_tab', 'songs');

//Initialisation of searchbar component,
// template example:
// {{> searchBar lovedToggle=0 viewToggle=0 collection="Playlists" playlistId=this._id }}
/*--------------------------
Available parameters
collection (Collection) Name of the collection to add objects to, requires extra code in
the add function, or sh*t will hit the fan (default: Playlists)
playlistId (int) pointer to which playlist songs should be added (required)
viewToggle (boolean) show/hide the toggle view buttons (default: show)
lovedToggle (boolean) show/hide the add songs from loved songs button (default: show)
---------------------------*/

Template.searchBar.created = function( template ) {
//debug purposes
var d = Template.currentData() || {}; //at least return an obj
this.collection = (typeof d.playlistId !== "undefined") ? window[d.collection] : window.Playlists;
this.playlistId = (typeof d.playlistId !== "undefined") ? d.playlistId : null;
this.lovedToggle = (typeof d.lovedToggle !== "undefined") ? d.lovedToggle : 1;
this.viewToggle = (typeof d.viewToggle !== "undefined") ? d.viewToggle : 1;


this.lovedToggleWidth = (this.lovedToggle === 1) ? 1 : 0;
this.viewToggleWidth = (this.viewToggle === 1) ? 2 : 0;
this.searchBarWidth = 12 - this.lovedToggleWidth - this.viewToggleWidth;
console.log(this);

};

Template.searchBar.helpers({
isActiveTab: function(route) {
return Session.equals("active_tab", route) ? "active" : "";
},
lovedSongs: function() {
var user = Meteor.user();
if (!user)
return;
return Songs.find({_id: {$in: user.profile.lovedSongs} });
},
//get local template parameters (non-reactive)
param: function(parameter) {
return Template.instance()[parameter] || "";
}
});


Template.searchBar.events = {
'click ul.playlist-tabs > li': function (e) {
var li = $(e.currentTarget);
var route = li.data('id');
Session.set("active_tab", route);
},
'submit form.youtube-search': function (e) {
e.preventDefault();
},
'input input.youtube-query': function (e) {
var input = $(e.currentTarget);
youtubeSearch(input.val());
},
//hide/show results window
'focus input.youtube-query' : function(e) {
var results = $("#searchresults");
if(!results.is(":visible")) {
results.fadeIn('fast');
}
},
'click button[data-toggle="clearResults"]': function(e) {
$("input.youtube-query").val("");
searchResults = null;
searchResultsDependency.changed();
$("input.youtube-query").focus();
},

//add search result to Meteor collection
'click .youtube-result, click a.loved': function(e, template) {

var videoId = (this.id !== undefined) ? this.id : this._id;

//see if search bar is linked up to a collection
if (!template.collection) { console.warn("no collection defined"); return; }
if (!template.playlistId) { console.warn("no collection id defined"); return; }

console.log('queue video:', videoId, 'to playlist', template.playlistId);
$("input.youtube-query").focus();
var songObject = {
"added" : new Date(),
"author" : Meteor.userId(),
"songId" : videoId
};
template.collection.update(
{ _id: template.playlistId},
{ $push: { songs: songObject} }
);
},

//Loved a song!
'click button#quickLove': function(e) {
e.stopPropagation();
console.log("add "+this.snippet.title+" to loved songs");
var user = Meteor.users; //loved songs are stored in users profile
user.update(
{ _id: Meteor.userId() },
{ $addToSet : { 'profile.lovedSongs': this.id.videoId }}
);
},
'click [data-action="show-list"]' : function() {
Session.set("songView","list");
},
'click [data-action="show-grid"]' : function() {
Session.set("songView","grid");
}
};

// Youtube search results
var searchTimer;
var searchDelay = 250; // ms

function youtubeSearch(value) {
clearTimeout(searchTimer);
searchTimer = setTimeout(function() {
if (!value) {
SsearchResults = null;
searchError = 'Please search for something';
searchResultsDependency.changed();
return;
}
console.log('youtube search for:', value);
youtubeSearchQuery({
part: 'id,snippet',
type: 'video',
videoEmbeddable: 'true',
q: value
});
},searchDelay);
}

var searchError;
var searchResults;
var searchResultsDependency = new Deps.Dependency();

youtubeSearchQuery = function(options) {
options = options || {};
var currentSearchTimer = searchTimer;

Meteor.call('youtube_search', options, function(error, data) {
if (error) {
console.log('Youtube search API error:', error);
} else {
console.log('Youtube search API result:', data);
}
searchError = error;
searchResults = data; // TODO: search result data != videoQuery data
searchResultsDependency.changed();

if (currentSearchTimer != searchTimer) {
console.warn('cancel video query');
return;
}

// query for more details (needs optimization)
var ids = _.pluck(_.pluck(data.items, 'id'), 'videoId');
console.log('load more data for ', ids);

youtubeVideoQuery({
'part': 'snippet,contentDetails,statistics',
'id': ids,
});
});
};

youtubeVideoQuery = function(options) {
options = options || {};

Meteor.call('youtube_videos_list', options, function(error, data) {
if (error) {
console.log('Youtube list API error:', error);
} else {
searchResults = data; // TODO: search result data != videoQuery data
searchResultsDependency.changed();
}
});
};

Template.searchResults.result = function() {
Deps.depend(searchResultsDependency);
return searchResults;
};

Template.searchBar.error = function() {
Deps.depend(searchResultsDependency);
return searchError;
};
Loading

0 comments on commit a31ecb6

Please sign in to comment.