Permalink
Browse files

adding private chat to game - closes #10

  • Loading branch information...
1 parent 52161f9 commit 3ebae469f77666b967de23eec6b569d44df463a0 @ryanb committed Feb 12, 2011
@@ -0,0 +1,9 @@
+class MessagesController < ApplicationController
+ before_filter :user_required
+
+ def create
+ @message = Message.new(params[:message])
+ @message.user = current_user
+ @message.save
+ end
+end
@@ -34,4 +34,21 @@ def link_to_user(user)
"GNU Go"
end
end
+
+ def relative_time(time)
+ [relative_date(time.to_date), time.strftime("%I:%M %p")].compact.join(" ")
+ end
+
+ def relative_date(date)
+ today = Time.zone.now.to_date
+ if date == today
+ nil
+ elsif date == today-1
+ "yesterday"
+ elsif date.year == today.year
+ date.strftime("%b %d")
+ else
+ date.strftime("%b %d, %Y")
+ end
+ end
end
@@ -0,0 +1,2 @@
+module MessagesHelper
+end
View
@@ -16,6 +16,7 @@ def generate_thumbnail
belongs_to :black_player, :class_name => "User"
belongs_to :white_player, :class_name => "User"
belongs_to :current_player, :class_name => "User"
+ has_many :messages
###################
### Validations ###
@@ -269,4 +270,8 @@ def switch_current_player
def opponent(player = current_player)
player == black_player ? white_player : black_player
end
+
+ def player?(user)
+ black_player == user || white_player == user
+ end
end
View
@@ -0,0 +1,14 @@
+class Message < ActiveRecord::Base
+ attr_accessible :game_id, :content, :move_index
+ belongs_to :game
+ belongs_to :user
+
+ validate :user_playing_game
+ validates_presence_of :user_id, :game_id, :content
+
+ def user_playing_game
+ if game && !game.player?(user)
+ errors.add :game_id, "is not owned by you so you cannot send the message."
+ end
+ end
+end
View
@@ -2,6 +2,7 @@ class User < ActiveRecord::Base
attr_accessible :username, :email, :password, :password_confirmation, :guest, :rank, :email_on_invitation, :email_on_move
has_many :authentications
+ has_many :messages
attr_accessor :password
before_save :prepare_password
@@ -4,7 +4,19 @@
<%= render "your_games" %>
</div>
<% end %>
- <div class="column">
- <%= render "other_games" %>
- </div>
-</div>
+ <% if @game.player?(current_user) && @game.black_player.present? && @game.white_player.present? %>
+ <div class="column">
+ <h2>Private Chat</h2>
+ <div id="messages"><%= render @game.messages.order(:created_at) %></div>
+ <%= form_for Message.new(:game_id => @game.id) do |f| %>
+ <%= f.hidden_field :game_id %>
+ <%= f.text_field :content %>
+ <%= f.submit "Send" %>
+ <% end %>
+ </div>
+ <% else %>
+ <div class="column">
+ <%= render "other_games" %>
+ </div>
+ <% end %>
+</div>
@@ -0,0 +1,4 @@
+<div class="message">
+ <div class="time"><%= relative_time(message.created_at) %></div>
+ <span class="user"><%= message.user.username %>:</span> <%= message.content %>
+</div>
@@ -0,0 +1,5 @@
+<% if @message.persisted? %>
+ $("#messages").append("<%= escape_javascript(render(@message)) %>");
+ $("#messages")[0].scrollTop = $("#messages")[0].scrollHeight;
+ $("#new_message")[0].reset();
+<% end %>
View
@@ -1,4 +1,6 @@
Govsgo::Application.routes.draw do
+ resources :messages
+
match 'auth/:provider/callback' => 'authentications#create'
match 'user/edit' => 'users#edit', :as => :edit_current_user
match 'signin' => 'authentications#index', :as => :signin
@@ -0,0 +1,15 @@
+class CreateMessages < ActiveRecord::Migration
+ def self.up
+ create_table :messages do |t|
+ t.integer :game_id
+ t.integer :user_id
+ t.text :content
+ t.integer :move_index
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :messages
+ end
+end
@@ -110,9 +110,16 @@ function setupGame() {
$.getScript(this.href);
return false;
});
+ $("#new_message").submit(function(e) {
+ $.post($(this).attr("action"), $(this).serialize());
+ e.preventDefault();
+ });
if ($("#board").attr("data-finished") != "true" && $("#board").attr("data-started") == "true") {
startPolling();
}
+ if ($("#messages").length > 0) {
+ $("#messages")[0].scrollTop = $("#messages")[0].scrollHeight;
+ }
}
function playMove(move) {
@@ -559,3 +559,38 @@ h2, h3 {
color: #FFF;
background-color: #444;
}
+
+
+/*** Messages ***/
+
+#messages {
+ background-image: url(/images/game/clear_white_overlay.png);
+ height: 150px;
+ overflow: auto;
+}
+
+#messages .message {
+ margin: 5px 10px;
+ font-size: 12px;
+}
+
+#messages .user {
+ font-weight: bold;
+}
+
+#messages .time {
+ float: right;
+ color: #CCC;
+ font-size: 10px;
+ margin-left: 10px;
+}
+
+#new_message {
+ background-image: url(/images/game/solid_white_overlay.png);
+ padding: 8px 10px;
+ margin: 0;
+}
+
+#new_message #message_content {
+ width: 210px;
+}
@@ -0,0 +1,27 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe MessagesController do
+ fixtures :all
+ render_views
+
+ describe "as guest" do
+ it "create action should redirect to signin url" do
+ get :create
+ response.should redirect_to(signin_url)
+ end
+ end
+
+ describe "as user" do
+ before(:each) do
+ @user = Factory(:user)
+ @controller.stubs(:current_user).returns(@user)
+ end
+
+ it "create action should render js template" do
+ Message.any_instance.stubs(:valid?).returns(true)
+ post :create, :format => "js"
+ response.should render_template("create")
+ assigns(:message).user == @user
+ end
+ end
+end
View
@@ -12,3 +12,9 @@
f.board_size 19
f.started_at Time.now
end
+
+Factory.define :message do |f|
+ f.association(:game, :factory => :game)
+ f.user { |m| m.game.black_player }
+ f.content "Hello World"
+end
View
@@ -0,0 +1,11 @@
+one:
+ game_id: 1
+ user_id: 1
+ content: MyText
+ move_index: 1
+
+two:
+ game_id: 1
+ user_id: 1
+ content: MyText
+ move_index: 1
View
@@ -228,4 +228,11 @@
game.winner.should be_nil
game.loser.should be_nil
end
+
+ it "should know if a user is a player in a game" do
+ game = Factory.build(:game)
+ game.should be_player(game.black_player)
+ game.should be_player(game.white_player)
+ game.should_not be_player(Factory.build(:user))
+ end
end
@@ -0,0 +1,16 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe Message do
+ it "should validate that the user is a player in a game" do
+ game = Factory(:game)
+ Factory.build(:message, :game => game, :user => game.black_player).should be_valid
+ Factory.build(:message, :game => game, :user => Factory(:user)).should have(1).error_on(:game_id)
+ end
+
+ it "should validate the presence of game, user and content" do
+ message = Factory.build(:message, :game_id => "", :user_id => "", :content => "")
+ message.should have(1).error_on(:game_id)
+ message.should have(1).error_on(:user_id)
+ message.should have(1).error_on(:content)
+ end
+end

0 comments on commit 3ebae46

Please sign in to comment.