Commits

Scott Nixon  committed 291d2a8

Updated tracks to ingredients.

  • Participants

Comments (0)

Files changed (3)

+syntax: glob
+.DS_Store
+.Python
+bin
+include
+lib
+inbounding/settings_development.py
+inbounding/settings_production.py
+*.pyc
+db
+*~
+src
+<!doctype html>
+
+<!--[if lt IE 7]> <html lang="en" class="no-js ie6"> <![endif]-->
+<!--[if IE 7]>    <html lang="en" class="no-js ie7"> <![endif]-->
+<!--[if IE 8]>    <html lang="en" class="no-js ie8"> <![endif]-->
+<!--[if IE 9]>    <html lang="en" class="no-js ie9"> <![endif]-->
+<!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js"> <!--<![endif]-->
+  <head>
+    <meta charset="utf-8">
+
+    <title>Happy Herbivore Recipes</title>
+
+    <link rel="stylesheet" href="style/screen.css" media="screen, projection">
+    <link rel="stylesheet" href="style/fancypants.css" media="screen, projection">
+
+    <script src="js/vendor/modernizr-1.6.min.js"></script>
+    <script src="js/vendor/jquery-1.5.1.min.js"></script>
+    <script src="js/vendor/underscore.js"></script>
+    <script src="js/vendor/backbone.js"></script>
+    <script src="js/recipes.js"></script>
+
+    <script type="text/template" id="library-template">
+      <h1>Recipe Details</h1>
+      <ul class="albums"></ul>
+    </script>
+
+    <script type="text/template" id="playlist-template">
+      <h1>Recipe List</h1>
+      <ul class="albums">
+      </ul>
+    </script>
+
+    <script type="text/template" id="album-template">
+      <button class="queue add"><img src="images/add.png"></button>
+      <button class="queue remove"><img src="images/remove.png"></button>
+      <span class="album-title"><%= recipe_name %></span><!--title -->&nbsp;&nbsp;
+      <span class="artist-name"><%= recipe_description %></span><!--artist -->
+      <ol class="ingredients">
+        <% _.each(ingredients, function(ingredient) { %>
+          <li><%= ingredient.title %></li>
+        <% }); %>
+      </ol>
+    </script>
+
+    <script type="application/javascript">
+      jQuery(function() {
+        window.library.reset([{
+        "featured_items": "0", 
+        "protein": "2.00", 
+        "id": 81, 
+        "recipe_enable_comments": false, 
+        "published_on": "2010-02-07 00:00:00", 
+        "carbohydrates": "23.00", 
+        "sugar": "10.00", 
+        "recipe_name": "Acorn Squash & Apple Soup", 
+        "recipe_date_lastmod": "2011-08-01", 
+        "recipe_description": "<p>Like warm apple pie in a bowl!</p>\r\n<p>Chef's Notes: Any red-skinned apple will do such granny smith, gala or mcintosh. You can also substitute brown sugar for the pure maple syrup.</p>", 
+        "fiber": "2.00", 
+        "recipe_date_create": "2010-02-07", 
+        "recipe_servings": "4.00", 
+        "fat": "0.20", 
+        "cook_time": "20.00", 
+        "calories": "94.00", 
+        "recipe_slug": "acorn-apple-soup", 
+        "prep_time": "10.00", 
+        "recipe_instructions": "<p>Cook whole squash in microwave for 8-10 minutes or until you can stab it with a fork easily. Allow the squash to slightly cool so it is safe to handle. Cut in half, scoop out the seeds and discard. Scoop out the flesh and transfer to a medium saucepan. Add apples, spices and 1 cup water, stirring to mix completely. Bring to a boil over high heat then reduce to low and simmer until apple pieces are very tender, about 15-20 minutes. Transfer to a blender, add non-dairy milk and puree until smooth and creamy. Add syrup and blend again.</p>", 
+        "cookbook": null, 
+        "rec_tags": "Soy-Free Gluten-Free Quick Soups", 
+        "cookbook_page": "",
+        "ingredients": [{
+                "title": "Black Beans",
+                "url": "music/blue.mp3"
+            },
+            {
+                "title": "Smoked Paprika",
+                "url": "music/jazz.mp3"
+            }]
+    }]);
+        // Needed for static-served app
+        window.App.home();
+      });
+    </script>
+  </head>
+
+  <body>
+    <div id="container">
+    </div>
+  </body>
+</html>

File js/recipes.js

+(function($) {
+
+    window.Album = Backbone.Model.extend({
+
+        isFirstTrack: function(index) {
+            return index == 0;
+        },
+
+        isLastTrack: function(index) {
+            return index >= this.get('ingredients').length - 1;
+        },
+
+        trackUrlAtIndex: function(index) {
+            if (this.get('ingredients').length >= index) {
+                return this.get('ingredients')[index].url;
+            }
+            return null;
+        }
+
+    });
+
+    window.Albums = Backbone.Collection.extend({
+        model: Album,
+        url: "/albums"
+    });
+
+    window.Playlist = Albums.extend({
+
+        isFirstAlbum: function(index) {
+            return (index == 0)
+        },
+
+        isLastAlbum: function(index) {
+            return (index == (this.models.length - 1))
+        }
+
+    });
+
+    window.Player = Backbone.Model.extend({
+        defaults: {
+            'currentAlbumIndex': 0,
+            'currentTrackIndex': 0,
+            'state': 'stop'
+        },
+
+        initialize: function() {
+            this.playlist = new Playlist();
+        },
+
+        reset: function() {
+            this.set({
+                'currentAlbumIndex': 0,
+                'currentTrackIndex': 0,
+                'state': 'stop'
+            });
+        },
+
+        play: function() {
+            this.set({
+                'state': 'play'
+            });
+            this.trigger('change:currentTrackIndex');
+            this.logCurrentAlbumAndTrack();
+        },
+
+        pause: function() {
+            this.set({
+                'state': 'pause'
+            });
+        },
+
+        isPlaying: function() {
+            return (this.get('state') == 'play');
+        },
+
+        isStopped: function() {
+            return (!this.isPlaying());
+        },
+
+        currentAlbum: function() {
+            return this.playlist.at(this.get('currentAlbumIndex'));
+        },
+
+        currentTrackUrl: function() {
+            var album = this.currentAlbum();
+            if (album) {
+                return album.trackUrlAtIndex(this.get('currentTrackIndex'));
+            } else {
+                return null;
+            }
+        },
+
+        nextTrack: function() {
+            var currentTrackIndex = this.get('currentTrackIndex'),
+            currentAlbumIndex = this.get('currentAlbumIndex');
+            if (this.currentAlbum().isLastTrack(currentTrackIndex)) {
+                if (this.playlist.isLastAlbum(currentAlbumIndex)) {
+                    this.set({
+                        'currentAlbumIndex': 0
+                    });
+                    this.set({
+                        'currentTrackIndex': 0
+                    });
+                } else {
+                    this.set({
+                        'currentAlbumIndex': currentAlbumIndex + 1
+                    });
+                    this.set({
+                        'currentTrackIndex': 0
+                    });
+                }
+            } else {
+                this.set({
+                    'currentTrackIndex': currentTrackIndex + 1
+                });
+            }
+            this.logCurrentAlbumAndTrack();
+        },
+
+        prevTrack: function() {
+            var currentTrackIndex = this.get('currentTrackIndex'),
+            currentAlbumIndex = this.get('currentAlbumIndex'),
+            lastModelIndex = 0;
+            if (this.currentAlbum().isFirstTrack(currentTrackIndex)) {
+                if (this.playlist.isFirstAlbum(currentAlbumIndex)) {
+                    lastModelIndex = this.playlist.models.length - 1;
+                    this.set({
+                        'currentAlbumIndex': lastModelIndex
+                    });
+                } else {
+                    this.set({
+                        'currentAlbumIndex': currentAlbumIndex - 1
+                    });
+                }
+                // In either case, go to last track on album
+                var lastTrackIndex =
+                this.currentAlbum().get('ingredients').length - 1;
+                this.set({
+                    'currentTrackIndex': lastTrackIndex
+                });
+            } else {
+                this.set({
+                    'currentTrackIndex': currentTrackIndex - 1
+                });
+            }
+            this.logCurrentAlbumAndTrack();
+        },
+
+        logCurrentAlbumAndTrack: function() {
+            console.log("Player " +
+            this.get('currentAlbumIndex') + ':' +
+            this.get('currentTrackIndex'), this);
+        }
+
+    });
+
+    window.library = new Albums();
+    window.player = new Player();
+
+
+    $(document).ready(function() {
+
+        window.AlbumView = Backbone.View.extend({
+            template: _.template($("#album-template").html()),
+            tag: 'li',
+            className: 'album',
+
+            initialize: function() {
+                _.bindAll(this, 'render');
+            },
+
+            render: function() {
+                $(this.el).html(this.template(this.model.toJSON()));
+                return this;
+            }
+        });
+
+        window.PlaylistAlbumView = AlbumView.extend({
+            events: {
+                'click .queue.remove': 'removeFromPlaylist'
+            },
+
+            initialize: function() {
+                _.bindAll(this, 'render',
+                                'updateState',
+                                'updateTrack',
+                                'remove');
+
+                this.player = this.options.player;
+                this.player.bind('change:state', this.updateState);
+                this.player.bind('change:currentTrackIndex', this.updateTrack);
+
+                this.model.bind('remove', this.remove);
+            },
+
+            render: function() {
+                $(this.el).html(this.template(this.model.toJSON()));
+                this.updateTrack();
+                return this;
+            },
+
+            updateState: function() {
+                var isAlbumCurrent = (this.player.currentAlbum() === this.model);
+                $(this.el).toggleClass('current', isAlbumCurrent);
+            },
+
+            updateTrack: function() {
+                var isAlbumCurrent = (this.player.currentAlbum() === this.model);
+                if (isAlbumCurrent) {
+                    var currentTrackIndex = this.player.get('currentTrackIndex');
+                    this.$("li").each(function(index, el) {
+                        $(el).toggleClass('current', index == currentTrackIndex);
+                    });
+                }
+                this.updateState();
+            },
+
+            removeFromPlaylist: function() {
+                this.options.playlist.remove(this.model);
+                this.player.reset();
+            }
+        });
+
+        window.LibraryAlbumView = AlbumView.extend({
+            events: {
+                'click .queue.add': 'select'
+            },
+
+            select: function() {
+                this.collection.trigger('select', this.model);
+            }
+        });
+
+        window.PlaylistView = Backbone.View.extend({
+            tag: 'section',
+            className: 'playlist',
+            template: _.template($("#playlist-template").html()),
+
+            events: {
+                'click .play': 'play',
+                'click .pause': 'pause',
+                'click .next': 'nextTrack',
+                'click .prev': 'prevTrack'
+            },
+
+            initialize: function() {
+                _.bindAll(this, 'render',
+                'renderAlbum',
+                'updateState',
+                'updateTrack',
+                'queueAlbum', 
+                'play', 'pause', 'nextTrack', 'prevTrack');
+
+                this.collection.bind('reset', this.render);
+                this.collection.bind('add', this.renderAlbum);
+
+                // TODO: May need to bind to currentAlbumIndex too
+                this.player = this.options.player;
+                this.player.bind('change:state', this.updateState);
+                this.player.bind('change:currentTrackIndex', this.updateTrack);
+                this.createAudio();
+
+                this.library = this.options.library;
+                this.library.bind('select', this.queueAlbum);
+
+                // HACK: This is required if not being served by a real webserver.
+                $('.play').live('click',  this.play);
+                $('.pause').live('click', this.pause);
+                $('.next').live('click',  this.nextTrack);
+                $('.prev').live('click',  this.prevTrack);
+            },
+
+            createAudio: function() {
+                this.audio = new Audio();
+            },
+
+            render: function() {
+                $(this.el).html(this.template(this.player.toJSON()));
+                this.collection.each(this.renderAlbum);
+
+                this.updateState();
+                return this;
+            },
+
+            renderAlbum: function(album) {
+                var view = new PlaylistAlbumView({
+                    model: album,
+                    player: this.player,
+                    playlist: this.collection
+                });
+                this.$("ul").append(view.render().el);
+            },
+
+            updateState: function() {
+                this.updateTrack();
+                this.$("button.play").toggle(this.player.isStopped());
+                this.$("button.pause").toggle(this.player.isPlaying());
+            },
+
+            updateTrack: function() {
+                this.audio.src = this.player.currentTrackUrl();
+                if (this.player.get('state') == 'play') {
+                    this.audio.play();
+                } else {
+                    this.audio.pause();
+                }
+            },
+
+            queueAlbum: function(album) {
+                this.collection.add(album);
+            },
+
+            play: function() {
+                this.player.play();
+            },
+
+            pause: function() {
+                this.player.pause();
+            },
+
+            nextTrack: function() {
+                this.player.nextTrack();
+            },
+
+            prevTrack: function() {
+                this.player.prevTrack();
+            }
+        });
+
+        window.LibraryView = Backbone.View.extend({
+            tagName: 'section',
+            className: 'library',
+            template: _.template($('#library-template').html()),
+
+            initialize: function() {
+                _.bindAll(this, 'render');
+                this.collection.bind('reset', this.render);
+            },
+
+            render: function() {
+                var $albums,
+                collection = this.collection;
+
+                $(this.el).html(this.template({}));
+                $albums = this.$(".albums");
+                this.collection.each(function(album) {
+                    var view = new LibraryAlbumView({
+                        model: album,
+                        collection: collection
+                    });
+                    $albums.append(view.render().el);
+                });
+
+                return this;
+            }
+        });
+
+        window.BackboneTunes = Backbone.Router.extend({
+            routes: {
+                '': 'home',
+                'blank': 'blank'
+            },
+
+            initialize: function() {
+                this.playlistView = new PlaylistView({
+                    collection: window.player.playlist,
+                    player: window.player,
+                    library: window.library
+                });
+
+                this.libraryView = new LibraryView({
+                    collection: window.library
+                });
+            },
+
+            home: function() {
+                $('#container').empty();
+                $("#container").append(this.playlistView.render().el);
+                $("#container").append(this.libraryView.render().el);
+            },
+
+            blank: function() {
+                $('#container').empty();
+                $('#container').text('blank');
+            }
+        });
+
+        // Kick off the application
+        window.App = new BackboneTunes();
+        Backbone.history.start();
+    });
+
+})(jQuery);
+
+// vim:sw=4:ts=4:expandtab