Stash moar
This commit is contained in:
parent
b344e9a816
commit
fd5158e712
17
README.md
17
README.md
@ -4,23 +4,24 @@ Thirteen Tien Len
|
||||
TODO
|
||||
----
|
||||
|
||||
- flexbox layout: http://codepen.io/anon/pen/ojJOjq
|
||||
|
||||
- graphics
|
||||
|
||||
- Remove PlayToBeat model and table.
|
||||
|
||||
- Implement run including face cards
|
||||
- Implement run including face cards (done?)
|
||||
|
||||
- BUG TODO: First player / lowest card holder should not be able to pass
|
||||
first play
|
||||
|
||||
- Fix tests. They mostly pass when run individually. Explore if `game_setup`
|
||||
is causing a bleedover between scenarios
|
||||
|
||||
- Bug: Players should not be able to pass outside of their turn.
|
||||
Validate play: play.player == game.current_player
|
||||
|
||||
- Replace publicly displayed emails with usernames
|
||||
|
||||
- Review attributions and license compliance
|
||||
|
||||
## Proposed Schema
|
||||
|
||||
Table
|
||||
@ -114,3 +115,11 @@ Rails Composer is open source and supported by subscribers. Please join RailsApp
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Attributions
|
||||
------------
|
||||
|
||||
## Felt subtle pattern
|
||||
|
||||
Source: http://subtlepatterns.com/felt/
|
||||
Author: http://atle.co/
|
||||
|
||||
@ -89,31 +89,28 @@ var Game = React.createClass({
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
return (
|
||||
<div id="game_show_container" style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
}}>
|
||||
<div>Title: {this.state.data.title}</div>
|
||||
<div>Game Id: {this.state.data.id}</div>
|
||||
<div>Current Player: {this.state.data.controlling_player_id}</div>
|
||||
<div>Hand to beat: {this.state.data.play_to_beat_string}</div>
|
||||
<div className='player-list'>
|
||||
<PlayerList
|
||||
game_id={this.props.id}
|
||||
players={this.state.data.players}
|
||||
onPlayHandSubmit={this.handlePlayHandSubmit}
|
||||
controlling_player_id={this.state.data.controlling_player_id}
|
||||
current_user_id={this.state.data.current_user_id} />
|
||||
</div>
|
||||
<div>
|
||||
{/* TODO: If not joinable, show why. i.e. game full*/ }
|
||||
{this.state.data.is_joinable ? <button onClick={this.handleJoin}>Join</button> : null }
|
||||
{/* TODO: If not startable, show why. i.e. need more players */}
|
||||
{this.state.data.is_started ? null : <button onClick={this.handleStart} disabled={this.state.data.is_startable ? null : "disabled" }>Start</button>}
|
||||
</div>
|
||||
<div>
|
||||
{this.state.data.winner_player_id ? "Winner: " + this.state.data.winner_player_id : null}
|
||||
</div>
|
||||
<div id='game-component'>
|
||||
<h1>{this.state.data.title}</h1>
|
||||
|
||||
{this.state.data.is_started
|
||||
?
|
||||
null
|
||||
:
|
||||
<section id='game-controls'>
|
||||
{/* TODO: If not joinable, show why. i.e. game full*/ }
|
||||
{this.state.data.is_joinable ? <button onClick={this.handleJoin}>Join</button> : null }
|
||||
{/* TODO: If not startable, show why. i.e. need more players */}
|
||||
<div id='start'>
|
||||
{this.state.data.is_started ? null : <button onClick={this.handleStart} disabled={this.state.data.is_startable ? null : "disabled" }>Start</button>}
|
||||
</div>
|
||||
</section>
|
||||
}
|
||||
|
||||
<PlayerList
|
||||
game={this.state.data}
|
||||
onPlayHandSubmit={this.handlePlayHandSubmit} />
|
||||
|
||||
{this.state.data.winner_player_id ? "Winner: " + this.state.data.winner_player_id : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -12,9 +12,9 @@ var Inventory = React.createClass({
|
||||
render: function() {
|
||||
if (this.props.cards) {
|
||||
return (
|
||||
<ul style={{ display: 'flex', flexDirection: 'row', justifyContent: 'center', listStyle: 'none' }} >
|
||||
<ul>
|
||||
{this.props.cards.map(function(card) {
|
||||
return <li key={card.id} style={{ paddingLeft: '16px' }}>
|
||||
return <li key={card.id}>
|
||||
<label>
|
||||
<input
|
||||
form={"player_controls_" + card.player_id}
|
||||
|
||||
@ -6,20 +6,22 @@ var Player = React.createClass({
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div style={{border: '1px solid', margin: '8px', padding: '8px'}}>
|
||||
<div>Player Id: {this.props.id}</div>
|
||||
<div>Email: {this.props.email}</div>
|
||||
<div>Inventory count: {this.props.inventory_count}</div>
|
||||
<div id={"player-" + this.props.id} className={"player " + (this.props.game.controlling_player_id == this.props.id ? 'has-control' : '')}>
|
||||
<div className='email'>{this.props.email}</div>
|
||||
{this.props.game.is_started
|
||||
?
|
||||
<div>Inventory count: {this.props.inventory_count}</div>
|
||||
: null }
|
||||
|
||||
{/* Show player controls if player is owned by current_user */}
|
||||
{this.props.user_id == this.props.current_user_id
|
||||
{(this.props.user_id == this.props.game.current_user_id) && (this.props.game.is_started == true)
|
||||
? (<PlayerControls
|
||||
key={this.props.id}
|
||||
onPlayHandSubmit={this.props.onPlayHandSubmit}
|
||||
game_id={this.props.game_id}
|
||||
game_id={this.props.game.id}
|
||||
player_id={this.props.id}
|
||||
inventory={this.props.inventory}
|
||||
controlling_player_id={this.props.controlling_player_id} /> )
|
||||
controlling_player_id={this.props.game.controlling_player_id} /> )
|
||||
: null }
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -4,24 +4,35 @@ var PlayerList = React.createClass({
|
||||
game_id: React.PropTypes.number
|
||||
},
|
||||
|
||||
render: function() {
|
||||
playerNodes: function() {
|
||||
var playerList = this;
|
||||
var playerNodes = this.props.players.map(function (player) {
|
||||
var playerNodes = this.props.game.players.map(function (player) {
|
||||
return (
|
||||
<Player
|
||||
key={player.id}
|
||||
onPlayHandSubmit={playerList.props.onPlayHandSubmit}
|
||||
controlling_player_id={playerList.props.controlling_player_id}
|
||||
current_user_id={playerList.props.current_user_id}
|
||||
user_id={player.user_id}
|
||||
game_id={playerList.props.game_id} {...player} />
|
||||
game={playerList.props.game}
|
||||
{...player} />
|
||||
);
|
||||
});
|
||||
return playerNodes;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div>
|
||||
PlayerList:
|
||||
{playerNodes}
|
||||
<div id="playerList">
|
||||
<div id="top">
|
||||
{this.playerNodes()[0]}
|
||||
</div>
|
||||
<div id="mid">
|
||||
{this.playerNodes()[1]}
|
||||
<div id="play-to-beat">Hand to beat: {this.props.game.play_to_beat_string}</div>
|
||||
{this.playerNodes()[2]}
|
||||
</div>
|
||||
<div id="bot">
|
||||
{this.playerNodes()[3]}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
38
app/assets/javascripts/header-scroll.js
Normal file
38
app/assets/javascripts/header-scroll.js
Normal file
@ -0,0 +1,38 @@
|
||||
// Hide Header on on scroll down
|
||||
var didScroll;
|
||||
var lastScrollTop = 0;
|
||||
var delta = 5;
|
||||
var navbarHeight = $('header > nav').outerHeight();
|
||||
|
||||
$(window).scroll(function(event){
|
||||
didScroll = true;
|
||||
});
|
||||
|
||||
setInterval(function() {
|
||||
if (didScroll) {
|
||||
hasScrolled();
|
||||
didScroll = false;
|
||||
}
|
||||
}, 250);
|
||||
|
||||
function hasScrolled() {
|
||||
var st = $(this).scrollTop();
|
||||
|
||||
// Make sure they scroll more than delta
|
||||
if(Math.abs(lastScrollTop - st) <= delta)
|
||||
return;
|
||||
|
||||
// If they scrolled down and are past the navbar, add class .nav-up.
|
||||
// This is necessary so you never see what is "behind" the navbar.
|
||||
if (st > lastScrollTop && st > navbarHeight){
|
||||
// Scroll Down
|
||||
$('header > nav').removeClass('nav-down').addClass('nav-up');
|
||||
} else {
|
||||
// Scroll Up
|
||||
if(st + $(window).height() < $(document).height()) {
|
||||
$('header > nav').removeClass('nav-up').addClass('nav-down');
|
||||
}
|
||||
}
|
||||
|
||||
lastScrollTop = st;
|
||||
}
|
||||
@ -16,17 +16,18 @@
|
||||
|
||||
html
|
||||
box-sizing: border-box
|
||||
display: flex
|
||||
//display: flex
|
||||
justify-content: center
|
||||
min-height: 100vh
|
||||
|
||||
body
|
||||
flex: 1 1 auto
|
||||
//flex: 1 1 auto
|
||||
display: flex
|
||||
flex-direction: column
|
||||
min-height: 100vmin
|
||||
min-height: 100vh
|
||||
margin: 0
|
||||
background: darkgreen
|
||||
background: url('backgrounds/felt-green.png')
|
||||
font-size: 4vmin
|
||||
|
||||
a
|
||||
text-decoration: none
|
||||
@ -35,22 +36,30 @@ a
|
||||
|
||||
h1
|
||||
font-size: 7vmin
|
||||
margin: 0 0 5vmin 0
|
||||
|
||||
header
|
||||
flex: 1 1 auto
|
||||
font-size: 3vmin
|
||||
margin-bottom: 10vmin
|
||||
nav
|
||||
padding: 1vmin
|
||||
background: #222
|
||||
position: fixed
|
||||
top: 0
|
||||
transition: top 0.2s ease-in-out
|
||||
width: 100%
|
||||
&.nav-up
|
||||
top: -40px
|
||||
ul
|
||||
margin: 0
|
||||
display: flex
|
||||
li
|
||||
flex: 1 1 auto
|
||||
text-align: center
|
||||
|
||||
#content
|
||||
flex: 3 1 auto
|
||||
background: darkgreen
|
||||
//background: hotpink
|
||||
display: flex
|
||||
flex-direction: column
|
||||
flex-wrap: wrap
|
||||
@ -62,6 +71,7 @@ header
|
||||
text-align: center
|
||||
h1
|
||||
font-size: 10vmin
|
||||
color: #111
|
||||
background: green
|
||||
padding: 5vmin
|
||||
margin: 0
|
||||
|
||||
@ -10,3 +10,105 @@
|
||||
display: inline-block
|
||||
width: 40%
|
||||
|
||||
//// New Game#new
|
||||
|
||||
.simple_form
|
||||
background: green
|
||||
padding: 5vmin
|
||||
outline: 2px solid black
|
||||
label
|
||||
font-size: 4vmin
|
||||
display: block
|
||||
input.string
|
||||
font-size: 6vmin
|
||||
margin-bottom: 2vmin
|
||||
input.btn
|
||||
font-size: 4vmin
|
||||
|
||||
//// Show Game#show
|
||||
|
||||
button
|
||||
font-size: 4vmin
|
||||
|
||||
#game-component-container-container
|
||||
display: flex
|
||||
flex-direction: column
|
||||
flex: 1 1 auto
|
||||
align-self: stretch
|
||||
#game-component-container
|
||||
flex: 1 1 auto
|
||||
display: flex
|
||||
|
||||
#game-component
|
||||
flex: 1 1 auto
|
||||
flex-direction: column
|
||||
align-self: stretch
|
||||
display: flex
|
||||
h1
|
||||
font-size: 4vmin
|
||||
#game-controls
|
||||
display: flex
|
||||
flex-direction: row
|
||||
margin-bottom: 5vh
|
||||
align-self: stretch
|
||||
align-items: flex-start
|
||||
div
|
||||
flex: 1 1 auto
|
||||
#start
|
||||
align-self: flex-end
|
||||
text-align: right
|
||||
.player-list
|
||||
display: flex
|
||||
|
||||
.player
|
||||
background: green
|
||||
padding: 2vmin
|
||||
outline: 2px solid black
|
||||
position: relative
|
||||
&.has-control
|
||||
background: lightgreen
|
||||
|
||||
#playerList
|
||||
display: flex
|
||||
flex-direction: row
|
||||
flex-wrap: wrap
|
||||
align-items: flex-start
|
||||
text-align: center
|
||||
#top
|
||||
flex: 0 0 100%
|
||||
display: flex
|
||||
.player
|
||||
flex: 1 1 auto
|
||||
#mid
|
||||
flex: 0 0 100%
|
||||
align-self: center
|
||||
align-items: flex-start
|
||||
display: flex
|
||||
.player
|
||||
flex: 1 1 auto
|
||||
.email
|
||||
//position: absolute
|
||||
//background: green
|
||||
&:first-of-type
|
||||
.email
|
||||
//left: -18.5vmin
|
||||
//transform: rotate(-90deg)
|
||||
&:last-of-type
|
||||
.email
|
||||
//transform: rotate(90deg)
|
||||
//right: -17vmin
|
||||
#play-to-beat
|
||||
flex: 1 1 auto
|
||||
#bot
|
||||
flex: 0 0 100%
|
||||
align-self: flex-end
|
||||
|
||||
////// Inventory
|
||||
|
||||
.player form
|
||||
ul
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
text-align: left
|
||||
li
|
||||
flex: 1 1 auto
|
||||
|
||||
@ -2,10 +2,6 @@
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
|
||||
#content
|
||||
h1
|
||||
flex: 1 1 auto
|
||||
|
||||
.games-container
|
||||
flex: 1 1 auto
|
||||
display: flex
|
||||
@ -20,9 +16,8 @@
|
||||
padding: 2vmin
|
||||
|
||||
.button
|
||||
flex: 1 1 auto
|
||||
text-align: center
|
||||
font-size: 4vmin
|
||||
padding: 2vmin 4vmin
|
||||
background: black
|
||||
margin-bottom: 2vmin
|
||||
margin-bottom: 5vmin
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
.form-inputs
|
||||
= f.input :title
|
||||
= f.association :players, as: :select, collection: User.all.map {|u| u.id}, include_blank: false, include_hidden: false
|
||||
-#= f.association :players, as: :select, collection: User.all.map {|u| u.id}, include_blank: false, include_hidden: false
|
||||
|
||||
.form-actions
|
||||
= f.button :submit
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
%h1 New game
|
||||
|
||||
= render 'form'
|
||||
|
||||
= link_to 'Back', games_path
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#game-component= react_component 'Game', url: "#{game_path @game}"
|
||||
#game-component-container-container= react_component 'Game', props = {url: "#{game_path @game}"}, html_options = {id: "game-component-container"}
|
||||
|
||||
-# TODO: Remove deprecated commented out code
|
||||
-#%p
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<nav>
|
||||
<ul>
|
||||
<li><%= link_to 'Main Menu', root_path %></li>
|
||||
<li><%= link_to 'Browse', games_path %></li>
|
||||
<li><%= link_to 'Games', games_path %></li>
|
||||
<% if user_signed_in? %>
|
||||
<li><%= link_to 'Edit account', edit_user_registration_path %></li>
|
||||
<li><%= link_to 'Sign out', destroy_user_session_path, :method=>'delete' %></li>
|
||||
|
||||
@ -120,7 +120,7 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
# next player is now the active player
|
||||
#expect(@game.controlling_player_id).to_not eq(@controlling_player_id)
|
||||
#expect(@game.controlling_player_id).to eq(@next_player_id)
|
||||
expect(page).to have_content("Current Player: #{@next_player_id}")
|
||||
expect(page).to have_selector("#player-#{@next_player_id}.has-control")
|
||||
end
|
||||
|
||||
# Scenario: Player can not play an invalid hand on their turn
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user