]> git.scottworley.com Git - reliable-chat/blob - webclient/rc.html
b83fa1a9fa5aa5741c00c2f62f99d533fa836073
[reliable-chat] / webclient / rc.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
5 <head>
6 <title>Reliable Chat</title>
7 <style type="text/css"><!--/*--><![CDATA[/*><!--*/
8 html, body {
9 width: 99.9%;
10 height: 100%;
11 margin: 0;
12 padding: 0;
13 font-family: monospace;
14 }
15 #container {
16 height: 100%;
17 }
18 #status {
19 width: 100%;
20 text-align: right;
21 background-color: #eef;
22 padding: 5px 5px 5px 0px;
23 }
24 #client {
25 width: 98.5%;
26 padding: 0px 0px 0px 5px;
27 height: 50px;
28 position: fixed;
29 bottom: 0;
30 }
31 #input {
32 width: 100%;
33 }
34 #say { width: 100% }
35 #history {
36 padding: 0px 5px 55px 5px;
37 vertical-align: bottom
38 }
39 img { width: 1px; height: 1px; }
40 iframe { display: none }
41 #status span { margin-right: 10px; }
42 #status span.sad {
43 background-color: #f00;
44 color: #fff;
45 border: 1px solid black;
46 border-radius: 5px;
47 padding-left: 5px;
48 padding-right: 5px;
49 }
50 #status span.happy {
51 background-color: #0f0;
52 color: #000;
53 border: 1px solid black;
54 border-radius: 5px;
55 padding-left: 5px;
56 padding-right: 5px;
57 }
58 /*]]>*/--></style>
59 <script type="text/javascript"><!--//--><![CDATA[//><!--
60 var servers = ['chkno.net', 'rc2.chkno.net', 'echto.net', 'the-wes.com', 'vibrantlogic.com'];
61
62 var session = Math.random();
63 var seen = {};
64
65 function rcnick() {
66 var nick = localStorage.getItem("nick");
67 if (nick) {
68 return nick;
69 }
70 return 'anonymous';
71 }
72
73 function rcsetnick(new_nick) {
74 localStorage.setItem("nick", new_nick);
75 }
76
77 function rcserverbase(server) {
78 // Add the default port if server doesn't contain a port number already
79 if (server.indexOf(":") == -1) {
80 return "http://" + server + ":21059";
81 } else {
82 return "http://" + server;
83 }
84 }
85
86 function rcchangeserverstatus(server, new_status) {
87 var statusbar = document.getElementById("status");
88 var spans = statusbar.getElementsByTagName("span");
89 for (var i in spans) {
90 if (spans[i].firstChild && 'data' in spans[i].firstChild && spans[i].firstChild.data == server) {
91 spans[i].setAttribute("class", new_status);
92 }
93 }
94 }
95
96 function rcaddmessagetohistory(message) {
97 var d = document.createElement("div");
98 d.appendChild(document.createTextNode(message));
99 var h = document.getElementById("history");
100 h.appendChild(d);
101 window.scrollTo(0, document.body.scrollHeight);
102 return d;
103 }
104
105 function make_seen_key(id, text) {
106 return id.replace(/@/g, "@@") + "_@_" + text.replace(/@/g, "@@");
107 }
108
109 function receiveMessage(server, time, id, text) {
110 var seen_key = make_seen_key(id, text);
111 if (!(seen_key in seen)) {
112 seen[seen_key] = true;
113 rcaddmessagetohistory(text);
114 for (var i in servers) {
115 rcchangeserverstatus(servers[i], "sad");
116 }
117 }
118 rcchangeserverstatus(server, "happy");
119 }
120
121 function receiveMessageEvent(event)
122 {
123 for (var i in servers) {
124 if (event.origin === rcserverbase(servers[i])) {
125 messages = JSON.parse(event.data);
126 for (var j in messages) {
127 if ('Time' in messages[j] &&
128 'ID' in messages[j] &&
129 'Text' in messages[j]) {
130 receiveMessage(servers[i], messages[j]['Time'], messages[j]['ID'], messages[j]['Text']);
131 }
132 }
133 }
134 }
135 }
136
137 function rcconnect() {
138 window.addEventListener("message", receiveMessageEvent, false);
139 for (var i in servers) {
140 // Create a hidden iframe for same-origin workaround
141 var iframe = document.createElement("iframe");
142 iframe.setAttribute("src", rcserverbase(servers[i]) + "/frame");
143 document.body.insertBefore(iframe, document.body.firstChild);
144 // Status bar entry
145 var status_indicator = document.createElement("span");
146 status_indicator.appendChild(document.createTextNode(servers[i]));
147 status_indicator.setAttribute("class", "sad");
148 document.getElementById("status").appendChild(status_indicator);
149 }
150 if (rcnick() == 'anonymous') {
151 rcaddmessagetohistory("-!- Set your nick with /nick");
152 }
153 }
154
155 function rcsend(d, message) {
156 var id = new Date().getTime() + "-" + session + "-" + Math.random();
157 seen[make_seen_key(id, message)] = true;
158 var path = "/speak" +
159 "?id=" + encodeURIComponent(id) +
160 "&text=" + encodeURIComponent(message);
161 for (var i in servers) {
162 var uri = rcserverbase(servers[i]) + path;
163 var img = document.createElement("img");
164 img.setAttribute("src", uri);
165 d.appendChild(img);
166 }
167 }
168
169 function rckeydown(event) {
170 if (event.keyCode == 13) {
171 var input = document.input.say.value;
172 document.input.say.value = "";
173
174 // Check nick change
175 var message;
176 var re = /^\/nick (.*)/;
177 var match = re.exec(input);
178 if (match) {
179 message = "*** " + rcnick() + " is now known as " + match[1];
180 rcsetnick(match[1]);
181 } else {
182 message = "<" + rcnick() + "> " + input;
183 }
184
185 // /me support
186 var message;
187 var re = /^\/me (.*)/;
188 var match = re.exec(input);
189 var inputme = input.substring(4);
190 if (match) {
191 message = "* " + rcnick() + " " + inputme;
192 } else {
193 message = "<" + rcnick() + "> " + input;
194 }
195
196 // Remind people to set their nick
197 if (rcnick() == 'anonymous') {
198 rcaddmessagetohistory("-!- Set your nick with /nick");
199 }
200
201 // Say the message
202 var d = rcaddmessagetohistory(message);
203 rcsend(d, message);
204 }
205 }
206 //--><!]]></script>
207
208 </head>
209
210 <body onload="rcconnect()">
211 <div id="container">
212 <div id="history"></div>
213 <div id="client">
214 <div id="input">
215 <form name="input" onsubmit="return false" autocomplete="off">
216 <input id="say" onkeydown="return rckeydown(event)" autocomplete="off" autofocus="autofocus"></input>
217 </form></div>
218 <div id="status">&nbsp;</div>
219 </div>
220 </div>
221 </body>
222 </html>