diff --git a/app/controllers/microposts_controller.rb b/app/controllers/microposts_controller.rb index ff6b55e..be14e14 100644 --- a/app/controllers/microposts_controller.rb +++ b/app/controllers/microposts_controller.rb @@ -19,6 +19,12 @@ def create @track.session_name = Track.get_session_name(content) @track.name = Track.get_name(content, @track) @track.save + elsif Picture.is_picture_upload_post? content + @picture = Picture.new(params[:micropost][:picture]) + success_message = "Picture uploaded!" + @picture.session_name = Picture.get_session_name(content) + @picture.name = Picture.get_name(content, @picture) + @picture.save end params[:micropost][:content] = params[:micropost][:content][0..136] + '...' diff --git a/app/controllers/pictures_controller.rb b/app/controllers/pictures_controller.rb new file mode 100644 index 0000000..1da4b4d --- /dev/null +++ b/app/controllers/pictures_controller.rb @@ -0,0 +1,9 @@ +class PicturesController < ApplicationController + + def index + @pictures = Picture.all.shuffle + + render :index, :layout => 'g_application' + end + +end \ No newline at end of file diff --git a/app/controllers/tracks_controller.rb b/app/controllers/tracks_controller.rb index 7e4de0c..e87524d 100644 --- a/app/controllers/tracks_controller.rb +++ b/app/controllers/tracks_controller.rb @@ -18,4 +18,16 @@ def frontpage track.toggle!(:frontpage) redirect_to :tracks end + + def makepublic + track = Track.find(params[:id]) + track.toggle!(:public) + redirect_to :tracks + end + + def makeprivate + track = Track.find(params[:id]) + track.toggle!(:public) + redirect_to :tracks + end end diff --git a/app/helpers/tracks_helper.rb b/app/helpers/tracks_helper.rb index 4769c0f..9a10de4 100644 --- a/app/helpers/tracks_helper.rb +++ b/app/helpers/tracks_helper.rb @@ -1,2 +1,13 @@ module TracksHelper + + def get_track_status_action(track) + if not signed_in? then + return + end + if(track.public) + link_to "make private", tracks_private_path(track.id) + else + link_to "make public", tracks_public_path(track.id) + end + end end diff --git a/app/models/micropost.rb b/app/models/micropost.rb index e45508a..8fc5a80 100644 --- a/app/models/micropost.rb +++ b/app/models/micropost.rb @@ -26,6 +26,10 @@ class Micropost < ActiveRecord::Base def track @track || (@track = Track.new) end + + def picture + @picture || (@picture = Picture.new) + end private diff --git a/app/models/picture.rb b/app/models/picture.rb new file mode 100644 index 0000000..479a8c6 --- /dev/null +++ b/app/models/picture.rb @@ -0,0 +1,30 @@ +class Picture < ActiveRecord::Base + has_attached_file :image, + :storage => :s3, + :s3_credentials => "#{RAILS_ROOT}/config/s3.yml", + :path => 'images/:session_name/:basename.:extension', + :bucket => 'chriserin_paperclip_test' + + + class << self + def is_picture_upload_post?(post) + post =~ /^picture\supload/i + end + + def get_name(post, track) + if(post =~/n=(\w.*)/i) + $1.split(" ")[0] + else + post.split(" ")[2].split('.')[0] + end + end + + def get_session_name(post) + if(post =~/s=(\w.*)/i) + $1 + else + Date.today.strftime('%d%b%y') + end + end + end +end diff --git a/app/views/layouts/g_application.html.erb b/app/views/layouts/g_application.html.erb index 7acd9b6..769cab9 100644 --- a/app/views/layouts/g_application.html.erb +++ b/app/views/layouts/g_application.html.erb @@ -5,7 +5,8 @@ <%= csrf_meta_tag %> <%= render 'layouts/g_stylesheets' %> <%= javascript_include_tag :defaults %> - <%= javascript_include_tag 'jquery.jplayer.min' %> + <%= javascript_include_tag 'jquery.jplayer.min' %> + <%= javascript_include_tag 'jquery.masonry' %>
diff --git a/app/views/pictures/index.html.erb b/app/views/pictures/index.html.erb new file mode 100644 index 0000000..01c43c3 --- /dev/null +++ b/app/views/pictures/index.html.erb @@ -0,0 +1,15 @@ +This is the pictures index. + +
+<% @pictures.each do |picture| %> + <%= image_tag picture.image.url %> +<% end %> +
+ + \ No newline at end of file diff --git a/app/views/shared/_micropost_form.html.erb b/app/views/shared/_micropost_form.html.erb index 5fc1695..9d85852 100644 --- a/app/views/shared/_micropost_form.html.erb +++ b/app/views/shared/_micropost_form.html.erb @@ -10,5 +10,10 @@
<%= track_form.file_field :recording %>
+ <% end %> + <%= f.fields_for @micropost.picture do |picture_form| %> +
+ <%= picture_form.file_field :image %> +
<% end %> <% end %> \ No newline at end of file diff --git a/app/views/tracks/_track.html.erb b/app/views/tracks/_track.html.erb index 70dfd3c..ebe3cf5 100644 --- a/app/views/tracks/_track.html.erb +++ b/app/views/tracks/_track.html.erb @@ -1,5 +1,8 @@ + <% if signed_in? or track.public? %> <%= div_for track do %> <%= link_to track.name, track.recording.url, :class => 'audio_link', :id => track.id %> play - <%= link_to 'frontpage', tracks_frontpage_path(track.id) %> - <% end %> \ No newline at end of file + <%= link_to 'frontpage', tracks_frontpage_path(track.id) unless not signed_in? %> + <%= get_track_status_action(track) %> + <% end %> + <% end %> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index db8f7eb..dbfb51f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,13 +12,16 @@ resources :microposts, :only => [:create, :destroy] resources :relationships, :only => [:create, :destroy] resources :tracks, :only => [:index] + resources :pictures, :only => [:index] root :to => "geronimo#index" match "/myspace" => redirect("http://www.myspace.com/thegeronimoband") match "/facebook" => redirect("http://www.facebook.com/thegeronimoband") - match '/tracks/:id/frontpage', :to => 'tracks#frontpage', :as => 'tracks_frontpage' + match '/tracks/:id/frontpage', :to => 'tracks#frontpage', :as => 'tracks_frontpage' + match '/tracks/:id/makepublic', :to => 'tracks#makepublic', :as => 'tracks_public' + match '/tracks/:id/makeprivate', :to => 'tracks#makeprivate', :as => 'tracks_private' match '/everything', :to => 'geronimo#everything' match '/blogs', :to => 'geronimo#blogs' match '/all_shows', :to => 'geronimo#shows' @@ -29,61 +32,4 @@ match '/signin', :to => 'sessions#new' match '/signout', :to => 'sessions#destroy' match '/home', :to => 'pages#home' - - # The priority is based upon order of creation: - # first created -> highest priority. - - # Sample of regular route: - # match 'products/:id' => 'catalog#view' - # Keep in mind you can assign values other than :controller and :action - - # Sample of named route: - # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase - # This route can be invoked with purchase_url(:id => product.id) - - # Sample resource route (maps HTTP verbs to controller actions automatically): - # resources :products - - # Sample resource route with options: - # resources :products do - # member do - # get :short - # post :toggle - # end - # - # collection do - # get :sold - # end - # end - - # Sample resource route with sub-resources: - # resources :products do - # resources :comments, :sales - # resource :seller - # end - - # Sample resource route with more complex sub-resources - # resources :products do - # resources :comments - # resources :sales do - # get :recent, :on => :collection - # end - # end - - # Sample resource route within a namespace: - # namespace :admin do - # # Directs /admin/products/* to Admin::ProductsController - # # (app/controllers/admin/products_controller.rb) - # resources :products - # end - - # You can have the root of your site routed with "root" - # just remember to delete public/index.html. - # root :to => "welcome#index" - - # See how all your routes lay out with "rake routes" - - # This is a legacy wild controller route that's not recommended for RESTful applications. - # Note: This route will make all actions in every controller accessible via GET requests. - # match ':controller(/:action(/:id(.:format)))' end diff --git a/db/migrate/20110407224907_add_public_to_track.rb b/db/migrate/20110407224907_add_public_to_track.rb new file mode 100644 index 0000000..8c1be76 --- /dev/null +++ b/db/migrate/20110407224907_add_public_to_track.rb @@ -0,0 +1,9 @@ +class AddPublicToTrack < ActiveRecord::Migration + def self.up + add_column :tracks, :public, :boolean + end + + def self.down + remove_column :tracks, :public + end +end diff --git a/db/migrate/20110503191359_create_pictures.rb b/db/migrate/20110503191359_create_pictures.rb new file mode 100644 index 0000000..0cd70b2 --- /dev/null +++ b/db/migrate/20110503191359_create_pictures.rb @@ -0,0 +1,17 @@ +class CreatePictures < ActiveRecord::Migration + def self.up + create_table :pictures do |t| + t.string :image_file_name + t.string :image_content_type + t.integer :image_file_size + t.datetime :image_updated_at + t.string :session_name + t.string :name + t.timestamps + end + end + + def self.down + drop_table :pictures + end +end diff --git a/db/schema.rb b/db/schema.rb index fd96014..3cfbb24 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20110224030948) do +ActiveRecord::Schema.define(:version => 20110503191359) do create_table "blogs", :force => true do |t| t.integer "user_id" @@ -31,6 +31,17 @@ add_index "microposts", ["user_id"], :name => "index_microposts_on_user_id" + create_table "pictures", :force => true do |t| + t.string "image_file_name" + t.string "image_content_type" + t.integer "image_file_size" + t.datetime "image_updated_at" + t.string "session_name" + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "relationships", :force => true do |t| t.integer "follower_id" t.integer "followed_id" @@ -59,6 +70,7 @@ t.string "session_name" t.string "name" t.boolean "frontpage", :default => false + t.boolean "public" end create_table "users", :force => true do |t| diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 58ffc7b..4ef244a 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -4,9 +4,15 @@ $(function(){ $("#micropost_content").keypress(function(e){ if($("#micropost_content").val() == 'track upload') { - $("#micropost_track_recording").click(); + document.getElementById("micropost_track_recording").click(); $("#track_chooser").css("z-index", 1); } + + if($("#micropost_content").val() == 'picture upload') + { + document.getElementById("micropost_picture_image").click(); + $("#picture_chooser").css("z-index", 1); + } }); $("#micropost_track_recording").bind('change', function(e) @@ -16,10 +22,22 @@ $(function(){ { filename = filename.split(/\\/)[2]; } - + $("#micropost_content").val($("#micropost_content").val() + filename); $("#track_chooser").css("z-index", -1); }); + + $("#micropost_picture_image").bind('change', function(e) + { + var filename = $("#micropost_picture_image").val(); + if(filename.search(/\\/) > 0) + { + filename = filename.split(/\\/)[2]; + } + + $("#micropost_content").val($("#micropost_content").val() + filename); + $("#picture_chooser").css("z-index", -1); + }); $(".play_button").bind('click', function(e){ diff --git a/public/javascripts/jquery.masonry.js b/public/javascripts/jquery.masonry.js new file mode 100644 index 0000000..e127b3a --- /dev/null +++ b/public/javascripts/jquery.masonry.js @@ -0,0 +1,298 @@ +/************************************************* +** jQuery Masonry version 1.3.2 +** Copyright David DeSandro, licensed MIT +** http://desandro.com/resources/jquery-masonry +**************************************************/ +;(function($){ + + /*! + * smartresize: debounced resize event for jQuery + * http://github.com/lrbabe/jquery-smartresize + * + * Copyright (c) 2009 Louis-Remi Babe + * Licensed under the GPL license. + * http://docs.jquery.com/License + * + */ + var event = $.event, + resizeTimeout; + + event.special.smartresize = { + setup: function() { + $(this).bind( "resize", event.special.smartresize.handler ); + }, + teardown: function() { + $(this).unbind( "resize", event.special.smartresize.handler ); + }, + handler: function( event, execAsap ) { + // Save the context + var context = this, + args = arguments; + + // set correct event type + event.type = "smartresize"; + + if (resizeTimeout) { clearTimeout(resizeTimeout); } + resizeTimeout = setTimeout(function() { + jQuery.event.handle.apply( context, args ); + }, execAsap === "execAsap"? 0 : 100); + } + }; + + $.fn.smartresize = function( fn ) { + return fn ? this.bind( "smartresize", fn ) : this.trigger( "smartresize", ["execAsap"] ); + }; + + + + // masonry code begin + $.fn.masonry = function(options, callback) { + + // all my sweet methods + var msnry = { + getBricks : function($wall, props, opts) { + var hasItemSelector = (opts.itemSelector === undefined); + if ( opts.appendedContent === undefined ) { + // if not appendedContent + props.$bricks = hasItemSelector ? + $wall.children() : + $wall.find(opts.itemSelector); + } else { + // if appendedContent... + props.$bricks = hasItemSelector ? + opts.appendedContent : + opts.appendedContent.filter( opts.itemSelector ); + } + }, + + placeBrick : function($brick, setCount, setY, props, opts) { + // get the minimum Y value from the columns... + var minimumY = Math.min.apply(Math, setY), + setHeight = minimumY + $brick.outerHeight(true), + i = setY.length, + shortCol = i, + setSpan = props.colCount + 1 - i; + // Which column has the minY value, closest to the left + while (i--) { + if ( setY[i] == minimumY ) { + shortCol = i; + } + } + + var position = { + left: props.colW * shortCol + props.posLeft, + top: minimumY + }; + + // position the brick + $brick.applyStyle(position, $.extend(true,{},opts.animationOptions) ); + + // apply setHeight to necessary columns + for ( i=0; i < setSpan; i++ ) { + props.colY[ shortCol + i ] = setHeight; + } + }, + + setup : function($wall, opts, props) { + msnry.getBricks($wall, props, opts); + + if ( props.masoned ) { + props.previousData = $wall.data('masonry'); + } + + if ( opts.columnWidth === undefined) { + props.colW = props.masoned ? + props.previousData.colW : + props.$bricks.outerWidth(true); + } else { + props.colW = opts.columnWidth; + } + + props.colCount = Math.floor( $wall.width() / props.colW ) ; + props.colCount = Math.max( props.colCount, 1 ); + }, + + arrange : function($wall, opts, props) { + var i; + + if ( !props.masoned || opts.appendedContent !== undefined ) { + // just the new bricks + props.$bricks.css( 'position', 'absolute' ); + } + + // if masonry hasn't been called before + if ( !props.masoned ) { + $wall.css( 'position', 'relative' ); + + // get top left position of where the bricks should be + var $cursor = $( document.createElement('div') ); + $wall.prepend( $cursor ); + props.posTop = Math.round( $cursor.position().top ); + props.posLeft = Math.round( $cursor.position().left ); + $cursor.remove(); + } else { + props.posTop = props.previousData.posTop; + props.posLeft = props.previousData.posLeft; + } + + // set up column Y array + if ( props.masoned && opts.appendedContent !== undefined ) { + // if appendedContent is set, use colY from last call + props.colY = props.previousData.colY; + + /* + * in the case that the wall is not resizeable, + * but the colCount has changed from the previous time + * masonry has been called + */ + for ( i = props.previousData.colCount; i < props.colCount; i++) { + props.colY[i] = props.posTop; + } + + } else { + // start new colY array, with starting values set to posTop + props.colY = []; + i = props.colCount; + while (i--) { + props.colY.push(props.posTop); + } + } + + // are we animating the rearrangement? + // use plugin-ish syntax for css or animate + $.fn.applyStyle = ( props.masoned && opts.animate ) ? $.fn.animate : $.fn.css; + + + // layout logic + if ( opts.singleMode ) { + props.$bricks.each(function(){ + var $brick = $(this); + msnry.placeBrick($brick, props.colCount, props.colY, props, opts); + }); + } else { + props.$bricks.each(function() { + var $brick = $(this), + //how many columns does this brick span + colSpan = Math.ceil( $brick.outerWidth(true) / props.colW); + colSpan = Math.min( colSpan, props.colCount ); + + if ( colSpan === 1 ) { + // if brick spans only one column, just like singleMode + msnry.placeBrick($brick, props.colCount, props.colY, props, opts); + } else { + // brick spans more than one column + + //how many different places could this brick fit horizontally + var groupCount = props.colCount + 1 - colSpan, + groupY = []; + + // for each group potential horizontal position + for ( i=0; i < groupCount; i++ ) { + // make an array of colY values for that one group + var groupColY = props.colY.slice(i, i+colSpan); + // and get the max value of the array + groupY[i] = Math.max.apply(Math, groupColY); + } + + msnry.placeBrick($brick, groupCount, groupY, props, opts); + } + }); // /props.bricks.each(function() { + } // /layout logic + + // set the height of the wall to the tallest column + props.wallH = Math.max.apply(Math, props.colY); + var wallCSS = { height: props.wallH - props.posTop }; + $wall.applyStyle( wallCSS, $.extend(true,[],opts.animationOptions) ); + + // add masoned class first time around + if ( !props.masoned ) { + // wait 1 millisec for quell transitions + setTimeout(function(){ + $wall.addClass('masoned'); + }, 1); + } + + // provide props.bricks as context for the callback + callback.call( props.$bricks ); + + // set all data so we can retrieve it for appended appendedContent + // or anyone else's crazy jquery fun + $wall.data('masonry', props ); + + }, // /msnry.arrange + + resize : function($wall, opts, props) { + props.masoned = !!$wall.data('masonry'); + var prevColCount = $wall.data('masonry').colCount; + msnry.setup($wall, opts, props); + if ( props.colCount != prevColCount ) { + msnry.arrange($wall, opts, props); + } + } + }; + + + /* + * let's begin + * IN A WORLD... + */ + return this.each(function() { + + var $wall = $(this), + props = {}; + + // checks if masonry has been called before on this object + props.masoned = !!$wall.data('masonry'); + + var previousOptions = props.masoned ? $wall.data('masonry').options : {}, + opts = $.extend( + {}, + $.fn.masonry.defaults, + previousOptions, + options + ), + resizeOn = previousOptions.resizeable; + + // should we save these options for next time? + props.options = opts.saveOptions ? opts : previousOptions; + + //picked up from Paul Irish + callback = callback || function(){}; + + msnry.getBricks($wall, props, opts); + + // if brickParent is empty, do nothing, go back home and eat chips + if ( !props.$bricks.length ) { + return this; + } + + // call masonry layout + msnry.setup($wall, opts, props); + msnry.arrange($wall, opts, props); + + // binding window resizing + if ( !resizeOn && opts.resizeable ) { + $(window).bind('smartresize.masonry', function() { msnry.resize($wall, opts, props); } ); + } + if ( resizeOn && !opts.resizeable ) { + $(window).unbind('smartresize.masonry'); + } + + + }); // /return this.each(function() + }; // /$.fn.masonry = function(options) + + + // Default plugin options + $.fn.masonry.defaults = { + singleMode: false, + columnWidth: undefined, + itemSelector: undefined, + appendedContent: undefined, + saveOptions: true, + resizeable: true, + animate: false, + animationOptions: {} + }; + +})(jQuery); \ No newline at end of file diff --git a/public/stylesheets/custom.css b/public/stylesheets/custom.css index bbcb1da..6c40105 100644 --- a/public/stylesheets/custom.css +++ b/public/stylesheets/custom.css @@ -253,4 +253,13 @@ form.new_micropost textarea { position: relative; z-index: -1; margin-top: -80px; -} \ No newline at end of file + margin-bottom: 80px; +} + +#picture_chooser +{ + position: relative; + z-index: -1; + margin-top: -100px; + margin-bottom: 100px; +} diff --git a/public/stylesheets/geronimo.css b/public/stylesheets/geronimo.css index 1b9945d..2ecf5b5 100644 --- a/public/stylesheets/geronimo.css +++ b/public/stylesheets/geronimo.css @@ -297,4 +297,5 @@ nav ul li a:hover { { margin-top: 4px; margin-bottom: 4px; -} \ No newline at end of file +} + diff --git a/public/stylesheets/your_band.css b/public/stylesheets/your_band.css index daffbf7..3b67217 100644 --- a/public/stylesheets/your_band.css +++ b/public/stylesheets/your_band.css @@ -8,4 +8,17 @@ audio background-color: blue; border-style: solid; border-width: 5px; +} + +img +{ + margin: 10px; + -moz-box-shadow: 0 0 20px 5px green; + -webkit-box-shadow: 0 0 20px 5px green; + box-shadow: 0 0 20px 5px green; +} + +body +{ + background-color: red; } \ No newline at end of file diff --git a/spec/models/picture_spec.rb b/spec/models/picture_spec.rb new file mode 100644 index 0000000..5ef8eea --- /dev/null +++ b/spec/models/picture_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Picture do + pending "add some examples to (or delete) #{__FILE__}" +end