Permalink
Browse files

Following. Complete.

  • Loading branch information...
1 parent 6473b41 commit 3b8f15cd37ada10c54b24296b29c8e40ed7e6659 @sudara sudara committed Jan 5, 2009
@@ -80,6 +80,9 @@ def latest
@tab = 'home'
@welcome = true unless logged_in?
@feature = Feature.published.first
+ if logged_in? and current_user.has_followees?
+ @followee_tracks = current_user.new_tracks_from_followees(5)
+ end
end
wants.rss do
@assets = Asset.latest(50)
@@ -6,7 +6,7 @@ class UsersController < ApplicationController
before_filter :login_required, :except => [:index, :show, :new, :create, :activate, :bio]
skip_before_filter :login_by_token, :only => :sudo
- rescue_from NoMethodError, :with => :user_not_found
+ #rescue_from NoMethodError, :with => :user_not_found
def index
@page_title = "#{params[:sort] ? params[:sort].titleize+' - ' : ''} Musicians and Listeners"
@@ -169,6 +169,11 @@ def toggle_favorite
end
render :nothing => true
end
+
+ def toggle_follow
+ current_user.add_or_remove_followee(params[:followee_id])
+ render :nothing => true
+ end
def destroy
return unless admin?
@@ -48,10 +48,18 @@ def setting(symbol_or_string, user=current_user)
def favorite_toggle(asset)
return unless logged_in?
is_favorite = current_user.has_as_favorite?(asset)
- link_to((is_favorite ? 'remove from favorites' : 'add to favorites'), toggle_favorite_user_path(current_user, :asset_id => asset.id),
+ link_to((is_favorite ? 'remove from favorites' : 'add to favorites'),
+ toggle_favorite_user_path(current_user, :asset_id => asset.id),
:class => 'add_to_favorites '+(is_favorite ? 'favorited' : ''))
end
+ def follow_toggle(user)
+ return unless logged_in? and user.id != current_user.id
+ is_favorite = current_user.is_following?(user)
+ link_to ' ', toggle_follow_user_path(current_user, :followee_id => user.id),
+ :class => 'follow '+(is_favorite ? 'following' : '')
+ end
+
def new_to_user?(thing)
thing && (logged_in? and current_user.last_session_at) && (current_user.last_session_at < thing.created_at.utc)
end
View
@@ -96,7 +96,7 @@ def self.conditions_by_like(value, *columns)
end
def self.latest(limit=10)
- find(:all, :include => [:user], :limit => limit, :order => 'assets.created_at DESC')
+ find(:all, :include => [{:user => :pic}, :first_playlist], :limit => limit, :order => 'assets.created_at DESC')
end
# needed for views in case we've got multiple assets on the same page
View
@@ -0,0 +1,32 @@
+class AssetMailer < ActionMailer::Base
+
+
+ def upload_notification(asset, emails, sent_at = Time.now)
+ subject "[alonetone] '#{asset.user.name}' uploaded a new track!"
+ recipients ''
+ from 'noreply@alonetone.com'
+ bcc emails.join(', ')
+ sent_on sent_at
+ body :track => asset.name,
+ :name => asset.user.name,
+ :download_link => download_link_for(asset),
+ :play_link => play_link_for(asset),
+ :user_link => user_link_for(asset),
+ :exclamation => ["Sweet", "Yes", "Oooooh", "Alright", "Booya", "Yum","Celebrate", "OMG"]
+ end
+
+ protected
+
+ def user_link_for(asset)
+ 'http://' + ALONETONE.url + '/' + asset.user.login
+ end
+
+ def play_link_for(asset)
+ user_link_for(asset) + '/tracks/' + asset.id.to_s
+ end
+
+ def download_link_for(asset)
+ play_link_for(asset) + '.mp3?source=email'
+ end
+
+end
@@ -0,0 +1,29 @@
+class AssetObserver < ActiveRecord::Observer
+ def after_create(asset)
+ if followers_exist_for?(asset)
+ AssetMailer.deliver_upload_notification(asset,emails_of_followers(asset))
+ end
+ end
+
+ protected
+
+ def followers_exist_for?(asset)
+ emails_of_followers(asset).size > 0
+ end
+
+ def emails_of_followers(asset)
+ followers_of(asset).inject([]) do |emails, follower|
+ emails << follower.email if user_wants_email?(follower)
+ emails
+ end
+ end
+
+ def followers_of(asset)
+ asset.user.followers
+ end
+
+ def user_wants_email?(user)
+ # anyone who doesn't have it set to false, aka, opt-out
+ (user.settings == nil) || (user.settings[:email_new_tracks] != "false")
+ end
+end
View
@@ -3,7 +3,7 @@ class Comment < ActiveRecord::Base
named_scope :public, {
:conditions => {:spam => false, :private => :false},
:order => 'created_at DESC',
- :include => [:commenter => :pic]
+ :include => [{:commenter => :pic}, :commentable]
}
named_scope :include_private, {
View
@@ -0,0 +1,7 @@
+class Following < ActiveRecord::Base
+
+ belongs_to :user, :counter_cache => :followers_count
+ belongs_to :follower, :class_name => 'User'
+
+ validates_presence_of :user_id, :follower_id
+end
View
@@ -10,9 +10,9 @@ class Playlist < ActiveRecord::Base
named_scope :favorites, {:conditions => ['is_favorite = ?',true]}
- named_scope :public, {:conditions => ['private != ? AND is_favorite = ? AND tracks_count > 1',true, false ]}
+ named_scope :public, {:include => :pic, :conditions => ['private != ? AND is_favorite = ? AND tracks_count > 1',true, false ]}
- named_scope :include_private, {:conditions => ['is_favorite = ?',false]}
+ named_scope :include_private, {:include => :pic, :conditions => ['is_favorite = ?',false]}
has_one :pic, :as => :picable, :dependent => :destroy
View
@@ -1,6 +0,0 @@
-class Stalking < ActiveRecord::Base
-
- belongs_to :stalker, :class_name => 'User'
- belongs_to :stalkee, :class_name => 'User'
-
-end
View
@@ -20,7 +20,7 @@ class Track < ActiveRecord::Base
:select => 'DISTINCT assets.*, tracks.*',
:conditions => ['is_favorite = ?',true],
:order => 'tracks.created_at DESC',
- :joins => :asset
+ :joins => {:asset => {:user => :pic}}
}
View
@@ -71,14 +71,15 @@ class User < ActiveRecord::Base
:limit => 10,
:order => 'listens_count DESC'
- # stalking
- has_many :stalkers, :class_name => 'Stalking'
-
- has_many :stalkees, :class_name => 'Stalking'
+
+ has_many :followings, :dependent => :destroy
+ has_many :follows, :dependent => :destroy, :class_name => 'Following', :foreign_key => 'follower_id'
+
+ # people who are following this musician
+ has_many :followers, :through => :followings
- has_many :new_tracks_from_stalkees,
- :through => :stalkees,
- :class_name => 'Asset'
+ # musicians who this person follows
+ has_many :followees, :through => :follows, :source => :follower
# The following attributes can be changed via mass assignment
attr_accessible :login, :email, :password, :password_confirmation, :website, :myspace,
@@ -122,12 +123,38 @@ def hasnt_been_here_in(hours)
last_seen_at < hours.ago.utc
end
+ def is_following?(user)
+ follows.find_by_user_id(user)
+ end
+
+ def new_tracks_from_followees(limit)
+ Asset.find(:all, :limit => limit, :order => 'assets.created_at DESC',
+ :conditions => {:user_id => followee_ids})
+ end
+
+ def has_followees?
+ follows.count > 0
+ end
+
+ def add_or_remove_followee(followee_id)
+ return if followee_id == id # following yourself would be a pointless affair!
+ if is_following?(followee_id)
+ is_following?(followee_id).destroy
+ else
+ follows.find_or_create_by_user_id(followee_id)
+ end
+ end
+
def type
self.class.name
end
protected
+ def followee_ids
+ follows.find(:all, :select => 'user_id').collect(&:user_id)
+ end
+
def make_first_user_admin
self.admin = true if User.count == 0
@@ -0,0 +1,20 @@
+Hi!
+
+<%= @name %> just uploaded a new track on alonetone. <%= @exclamation.randomly_pick(1) %>!
+
+It's so piping hot we don't even know the juicy details yet. <%= @name %> is still typing them in.
+
+Listen to it at alonetone:
+<%= @play_link %>
+
+Download it directly:
+<%= @download_link%>
+
+-----8<-------------------------
+
+You are getting this email because you decided to follow <%= @name %>. You can change your mind by clicking "un-follow" here:
+<%= @user_link %>
+
+You can also turn off all emails by editing your profile at alonetone.
+
+
@@ -46,6 +46,13 @@
:title => 'alonetone radio: currently kicking ass' %>
</div>
+ <% if @followee_tracks %>
+ <h2 id="kicking_ass" class="box">Tracks from those you follow</h2>
+ <div class="box">
+ <%= render :partial => 'assets/asset', :collection => @followee_tracks %>
+ </div>
+ <% end %>
+
<h2 id="recently_favorited" class="box">Recently favorited</h2>
<div class="box">
<%= render :partial => 'shared/favorite', :collection => @favorites %>
@@ -4,8 +4,9 @@
<div class="user_title">
<h1 class="user"><%=h @user.name %></h1><span class="user_location"><%= user_location(@user) %></span>
+ <%= follow_toggle(@user) %>
<% if authorized? %>
- <%= link_to 'edit your profile', edit_user_path(@user), :class => 'edit_profile' %>
+ <%= link_to 'edit your profile', edit_user_path(@user), :class => "edit_profile #{ admin? ? 'admin' : ''}" %>
<%= link_to image_tag('icons/alonetone_plus_small.png'), user_plus_path(@user), :class=> 'alonetone_plus_link' if authorized? && @user.plus_enabled? %>
<% end %>
</div>
@@ -98,12 +98,21 @@
</div>
<div class="static_content">
- Email you new comments on your tracks?<br/>
+ Should we email you new comments on your tracks?<br/>
<%= select_tag('user[settings][email_comments]',
options_for_select([['of course, silly!','true'], ['I do not like email','false']],
setting(:email_comments))) %>
</div>
+
+ <div class="static_content">
+ Email notifications when folks you follow upload tracks?<br/>
+ <%= select_tag('user[settings][email_new_tracks]',
+ options_for_select([['please! it helps me keep track of the artists i love','true'], ['I told you already, I hate email','false']],
+ setting(:email_new_tracks))) %>
+
+ </div>
+
<div class="static_content">
<%= submit_tag "Save your alonetone settings" %>
View
@@ -28,5 +28,5 @@
config.action_controller.session_store = :active_record_store
- config.active_record.observers = :user_observer, :comment_observer
+ config.active_record.observers = :user_observer, :comment_observer, :asset_observer
end
@@ -0,0 +1,15 @@
+class ReplaceStalkingsWithFollowers < ActiveRecord::Migration
+ def self.up
+ drop_table :stalkings
+ create_table :followings do |t|
+ t.integer :user_id
+ t.integer :follower_id
+ t.timestamps
+ end
+ add_index :followings, :user_id
+ add_index :followings, :follower_id
+ end
+
+ def self.down
+ end
+end
@@ -0,0 +1,8 @@
+class AddFollowersCountToUser < ActiveRecord::Migration
+ def self.up
+ add_column :users, :followers_count, :integer, :default => 0
+ end
+
+ def self.down
+ end
+end
@@ -58,9 +58,9 @@ FavoriteToggle = $.klass(Remote.Link,{
FollowToggle = $.klass(Remote.Link,{
beforeSend:function(e){
if(this.element.hasClass('following'))
- this.element.removeClass('following').html('Follow');
+ this.element.removeClass('following');
else
- this.element.addClass('following').html('Stop Following');
+ this.element.addClass('following');
}
});
@@ -895,7 +895,7 @@ jQuery(function($) {
$('#single_track a.add_to_favorites').attach(FavoriteToggle);
// bio
- $('a.follow',this.more).attach(FollowToggle);
+ $('a.follow').attach(FollowToggle);
// sort playlists
@@ -366,9 +366,9 @@ a.edit_in_box
&:active
:background-position -146px 0px
-a.edit_profile
+a.edit_profile, a.follow
:display block
- :background url(../images/icons/edit_profile.png) no-repeat left center
+ :background url(../images/icons/follow.png) no-repeat left center
:text-indent -1000px
:width 48px
:height 48px
@@ -379,11 +379,22 @@ a.edit_profile
:background-position -48px 0px
&:active
:background-position -96px 0px
+a.edit_profile
+ :right 2px
+ :background url(../images/icons/edit_profile.png) no-repeat left center
+ &.admin
+ :right 50px
+a.follow.following
+ :background-position -144px 0px
+ &:hover
+ :background-position -192px 0px
+ &:active
+ :background-position -240px 0px
a.alonetone_plus_link
:position absolute
:float right
:top 12px
- :right 60px
+ :right 110px
.button_wrapper
:float right

0 comments on commit 3b8f15c

Please sign in to comment.