Merge pull request #6 from alexfriesen/gh-pages

md cleanup, responsive playerlist, chat improvements
This commit is contained in:
Garry Newman
2016-06-08 22:42:01 +01:00
11 changed files with 204 additions and 215 deletions
+10 -1
View File
@@ -1,6 +1,15 @@
<div ng-controller="ChatController" id="ChatController">
<div id="vertical-container" style="height: 600px" class="Output scrollable"><div ng-repeat="line in Output" ng-class="line.Class"><span class="chatname"><a href="#/{{address}}/player/{{line.UserId}}/" style="color: {{line.Color}}">{{line.Username}}</a>:</span> {{line.Message}}</div></div>
<div style="height: 600px" class="Output scrollable">
<div ng-repeat="line in Output" ng-class="line.Class">
<span class="badge">
{{(line.Time * 1000) | date:'shortTime'}}
<a href="#/{{address}}/player/{{line.UserId}}/" style="color: {{line.Color}}">
{{line.Username}}
</a>
</span> {{line.Message}}
</div>
</div>
<form ng-submit="SubmitCommand()" class="md-inline-form">
<div>
+12 -9
View File
@@ -4,24 +4,25 @@
<h2>Connect</h2>
<div class="alert alert-danger" ng-show="LastErrorMessage != null">{{LastErrorMessage}}</div>
<div class="alert alert-danger" ng-show="LastErrorMessage != null">
{{LastErrorMessage}}
</div>
<p>Enter the address (including rcon port) and the rcon password below to connect.</p>
<form ng-submit="Connect()">
<div class="md-inline-form">
<div class="md-block form-group" flex-gt-xs>
<div class="form-group">
<label for="conncetion-adress">Address</label>
<input required minlength=5 ng-model="Address" name="Address" class="form-control" placeholder="xxx.xxx.xxx.xxx:28016" id="conncetion-adress">
</div>
<div class="md-block form-group" flex-gt-xs>
<div class="form-group">
<label for="conncetion-password">Password</label>
<input required minlength=2 type="password" ng-model="Password" name="Password" class="form-control" id="conncetion-password">
</div>
<div class="checkbox right">
<div class="checkbox pull-right">
<label>
<input type="checkbox" ng-model="SaveConnection"> Save Connection
</label>
@@ -29,8 +30,6 @@
<button type="submit" class="btn btn-primary btn-block" ng-click="Connect()">Connect</button>
</div>
</form>
</div>
@@ -39,10 +38,14 @@
<div ng-show="PreviousConnects.length > 0">
<h2>Saved Connections</h2>
<ul ng-repeat="c in PreviousConnects | orderBy:array:true | limitTo:connectionsLimit">
<li><a ng-click="ConnectTo( c )" href="#/{{c.Address}}/info">{{c.Address}}</a> - {{c.date | date:'short'}}</li>
<li>
<a ng-click="ConnectTo( c )" href="#/{{c.Address}}/info">{{c.Address}}</a> - {{c.date | date:'short'}}
</li>
</ul>
<div ng-show="PreviousConnects.length > connectionsLimit || connectionsLimit === undefined">
<button type="submit" class="btn btn-primary btn-block" ng-click="toggleConnectionsLimit()">Show {{(connectionsLimit === undefined) ? 'less' : 'more'}}</button>
<button type="submit" class="btn btn-primary btn-block" ng-click="toggleConnectionsLimit()">
Show {{(connectionsLimit === undefined) ? 'less' : 'more'}}
</button>
</div>
</div>
+2 -2
View File
@@ -1,10 +1,10 @@
<div ng-controller="ConsoleController" id="ConsoleController">
<div id="vertical-container" style="height: 600px" class="Output scrollable">
<div style="height: 600px" class="Output scrollable">
<div ng-repeat="line in Output" ng-class="line.Class">{{line.Message}}</div>
</div>
<form ng-submit="SubmitCommand()" class="md-inline-form">
<form ng-submit="SubmitCommand()">
<input type="text" class="form-control" ng-model="Command" ng-keyup="KeyUp($event)" />
</form>
+1 -1
View File
@@ -1,5 +1,5 @@
<div ng-controller="PlayerInfoController" flex layout="column" id="PlayerInfoController">
<div ng-controller="PlayerInfoController" id="PlayerInfoController">
<div class="row">
+31 -52
View File
@@ -1,63 +1,42 @@
<div ng-controller="PlayerXpController" flex layout="column" id="PlayerXpController">
<div ng-controller="PlayerXpController" id="PlayerXpController">
<md-content flex layout-padding>
<h2>Statistics for player <a href="#/{{address}}/player/{{userid}}/">{{userid}}</a></h2>
<div layout="row" layout-sm="column">
<div flex>
<md-card>
<md-card-title>
<md-card-title-text>
<span class="md-headline">Xp Income Sources</span>
<span class="md-subhead">Where has this user got their Xp from</span>
</md-card-title-text>
</md-card-title>
<md-card-content layout="row" layout-align="space-between">
<md-card-title-media flex>
<nvd3 flex options="Sources.Options" data="Sources.Data"></nvd3>
</md-card-title-media>
</md-card-content>
</md-card>
<div class="row">
<div class="col-md-12">
<h2>
Statistics for player: <a href="#/{{address}}/player/{{userid}}/">{{userid}}</a>
</h2>
</div>
</div>
<div flex>
<md-card>
<md-card-title>
<md-card-title-text>
<span class="md-headline">Xp Outgoing Sources</span>
<span class="md-subhead">Where has this user spent their Xp</span>
</md-card-title-text>
</md-card-title>
<md-card-content layout="row" layout-align="space-between">
<md-card-title-media flex>
<div class="row">
<div class="col-md-12">
<h3>Xp Income Sources</h3>
<h5>Where has this user got their Xp from</h5>
<div class="panel">
<nvd3 options="Sources.Options" data="Sources.Data"></nvd3>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h3>Xp Outgoing Sources</h3>
<h5>Where has this user spent their Xp</h5>
<div class="panel">
<nvd3 flex options="Outgoings.Options" data="Outgoings.Data"></nvd3>
</md-card-title-media>
</md-card-content>
</md-card>
</div>
</div>
</div>
</div>
<div flex>
<md-card>
<md-card-title>
<md-card-title-text>
<span class="md-headline">Xp Over Time</span>
<span class="md-subhead">How much XP has this user got over time</span>
</md-card-title-text>
</md-card-title>
<md-card-content layout="row" layout-align="space-between">
<md-card-title-media flex>
<div class="row">
<div class="col-md-12">
<h3>Xp Over Time</h3>
<h5>How much XP has this user got over time</h5>
<div class="panel">
<nvd3 flex options="OverTime.Options" data="OverTime.Data"></nvd3>
</md-card-title-media>
</md-card-content>
</md-card>
</div>
</div>
</div>
</md-content>
</div>
+26 -21
View File
@@ -1,28 +1,30 @@
<div ng-controller="PlayerListController" flex layout="column" id="PlayerListController">
<div ng-controller="PlayerListController" id="PlayerListController">
<div class="right row">
<div class="float-left">
<input ng-model="FilterText" style="width: 300px" class="form-control" placeholder="Filter..">
<div class="row">
<div class="col-xs-6">
<input ng-model="FilterText" class="form-control" placeholder="Filter..">
</div>
<div class="btn-group">
<button ng-click="Refresh()" class="btn btn-default" type="button"><i class="glyphicon glyphicon-refresh"></i></button>
<div class="col-xs-6">
<button ng-click="Refresh()" class="btn btn-default pull-right" type="button"><span class="glyphicon glyphicon-refresh"></span></button>
</div>
</div>
<div class="row">
<table>
<div class="col-sm-12">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Actions</th>
<th ng-click="Order( 'DisplayName' )" ng-class="SortClass( 'DisplayName' )">Username</th>
<th style="text-align: right" ng-click="Order( 'SteamID' )" ng-class="SortClass( 'SteamID' )">Steamid</th>
<th style="text-align: right" ng-click="Order( 'VoiationLevel' )" ng-class="SortClass( 'VoiationLevel' )">Voilation</th>
<th style="text-align: right" ng-click="Order( 'CurrentLevel' )" ng-class="SortClass( 'CurrentLevel' )">Level</th>
<th style="text-align: right" ng-click="Order( 'UnspentXp' )" ng-class="SortClass( 'UnspentXp' )">XP</th>
<th style="text-align: right" ng-click="Order( 'Address' )" ng-class="SortClass( 'Address' )">Address</th>
<th ng-click="Order( 'Ping' )" ng-class="SortClass( 'Ping' )">Ping</th>
<th ng-click="Order( 'ConnectedSeconds' )" ng-class="SortClass( 'ConnectedSeconds' )">Duration</th>
<th class="text-right" ng-click="Order( 'SteamID' )" ng-class="SortClass( 'SteamID' )">Steamid</th>
<th class="text-right" ng-click="Order( 'VoiationLevel' )" ng-class="SortClass( 'VoiationLevel' )">Voilation</th>
<th class="text-right" ng-click="Order( 'CurrentLevel' )" ng-class="SortClass( 'CurrentLevel' )">Level</th>
<th class="text-right" ng-click="Order( 'UnspentXp' )" ng-class="SortClass( 'UnspentXp' )">XP</th>
<th class="text-right" ng-click="Order( 'Address' )" ng-class="SortClass( 'Address' )">Address</th>
<th class="text-right" ng-click="Order( 'Ping' )" ng-class="SortClass( 'Ping' )">Ping</th>
<th class="text-right" ng-click="Order( 'ConnectedSeconds' )" ng-class="SortClass( 'ConnectedSeconds' )">Duration</th>
</tr>
</thead>
<tr ng-repeat="line in Players | orderBy: OrderBy | filter:FilterText" href="#/{{address}}/player/{{line.SteamID}}/">
@@ -64,32 +66,35 @@
<a href="#/{{address}}/player/{{line.SteamID}}/">{{line.SteamID}}</a>
</td>
<td style="text-align: right" ng-class="{fade: line.VoiationLevel == 0 }">
<td class="text-right" ng-class="{fade: line.VoiationLevel == 0 }">
{{line.VoiationLevel}}
</td>
<td style="text-align: right">
<td class="text-right">
{{line.CurrentLevel}}
</td>
<td style="text-align: right">
<td class="text-right">
<a href="#/{{address}}/player/{{line.SteamID}}/xp">{{line.UnspentXp}}</a>
</td>
<td style="text-align: right">
<td class="text-right">
{{line.Address}}
</td>
<td class="md-list-item-text" style="text-align: right">{{line.Ping}}</td>
<td class="text-right">
{{line.Ping}}
</td>
<td style="text-align: right">
<td class="text-right">
{{line.ConnectedSeconds | SecondsToDuration}}
</td>
<md-divider></md-divider>
</tr>
</table>
</div>
</div>
</div>
</div>
+9 -2
View File
@@ -3,15 +3,20 @@
<div class="row">
<div class="col-lg-12">
<div class="col-sm-12">
<h2 class="center">
{{info.Hostname}}
<div class="btn-group pull-right">
<button ng-click="Refresh()" class="btn btn-default" type="button"><i class="glyphicon glyphicon-refresh"></i></button>
<button ng-click="refresh()" class="btn btn-default" type="button"><i class="glyphicon glyphicon-refresh"></i></button>
</div>
</h2>
</div>
<div class="col-sm-4" ng-repeat="(key, value) in info">
<p>{{key}}: <span class="badge">{{value}}</span></p>
</div>
<!--
<div class="col-sm-4">
<p>Map: {{info.Map}}</p>
</div>
@@ -48,6 +53,8 @@
<p>Queued: <span class="badge">{{info.Queued}}</span></p>
</div>
-->
</div>
</div>
+37 -8
View File
@@ -3,7 +3,7 @@ app.controller( 'ChatController', ChatController );
function ChatController( $scope, rconService, $timeout )
{
$scope.Output = new Array();
$scope.Output = [];
$scope.SubmitCommand = function ()
{
@@ -13,7 +13,7 @@ function ChatController( $scope, rconService, $timeout )
$scope.$on( "OnMessage", function ( event, msg )
{
if ( msg.Type != "Chat" ) return;
if ( msg.Type !== "Chat" ) return;
$scope.OnMessage( JSON.parse( msg.Message ) );
});
@@ -21,13 +21,40 @@ function ChatController( $scope, rconService, $timeout )
$scope.OnMessage = function( msg )
{
$scope.Output.push( msg );
$timeout( $scope.ScrollToBottom, 50 );
if($scope.isOnBottom()) {
$scope.ScrollToBottom();
}
}
$scope.ScrollToBottom = function()
{
// TODO - don't scroll if we're not at the bottom !
$( "#ChatController .Output" ).scrollTop( $( "#ChatController .Output" )[0].scrollHeight );
var element = $( "#ChatController .Output" );
$timeout( function() {
element.scrollTop( element.prop('scrollHeight') );
}, 50 );
}
$scope.isOnBottom = function()
{
// get jquery element
var element = $( "#ChatController .Output" );
// height of the element
var height = element.height();
// scroll position from top position
var scrollTop = element.scrollTop();
// full height of the element
var scrollHeight = element.prop('scrollHeight');
if((scrollTop + height) > (scrollHeight - 10)) {
return true;
}
return false;
}
//
@@ -36,13 +63,15 @@ function ChatController( $scope, rconService, $timeout )
//
$scope.GetHistory = function ()
{
console.log( "GetHistory" );
rconService.Request( "chat.tail 512", $scope, function ( msg )
{
var messages = JSON.parse( msg.Message );
messages.forEach( function ( x ) { $scope.OnMessage( x ); } );
messages.forEach( function ( message ) {
$scope.OnMessage( message );
});
$scope.ScrollToBottom();
} );
}
+12 -12
View File
@@ -14,20 +14,20 @@ function PlayerListController( $scope, rconService, $interval )
});
}
$scope.Order = function( o )
$scope.Order = function( field )
{
if ( $scope.OrderBy == o )
if ( $scope.OrderBy === field )
{
o = '-' + o;
field = '-' + field;
}
$scope.OrderBy = o;
$scope.OrderBy = field;
}
$scope.SortClass = function( o )
$scope.SortClass = function( field )
{
if ( $scope.OrderBy == o ) return "active";
if ( $scope.OrderBy == "-" + o ) return "active descending";
if ( $scope.OrderBy === field ) return "sorting";
if ( $scope.OrderBy === "-" + field ) return "sorting descending";
return null;
}
@@ -41,10 +41,10 @@ function PlayerListController( $scope, rconService, $interval )
rconService.InstallService( $scope, $scope.Refresh )
var timer = $interval( function ()
{
//$scope.Refresh();
}.bind( this ), 1000 );
// var timer = $interval( function ()
// {
// //$scope.Refresh();
// }.bind( this ), 1000 );
$scope.$on( '$destroy', function () { $interval.cancel( timer ) } )
//$scope.$on( '$destroy', function () { $interval.cancel( timer ) } )
}
+3 -7
View File
@@ -5,16 +5,12 @@ function ServerInfoController( $scope, rconService, $routeParams )
{
$scope.info = {};
$scope.Refresh = function ()
{
rconService.Request( 'serverinfo', $scope, function ( msg )
$scope.refresh = function ()
{
rconService.Request( 'serverinfo', $scope, function ( msg ) {
$scope.info = JSON.parse( msg.Message );
// $scope.Players = JSON.parse( msg.Message );
console.log($scope.info);
});
}
rconService.InstallService( $scope, $scope.Refresh );
rconService.InstallService( $scope, $scope.refresh );
}
+3 -42
View File
@@ -21,19 +21,11 @@ a:hover
text-decoration: none;
}
.right
{
text-align: right;
}
.center
{
text-align: center;
}
.float-left { float: left; }
#ConsoleController .Output
{
font-family: monospace;
@@ -68,53 +60,22 @@ a:hover
background-color: #428bca;
}
table
{
border-collapse: collapse;
border-spacing: 0;
width: 100%;
}
.fade
{
opacity: 0.5;
}
th, td
.table > tbody > tr:hover
{
padding: 5px 8px;
border-bottom: 1px solid #414758;
background-color: rgba( 255, 255, 255, 0.3 );
}
th.active
.table > thead > tr > th.sorting
{
color: #1bc98e;
border-color: #1bc98e;
}
th
{
border-bottom: 2px solid #414758;
border-radius: 10px;
}
th:first-child
{
border-radius: 6px;
}
th:last-child
{
border-radius: 0 6px 0 0;
}
th:only-child
{
border-radius: 6px 6px 0 0;
}
.btn-default, .btn-default:active, .form-control
{
background: rgba( 255, 255, 255, 0.3 );