10 changed files with 752 additions and 77 deletions
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
.clientOutput { |
||||
height: 500px; |
||||
text-align:left; |
||||
margin:0 auto; |
||||
margin-bottom:25px; |
||||
padding:10px; |
||||
background:#fff; |
||||
border:1px solid #ACD8F0; |
||||
overflow:auto; |
||||
} |
||||
|
||||
.locationList { |
||||
list-style: none; |
||||
text-align: center; |
||||
} |
||||
|
||||
.locationList .locationTab { |
||||
border-top: 1px solid #666; |
||||
border-left: 1px solid #666; |
||||
border-bottom: 1px solid #666; |
||||
border-right: 8px solid #666; |
||||
background-color: #ddd; |
||||
margin: 8px 0; |
||||
} |
||||
|
||||
.locationList .locationTab:hover { |
||||
border-right: 8px solid #333; |
||||
} |
||||
|
||||
.locationList .locationTab.selected { |
||||
border-left: none; |
||||
background-color: #fff; |
||||
border-right: 8px solid #006699; |
||||
} |
||||
|
||||
.locationList .locationTab a, |
||||
.locationList .locationTab a:visited { |
||||
text-decoration: none; |
||||
color: #666; |
||||
display: block; |
||||
padding: 15px 5px; |
||||
} |
||||
|
||||
.locationList .locationTab a:hover { |
||||
color: #000; |
||||
} |
@ -1,18 +1,247 @@
@@ -1,18 +1,247 @@
|
||||
$(document).ready(function () { |
||||
var clientViews = []; |
||||
var serverView = '--Server--'; |
||||
var currentLocation = serverView; |
||||
var currentNick; |
||||
var connected = false; |
||||
|
||||
$(document).ready(function () { |
||||
// UI interaction
|
||||
$('#message').bind("enterKey", function (e) { |
||||
sendMessage($('#message').val()); |
||||
$('#message').val(''); |
||||
}); |
||||
|
||||
$('#sendMessage').click(function () { |
||||
sendMessage($('#message').val()); |
||||
$('#message').val(''); |
||||
}); |
||||
|
||||
$('#guestSignIn').click(function () { |
||||
var result = irc.server.connect(); |
||||
if (result && result != '') { |
||||
$('#clientLogin').hide(); |
||||
$('#client').show(); |
||||
} |
||||
else { |
||||
$("#verifyStatus").css('display', 'inline', 'important'); |
||||
$("#verifyStatus").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Unable to Connect</div>'); |
||||
} |
||||
}); |
||||
|
||||
$('#verifyModal').on('shown.bs.modal', function (e) { |
||||
$('#verifyPassword').focus(); |
||||
}); |
||||
|
||||
$('#verifyModal').on('hide.bs.modal', function (e) { |
||||
$("#verifyStatus").css('display', 'none', 'important'); |
||||
$("#verifyStatus").html(''); |
||||
$('#verifyPassword').val(''); |
||||
}); |
||||
|
||||
$('#verifySubmit').click(function () { |
||||
var username = $('#verifyUsername').val(); |
||||
var password = $('#verifyPassword').val(); |
||||
var result = irc.server.connect(username, password); |
||||
if (result) { |
||||
$('#clientLogin').hide(); |
||||
$('#client').show(); |
||||
$('#verifyModal').modal('hide'); |
||||
} |
||||
else { |
||||
$("#verifyStatus").css('display', 'inline', 'important'); |
||||
$("#verifyStatus").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Unable to Login</div>'); |
||||
} |
||||
}); |
||||
|
||||
function sendMessage(message) { |
||||
irc.server.sendMessage(currentLocation, message); |
||||
} |
||||
|
||||
$('#message').keyup(function (e) { |
||||
if (e.keyCode == 13) { |
||||
$(this).trigger("enterKey"); |
||||
} |
||||
}); |
||||
|
||||
/* ---------------------------------------- |
||||
Websocket for the irc client |
||||
-----------------------------------------*/ |
||||
var irc = $.connection.ircClient; |
||||
|
||||
irc.client.rawMessageReceived = function (message) { |
||||
var txt = $('#clientOutput'); |
||||
txt.val(txt.val() + '\n' + message); |
||||
irc.client.privateMessageCommand = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, currentNick + ': ' + message.Message); |
||||
addOutput(message.Recipient, msg); |
||||
}; |
||||
|
||||
irc.client.privateNoticeCommand = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, currentNick + ' -NOTICE-: ' + message.Message); |
||||
addOutput(currentLocation, msg); |
||||
}; |
||||
|
||||
irc.client.channelMessage = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, message.Sender.Nickname + ': ' + message.Message); |
||||
addOutput(message.Channel, msg); |
||||
}; |
||||
|
||||
irc.client.channelNotice = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, message.Sender.Nickname + ': ' + message.Message); |
||||
addOutput(currentLocation, msg); |
||||
}; |
||||
|
||||
irc.client.channelModeChange = function (message, modes) { |
||||
var msg = formatMessage(message.TimeStamp, ' * ' + message.Nick.Nickname + ' sets mode ' + modes); |
||||
addOutput(message.Channel, msg); |
||||
}; |
||||
|
||||
irc.client.privateMessage = function (message) { |
||||
var location = message.Sender.Nickname; |
||||
if (location.toLowerCase() == 'nickserv' || location.toLowerCase() == 'chanserv') { |
||||
location = serverView; |
||||
} |
||||
var msg = formatMessage(message.TimeStamp, message.Sender.Nickname + ': ' + message.Message); |
||||
addOutput(location, msg); |
||||
}; |
||||
|
||||
irc.client.privateNotice = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, message.Sender.Nickname + ' -NOTICE-: ' + message.Message); |
||||
addOutput(currentLocation, msg); |
||||
}; |
||||
|
||||
irc.client.ctcpMessage = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, '[CTCP] [' + message.Command + '] ' + message.Sender.Nickname + ': ' + message.Arguments); |
||||
addOutput(message.Location, msg); |
||||
}; |
||||
|
||||
irc.client.joinChannel = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, message.Nick.Nickname + ' has joined ' + message.Channel); |
||||
addOutput(message.Channel, msg); |
||||
}; |
||||
|
||||
irc.client.inviteChannel = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, ' * ' + message.Requester.Nickname + ' invited ' + message.Recipient.Nickname); |
||||
addOutput(message.Channel, msg); |
||||
}; |
||||
|
||||
irc.client.partChannel = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, message.Nick.Nickname + ' has left ' + message.Channel); |
||||
addOutput(message.Channel, msg); |
||||
}; |
||||
|
||||
irc.client.quit = function (message) { |
||||
var quitMsg = message.Nick.Nickname; |
||||
if (message.Message != '') { |
||||
quitMsg = message.Message; |
||||
} |
||||
var msg = formatMessage(message.TimeStamp, message.Nick.Nickname + ' has quit: (' + quitMsg + ')'); |
||||
addOutput(message.Channel, msg); |
||||
}; |
||||
|
||||
irc.client.kick = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, ' * ' + message.Nick.Nickname + ' has kicked ' + message.KickedNick.Nickname + ' (' + message.Reason + ')'); |
||||
addOutput(message.Channel, msg); |
||||
}; |
||||
|
||||
irc.client.topicChange = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, ' * ' + message.Nick.Nickname + ' has changed the topic to: ' + message.Topic); |
||||
addOutput(message.Channel, msg); |
||||
}; |
||||
|
||||
irc.client.userModeChange = function (message, modes) { |
||||
var msg = formatMessage(message.TimeStamp, ' * ' + message.Nick.Nickname + ' sets mode ' + modes); |
||||
addOutput(currentLocation, msg); |
||||
}; |
||||
|
||||
irc.client.nickChange = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, ' * ' + message.OldNick.Nickname + ' is now known as ' + message.NewNick.Nickname); |
||||
addOutput(currentLocation, msg); |
||||
}; |
||||
|
||||
irc.client.serverReply = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, '*: ' + message.Message); |
||||
addOutput(serverView, msg); |
||||
}; |
||||
|
||||
irc.client.serverError = function (message) { |
||||
var msg = formatMessage(message.TimeStamp, '*: ' + message.Message); |
||||
addOutput(serverView, msg); |
||||
}; |
||||
|
||||
irc.client.connected = function () { |
||||
connected = true; |
||||
}; |
||||
|
||||
irc.client.disconnected = function () { |
||||
connected = false; |
||||
}; |
||||
|
||||
irc.client.exception = function (exception) { |
||||
$("#top_msg").css('display', 'inline', 'important'); |
||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + exception + '</div>'); |
||||
}; |
||||
|
||||
irc.client.nickChanged = function (nickname) { |
||||
currentNick = nickname; |
||||
$('#clientTitle').html('<p>Logged in as: <strong>' + nickname + '</strong></p>'); |
||||
}; |
||||
|
||||
$.connection.hub.start(); |
||||
}); |
||||
|
||||
$('#sendMessage').click(function () { |
||||
irc.server.sendRawMessage($('#message').val()); |
||||
$('#message').val(''); |
||||
function formatMessage(timeStamp, message) { |
||||
var timeStamp = new Date(timeStamp); |
||||
var msg = '[' + timeStamp.getHours() + ':' + timeStamp.getMinutes() + ':' + timeStamp.getSeconds() + '] : ' + message; |
||||
return msg; |
||||
} |
||||
|
||||
function addOutput(location, message) { |
||||
// If the current view is the same location as the output, append it to the view
|
||||
if (currentLocation == location) { |
||||
var txt = $('#clientOutput'); |
||||
if (txt.text() == '') { |
||||
txt.text(message); |
||||
} |
||||
else { |
||||
txt.text(txt.text() + '\n' + message); |
||||
} |
||||
txt.scrollTop(txt[0].scrollHeight); |
||||
} |
||||
|
||||
// Add it to the in memory buffer for this location
|
||||
var clientView = getClientView(location); |
||||
if (clientView) { |
||||
clientView.output.push(message); |
||||
} |
||||
} |
||||
|
||||
function changeClientView(location) { |
||||
var clientView = getClientView(location); |
||||
if (clientView) { |
||||
currentLocation = location; |
||||
$('#clientOutput').text(clientView.output.join('\n')); |
||||
$('#clientOutput').scrollTop($('#clientOutput')[0].scrollHeight); |
||||
} |
||||
} |
||||
|
||||
function getClientView(location) { |
||||
// Get the item from the master list
|
||||
var foundView = clientViews.find(function (item) { |
||||
return item.location === location; |
||||
}); |
||||
if (!foundView) { |
||||
foundView = createClientView(location); |
||||
} |
||||
return foundView; |
||||
} |
||||
|
||||
function createClientView(location) { |
||||
// Create new view item
|
||||
var item = { location: location, output: [] }; |
||||
clientViews.push(item); |
||||
// Add the new location to the UI
|
||||
var itemDiv = $('<li class="locationTab" id="' + location + '"><a href="#">' + location + '</a></li>'); |
||||
itemDiv.find('a').click(function () { |
||||
changeClientView(location); |
||||
}); |
||||
}); |
||||
$('#locationList').append(itemDiv); |
||||
return item; |
||||
} |
@ -0,0 +1,90 @@
@@ -0,0 +1,90 @@
|
||||
@model Teknik.Areas.IRC.ViewModels.ClientViewModel |
||||
|
||||
@using Teknik.Utilities |
||||
|
||||
@Styles.Render("~/Content/irc") |
||||
|
||||
@if (Model.Config.UserConfig.LoginEnabled) |
||||
{ |
||||
<div class="modal fade" id="verifyModal" tabindex="-1" role="dialog" aria-labelledby="verifyModalLabel" aria-hidden="true"> |
||||
<div class="modal-dialog modal-sm"> |
||||
<div class="modal-content"> |
||||
<div class="modal-header modal-header-default"> |
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button> |
||||
<h4 class="modal-title" id="verifyModalLabel">Teknik Login</h4> |
||||
</div> |
||||
<div class="modal-body"> |
||||
<div class="row"> |
||||
<div class="col-sm-12 text-center"> |
||||
<div id="verifyStatus"> |
||||
@if (Model.Error) |
||||
{ |
||||
<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button></div> |
||||
} |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<form id="verifyForm" action="#" method="post" accept-charset="UTF-8"> |
||||
<div class="form-group"> |
||||
<input type="text" class="form-control" id="verifyUsername" value="@((User.Identity.IsAuthenticated) ? User.Info.Username : string.Empty)" placeholder="Username" /> |
||||
</div> |
||||
<div class="form-group"> |
||||
<input type="password" class="form-control" id="verifyPassword" value="" placeholder="Password" /> |
||||
</div> |
||||
<div class="form-group text-center"> |
||||
<button class="btn btn-primary" id="verifySubmit" type="button">Sign In</button> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
} |
||||
|
||||
<div class="container"> |
||||
<div class="row"> |
||||
<div class="col-sm-12 text-center"> |
||||
<h2>Teknik IRC Web Client</h2> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="container" id="clientLogin"> |
||||
<div class="row"> |
||||
<div class="col-sm-5"><h2 class="text-center">Sign In as Guest</h2></div> |
||||
<div class="col-sm-2"><h2 class="text-center">or</h2></div> |
||||
<div class="col-sm-5"><h2 class="text-center">Sign In with Teknik Account</h2></div> |
||||
</div> |
||||
<br /> |
||||
<div class="row"> |
||||
<div class="col-sm-5"><button type="button" class="btn btn-primary center-block" id="guestSignIn">Enter as Guest</button></div> |
||||
<div class="col-sm-5 col-sm-offset-2"><button type="button" class="btn btn-primary center-block" id="accountSignIn" data-toggle="modal" data-target="#verifyModal">Sign In</button></div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="container" id="client" style="display:none"> |
||||
<div class="row"> |
||||
<div class="col-sm-12" id="clientTitle"></div> |
||||
</div> |
||||
<div class="row"> |
||||
<div class="col-sm-10"> |
||||
<pre class="clientOutput" id="clientOutput"></pre> |
||||
</div> |
||||
<div class="col-sm-2"> |
||||
<ul class="locationList" id="locationList"> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
<div class="row"> |
||||
<div class="col-sm-10"> |
||||
<input type="text" class="form-control" name="message" id="message"> |
||||
</div> |
||||
<div class="col-sm-2"> |
||||
<button type="button" class="btn btn-primary" id="sendMessage">Submit</button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
@Scripts.Render("~/bundles/signalr") |
||||
@Scripts.Render("~/signalr/hubs") |
||||
@Scripts.Render("~/bundles/irc") |
@ -1,35 +0,0 @@
@@ -1,35 +0,0 @@
|
||||
@model Teknik.Areas.IRC.ViewModels.ClientViewModel |
||||
|
||||
@using Teknik.Utilities |
||||
|
||||
@Scripts.Render("~/bundles/signalr") |
||||
@Scripts.Render("~/signalr/hubs") |
||||
@Scripts.Render("~/bundles/irc") |
||||
|
||||
<div class="container"> |
||||
@if (User.Identity.IsAuthenticated) |
||||
{ |
||||
<div class="row"> |
||||
<div class="col-sm-10"> |
||||
<textarea class="form-control" name="clientOutput" id="clientOutput" rows="20"></textarea> |
||||
</div> |
||||
</div> |
||||
<br /> |
||||
<div class="row"> |
||||
<div class="col-sm-10"> |
||||
<input type="text" class="form-control" name="message" id="message"> |
||||
</div> |
||||
<div class="col-sm-2"> |
||||
<button type="button" class="btn btn-primary" id="sendMessage">Submit</button> |
||||
</div> |
||||
</div> |
||||
} |
||||
else |
||||
{ |
||||
<div class="row"> |
||||
<div class="col-sm-10 col-sm-offset-1"> |
||||
<p>You need to be authenticated to view this page.</p> |
||||
</div> |
||||
</div> |
||||
} |
||||
</div> |
Loading…
Reference in new issue