Permalink
Browse files

Add channel topics

A whole bunch of CSS shenanigans necessary to accommodate this --
eventually got the scrolling right with a bunch of absolute positioning.

Also got a box above the nicks for stats there (total in the channel etc.),
but it's hidden for now as there's no code yet to show the stats.
  • Loading branch information...
akavlie committed Nov 9, 2011
1 parent 96dde66 commit 72f063d36e6d4ecba1e65438b59e8edca4f70770
Showing with 105 additions and 31 deletions.
  1. +46 −9 app.css
  2. +48 −18 app.js
  3. +10 −4 index.html
  4. +1 −0 server.js
View
55 app.css
@@ -38,14 +38,32 @@ header {
position: relative;
}
-#frame #output {
+#output {
font-size: 14px;
- border: 1px solid #444;
- padding: 5px;
+ position: relative;
margin-bottom: 5px;
- overflow: auto;
+ border: 1px solid #888;
+}
+
+#output #topic {
position: relative;
+ min-height: 40px;
+ padding: 5px;
+ background-color: #e2e2e2;
+ border-bottom: 1px solid #444;
+ display: none;
+ z-index: 2;
+}
+
+#output #messages {
+ position: absolute;
+ padding: 5px;
+ overflow: auto;
z-index: 10;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
}
#frame .gutter {
@@ -87,16 +105,35 @@ header {
margin-left: 0;
}
-#frame .nicks {
- float: right;
+#sidebar {
width: 200px;
- overflow: auto;
- padding: 5px;
margin: 0 0 5px 5px;
- border: 1px solid gray;
+ border: 1px solid #888;
+ float: right;
+ position: relative;
+ display: none;
+}
+
+#sidebar .stats {
+ position: relative;
+ top: 0;
+ height: 40px;
+ background-color: #e2e2e2;
+ border-bottom: 1px solid #888;
display: none;
}
+#sidebar .nicks {
+ position: absolute;
+ overflow: auto;
+ padding: 5px;
+ top: 0;
+ /*top: 40px;*/
+ bottom: 0;
+ left: 0;
+ right: 0;
+}
+
#prime-input {
font-size: 15px;
position: relative;
View
66 app.js
@@ -180,19 +180,24 @@ $(function() {
addMessage: function(message, single) {
// Expensive -- only do this on single message additions
if (single) {
- var position = $('#output').scrollTop();
- atBottom = $('#output')[0].scrollHeight - position
- == $('#output').innerHeight();
- var position = this.$('#output').scrollTop();
+ var position = $('#output #messages').scrollTop();
+ var atBottom = $('#output #messages')[0].scrollHeight - position
+ == $('#output #messages').innerHeight();
+ var position = this.$('#output #messages').scrollTop();
}
var view = new MessageView({model: message});
- $('#output').append(view.el);
+ $('#output #messages').append(view.el);
// Scroll to bottom on new message if already at bottom
if (atBottom) {
$('#output').scrollTop(position + 100);
}
},
+ updateTopic: function(channel) {
+ this.$('#topic').text(channel.get('topic')).show();
+ $('#messages').css('top', $('#topic').outerHeight(true));
+ },
+
// Switch focus to a different frame
focus: function(frame) {
// Save scroll position for frame before switching
@@ -201,7 +206,7 @@ $(function() {
}
this.focused = frame;
frames.setActive(this.focused);
- this.$('#output').empty();
+ this.$('#output #messages').empty();
var self = this;
frame.stream.each(function(message) {
@@ -210,19 +215,28 @@ $(function() {
nickList.addAll(frame.participants);
- if (frame.get('type') == 'channel')
- this.$('.nicks').show();
- else
- this.$('.nicks').hide();
+ if (frame.get('type') == 'channel') {
+ this.$('#sidebar').show();
+ this.$('#topic').show();
+ $('.wrapper').css('margin-right', 205);
+ $('#messages').css('top', $('#topic').outerHeight(true));
+ } else {
+ this.$('#sidebar').hide();
+ this.$('#topic').hide();
+ $('.wrapper').css('margin-right', 0);
+ $('#messages').css('top', 0);
+ }
$(this.el).removeClass().addClass(frame.get('type'));
- this.$('#output').scrollTop(this.position[frame.get('name')] || 0);
+ this.$('#output #messsages').scrollTop(this.position[frame.get('name')] || 0);
// Only the selected frame should send messages
frames.each(function(frm) {
frm.stream.unbind('add');
frm.participants.unbind();
+ frm.unbind();
});
+ frame.bind('change:topic', this.updateTopic, this);
frame.stream.bind('add', this.addMessage, this);
nickList.switchChannel(frame);
},
@@ -368,7 +382,8 @@ $(function() {
$(window).resize(function() {
sizeContent($('#frame #output'));
- sizeContent($('#frame .nicks'));
+ sizeContent($('#frame #sidebar'));
+ sizeContent($('#sidebar .nicks', '.stats'));
});
}
@@ -416,7 +431,8 @@ $(function() {
frames.add({name: 'status', type: 'status'});
sizeContent($('#frame #output'));
- sizeContent($('#frame .nicks'));
+ sizeContent($('#frame #sidebar'));
+ sizeContent($('#sidebar .nicks', '.stats'));
}
});
@@ -436,11 +452,14 @@ $(function() {
}
// Set output window to full height, minus other elements
- function sizeContent(sel) {
- var newHeight = $('html').height() - $('header').outerHeight(true) -
- $('#prime-input').outerHeight(true) -
- (sel.outerHeight(true) - sel.height()) - 10;
- // (10 = #content padding)
+ function sizeContent(sel, additional) {
+ var newHeight = $('html').height() - $('header').outerHeight(true)
+ - $('#prime-input').outerHeight(true)
+ - (sel.outerHeight(true) - sel.height()) - 10;
+ // 10 = #content padding
+ if (additional) {
+ newHeight -= $(additional).outerHeight(true);
+ }
sel.height(newHeight);
}
@@ -464,12 +483,14 @@ $(function() {
frames.add(pm);
})
+ // Message of the Day event (on joining a server)
socket.on('motd', function(data) {
data.motd.split('\n').forEach(function(line) {
frames.getByName('status').stream.add({sender: '', text: line});
});
});
+ // Join channel event
socket.on('join', function(data) {
console.log('Join event received for ' + data.channel + ' - ' + data.nick);
if (data.nick == irc.me.get('nick')) {
@@ -483,6 +504,7 @@ $(function() {
}
});
+ // Part channel event
socket.on('part', function(data) {
console.log('Part event received for ' + data.channel + ' - ' + data.nick);
if (data.nick == irc.me.get('nick')) {
@@ -496,6 +518,14 @@ $(function() {
}
});
+ // Set topic event
+ socket.on('topic', function(data) {
+ var channel = frames.getByName(data.channel);
+ channel.set({topic: data.topic});
+ // TODO: Show this was changed by data.nick in the channel stream
+ });
+
+ // Nick change event
socket.on('nick', function(data) {
// Update my info, if it's me
if (data.oldNick == irc.me.get('nick')) {
View
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>Webby IRC</title>
+ <title>web-irc</title>
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/1.4.0/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="app.css">
@@ -14,10 +14,16 @@
</header>
<div id="frame">
- <div class="nicks"></div>
+ <div id="sidebar">
+ <div class="stats">nick count here</div>
+ <div class="nicks"></div>
+ </div>
<div class="wrapper">
- <div id="output"></div>
- <div class="gutter"></div>
+ <div id="output">
+ <div id="topic">channel topic here</div>
+ <div id="messages"></div>
+ <div class="gutter"></div>
+ </div>
</div>
<input id="prime-input" type="text">
</div>
View
@@ -24,6 +24,7 @@ io.sockets.on('connection', function(socket) {
var events = {
'join': ['channel', 'nick'],
'part': ['channel', 'nick'],
+ 'topic': ['channel', 'topic', 'nick'],
'nick': ['oldNick', 'newNick', 'channels'],
'names': ['channel', 'nicks'],
'message': ['from', 'to', 'text'],

0 comments on commit 72f063d

Please sign in to comment.