631 lines
18 KiB
JavaScript
631 lines
18 KiB
JavaScript
|
User = {
|
||
|
disable_samples: function() {
|
||
|
new Ajax.Request("/user/update.json", {
|
||
|
parameters: {
|
||
|
"user[show_samples]": false
|
||
|
},
|
||
|
|
||
|
onComplete: function(resp) {
|
||
|
var resp = resp.responseJSON
|
||
|
|
||
|
if (resp.success) {
|
||
|
$("resized_notice").hide();
|
||
|
$("samples_disabled").show();
|
||
|
Post.highres();
|
||
|
} else {
|
||
|
notice("Error: " + resp.reason)
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
},
|
||
|
|
||
|
destroy: function(id) {
|
||
|
notice("Deleting record #" + id)
|
||
|
|
||
|
new Ajax.Request("/user_record/destroy.json", {
|
||
|
parameters: {
|
||
|
"id": id
|
||
|
},
|
||
|
onComplete: function(resp) {
|
||
|
if (resp.status == 200) {
|
||
|
notice("Record deleted")
|
||
|
} else {
|
||
|
notice("Access denied")
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
},
|
||
|
|
||
|
current_check: null,
|
||
|
cancel_check: function() {
|
||
|
current_check = null;
|
||
|
},
|
||
|
|
||
|
/* If background is true, this is a request being made as an indirect result of other
|
||
|
* input; these can be cancelled (rather, the result is ignord) and are automatically
|
||
|
* cancelled if another is started while a previous one is still running.
|
||
|
*
|
||
|
* If background is false, this is an explicit user action (user submitted the form)
|
||
|
* and the action must not be cancelled by unrelated background actions.
|
||
|
*/
|
||
|
reset_password: function(username, email, func) {
|
||
|
var new_check = new Ajax.Request("/user/reset_password.json", {
|
||
|
parameters: {
|
||
|
"user[name]": username,
|
||
|
"user[email]": email
|
||
|
},
|
||
|
onComplete: function(resp) {
|
||
|
var resp = resp.responseJSON;
|
||
|
func(resp);
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
check: function(username, password, background, func) {
|
||
|
var parameters = {
|
||
|
"username": username
|
||
|
}
|
||
|
if(password)
|
||
|
parameters.password = password;
|
||
|
|
||
|
var new_check = new Ajax.Request("/user/check.json", {
|
||
|
parameters: parameters,
|
||
|
|
||
|
onSuccess: function(resp) {
|
||
|
if(background && resp.request != current_check)
|
||
|
return;
|
||
|
current_check = null;
|
||
|
|
||
|
var resp = resp.responseJSON;
|
||
|
func(resp);
|
||
|
|
||
|
}
|
||
|
});
|
||
|
if(background)
|
||
|
current_check = new_check;
|
||
|
},
|
||
|
|
||
|
create: function(username, password, email, func) {
|
||
|
var parameters = {
|
||
|
"user[name]": username,
|
||
|
"user[password]": password
|
||
|
}
|
||
|
if(email)
|
||
|
parameters["user[email]"] = email;
|
||
|
|
||
|
var new_check = new Ajax.Request("/user/create.json", {
|
||
|
parameters: parameters,
|
||
|
|
||
|
onComplete: function(resp) {
|
||
|
var resp = resp.responseJSON;
|
||
|
func(resp);
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
set_login: function(username, pass_hash, user_info)
|
||
|
{
|
||
|
Cookie.put("login", username)
|
||
|
Cookie.put("pass_hash", pass_hash)
|
||
|
Cookie.put("user_info", user_info)
|
||
|
},
|
||
|
|
||
|
check_name_timer: null,
|
||
|
last_username_in_form: null,
|
||
|
success_func: null,
|
||
|
messages: [],
|
||
|
|
||
|
init: function()
|
||
|
{
|
||
|
$("login-popup-notices").select("SPAN").each(function(e) {
|
||
|
User.messages.push(e.id);
|
||
|
});
|
||
|
|
||
|
/*
|
||
|
* IE makes us jump lots of hoops. We have to watch submit events on every object
|
||
|
* instead of just window because IE doesn't support event capturing. We have to
|
||
|
* override the submit method in every form to catch programmatic submits, because
|
||
|
* IE doesn't seem to support initiating events by firing them.
|
||
|
*
|
||
|
* Also, since we can't capture events, we need to be sure our submit event is done
|
||
|
* before other handlers, so if we cancel the event, we prevent other event handlers
|
||
|
* from continuing. However, we need to attach after forms have been created. So,
|
||
|
* this needs to be run as an early DOMLoaded event, and any other code that attaches
|
||
|
* submit events to code needs to be run in a later DOMLoaded event (or later events).
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
$$("FORM.need-signup").each(function(form) {
|
||
|
form.observe("submit", User.run_login_onsubmit);
|
||
|
});
|
||
|
|
||
|
/* If you select an item from the history dropdown in IE7, change events never fire, so
|
||
|
* use keyup instead. This isn't a problem with password fields, since there's no history
|
||
|
* dropdown. */
|
||
|
$("login-popup").observe("submit", function(e) {
|
||
|
e.stop();
|
||
|
User.form_submitted();
|
||
|
});
|
||
|
|
||
|
$("login-popup-submit").observe("click", function(e) {
|
||
|
e.stop();
|
||
|
User.form_submitted();
|
||
|
});
|
||
|
|
||
|
$("login-popup-cancel").observe("click", function(e) { e.stop(); User.close(false); });
|
||
|
$("login-popup-username").observe("blur", function(e) { User.form_username_blur(); });
|
||
|
$("login-popup-username").observe("focus", function(e) { User.form_username_focus(); });
|
||
|
$("login-popup-username").observe("keyup", function(e) { User.form_username_changed(true); });
|
||
|
$("login-tabs").select("LI").each(function(a) { a.observe("mousedown", function(e) { e.stop(); }); });
|
||
|
$("login-tabs").select("LI").each(function(a) { a.observe("click", function(e) { e.stop(); User.set_tab(a.id); }); });
|
||
|
|
||
|
/* IE and FF are glitchy with form submission: they fail to submit forms unless
|
||
|
* there's an <INPUT type="submit"> somewhere in the form. IE is even worse:
|
||
|
* even if there is one, if it's hidden on page load (including if it's a parent
|
||
|
* element hidden), it'll never submit the form, even if it's shown later. Don't
|
||
|
* rely on this behavior; just catch enter presses and submit the form explicitly. */
|
||
|
OnKey(13, {AllowInputFields: true, Element: $("login-popup")}, function(e)
|
||
|
{
|
||
|
e.stop();
|
||
|
User.form_submitted();
|
||
|
});
|
||
|
|
||
|
/* Escape closes the login box. */
|
||
|
OnKey(27, {AllowInputFields: true, AlwaysAllowOpera: true}, function(e)
|
||
|
{
|
||
|
if(!User.success_func)
|
||
|
return false;
|
||
|
|
||
|
User.close(false);
|
||
|
return true;
|
||
|
});
|
||
|
},
|
||
|
|
||
|
open: function(success)
|
||
|
{
|
||
|
if(User.success_func)
|
||
|
User.close(false);
|
||
|
User.success_func = success;
|
||
|
|
||
|
$("login-background").show();
|
||
|
$("login-container").show();
|
||
|
|
||
|
User.set_tab("tab-login");
|
||
|
},
|
||
|
|
||
|
close: function(run_success_func)
|
||
|
{
|
||
|
if(!User.success_func)
|
||
|
return;
|
||
|
|
||
|
$("login-background").hide();
|
||
|
$("login-container").hide();
|
||
|
User.active_tab = null;
|
||
|
User.check_name_timer = null;
|
||
|
var func = User.success_func;
|
||
|
User.success_func = null;
|
||
|
|
||
|
success_func = null;
|
||
|
if(run_success_func)
|
||
|
window.setTimeout(func, 0);
|
||
|
},
|
||
|
|
||
|
/* Handle login from an onclick. If login is not needed, return true. Otherwise,
|
||
|
* start the login, and return false; the object will receive another click when
|
||
|
* the login is successful. */
|
||
|
run_login_onclick: function(event)
|
||
|
{
|
||
|
event = Event.extend(event);
|
||
|
|
||
|
/* event.target is not copied by clone_event. */
|
||
|
var target = $(event.target);
|
||
|
|
||
|
/* event is not available when we get to the callback in IE7. */
|
||
|
var e = clone_event(event);
|
||
|
|
||
|
if(User.run_login(true, function() {
|
||
|
if(target.hasClassName("login-button"))
|
||
|
{
|
||
|
/* This is a login button, and not an action that happened to need login. After
|
||
|
* a successful login, don't click the button; that'll just go to the login page.
|
||
|
* Instead, just reload the current page. */
|
||
|
Cookie.put("notice", "You have been logged in.");
|
||
|
document.location.reload();
|
||
|
return;
|
||
|
}
|
||
|
target.simulate_anchor_click(e);
|
||
|
}))
|
||
|
return true;
|
||
|
|
||
|
/* Login is running, so stop the event. Don't just return false; call stop(), so
|
||
|
* event.stopped is available to the caller if we've been sent this message via
|
||
|
* Element.dispatchEvent. */
|
||
|
event.stop();
|
||
|
return false;
|
||
|
},
|
||
|
|
||
|
/* Handle login from an onsubmit. If login is needed, stop the event and resubmit
|
||
|
* it when the login completes. If login is not needed, return and let the submit
|
||
|
* complete normally. */
|
||
|
run_login_onsubmit: function(event)
|
||
|
{
|
||
|
/* Set skip_complete_on_true, so if we don't need to login, we don't resubmit the
|
||
|
* event; we just don't cancel it. */
|
||
|
var target = $(event.target);
|
||
|
if(!User.run_login(true, function() { target.simulate_submit(); }))
|
||
|
event.stop();
|
||
|
},
|
||
|
|
||
|
/* Handle login. If we're already logged in, run complete (unless only_complete_on_login
|
||
|
* is true) and return true. If we need to log in, start the login dialog; it'll call
|
||
|
* complete() on successful login. */
|
||
|
run_login: function(only_complete_on_login, complete)
|
||
|
{
|
||
|
if(Cookie.get("login") != "")
|
||
|
{
|
||
|
if(!only_complete_on_login)
|
||
|
complete();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
User.open(complete);
|
||
|
|
||
|
return false;
|
||
|
},
|
||
|
|
||
|
active_tab: null,
|
||
|
set_tab: function(tab)
|
||
|
{
|
||
|
if(User.active_tab == tab)
|
||
|
return;
|
||
|
User.active_tab = tab;
|
||
|
|
||
|
User.check_name_timer = null;
|
||
|
User.last_username_in_form = null;
|
||
|
|
||
|
$("login-tabs").select("LI").each(function(li) { li.removeClassName("selected"); });
|
||
|
$("login-tabs").down("#" + tab).addClassName("selected");
|
||
|
|
||
|
|
||
|
$$(".tab-header-text").each(function(li) { li.hide(); });
|
||
|
$(tab + "-text").show();
|
||
|
|
||
|
if(tab == "tab-login")
|
||
|
{
|
||
|
/* If the user's browser fills in a username but no password, focus the password. Otherwise,
|
||
|
* focus the username. */
|
||
|
if($("login-popup-password").value == "" && $("login-popup-username").value != "")
|
||
|
$("login-popup-password").focus();
|
||
|
else
|
||
|
$("login-popup-username").focus();
|
||
|
|
||
|
User.set_state("login-blank");
|
||
|
}
|
||
|
else if(tab == "tab-reset")
|
||
|
{
|
||
|
User.set_state("reset-blank");
|
||
|
$("login-popup-username").focus();
|
||
|
}
|
||
|
User.form_username_changed();
|
||
|
},
|
||
|
|
||
|
message: function(text)
|
||
|
{
|
||
|
for (var i = 0, l = User.messages.length; i < l; i++) {
|
||
|
var elem = User.messages[i];
|
||
|
$(elem).hide();
|
||
|
}
|
||
|
|
||
|
$("login-popup-message").update(text);
|
||
|
$("login-popup-message").show();
|
||
|
},
|
||
|
|
||
|
set_state: function(state)
|
||
|
{
|
||
|
var show = {};
|
||
|
if(state.match(/^login-/))
|
||
|
{
|
||
|
show["login-popup-password-box"] = true;
|
||
|
if(state == "login-blank")
|
||
|
$("login-popup-submit").update("Login");
|
||
|
else if(state == "login-user-exists")
|
||
|
$("login-popup-submit").update("Login");
|
||
|
else if(state == "login-confirm-password")
|
||
|
{
|
||
|
show["login-popup-password-confirm-box"] = true;
|
||
|
$("login-popup-submit").update("Create account");
|
||
|
}
|
||
|
else if(state == "login-confirm-password-mismatch")
|
||
|
$("login-popup-submit").update("Create account");
|
||
|
show["login-popup-" + state] = true;
|
||
|
}
|
||
|
else if(state.match(/^reset-/))
|
||
|
{
|
||
|
show["login-popup-email-box"] = true;
|
||
|
$("login-popup-submit").update("Reset password");
|
||
|
|
||
|
show["login-popup-" + state] = true;
|
||
|
}
|
||
|
|
||
|
var all = ["login-popup-email-box", "login-popup-password-box", "login-popup-password-confirm-box"].concat(User.messages);
|
||
|
|
||
|
current_state = state;
|
||
|
for (var i = 0, l = all.length; i < l; i++) {
|
||
|
var elem = all[i];
|
||
|
if(show[elem])
|
||
|
$(elem).show();
|
||
|
else
|
||
|
$(elem).hide();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
pending_username: null,
|
||
|
form_username_changed: function(keyup)
|
||
|
{
|
||
|
var username = $("login-popup-username").value;
|
||
|
if(username == User.last_username_in_form)
|
||
|
return;
|
||
|
User.last_username_in_form = username;
|
||
|
|
||
|
User.cancel_check();
|
||
|
if(User.check_name_timer)
|
||
|
window.clearTimeout(User.check_name_timer);
|
||
|
User.pending_username = null;
|
||
|
|
||
|
if(username == "")
|
||
|
{
|
||
|
if(User.active_tab == "tab-login")
|
||
|
User.set_state("login-blank");
|
||
|
else if(User.active_tab == "tab-reset")
|
||
|
User.set_state("reset-blank");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Delay on keyup, so we don't send tons of requests. Don't delay otherwise,
|
||
|
* so we don't introduce lag when we don't have to. */
|
||
|
var ms = 500;
|
||
|
if(!keyup && User.check_name_timer)
|
||
|
ms = 0;
|
||
|
|
||
|
/*
|
||
|
* Make sure the UI is still usable if this never finished. This way, we don't
|
||
|
* lag the interface if these JSON requests are taking longer than usual; you should
|
||
|
* be able to click "login" immediately as soon as a username and password are entered.
|
||
|
* Entering a username and password and clicking "login" should still behave properly
|
||
|
* if the username doesn't exist and the check_name_timer JSON request hasn't come
|
||
|
* back yet.
|
||
|
*
|
||
|
* If the state isn't "blank", the button is already enabled.
|
||
|
*/
|
||
|
User.check_name_timer = window.setTimeout(function() {
|
||
|
User.check_name_timer = null;
|
||
|
User.check(username, null, true, function(resp)
|
||
|
{
|
||
|
if(resp.exists)
|
||
|
{
|
||
|
/* Update the username to match the actual user's case. If the form contents have
|
||
|
* changed since we started this check, don't do this. (We cancel this event if we
|
||
|
* see the contents change, but the contents can change without this event firing
|
||
|
* at all.) */
|
||
|
var current_username = $("login-popup-username").value;
|
||
|
if(current_username == username)
|
||
|
{
|
||
|
/* If the element doesn't have focus, change the text to match. If it does, wait
|
||
|
* until it loses focus, so it doesn't interfere with the user editing it. */
|
||
|
if(!$("login-popup").focused)
|
||
|
$("login-popup-username").value = resp.name;
|
||
|
else
|
||
|
User.pending_username = resp.name;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(User.active_tab == "tab-login")
|
||
|
{
|
||
|
if(!resp.exists)
|
||
|
{
|
||
|
User.set_state("login-confirm-password");
|
||
|
return;
|
||
|
}
|
||
|
else
|
||
|
User.set_state("login-user-exists");
|
||
|
}
|
||
|
else if(User.active_tab == "tab-reset")
|
||
|
{
|
||
|
if(!resp.exists)
|
||
|
User.set_state("reset-blank");
|
||
|
else if(resp.no_email)
|
||
|
User.set_state("reset-user-has-no-email");
|
||
|
else
|
||
|
User.set_state("reset-user-exists");
|
||
|
}
|
||
|
});
|
||
|
}, ms);
|
||
|
},
|
||
|
|
||
|
form_username_focus: function()
|
||
|
{
|
||
|
$("login-popup").focused = true;
|
||
|
},
|
||
|
|
||
|
form_username_blur: function()
|
||
|
{
|
||
|
$("login-popup").focused = false;
|
||
|
|
||
|
/* When the username field loses focus, update the username case to match the
|
||
|
* result we got back from check(), if any. */
|
||
|
if(User.pending_username)
|
||
|
{
|
||
|
$("login-popup").username.value = User.pending_username;
|
||
|
User.pending_username = null;
|
||
|
}
|
||
|
|
||
|
/* We watch keyup on the username, because change events are unreliable in IE; update
|
||
|
* when focus is lost, too, so we see changes made without using the keyboard. */
|
||
|
User.form_username_changed(false);
|
||
|
},
|
||
|
|
||
|
form_submitted: function()
|
||
|
{
|
||
|
User.cancel_check();
|
||
|
if(User.check_name_timer)
|
||
|
window.clearTimeout(User.check_name_timer);
|
||
|
|
||
|
var username = $("login-popup-username").value;
|
||
|
var password = $("login-popup-password").value;
|
||
|
var password_confirm = $("login-popup-password-confirm").value;
|
||
|
var email = $("login-popup-email").value;
|
||
|
|
||
|
if(username == "")
|
||
|
return;
|
||
|
|
||
|
if(User.active_tab == "tab-login")
|
||
|
{
|
||
|
if(password == "")
|
||
|
{
|
||
|
User.message("Please enter a password.");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(current_state == "login-confirm-password")
|
||
|
{
|
||
|
if(password != password_confirm)
|
||
|
User.message("The passwords you've entered don't match.");
|
||
|
else
|
||
|
{
|
||
|
// create account
|
||
|
User.create(username, password, null, function(resp) {
|
||
|
if(resp.response == "success")
|
||
|
{
|
||
|
User.set_login(resp.name, resp.pass_hash, resp.user_info);
|
||
|
User.close(true);
|
||
|
}
|
||
|
else if(resp.response == "error")
|
||
|
{
|
||
|
User.message(resp.errors.join("<br>"))
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
User.check(username, password, false, function(resp)
|
||
|
{
|
||
|
if(!resp.exists)
|
||
|
{
|
||
|
User.set_state("login-confirm-password");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* We've authenticated successfully. Our hash is in password_hash; insert the
|
||
|
* login cookies manually. */
|
||
|
if(resp.response == "wrong-password")
|
||
|
{
|
||
|
notice("Incorrect password");
|
||
|
return;
|
||
|
}
|
||
|
User.set_login(resp.name, resp.pass_hash, resp.user_info);
|
||
|
User.close(true);
|
||
|
});
|
||
|
}
|
||
|
else if(User.active_tab == "tab-reset")
|
||
|
{
|
||
|
if(email == "")
|
||
|
return;
|
||
|
|
||
|
User.reset_password(username, email, function(resp)
|
||
|
{
|
||
|
if(resp.result == "success")
|
||
|
User.set_state("reset-successful");
|
||
|
else if(resp.result == "unknown-user")
|
||
|
User.set_state("reset-unknown-user");
|
||
|
else if(resp.result == "wrong-email")
|
||
|
User.set_state("reset-user-email-incorrect");
|
||
|
else if(resp.result == "no-email")
|
||
|
User.set_state("reset-user-has-no-email");
|
||
|
else if(resp.result == "invalid-email")
|
||
|
User.set_state("reset-user-email-invalid");
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
|
||
|
modify_blacklist: function(add, remove, success)
|
||
|
{
|
||
|
new Ajax.Request("/user/modify_blacklist.json", {
|
||
|
parameters: {
|
||
|
"add[]": add,
|
||
|
"remove[]": remove
|
||
|
},
|
||
|
onComplete: function(resp) {
|
||
|
var resp = resp.responseJSON;
|
||
|
|
||
|
if (resp.success)
|
||
|
{
|
||
|
if(success) success(resp);
|
||
|
} else {
|
||
|
notice("Error: " + resp.reason);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
set_pool_browse_mode: function(browse_mode) {
|
||
|
new Ajax.Request("/user/update.json", {
|
||
|
parameters: {
|
||
|
"user[pool_browse_mode]": browse_mode
|
||
|
},
|
||
|
|
||
|
onComplete: function(resp) {
|
||
|
var resp = resp.responseJSON;
|
||
|
|
||
|
if (resp.success) {
|
||
|
window.location.reload();
|
||
|
} else {
|
||
|
notice("Error: " + resp.reason);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
get_current_user_info: function()
|
||
|
{
|
||
|
var user_info = Cookie.get("user_info");
|
||
|
if(!user_info)
|
||
|
return null;
|
||
|
return user_info.split(";");
|
||
|
},
|
||
|
get_current_user_info_field: function(idx, def)
|
||
|
{
|
||
|
var user_info = User.get_current_user_info();
|
||
|
if(!user_info)
|
||
|
return def;
|
||
|
if(idx >= user_info.length)
|
||
|
return def;
|
||
|
return user_info[idx];
|
||
|
},
|
||
|
get_current_user_id: function()
|
||
|
{
|
||
|
return parseInt(User.get_current_user_info_field(0, 0));
|
||
|
},
|
||
|
|
||
|
get_current_user_level: function()
|
||
|
{
|
||
|
return parseInt(User.get_current_user_info_field(1, 0));
|
||
|
},
|
||
|
|
||
|
get_use_browser: function()
|
||
|
{
|
||
|
var setting = User.get_current_user_info_field(2, "0");
|
||
|
return setting == "1";
|
||
|
},
|
||
|
|
||
|
is_member_or_higher: function()
|
||
|
{
|
||
|
return User.get_current_user_level() >= 20;
|
||
|
},
|
||
|
|
||
|
is_mod_or_higher: function()
|
||
|
{
|
||
|
return User.get_current_user_level() >= 40;
|
||
|
}
|
||
|
}
|
||
|
|