]> jfr.im git - irc/quakenet/qwebirc.git/blame - js/ui/baseui.js
Add feedback support.
[irc/quakenet/qwebirc.git] / js / ui / baseui.js
CommitLineData
e20e5a6b
CP
1qwebirc.ui.WINDOW_STATUS = 1;
2qwebirc.ui.WINDOW_QUERY = 2;
3qwebirc.ui.WINDOW_CHANNEL = 3;
4qwebirc.ui.WINDOW_CUSTOM = 4;
5qwebirc.ui.WINDOW_CONNECT = 5;
f74802c5 6qwebirc.ui.WINDOW_MESSAGES = 6;
e20e5a6b 7qwebirc.ui.CUSTOM_CLIENT = "custom";
9e769c12 8
e20e5a6b 9qwebirc.ui.BaseUI = new Class({
2cad083e 10 Implements: [Events],
a59dc700 11 initialize: function(parentElement, windowClass, uiName, options) {
2cad083e 12 this.options = options;
a59dc700 13
9e769c12 14 this.windows = {};
ffbb638d 15 this.clients = {};
e20e5a6b 16 this.windows[qwebirc.ui.CUSTOM_CLIENT] = {};
9e769c12
CP
17 this.windowArray = [];
18 this.windowClass = windowClass;
19 this.parentElement = parentElement;
20 this.parentElement.addClass("qwebirc");
21 this.parentElement.addClass("qwebirc-" + uiName);
e8db8558 22 this.firstClient = false;
e20e5a6b 23 this.commandhistory = new qwebirc.irc.CommandHistory();
ffbb638d 24 this.clientId = 0;
9e769c12
CP
25 },
26 newClient: function(client) {
ffbb638d 27 client.id = this.clientId++;
96f28062
CP
28 client.hilightController = new qwebirc.ui.HilightController(client);
29
ffbb638d
CP
30 this.windows[client.id] = {}
31 this.clients[client.id] = client;
e20e5a6b 32 var w = this.newWindow(client, qwebirc.ui.WINDOW_STATUS, "Status");
9e769c12 33 this.selectWindow(w);
e8db8558
CP
34 if(!this.firstClient) {
35 this.firstClient = true;
e20e5a6b 36 w.addLine("", "qwebirc v" + qwebirc.VERSION);
391f51ff 37 w.addLine("", "Copyright (C) 2008-2009 Chris Porter. All rights reserved.");
e8db8558 38 w.addLine("", "http://webchat.quakenet.org/");
4094890f 39 w.addLine("", "This is BETA quality software, please report bugs to slug@quakenet.org");
e8db8558 40 }
9e769c12
CP
41 return w;
42 },
ffbb638d
CP
43 getClientId: function(client) {
44 if(client == qwebirc.ui.CUSTOM_CLIENT) {
45 return qwebirc.ui.CUSTOM_CLIENT;
46 } else {
47 return client.id;
48 }
49 },
f74802c5
CP
50 getWindowIdentifier: function(type, name) {
51 if(type == qwebirc.ui.WINDOW_MESSAGES)
52 return "-M";
e20e5a6b 53 if(type == qwebirc.ui.WINDOW_STATUS)
f74802c5 54 return "";
26c81b65 55 return "_" + name.toIRCLower();
f74802c5
CP
56 },
57 newWindow: function(client, type, name) {
58 var w = this.getWindow(client, type, name);
59 if($defined(w))
60 return w;
9e769c12 61
f74802c5
CP
62 var wId = this.getWindowIdentifier(type, name);
63 var w = this.windows[this.getClientId(client)][wId] = new this.windowClass(this, client, type, name, wId);
9e769c12
CP
64 this.windowArray.push(w);
65
66 return w;
67 },
f74802c5
CP
68 getWindow: function(client, type, name) {
69 var c = this.windows[this.getClientId(client)];
70 if(!$defined(c))
71 return null;
72
73 return c[this.getWindowIdentifier(type, name)];
74 },
9e769c12
CP
75 getActiveWindow: function() {
76 return this.active;
77 },
1d42a76f
CP
78 getActiveIRCWindow: function(client) {
79 if(!this.active || this.active.type == qwebirc.ui.WINDOW_CUSTOM) {
f74802c5 80 return this.windows[this.getClientId(client)][this.getWindowIdentifier(qwebirc.ui.WINDOW_STATUS)];
1d42a76f
CP
81 } else {
82 return this.active;
83 }
84 },
9e769c12
CP
85 __setActiveWindow: function(window) {
86 this.active = window;
87 },
88 selectWindow: function(window) {
89 if(this.active)
90 this.active.deselect();
91 window.select(); /* calls setActiveWindow */
a59dc700 92 document.title = window.name + " - " + this.options.appTitle;
9e769c12 93 },
ff4befd8
CP
94 nextWindow: function(direction) {
95 if(this.windowArray.length == 0 || !this.active)
96 return;
97
98 if(!direction)
99 direction = 1;
100
101 var index = this.windowArray.indexOf(this.active);
102 if(index == -1)
103 return;
104
105 index = index + direction;
106 if(index < 0) {
107 index = this.windowArray.length - 1;
108 } else if(index >= this.windowArray.length) {
109 index = 0;
110 }
111
112 this.selectWindow(this.windowArray[index]);
113 },
114 prevWindow: function() {
115 this.nextWindow(-1);
116 },
9e769c12
CP
117 __closed: function(window) {
118 if(window.active) {
119 this.active = undefined;
120 if(this.windowArray.length == 1) {
121 this.windowArray = [];
122 } else {
123 var index = this.windowArray.indexOf(window);
6f2e4a37
CP
124 if(index == -1) {
125 return;
126 } else if(index == 0) {
9e769c12
CP
127 this.selectWindow(this.windowArray[1]);
128 } else {
129 this.selectWindow(this.windowArray[index - 1]);
130 }
9e769c12
CP
131 }
132 }
133
404cfb58 134 this.windowArray = this.windowArray.erase(window);
ffbb638d 135 delete this.windows[this.getClientId(window.client)][window.identifier];
eb9b087b 136 },
eb9b087b
CP
137 /*
138 this shouldn't be called by overriding classes!
66de775f 139 they should implement their own!
eb9b087b
CP
140 some form of user input MUST be received before an
141 IRC connection is made, else users are going to get
142 tricked into getting themselves glined
143 */
66de775f 144 loginBox: function(callback, initialNickname, initialChannels, autoConnect, autoNick) {
2cad083e 145 qwebirc.ui.GenericLoginBox(this.parentElement, callback, initialNickname, initialChannels, autoConnect, autoNick, this.options.networkName);
9e769c12
CP
146 }
147});
381fddfd 148
e20e5a6b
CP
149qwebirc.ui.StandardUI = new Class({
150 Extends: qwebirc.ui.BaseUI,
43cb8910
CP
151 UICommands: [
152 ["Options", "options"],
153 ["Add webchat to your site", "embedded"],
154 ["Privacy policy", "privacy"],
391f51ff 155 ["Feedback", "feedback"],
43cb8910
CP
156 ["About qwebirc", "about"]
157 ],
381fddfd
CP
158 initialize: function(parentElement, windowClass, uiName, options) {
159 this.parent(parentElement, windowClass, uiName, options);
3184781b
CP
160
161 this.tabCompleter = new qwebirc.ui.TabCompleterFactory(this);
fb71087a 162 this.uiOptions = new qwebirc.ui.DefaultOptionsClass(this);
ebb21d2e
CP
163 this.customWindows = {};
164
20157c51
CP
165 if(Browser.Engine.trident) {
166 ev = "keydown";
167 } else {
168 ev = "keypress";
169 }
170 document.addEvent(ev, this.__handleHotkey.bind(this));
171 },
172 __handleHotkey: function(x) {
173 if(!x.alt || x.control) {
174 if(x.key == "backspace" || x.key == "/")
175 if(!this.getInputFocused(x))
176 new Event(x).stop();
177 return;
178 }
179 var success = false;
180 if(x.key == "a" || x.key == "A") {
181 var highestNum = 0;
182 var highestIndex = -1;
183 success = true;
184
185 new Event(x).stop();
186 for(var i=0;i<this.windowArray.length;i++) {
187 var h = this.windowArray[i].hilighted;
188 if(h > highestNum) {
189 highestIndex = i;
190 highestNum = h;
381fddfd 191 }
20157c51
CP
192 }
193 if(highestIndex > -1)
194 this.selectWindow(this.windowArray[highestIndex]);
195 } else if(x.key >= '0' && x.key <= '9') {
196 success = true;
197
198 number = x.key - '0';
199 if(number == 0)
200 number = 10
424608ac 201
20157c51
CP
202 number = number - 1;
203
204 if(number >= this.windowArray.length)
205 return;
381fddfd 206
20157c51
CP
207 this.selectWindow(this.windowArray[number]);
208 } else if(x.key == "left") {
209 this.prevWindow();
210 success = true;
211 } else if(x.key == "right") {
212 this.nextWindow();
213 success = true;
214 }
215 if(success)
216 new Event(x).stop();
217 },
218 getInputFocused: function(x) {
96a805a2 219 return $$("input").indexOf(x.target) > -1;
841a451d 220 },
8af49135
CP
221 newCustomWindow: function(name, select, type) {
222 if(!type)
e20e5a6b 223 type = qwebirc.ui.WINDOW_CUSTOM;
8af49135 224
e20e5a6b 225 var w = this.newWindow(qwebirc.ui.CUSTOM_CLIENT, type, name);
8af49135 226 w.addEvent("close", function(w) {
f74802c5 227 delete this.windows[qwebirc.ui.CUSTOM_CLIENT][w.identifier];
8af49135
CP
228 }.bind(this));
229
230 if(select)
231 this.selectWindow(w);
6c19eb8f 232
8af49135
CP
233 return w;
234 },
ebb21d2e
CP
235 addCustomWindow: function(windowName, class_, cssClass, options) {
236 if(!$defined(options))
237 options = {};
238
239 if(this.customWindows[windowName]) {
240 this.selectWindow(this.customWindows[windowName]);
8af49135 241 return;
841a451d 242 }
8af49135 243
ebb21d2e
CP
244 var d = this.newCustomWindow(windowName, true);
245 this.customWindows[windowName] = d;
246
247 d.addEvent("close", function() {
248 this.customWindows[windowName] = null;
8af49135
CP
249 }.bind(this));
250
ebb21d2e 251 if(cssClass)
e1a91a8a 252 d.lines.addClass("qwebirc-" + cssClass);
ebb21d2e
CP
253
254 var ew = new class_(d.lines, options);
8af49135 255 ew.addEvent("close", function() {
ebb21d2e 256 d.close();
8af49135 257 }.bind(this));
841a451d 258 },
ebb21d2e 259 embeddedWindow: function() {
b35116e2 260 this.addCustomWindow("Embedding wizard", qwebirc.ui.EmbedWizard, "embeddedwizard");
ebb21d2e
CP
261 },
262 optionsWindow: function() {
263 this.addCustomWindow("Options", qwebirc.ui.OptionsPane, "optionspane", this.uiOptions);
264 },
e1a91a8a
CP
265 aboutWindow: function() {
266 this.addCustomWindow("About", qwebirc.ui.AboutPane, "aboutpane", this.uiOptions);
267 },
b35116e2
CP
268 privacyWindow: function() {
269 this.addCustomWindow("Privacy policy", qwebirc.ui.PrivacyPolicyPane, "privacypolicypane", this.uiOptions);
270 },
391f51ff
CP
271 feedbackWindow: function() {
272 this.addCustomWindow("Feedback", qwebirc.ui.FeedbackPane, "feedbackpane", this.uiOptions);
273 },
8af49135
CP
274 urlDispatcher: function(name) {
275 if(name == "embedded")
925fc357 276 return ["a", this.embeddedWindow.bind(this)];
ebb21d2e
CP
277
278 if(name == "options")
279 return ["a", this.optionsWindow.bind(this)];
8af49135
CP
280
281 return null;
3184781b
CP
282 },
283 tabComplete: function(element) {
284 this.tabCompleter.tabComplete(element);
285 },
286 resetTabComplete: function() {
287 this.tabCompleter.reset();
8af49135 288 }
381fddfd 289});
6f2e4a37 290
fb71087a 291qwebirc.ui.SoundUI = new Class({
e20e5a6b 292 Extends: qwebirc.ui.StandardUI,
fb71087a
CP
293 initialize: function(parentElement, windowClass, uiName, options) {
294 this.parent(parentElement, windowClass, uiName, options);
295
127631e0 296 this.soundInited = false;
fb71087a 297 this.soundReady = false;
fb71087a 298
127631e0 299 this.setBeepOnMention(this.uiOptions.BEEP_ON_MENTION);
fb71087a 300 },
127631e0
CP
301 soundInit: function() {
302 if(this.soundInited)
fb71087a 303 return;
127631e0
CP
304 if(!$defined(Browser.Plugins.Flash) || Browser.Plugins.Flash.version < 8)
305 return;
306 this.soundInited = true;
307
308 this.soundPlayer = new qwebirc.sound.SoundPlayer();
309 this.soundPlayer.addEvent("ready", function() {
310 this.soundReady = true;
311 }.bind(this));
312 this.soundPlayer.go();
fb71087a 313 },
127631e0
CP
314 setBeepOnMention: function(value) {
315 if(value)
316 this.soundInit();
317 this.beepOnMention = value;
318 },
319 beep: function() {
320 if(!this.soundReady || !this.beepOnMention)
fb71087a 321 return;
127631e0
CP
322
323 this.soundPlayer.beep();
fb71087a
CP
324 }
325});
326
327qwebirc.ui.QuakeNetUI = new Class({
328 Extends: qwebirc.ui.SoundUI,
2cd9e32d
CP
329 urlDispatcher: function(name, window) {
330 if(name == "qwhois") {
7cb09779 331 return ["span", function(auth) {
2cd9e32d 332 this.client.exec("/MSG Q whois #" + auth);
925fc357
CP
333 }.bind(window)];
334 }
335 if(name == "whois") {
336 return ["span", function(nick) {
337 this.client.exec("/WHOIS " + nick);
338 }.bind(window)];
2cd9e32d 339 }
2cd9e32d 340 return this.parent(name);
ffbb638d
CP
341 },
342 logout: function() {
343 if(!qwebirc.auth.loggedin())
344 return;
345 if(confirm("Log out?")) {
346 for(var client in this.clients) {
347 this.clients[client].quit("Logged out");
348 };
349 document.location = "/auth?logout=1";
350 }
2cd9e32d
CP
351 }
352});
353
354qwebirc.ui.NewLoginUI = new Class({
355 Extends: qwebirc.ui.QuakeNetUI,
6f2e4a37
CP
356 loginBox: function(callbackfn, initialNickname, initialChannels, autoConnect, autoNick) {
357 this.postInitialize();
c38a0240 358
e20e5a6b 359 var w = this.newCustomWindow("Connect", true, qwebirc.ui.WINDOW_CONNECT);
6f2e4a37
CP
360 var callback = function(args) {
361 w.close();
362 callbackfn(args);
363 };
364
2cad083e 365 qwebirc.ui.GenericLoginBox(w.lines, callback, initialNickname, initialChannels, autoConnect, autoNick, this.options.networkName);
6f2e4a37
CP
366 }
367});