Updated chat rendering

This commit is contained in:
Mattias Erming 2014-07-07 14:42:46 +02:00
parent cb663777b4
commit 9c2ffee7d0
5 changed files with 137 additions and 140 deletions

View File

@ -11,14 +11,17 @@
});
}
console.log("YES");
var isBottom = false;
var self = this;
this.on("beforeAppend", function() {
this.unbind(".sticky");
this.on("beforeAppend.sticky", function() {
isBottom = isScrollBottom.call(self);
});
this.on("afterAppend", function() {
this.on("afterAppend.sticky", function() {
if (isBottom) {
self.scrollBottom();
}
@ -32,6 +35,8 @@
"overflow-y": overflow
});
this.scrollBottom();
return this;
};

View File

@ -1,5 +1,5 @@
@import url(
http://fonts.googleapis.com/css?family=Lato:300,400,700
http://fonts.googleapis.com/css?family=Lato:400,700
);
@font-face {
font-family: "Octicons";
@ -29,10 +29,6 @@ h2 {
line-height: inherit;
margin: 0;
}
h1 {
color: #2c3e50;
font: 300 48px Lato, sans-serif;
}
button {
background: 0;
border: none;
@ -75,15 +71,14 @@ button {
background: #323841;
color: #fff;
}
#networks {
display: none;
#sidebar .networks {
min-height: 100%;
padding: 30px 40px 80px;
}
#networks .network + .network {
#sidebar .network + .network {
margin-top: 30px;
}
#networks .chan {
#sidebar .chan {
display: block;
margin: 1px -10px;
padding: 6px 10px 8px;
@ -92,12 +87,12 @@ button {
transition: all .2s;
width: 160px;
}
#networks .chan:first-child {
#sidebar .chan:first-child {
color: #84d1ff;
font-size: 15px;
font-weight: bold;
}
#networks .badge {
#sidebar .badge {
background: rgba(255, 255, 255, .06);
border-radius: 3px;
color: #afb6c0;
@ -108,7 +103,7 @@ button {
right: 10px;
transition: all .1s;
}
#networks .badge:empty {
#sidebar .badge:empty {
display: none;
}
#footer {
@ -176,8 +171,14 @@ button {
top: 0px;
width: 100%;
}
#windows > div {
display: none;
#windows > div,
#windows .chan {
background: #fff;
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
#chat {
font: 13px Consolas, monospace;
@ -188,7 +189,7 @@ button {
#chat button:hover {
opacity: .6;
}
#chat .window {
#chat .chat {
bottom: 0;
left: 0;
overflow: auto;
@ -206,37 +207,36 @@ button {
right: 0;
top: 0;
width: 180px;
z-index: 1;
}
#messages {
#chat .messages {
display: table;
table-layout: fixed;
height: 100%;
width: 100%;
}
#messages .msg {
#chat .msg {
display: table-row;
word-wrap: break-word;
}
#messages .msg:last-child {
#chat .msg:last-child {
height: 100%;
}
#messages .msg:last-child .text {
#chat .msg:last-child .text {
padding-bottom: 5px;
}
#messages .time,
#messages .from,
#messages .text {
#chat .time,
#chat .from,
#chat .text {
display: table-cell;
padding: 5px 0 0;
}
#messages .time {
#chat .time {
background: #f9f9f9;
color: #ddd;
text-align: right;
width: 46px;
}
#messages .from {
#chat .from {
background: #f9f9f9;
border-right: 1px solid #f4f4f4;
color: #ddd;
@ -244,46 +244,46 @@ button {
text-align: right;
width: 134px;
}
#messages a,
#messages .from button {
#chat a,
#chat .from button {
color: #33b0f7;
}
#messages .text {
#chat .text {
padding-left: 10px;
padding-right: 6px;
}
#messages .text a {
#chat .text a {
word-break: break-all;
}
#messages .type {
#chat .type {
color: #ccc;
display: none;
}
#messages .join .type,
#messages .part .type,
#messages .mode .type,
#messages .nick .type,
#messages .kick .type,
#messages .quit .type,
#messages .quit .type,
#messages .notice .type,
#messages .topic .type {
#chat .join .type,
#chat .part .type,
#chat .mode .type,
#chat .nick .type,
#chat .kick .type,
#chat .quit .type,
#chat .quit .type,
#chat .notice .type,
#chat .topic .type {
display: inline;
}
#meta {
#chat .meta {
height: 80px;
padding: 25px 0 0 20px;
}
#meta h1 {
#chat .meta h1 {
color: #222;
font-size: 15px;
}
#meta .type {
#chat .meta .type {
color: #ccc;
text-transform: capitalize;
}
#count {
#chat .count {
background: #f9f9f9;
border-top: 1px dashed #e9ecef;
border-bottom: 1px solid #e9ecef;
@ -293,7 +293,7 @@ button {
right: 0;
top: 80px;
}
#count:before {
#chat .count:before {
color: #eee;
font: 16px Octicons;
content: "\f02e";
@ -301,8 +301,9 @@ button {
right: 18px;
line-height: 40px;
transition: color .2s;
z-index: -1;
}
#search {
#chat .search {
color: #222;
border: 0;
background: none;
@ -311,9 +312,8 @@ button {
padding: 12px 20px;
position: relative;
width: 100%;
z-index: 2;
}
#users {
#chat .names {
bottom: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
@ -322,7 +322,7 @@ button {
top: 120px;
width: 100%;
}
#users button {
#chat .names button {
display: block;
line-height: 1.6em;
}

View File

@ -18,7 +18,7 @@
<body>
<aside id="sidebar">
<div id="networks"></div>
<div class="networks"></div>
<footer id="footer">
<button id="btn-1" data-target="#connect"></button>
<button id="btn-2" data-target="#settings"></button>
@ -32,19 +32,23 @@
</header>
<div id="windows">
<div id="chat"></div>
<div id="connect" class="container">
<div id="connect">
<div class="container">
<div class="row">
<div class="col-sm-12">
<h1>Connect</h1>
</div>
</div>
</div>
</div>
<div id="settings" class="container">
<div id="settings">
<div class="container">
<div class="row">
<div class="col-sm-12">
<h1>Settings</h1>
</div>
</div>
</div>
</div>
</div>
<form id="form" action="">
@ -64,7 +68,7 @@
<script type="text/html" class="channels">
{{#each channels}}
<button id="chan-{{id}}" class="chan" data-type="{{type}}">
<button data-id="{{id}}" data-target="#chan-{{id}}" class="chan">
<span class="badge"></span>
{{name}}
</button>
@ -72,29 +76,33 @@
</script>
<script type="text/html" class="chat">
<div class="window">
<div id="messages">
{{#each channels}}
<div id="chan-{{id}}" data-type="{{type}}" class="chan">
<div class="chat">
<div class="messages">
{{partial "messages"}}
</div>
</div>
<aside class="sidebar">
{{partial "users"}}
<div class="meta">
<h1>{{name}}</h1>
<span class="type">{{type}}</span>
</div>
<div class="users">
{{partial "users"}}
</div>
</aside>
</div>
{{/each}}
</script>
<script type="text/html" class="users">
<div id="meta">
<h1>{{name}}</h1>
<span class="type">
{{type}}
</span>
</div>
{{#if users.length}}
<div id="count">
<input id="search" placeholder="{{users.length}} users">
<div class="count">
<input class="search" placeholder="{{users.length}} users">
</div>
{{/if}}
<div id="users">
<div class="names">
{{#each users}}
<button class="user">{{mode}}{{name}}</button>
{{/each}}

View File

@ -34,10 +34,6 @@ $(function() {
var sidebar = $("#sidebar");
var chat = $("#chat");
var networks = $("#networks");
var channels = [];
var active = null;
var tpl = [];
function render(name, data) {
tpl[name] = tpl[name] || Handlebars.compile($("#templates ." + name).html());
@ -49,59 +45,61 @@ $(function() {
});
socket.on("init", function(data) {
networks.empty();
channels = $.map(data.networks, function(n) {
var channels = $.map(data.networks, function(n) {
return n.channels;
});
networks.append(
sidebar.find(".networks").html(
render("networks", {
networks: data.networks
})
).fadeIn();
var active = $($.cookie("active"));
if (active.length === 0) {
active = networks.find(".chan").eq(0);
);
chat.html(
render("chat", {
channels: channels
})
);
var id = $.cookie("target");
var target = sidebar.find("[data-target=" + id + "]");
if (target.length !== 0) {
target.trigger("click");
} else {
sidebar.find(".chan")
.eq(0)
.trigger("click");
}
active.trigger("click");
});
socket.on("join", function(data) {
channels.push(data.chan);
var id = data.network;
var network = networks
.find("#network-" + id)
.eq(0);
var network = sidebar.find("#network-" + id);
network.append(
render("channels", {
channels: [data.chan]
})
);
network.find(".chan")
chat.append(
render("chat", {
channels: [data.chan]
})
);
sidebar.find(".chan")
.last()
.trigger("click");
});
socket.on("msg", function(data) {
var chan = find(data.chan);
if (typeof chan !== "undefined") {
chan.messages.push(data.msg);
if (isActive(chan)) {
chat.find("#messages").append(
render("messages", {messages: [data.msg]})
);
}
}
chat.find("#chan-" + data.chan)
.find(".messages")
.append(render("messages", {messages: [data.msg]}));
});
socket.on("network", function(data) {
var lobby = data.network.channels[0];
channels.push(lobby);
networks.append(
sidebar.find(".networks").append(
render("networks", {
networks: [data.network]
})
);
networks.find(".chan")
sidebar.find(".chan")
.last()
.trigger("click");
});
@ -112,7 +110,7 @@ $(function() {
socket.on("part", function(data) {
var id = data.chan;
networks.find("#chan-" + id)
sidebar.find("[data-target=#chan-" + id + "]")
.remove()
.end()
.find(".chan")
@ -122,7 +120,7 @@ $(function() {
socket.on("quit", function(data) {
var id = data.network;
networks.find("#network-" + id)
sidebar.find("#network-" + id)
.remove()
.end()
.find(".chan")
@ -131,13 +129,9 @@ $(function() {
});
socket.on("users", function(data) {
var chan = find(data.chan);
if (typeof chan !== "undefined") {
chan.users = data.users;
if (isActive(chan)) {
chat.find(".sidebar").html(render("users", chan));
}
}
chat.find("#chan-" + data.chan)
.find(".users")
.html(render("users", data));
});
var input = $("#input")
@ -149,45 +143,41 @@ $(function() {
var value = input.val();
input.val("");
socket.emit("input", {
target: active.id || -1,
target: chat.data("id"),
text: value
});
});
var top = 1;
sidebar.on("click", "button:not(.active)", function() {
var btn = $(this);
var id = "#" + btn.attr("id");
var self = $(this);
var target = self.data("target");
if (!target) {
return;
}
$.cookie("active", id);
$.cookie("target", target);
chat.data(
"id",
self.data("id")
);
sidebar.find(".active").removeClass("active");
btn.addClass("active");
self.addClass("active")
.find(".badge")
.removeClass("highlight")
.empty();
active = null;
if (btn.hasClass("chan")) {
var chan = find(id.replace("#chan-", ""));
if (typeof chan !== "undefined") {
active = chan;
chat.fadeIn();
chat.siblings().hide();
chat.html(render("chat", chan));
chat.find(".window")
.sticky()
.scrollBottom();
}
} else {
chat.empty();
var target = $(btn.data("target"));
if (target.length !== 0) {
target.fadeIn();
target.siblings().hide();
}
}
var chan = $(target)
.css("z-index", top++)
.find(".chat")
.sticky();
});
chat.on("input", "#search", function() {
chat.on("input", ".search", function() {
var val = $(this).val();
$("#users").find("button").each(function() {
var names = $(this).closest(".users").find(".names");
names.find("button").each(function() {
var btn = $(this);
if (btn.text().toLowerCase().indexOf(val) === 0) {
btn.show();
@ -203,7 +193,7 @@ $(function() {
return;
}
socket.emit("input", {
target: active.id || -1,
target: active,
text: "/whois " + user
});
});
@ -212,12 +202,6 @@ $(function() {
return active !== null && chan == active;
}
function find(id) {
return $.grep(channels, function(c) {
return c.id == id;
})[0];
}
function complete(word) {
return $.grep(
commands,

File diff suppressed because one or more lines are too long