Refactor most pug templates to share a common layout template
This commit is contained in:
parent
0810591fe3
commit
712a8c228b
|
@ -1,103 +1,88 @@
|
||||||
doctype html
|
extends layout.pug
|
||||||
html(lang="en")
|
|
||||||
head
|
|
||||||
include head
|
|
||||||
+head()
|
|
||||||
body
|
|
||||||
#wrap
|
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
|
||||||
include nav
|
|
||||||
+navheader()
|
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
|
||||||
ul.nav.navbar-nav
|
|
||||||
+navdefaultlinks()
|
|
||||||
+navloginlogout()
|
|
||||||
section#mainpage
|
|
||||||
.container
|
|
||||||
if !loggedIn
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
.alert.alert-danger.messagebox.center
|
|
||||||
strong Authorization Required
|
|
||||||
p You must be <a href="/login">logged in</a> to view this page.
|
|
||||||
else
|
|
||||||
.col-lg-6.col-md-6
|
|
||||||
h3 My Channels
|
|
||||||
if deleteChannelError
|
|
||||||
.alert.alert-danger.center.messagebox
|
|
||||||
strong Channel Deletion Failed
|
|
||||||
p= deleteChannelError
|
|
||||||
if channels.length == 0
|
|
||||||
.center
|
|
||||||
strong You haven't registered any channels
|
|
||||||
else
|
|
||||||
table.table.table-bordered
|
|
||||||
thead
|
|
||||||
tr
|
|
||||||
th Channel
|
|
||||||
tbody
|
|
||||||
for c in channels
|
|
||||||
tr
|
|
||||||
th
|
|
||||||
form.form-inline.pull-right(action="/account/channels", method="post", onsubmit="return confirm('Are you sure you want to delete " +c.name+ "? This cannot be undone');")
|
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
|
||||||
input(type="hidden", name="action", value="delete_channel")
|
|
||||||
input(type="hidden", name="name", value=c.name)
|
|
||||||
button.btn.btn-xs.btn-danger(type="submit") Delete
|
|
||||||
span.glyphicon.glyphicon-trash
|
|
||||||
a(href=`/${channelPath}/${c.name}`, style="margin-left: 5px")= c.name
|
|
||||||
.col-lg-6.col-md-6
|
|
||||||
h3 Register a new channel
|
|
||||||
if newChannelError
|
|
||||||
.alert.alert-danger.messagebox.center
|
|
||||||
strong Channel Registration Failed
|
|
||||||
p= newChannelError
|
|
||||||
form(action="/account/channels", method="post")
|
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
|
||||||
input(type="hidden", name="action", value="new_channel")
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="channelname") Channel URL
|
|
||||||
.input-group
|
|
||||||
span.input-group-addon #{baseUrl}/#{channelPath}/
|
|
||||||
input#channelname.form-control(type="text", name="name", maxlength="30", onkeyup="checkChannel()")
|
|
||||||
p#validate_channel.text-danger.pull-right
|
|
||||||
button#register.btn.btn-primary.btn-block(type="submit") Register
|
|
||||||
|
|
||||||
include footer
|
block content
|
||||||
+footer()
|
if !loggedIn
|
||||||
script( type='text/javascript').
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
function checkChannel(){
|
.alert.alert-danger.messagebox.center
|
||||||
function nameIsInvalid(id){
|
strong Authorization Required
|
||||||
if(/\s/.test(id)){
|
p You must be <a href="/login">logged in</a> to view this page.
|
||||||
return 'Channel URL may not contain spaces';
|
else
|
||||||
}
|
.col-lg-6.col-md-6
|
||||||
if(id === ''){
|
h3 My Channels
|
||||||
return 'Channel URL must not be empty';
|
if deleteChannelError
|
||||||
}
|
.alert.alert-danger.center.messagebox
|
||||||
if(!/^[\w-]{1,30}$/.test(id)){
|
strong Channel Deletion Failed
|
||||||
return 'Channel URL may only consist of a-z, A-Z, 0-9, - and _';
|
p= deleteChannelError
|
||||||
}
|
if channels.length == 0
|
||||||
return false;
|
.center
|
||||||
|
strong You haven't registered any channels
|
||||||
|
else
|
||||||
|
table.table.table-bordered
|
||||||
|
thead
|
||||||
|
tr
|
||||||
|
th Channel
|
||||||
|
tbody
|
||||||
|
for c in channels
|
||||||
|
tr
|
||||||
|
th
|
||||||
|
form.form-inline.pull-right(action="/account/channels", method="post", onsubmit="return confirm('Are you sure you want to delete " +c.name+ "? This cannot be undone');")
|
||||||
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
|
input(type="hidden", name="action", value="delete_channel")
|
||||||
|
input(type="hidden", name="name", value=c.name)
|
||||||
|
button.btn.btn-xs.btn-danger(type="submit") Delete
|
||||||
|
span.glyphicon.glyphicon-trash
|
||||||
|
a(href=`/${channelPath}/${c.name}`, style="margin-left: 5px")= c.name
|
||||||
|
.col-lg-6.col-md-6
|
||||||
|
h3 Register a new channel
|
||||||
|
if newChannelError
|
||||||
|
.alert.alert-danger.messagebox.center
|
||||||
|
strong Channel Registration Failed
|
||||||
|
p= newChannelError
|
||||||
|
form(action="/account/channels", method="post")
|
||||||
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
|
input(type="hidden", name="action", value="new_channel")
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="channelname") Channel URL
|
||||||
|
.input-group
|
||||||
|
span.input-group-addon #{baseUrl}/#{channelPath}/
|
||||||
|
input#channelname.form-control(type="text", name="name", maxlength="30", onkeyup="checkChannel()")
|
||||||
|
p#validate_channel.text-danger.pull-right
|
||||||
|
button#register.btn.btn-primary.btn-block(type="submit") Register
|
||||||
|
|
||||||
|
append footer
|
||||||
|
script(type='text/javascript').
|
||||||
|
function checkChannel(){
|
||||||
|
function nameIsInvalid(id){
|
||||||
|
if(/\s/.test(id)){
|
||||||
|
return 'Channel URL may not contain spaces';
|
||||||
}
|
}
|
||||||
|
if(id === ''){
|
||||||
var box = $("#channelname");
|
return 'Channel URL must not be empty';
|
||||||
var value = box.val();
|
}
|
||||||
var lastkey = Date.now();
|
if(!/^[\w-]{1,30}$/.test(id)){
|
||||||
box.data("lastkey", lastkey);
|
return 'Channel URL may only consist of a-z, A-Z, 0-9, - and _';
|
||||||
|
}
|
||||||
setTimeout(function () {
|
return false;
|
||||||
if (box.data("lastkey") !== lastkey || box.val() !== value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(nameIsInvalid(value)){
|
|
||||||
$('#validate_channel').text(nameIsInvalid(value))
|
|
||||||
.parent().addClass('has-error').removeClass('has-success');
|
|
||||||
$('#register').addClass('disabled');
|
|
||||||
} else {
|
|
||||||
$('#validate_channel').text('')
|
|
||||||
.parent().addClass('has-success').removeClass('has-error');
|
|
||||||
$('#register').removeClass('disabled');
|
|
||||||
}
|
|
||||||
}, 200);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var box = $("#channelname");
|
||||||
|
var value = box.val();
|
||||||
|
var lastkey = Date.now();
|
||||||
|
box.data("lastkey", lastkey);
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
if (box.data("lastkey") !== lastkey || box.val() !== value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(nameIsInvalid(value)){
|
||||||
|
$('#validate_channel').text(nameIsInvalid(value))
|
||||||
|
.parent().addClass('has-error').removeClass('has-success');
|
||||||
|
$('#register').addClass('disabled');
|
||||||
|
} else {
|
||||||
|
$('#validate_channel').text('')
|
||||||
|
.parent().addClass('has-success').removeClass('has-error');
|
||||||
|
$('#register').removeClass('disabled');
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,96 +1,83 @@
|
||||||
doctype html
|
extends layout.pug
|
||||||
html(lang="en")
|
|
||||||
head
|
|
||||||
include head
|
|
||||||
+head()
|
|
||||||
body
|
|
||||||
#wrap
|
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
|
||||||
include nav
|
|
||||||
+navheader()
|
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
|
||||||
ul.nav.navbar-nav
|
|
||||||
+navdefaultlinks()
|
|
||||||
+navloginlogout()
|
|
||||||
section#mainpage
|
|
||||||
.container
|
|
||||||
if !loggedIn
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
.alert.alert-danger.messagebox.center
|
|
||||||
strong Authorization Required
|
|
||||||
p You must be <a href="/login">logged in</a> to view this page.
|
|
||||||
else
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
if successMessage
|
|
||||||
.alert.alert-success.center
|
|
||||||
p= successMessage
|
|
||||||
else if errorMessage
|
|
||||||
.alert.alert-danger.center
|
|
||||||
p= errorMessage
|
|
||||||
h3 Change Password
|
|
||||||
form(action="/account/edit", method="post", onsubmit="return validatePasswordChange()")
|
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
|
||||||
input(type="hidden", name="action", value="change_password")
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="username") Username
|
|
||||||
input#username.form-control(type="text", name="name", value=loginName, disabled=true)
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="oldpassword") Current Password
|
|
||||||
input#oldpassword.form-control(type="password", name="oldpassword")
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="newpassword") New Password
|
|
||||||
input#newpassword.form-control(type="password", name="newpassword")
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="newpassword_confirm") Confirm New Password
|
|
||||||
input#newpassword_confirm.form-control(type="password", name="newpassword_confirm")
|
|
||||||
button#changepassbtn.btn.btn-danger.btn-block(type="submit") Change Password
|
|
||||||
hr
|
|
||||||
h3 Change Email
|
|
||||||
form(action="/account/edit", method="post", onsubmit="return submitEmail()")
|
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
|
||||||
input(type="hidden", name="action", value="change_email")
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="username2") Username
|
|
||||||
input#username2.form-control(type="text", name="name", value=loginName, disabled=true)
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="password2") Password
|
|
||||||
input#password2.form-control(type="password", name="password")
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="email") New Email
|
|
||||||
input#email.form-control(type="email", name="email")
|
|
||||||
button#changeemailbtn.btn.btn-danger.btn-block(type="submit") Change Email
|
|
||||||
include footer
|
|
||||||
+footer()
|
|
||||||
script(type="text/javascript").
|
|
||||||
function validatePasswordChange() {
|
|
||||||
var pw = $("#newpassword").val();
|
|
||||||
var pwc = $("#newpassword_confirm").val();
|
|
||||||
$("#passwordempty").remove();
|
|
||||||
$("#passwordmismatch").remove();
|
|
||||||
|
|
||||||
if (pw === '') {
|
block content
|
||||||
|
if !loggedIn
|
||||||
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
|
.alert.alert-danger.messagebox.center
|
||||||
|
strong Authorization Required
|
||||||
|
p You must be <a href="/login">logged in</a> to view this page.
|
||||||
|
else
|
||||||
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
|
if successMessage
|
||||||
|
.alert.alert-success.center
|
||||||
|
p= successMessage
|
||||||
|
else if errorMessage
|
||||||
|
.alert.alert-danger.center
|
||||||
|
p= errorMessage
|
||||||
|
h3 Change Password
|
||||||
|
form(action="/account/edit", method="post", onsubmit="return validatePasswordChange()")
|
||||||
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
|
input(type="hidden", name="action", value="change_password")
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="username") Username
|
||||||
|
input#username.form-control(type="text", name="name", value=loginName, disabled=true)
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="oldpassword") Current Password
|
||||||
|
input#oldpassword.form-control(type="password", name="oldpassword")
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="newpassword") New Password
|
||||||
|
input#newpassword.form-control(type="password", name="newpassword")
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="newpassword_confirm") Confirm New Password
|
||||||
|
input#newpassword_confirm.form-control(type="password", name="newpassword_confirm")
|
||||||
|
button#changepassbtn.btn.btn-danger.btn-block(type="submit") Change Password
|
||||||
|
hr
|
||||||
|
h3 Change Email
|
||||||
|
form(action="/account/edit", method="post", onsubmit="return submitEmail()")
|
||||||
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
|
input(type="hidden", name="action", value="change_email")
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="username2") Username
|
||||||
|
input#username2.form-control(type="text", name="name", value=loginName, disabled=true)
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="password2") Password
|
||||||
|
input#password2.form-control(type="password", name="password")
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="email") New Email
|
||||||
|
input#email.form-control(type="email", name="email")
|
||||||
|
button#changeemailbtn.btn.btn-danger.btn-block(type="submit") Change Email
|
||||||
|
|
||||||
|
append footer
|
||||||
|
script(type="text/javascript").
|
||||||
|
function validatePasswordChange() {
|
||||||
|
var pw = $("#newpassword").val();
|
||||||
|
var pwc = $("#newpassword_confirm").val();
|
||||||
|
$("#passwordempty").remove();
|
||||||
|
$("#passwordmismatch").remove();
|
||||||
|
|
||||||
|
if (pw === '') {
|
||||||
|
$("#newpassword").parent().addClass("has-error");
|
||||||
|
$("<p/>").addClass("text-danger")
|
||||||
|
.attr("id", "passwordempty")
|
||||||
|
.text("Password must not be empty")
|
||||||
|
.insertAfter($("#newpassword"));
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (pw !== pwc) {
|
||||||
|
$("#newpassword_confirm").parent().addClass("has-error");
|
||||||
$("#newpassword").parent().addClass("has-error");
|
$("#newpassword").parent().addClass("has-error");
|
||||||
$("<p/>").addClass("text-danger")
|
$("<p/>").addClass("text-danger")
|
||||||
.attr("id", "passwordempty")
|
.attr("id", "passwordmismatch")
|
||||||
.text("Password must not be empty")
|
.text("Passwords do not match")
|
||||||
.insertAfter($("#newpassword"));
|
.insertAfter($("#newpassword_confirm"));
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (pw !== pwc) {
|
$("#username").attr("disabled", false);
|
||||||
$("#newpassword_confirm").parent().addClass("has-error");
|
return true;
|
||||||
$("#newpassword").parent().addClass("has-error");
|
|
||||||
$("<p/>").addClass("text-danger")
|
|
||||||
.attr("id", "passwordmismatch")
|
|
||||||
.text("Passwords do not match")
|
|
||||||
.insertAfter($("#newpassword_confirm"));
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
$("#username").attr("disabled", false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function submitEmail() {
|
}
|
||||||
$("#username2").attr("disabled", false);
|
function submitEmail() {
|
||||||
return true;
|
$("#username2").attr("disabled", false);
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -1,28 +1,13 @@
|
||||||
doctype html
|
extends layout.pug
|
||||||
html(lang="en")
|
|
||||||
head
|
block content
|
||||||
include head
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
+head()
|
h3 Recover Password
|
||||||
body
|
if recovered
|
||||||
#wrap
|
.alert.alert-success.center.messagebox
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
strong Your password has been changed
|
||||||
include nav
|
p Your account has been assigned the temporary password <code>#{recoverPw}</code>. You may now use this password to log in and choose a new password by visiting the <a href="/account/edit">change password/email</a> page.
|
||||||
+navheader()
|
else
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
.alert.alert-danger.center.messagebox
|
||||||
ul.nav.navbar-nav
|
strong Password recovery failed
|
||||||
+navdefaultlinks()
|
p= recoverErr
|
||||||
+navloginlogout()
|
|
||||||
section#mainpage
|
|
||||||
.container
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
h3 Recover Password
|
|
||||||
if recovered
|
|
||||||
.alert.alert-success.center.messagebox
|
|
||||||
strong Your password has been changed
|
|
||||||
p Your account has been assigned the temporary password <code>#{recoverPw}</code>. You may now use this password to log in and choose a new password by visiting the <a href="/account/edit">change password/email</a> page.
|
|
||||||
else
|
|
||||||
.alert.alert-danger.center.messagebox
|
|
||||||
strong Password recovery failed
|
|
||||||
p= recoverErr
|
|
||||||
include footer
|
|
||||||
+footer()
|
|
||||||
|
|
|
@ -1,38 +1,22 @@
|
||||||
doctype html
|
extends layout.pug
|
||||||
html(lang="en")
|
|
||||||
head
|
|
||||||
include head
|
|
||||||
+head()
|
|
||||||
body
|
|
||||||
#wrap
|
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
|
||||||
include nav
|
|
||||||
+navheader()
|
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
|
||||||
ul.nav.navbar-nav
|
|
||||||
+navdefaultlinks()
|
|
||||||
+navloginlogout()
|
|
||||||
section#mainpage
|
|
||||||
.container
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
h3 Reset Password
|
|
||||||
if reset
|
|
||||||
.alert.alert-success.center.messagebox
|
|
||||||
strong Password reset request sent
|
|
||||||
p Please check #{resetEmail} for your recovery link.
|
|
||||||
else if resetErr
|
|
||||||
.alert.alert-danger.center.messagebox
|
|
||||||
strong Error
|
|
||||||
p= resetErr
|
|
||||||
form(action="/account/passwordreset", method="post", role="form")
|
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="username") Username
|
|
||||||
input#username.form-control(type="text", name="name")
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="email") Email address
|
|
||||||
input#email.form-control(type="email", name="email")
|
|
||||||
button.btn.btn-primary.btn-block(type="submit") Send reset request
|
|
||||||
|
|
||||||
include footer
|
block content
|
||||||
+footer()
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
|
h3 Reset Password
|
||||||
|
if reset
|
||||||
|
.alert.alert-success.center.messagebox
|
||||||
|
strong Password reset request sent
|
||||||
|
p Please check #{resetEmail} for your recovery link.
|
||||||
|
else if resetErr
|
||||||
|
.alert.alert-danger.center.messagebox
|
||||||
|
strong Error
|
||||||
|
p= resetErr
|
||||||
|
form(action="/account/passwordreset", method="post", role="form")
|
||||||
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="username") Username
|
||||||
|
input#username.form-control(type="text", name="name")
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="email") Email address
|
||||||
|
input#email.form-control(type="email", name="email")
|
||||||
|
button.btn.btn-primary.btn-block(type="submit") Send reset request
|
||||||
|
|
|
@ -1,76 +1,62 @@
|
||||||
doctype html
|
extends layout.pug
|
||||||
html(lang="en")
|
|
||||||
head
|
|
||||||
include head
|
|
||||||
+head()
|
|
||||||
body
|
|
||||||
#wrap
|
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
|
||||||
include nav
|
|
||||||
+navheader()
|
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
|
||||||
ul.nav.navbar-nav
|
|
||||||
+navdefaultlinks()
|
|
||||||
+navloginlogout()
|
|
||||||
section#mainpage
|
|
||||||
.container
|
|
||||||
if !loggedIn
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
.alert.alert-danger.messagebox.center
|
|
||||||
strong Authorization Required
|
|
||||||
p You must be <a href="/login">logged in</a> to view this page.
|
|
||||||
else
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
h3 Profile
|
|
||||||
if profileError
|
|
||||||
.alert.alert-danger.center.messagebox
|
|
||||||
strong Profile Error
|
|
||||||
p= profileError
|
|
||||||
.profile-box.linewrap(style="position: inherit; z-index: auto;")
|
|
||||||
img.profile-image(src=profileImage)
|
|
||||||
strong= loginName
|
|
||||||
p= profileText
|
|
||||||
h3 Edit Profile
|
|
||||||
form(action="/account/profile", method="post", role="form")
|
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="profileimage") Image
|
|
||||||
input#profileimage.form-control(type="text", name="image", maxlength="255")
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="profiletext") Text
|
|
||||||
textarea#profiletext.form-control(cols="10", name="text", maxlength="255")= profileText
|
|
||||||
button.btn.btn-primary.btn-block(type="submit") Save
|
|
||||||
|
|
||||||
include footer
|
block content
|
||||||
+footer()
|
if !loggedIn
|
||||||
script(type="text/javascript").
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
var $profileImage = $("#profileimage");
|
.alert.alert-danger.messagebox.center
|
||||||
$profileImage.val("#{profileImage}");
|
strong Authorization Required
|
||||||
var hasError = false;
|
p You must be <a href="/login">logged in</a> to view this page.
|
||||||
function validateImage() {
|
else
|
||||||
var value = $profileImage.val().trim();
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
$profileImage.val(value);
|
h3 Profile
|
||||||
if (!/^$|^https:/.test(value)) {
|
if profileError
|
||||||
hasError = true;
|
.alert.alert-danger.center.messagebox
|
||||||
$profileImage.parent().addClass("has-error");
|
strong Profile Error
|
||||||
var $error = $("#profileimage-error");
|
p= profileError
|
||||||
if ($error.length === 0) {
|
.profile-box.linewrap(style="position: inherit; z-index: auto;")
|
||||||
$error = $("<p/>")
|
img.profile-image(src=profileImage)
|
||||||
.attr({ id: "profileimage-error" })
|
strong= loginName
|
||||||
.addClass("text-danger")
|
p= profileText
|
||||||
.html("Profile image must be a URL beginning with <code>https://</code>")
|
h3 Edit Profile
|
||||||
.insertAfter($profileImage);
|
form(action="/account/profile", method="post", role="form")
|
||||||
}
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
} else {
|
.form-group
|
||||||
hasError = false;
|
label.control-label(for="profileimage") Image
|
||||||
$profileImage.parent().removeClass("has-error");
|
input#profileimage.form-control(type="text", name="image", maxlength="255")
|
||||||
$("#profileimage-error").remove();
|
.form-group
|
||||||
|
label.control-label(for="profiletext") Text
|
||||||
|
textarea#profiletext.form-control(cols="10", name="text", maxlength="255")= profileText
|
||||||
|
button.btn.btn-primary.btn-block(type="submit") Save
|
||||||
|
|
||||||
|
append footer
|
||||||
|
script(type="text/javascript").
|
||||||
|
var $profileImage = $("#profileimage");
|
||||||
|
$profileImage.val("#{profileImage}");
|
||||||
|
var hasError = false;
|
||||||
|
function validateImage() {
|
||||||
|
var value = $profileImage.val().trim();
|
||||||
|
$profileImage.val(value);
|
||||||
|
if (!/^$|^https:/.test(value)) {
|
||||||
|
hasError = true;
|
||||||
|
$profileImage.parent().addClass("has-error");
|
||||||
|
var $error = $("#profileimage-error");
|
||||||
|
if ($error.length === 0) {
|
||||||
|
$error = $("<p/>")
|
||||||
|
.attr({ id: "profileimage-error" })
|
||||||
|
.addClass("text-danger")
|
||||||
|
.html("Profile image must be a URL beginning with <code>https://</code>")
|
||||||
|
.insertAfter($profileImage);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
hasError = false;
|
||||||
|
$profileImage.parent().removeClass("has-error");
|
||||||
|
$("#profileimage-error").remove();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$("form").submit(function (event) {
|
$("form").submit(function (event) {
|
||||||
validateImage();
|
validateImage();
|
||||||
if (hasError) {
|
if (hasError) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,47 +1,34 @@
|
||||||
|
extends layout.pug
|
||||||
|
|
||||||
mixin email(e, k)
|
mixin email(e, k)
|
||||||
button.btn.btn-xs.btn-default(onclick="showEmail(this, '"+e+"', '"+k+"')") Show Email
|
button.btn.btn-xs.btn-default(onclick="showEmail(this, '"+e+"', '"+k+"')") Show Email
|
||||||
|
|
||||||
doctype html
|
block content
|
||||||
html(lang="en")
|
.col-md-8.col-md-offset-2
|
||||||
head
|
h1 Contact
|
||||||
include head
|
h3 Email
|
||||||
+head()
|
if contacts.length == 0
|
||||||
body
|
p No contacts listed.
|
||||||
#wrap
|
else
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
each contact in contacts
|
||||||
include nav
|
strong= contact.name
|
||||||
+navheader()
|
p.text-muted= contact.title
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
+email(contact.email, contact.emkey)
|
||||||
ul.nav.navbar-nav
|
br
|
||||||
+navdefaultlinks()
|
hr
|
||||||
+navloginlogout()
|
|
||||||
section#mainpage
|
append footer
|
||||||
.container
|
script(type="text/javascript").
|
||||||
.col-md-8.col-md-offset-2
|
function showEmail(btn, email, key) {
|
||||||
h1 Contact
|
email = unescape(email);
|
||||||
h3 Email
|
key = unescape(key);
|
||||||
if contacts.length == 0
|
var dest = new Array(email.length);
|
||||||
p No contacts listed.
|
for (var i = 0; i < email.length; i++) {
|
||||||
else
|
dest[i] = String.fromCharCode(email.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
||||||
each contact in contacts
|
|
||||||
strong= contact.name
|
|
||||||
p.text-muted= contact.title
|
|
||||||
+email(contact.email, contact.emkey)
|
|
||||||
br
|
|
||||||
hr
|
|
||||||
include footer
|
|
||||||
+footer()
|
|
||||||
script(type="text/javascript").
|
|
||||||
function showEmail(btn, email, key) {
|
|
||||||
email = unescape(email);
|
|
||||||
key = unescape(key);
|
|
||||||
var dest = new Array(email.length);
|
|
||||||
for (var i = 0; i < email.length; i++) {
|
|
||||||
dest[i] = String.fromCharCode(email.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
|
||||||
}
|
|
||||||
email = dest.join("");
|
|
||||||
$("<a/>").attr("href", "mailto:" + email)
|
|
||||||
.text(email)
|
|
||||||
.insertBefore(btn);
|
|
||||||
$(btn).remove();
|
|
||||||
}
|
}
|
||||||
|
email = dest.join("");
|
||||||
|
$("<a/>").attr("href", "mailto:" + email)
|
||||||
|
.text(email)
|
||||||
|
.insertBefore(btn);
|
||||||
|
$(btn).remove();
|
||||||
|
}
|
||||||
|
|
|
@ -1,31 +1,15 @@
|
||||||
doctype html
|
extends layout.pug
|
||||||
html(lang="en")
|
|
||||||
head
|
|
||||||
include head
|
|
||||||
+head()
|
|
||||||
body
|
|
||||||
#wrap
|
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
|
||||||
include nav
|
|
||||||
+navheader()
|
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
|
||||||
ul.nav.navbar-nav
|
|
||||||
+navdefaultlinks()
|
|
||||||
+navloginlogout()
|
|
||||||
|
|
||||||
section#mainpage.container
|
block content
|
||||||
.col-md-12
|
.col-md-12
|
||||||
.alert.alert-danger
|
.alert.alert-danger
|
||||||
h1 Invalid Session
|
h1 Invalid Session
|
||||||
p Your browser attempted to submit form data to <code>#{path}</code> with an invalid authentication token. This may be because:
|
p Your browser attempted to submit form data to <code>#{path}</code> with an invalid authentication token. This may be because:
|
||||||
ul
|
ul
|
||||||
li Your session has expired
|
li Your session has expired
|
||||||
li Your request was missing the authentication token
|
li Your request was missing the authentication token
|
||||||
li A malicious user has attempted to tamper with your session
|
li A malicious user has attempted to tamper with your session
|
||||||
li Your browser does not support cookies, or they are not enabled
|
li Your browser does not support cookies, or they are not enabled
|
||||||
| If the problem persists, please contact an administrator.
|
| If the problem persists, please contact an administrator.
|
||||||
if referer
|
if referer
|
||||||
a(href=referer) Return to previous page
|
a(href=referer) Return to previous page
|
||||||
|
|
||||||
include footer
|
|
||||||
+footer()
|
|
||||||
|
|
|
@ -1,60 +1,44 @@
|
||||||
doctype html
|
extends layout.pug
|
||||||
html(lang="en")
|
|
||||||
head
|
|
||||||
include head
|
|
||||||
+head()
|
|
||||||
body
|
|
||||||
#wrap
|
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
|
||||||
include nav
|
|
||||||
+navheader()
|
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
|
||||||
ul.nav.navbar-nav
|
|
||||||
+navdefaultlinks()
|
|
||||||
+navloginlogout()
|
|
||||||
section#mainpage
|
|
||||||
.container
|
|
||||||
.col-md-8.col-md-offset-2
|
|
||||||
h1 Google Drive Userscript
|
|
||||||
h2 Why?
|
|
||||||
p.
|
|
||||||
Since Google Drive support was launched in early 2014, it has broken
|
|
||||||
at least 4-5 times, requiring increasing effort to get it working again
|
|
||||||
and disrupting many channels. This is because there is no official API
|
|
||||||
for it like there is for YouTube videos, which means support for it
|
|
||||||
relies on undocumented tricks. In August 2016, the decision was made
|
|
||||||
to phase out the native support for Google Drive and instead require
|
|
||||||
users to install a userscript, which allows to bypass certain browser
|
|
||||||
restrictions and make the code easier, simpler, and less prone to failure
|
|
||||||
(it could still break due to future Google Drive changes, but is less
|
|
||||||
likely to be difficult to fix).
|
|
||||||
h2 How It Works
|
|
||||||
p.
|
|
||||||
The userscript is a short script that you can install using a browser
|
|
||||||
extension such as Greasemonkey or Tampermonkey that runs on the page
|
|
||||||
and provides additional functionality needed to play Google Drive
|
|
||||||
videos.
|
|
||||||
h2 Installation
|
|
||||||
ul
|
|
||||||
li
|
|
||||||
strong Chrome
|
|
||||||
| —Install <a href="https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo" target="_blank">Tampermonkey</a>.
|
|
||||||
li
|
|
||||||
strong Firefox
|
|
||||||
| —Install <a href="https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/" target="_blank">Tampermonkey</a>
|
|
||||||
| or <a href="https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/" target="_blank">Greasemonkey</a>.
|
|
||||||
li
|
|
||||||
strong Other Browsers
|
|
||||||
| —Install the appropriate userscript plugin for your browser.
|
|
||||||
| Tampermonkey supports many browsers besides Chrome.
|
|
||||||
p.
|
|
||||||
Once you have installed the userscript manager addon for your browser,
|
|
||||||
you can <a href="/js/cytube-google-drive.user.js" target="_blank">
|
|
||||||
install the userscript</a>. If this link 404s, it means the administrator
|
|
||||||
of this server hasn't generated it yet.
|
|
||||||
p.
|
|
||||||
You can find a guide with screenshots of the installation process
|
|
||||||
<a href="https://github.com/calzoneman/sync/wiki/Google-Drive-Userscript-Installation-Guide" target="_blank">on GitHub</a>.
|
|
||||||
|
|
||||||
include footer
|
block content
|
||||||
+footer()
|
.col-md-8.col-md-offset-2
|
||||||
|
h1 Google Drive Userscript
|
||||||
|
h2 Why?
|
||||||
|
p.
|
||||||
|
Since Google Drive support was launched in early 2014, it has broken
|
||||||
|
at least 4-5 times, requiring increasing effort to get it working again
|
||||||
|
and disrupting many channels. This is because there is no official API
|
||||||
|
for it like there is for YouTube videos, which means support for it
|
||||||
|
relies on undocumented tricks. In August 2016, the decision was made
|
||||||
|
to phase out the native support for Google Drive and instead require
|
||||||
|
users to install a userscript, which allows to bypass certain browser
|
||||||
|
restrictions and make the code easier, simpler, and less prone to failure
|
||||||
|
(it could still break due to future Google Drive changes, but is less
|
||||||
|
likely to be difficult to fix).
|
||||||
|
h2 How It Works
|
||||||
|
p.
|
||||||
|
The userscript is a short script that you can install using a browser
|
||||||
|
extension such as Greasemonkey or Tampermonkey that runs on the page
|
||||||
|
and provides additional functionality needed to play Google Drive
|
||||||
|
videos.
|
||||||
|
h2 Installation
|
||||||
|
ul
|
||||||
|
li
|
||||||
|
strong Chrome
|
||||||
|
| —Install <a href="https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo" target="_blank">Tampermonkey</a>.
|
||||||
|
li
|
||||||
|
strong Firefox
|
||||||
|
| —Install <a href="https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/" target="_blank">Tampermonkey</a>
|
||||||
|
| or <a href="https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/" target="_blank">Greasemonkey</a>.
|
||||||
|
li
|
||||||
|
strong Other Browsers
|
||||||
|
| —Install the appropriate userscript plugin for your browser.
|
||||||
|
| Tampermonkey supports many browsers besides Chrome.
|
||||||
|
p.
|
||||||
|
Once you have installed the userscript manager addon for your browser,
|
||||||
|
you can <a href="/js/cytube-google-drive.user.js" target="_blank">
|
||||||
|
install the userscript</a>. If this link 404s, it means the administrator
|
||||||
|
of this server hasn't generated it yet.
|
||||||
|
p.
|
||||||
|
You can find a guide with screenshots of the installation process
|
||||||
|
<a href="https://github.com/calzoneman/sync/wiki/Google-Drive-Userscript-Installation-Guide" target="_blank">on GitHub</a>.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
extends layout.pug
|
||||||
|
|
||||||
mixin notfound()
|
mixin notfound()
|
||||||
h1 Not Found
|
h1 Not Found
|
||||||
p The page you were looking for doesn't seem to exist. Please check that you typed the URL correctly.
|
p The page you were looking for doesn't seem to exist. Please check that you typed the URL correctly.
|
||||||
|
@ -9,30 +11,13 @@ mixin forbidden()
|
||||||
mixin genericerror()
|
mixin genericerror()
|
||||||
h1 Oops
|
h1 Oops
|
||||||
p Your request could not be processed. Status code: <code>#{status}</code>, message: <code>#{message}</code>
|
p Your request could not be processed. Status code: <code>#{status}</code>, message: <code>#{message}</code>
|
||||||
doctype html
|
|
||||||
html(lang="en")
|
|
||||||
head
|
|
||||||
include head
|
|
||||||
+head()
|
|
||||||
body
|
|
||||||
#wrap
|
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
|
||||||
include nav
|
|
||||||
+navheader()
|
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
|
||||||
ul.nav.navbar-nav
|
|
||||||
+navdefaultlinks()
|
|
||||||
+navloginlogout()
|
|
||||||
|
|
||||||
section#mainpage.container
|
block content
|
||||||
.col-md-12
|
.col-md-12
|
||||||
.alert.alert-danger
|
.alert.alert-danger
|
||||||
if status == 404
|
if status == 404
|
||||||
+notfound()
|
+notfound()
|
||||||
else if status == 403
|
else if status == 403
|
||||||
+forbidden()
|
+forbidden()
|
||||||
else
|
else
|
||||||
+genericerror()
|
+genericerror()
|
||||||
|
|
||||||
include footer
|
|
||||||
+footer()
|
|
||||||
|
|
|
@ -1,42 +1,26 @@
|
||||||
doctype html
|
extends layout.pug
|
||||||
html(lang="en")
|
|
||||||
head
|
block content
|
||||||
include head
|
.col-lg-9.col-md-9
|
||||||
+head()
|
h3 Public Channels
|
||||||
body
|
table.table.table-bordered.table-striped
|
||||||
#wrap
|
thead
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
th Channel
|
||||||
include nav
|
th # Connected
|
||||||
+navheader()
|
th Now Playing
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
tbody
|
||||||
ul.nav.navbar-nav
|
each chan in channels
|
||||||
+navdefaultlinks()
|
tr
|
||||||
+navsuperadmin(false)
|
td: a(href=`/${channelPath}/${chan.name}`) #{chan.pagetitle} (#{chan.name})
|
||||||
+navloginlogout()
|
td= chan.usercount
|
||||||
section#mainpage
|
td= chan.mediatitle
|
||||||
.container
|
.col-lg-3.col-md-3
|
||||||
.col-lg-9.col-md-9
|
h3 Enter Channel
|
||||||
h3 Public Channels
|
input#channelname.form-control(type="text", placeholder="Channel Name")
|
||||||
table.table.table-bordered.table-striped
|
p.text-muted New channels can be registered from the <a href="/account/channels">My Channels</a> page.
|
||||||
thead
|
script(type="text/javascript").
|
||||||
th Channel
|
$("#channelname").keydown(function (ev) {
|
||||||
th # Connected
|
if (ev.keyCode === 13) {
|
||||||
th Now Playing
|
location.href = "/#{channelPath}/" + $("#channelname").val();
|
||||||
tbody
|
}
|
||||||
each chan in channels
|
});
|
||||||
tr
|
|
||||||
td: a(href=`/${channelPath}/${chan.name}`) #{chan.pagetitle} (#{chan.name})
|
|
||||||
td= chan.usercount
|
|
||||||
td= chan.mediatitle
|
|
||||||
.col-lg-3.col-md-3
|
|
||||||
h3 Enter Channel
|
|
||||||
input#channelname.form-control(type="text", placeholder="Channel Name")
|
|
||||||
p.text-muted New channels can be registered from the <a href="/account/channels">My Channels</a> page.
|
|
||||||
include footer
|
|
||||||
+footer()
|
|
||||||
script(type="text/javascript").
|
|
||||||
$("#channelname").keydown(function (ev) {
|
|
||||||
if (ev.keyCode === 13) {
|
|
||||||
location.href = "/#{channelPath}/" + $("#channelname").val();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
22
templates/layout.pug
Normal file
22
templates/layout.pug
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
doctype html
|
||||||
|
html(lang="en")
|
||||||
|
head
|
||||||
|
block head
|
||||||
|
include head
|
||||||
|
+head()
|
||||||
|
body
|
||||||
|
#wrap
|
||||||
|
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
||||||
|
include nav
|
||||||
|
+navheader()
|
||||||
|
#nav-collapsible.collapse.navbar-collapse
|
||||||
|
ul.nav.navbar-nav
|
||||||
|
+navdefaultlinks()
|
||||||
|
+navsuperadmin(false)
|
||||||
|
+navloginlogout()
|
||||||
|
section#mainpage
|
||||||
|
.container
|
||||||
|
block content
|
||||||
|
block footer
|
||||||
|
include footer
|
||||||
|
+footer()
|
|
@ -1,54 +1,39 @@
|
||||||
doctype html
|
extends layout.pug
|
||||||
html(lang="en")
|
|
||||||
head
|
block content
|
||||||
include head
|
if wasAlreadyLoggedIn
|
||||||
+head()
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
body
|
.alert.alert-info.messagebox.center
|
||||||
#wrap
|
h3(style="margin: 5px auto") Logged in as #{loginName}
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
else if !loggedIn
|
||||||
include nav
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
+navheader()
|
if loginError
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
.alert.alert-danger.messagebox.center
|
||||||
ul.nav.navbar-nav
|
strong Login Failed
|
||||||
+navdefaultlinks()
|
p= loginError
|
||||||
if loggedIn
|
h2 Login
|
||||||
+navlogoutform()
|
form(role="form", action="/login", method="post")
|
||||||
section#mainpage.container
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
if wasAlreadyLoggedIn
|
if redirect
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
input(type="hidden", name="dest", value=redirect)
|
||||||
.alert.alert-info.messagebox.center
|
.form-group
|
||||||
h3(style="margin: 5px auto") Logged in as #{loginName}
|
label(for="username") Username
|
||||||
else if !loggedIn
|
input#username.form-control(type="text", name="name")
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
.form-group
|
||||||
if loginError
|
label(for="password") Password
|
||||||
.alert.alert-danger.messagebox.center
|
input#password.form-control(type="password", name="password")
|
||||||
strong Login Failed
|
a(href="/account/passwordreset") Forgot password?
|
||||||
p= loginError
|
.form-group
|
||||||
h2 Login
|
.checkbox
|
||||||
form(role="form", action="/login", method="post")
|
label
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
input(type="checkbox", name="remember")
|
||||||
if redirect
|
| Remember me
|
||||||
input(type="hidden", name="dest", value=redirect)
|
button.btn.btn-success.btn-block(type="submit") Login
|
||||||
.form-group
|
else
|
||||||
label(for="username") Username
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
input#username.form-control(type="text", name="name")
|
.alert.alert-success.messagebox.center
|
||||||
.form-group
|
strong Login Successful
|
||||||
label(for="password") Password
|
p Logged in as #{loginName}
|
||||||
input#password.form-control(type="password", name="password")
|
if redirect
|
||||||
a(href="/account/passwordreset") Forgot password?
|
br
|
||||||
.form-group
|
a(href=redirect) Return to previous page
|
||||||
.checkbox
|
|
||||||
label
|
|
||||||
input(type="checkbox", name="remember")
|
|
||||||
| Remember me
|
|
||||||
button.btn.btn-success.btn-block(type="submit") Login
|
|
||||||
else
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
.alert.alert-success.messagebox.center
|
|
||||||
strong Login Successful
|
|
||||||
p Logged in as #{loginName}
|
|
||||||
if redirect
|
|
||||||
br
|
|
||||||
a(href=redirect) Return to previous page
|
|
||||||
include footer
|
|
||||||
+footer()
|
|
||||||
|
|
|
@ -1,23 +1,9 @@
|
||||||
doctype html
|
extends layout.pug
|
||||||
html(lang="en")
|
|
||||||
head
|
block content
|
||||||
include head
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
+head()
|
.alert.alert-info.center.messagebox
|
||||||
body
|
strong Logged out
|
||||||
#wrap
|
p
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
if redirect
|
||||||
include nav
|
a(href=redirect) Return to previous page
|
||||||
+navheader()
|
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
|
||||||
ul.nav.navbar-nav
|
|
||||||
+navdefaultlinks()
|
|
||||||
+navloginform("/")
|
|
||||||
section#mainpage.container
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
.alert.alert-info.center.messagebox
|
|
||||||
strong Logged out
|
|
||||||
p
|
|
||||||
if redirect
|
|
||||||
a(href=redirect) Return to previous page
|
|
||||||
include footer
|
|
||||||
+footer()
|
|
||||||
|
|
|
@ -1,127 +1,114 @@
|
||||||
doctype html
|
extends layout.pug
|
||||||
html(lang="en")
|
|
||||||
head
|
|
||||||
include head
|
|
||||||
+head()
|
|
||||||
body
|
|
||||||
#wrap
|
|
||||||
nav.navbar.navbar-inverse.navbar-fixed-top(role="navigation")
|
|
||||||
include nav
|
|
||||||
+navheader()
|
|
||||||
#nav-collapsible.collapse.navbar-collapse
|
|
||||||
ul.nav.navbar-nav
|
|
||||||
+navdefaultlinks()
|
|
||||||
if loggedIn
|
|
||||||
+navlogoutform()
|
|
||||||
section#mainpage.container
|
|
||||||
if loggedIn
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
.alert.alert-danger.messagebox.center
|
|
||||||
strong Already logged in
|
|
||||||
p.
|
|
||||||
You are already logged in. If you intend to register a new account, please <a href="/logout?redirect=/register">Logout</a> first.
|
|
||||||
// TODO Link to My Account page
|
|
||||||
else if !registered
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
if registerError
|
|
||||||
.alert.alert-danger.messagebox.center
|
|
||||||
strong Registration Failed
|
|
||||||
p= registerError
|
|
||||||
h2 Register
|
|
||||||
form(role="form", action="/register", method="post", onsubmit="return verify()")
|
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="username") Username
|
|
||||||
input#username.form-control(type="text", name="name", onkeyup="checkUsername()", maxlength="20")
|
|
||||||
p#validate_username.text-danger.pull-right
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="password") Password
|
|
||||||
input#password.form-control(type="password", name="password", onkeyup="checkPasswords()")
|
|
||||||
p#validate_password.text-danger.pull-right
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="password_confirm") Confirm Password
|
|
||||||
input#password_confirm.form-control(type="password", onkeyup="checkPasswords()")
|
|
||||||
p#validate_confirm.text-danger.pull-right
|
|
||||||
.form-group
|
|
||||||
label.control-label(for="email") Email (optional)
|
|
||||||
input#email.form-control(type="email", name="email")
|
|
||||||
p#validate_email.text-danger.pull-right
|
|
||||||
p
|
|
||||||
| Providing an email address is optional and will allow you to recover your account via email if you forget your password.
|
|
||||||
strong If you do not provide an email address, you will not be able to recover a lost account!
|
|
||||||
button#registerbtn.btn.btn-success.btn-block(type="submit") Register
|
|
||||||
else
|
|
||||||
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
|
||||||
.alert.alert-success.messagebox.center
|
|
||||||
strong Registration Successful
|
|
||||||
p Thanks for registering, #{registerName}! Now you can <a href="/login">Login</a> to use your account.
|
|
||||||
include footer
|
|
||||||
+footer()
|
|
||||||
script(type="text/javascript").
|
|
||||||
function verify() {
|
|
||||||
var valid = checkUsername();
|
|
||||||
valid = checkPasswords() && valid;
|
|
||||||
valid = checkEmail() && valid;
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
function checkUsername() {
|
|
||||||
function stateError(text){
|
|
||||||
target.parent()
|
|
||||||
.addClass("has-error")
|
|
||||||
.removeClass("has-success");
|
|
||||||
$("#validate_username").text(text);
|
|
||||||
}
|
|
||||||
var target = $("#username");
|
|
||||||
var name = target.val();
|
|
||||||
if (name === "") {
|
|
||||||
stateError('Username must not be empty')
|
|
||||||
return false;
|
|
||||||
} else if (!(/^[-\w\u00c0-\u00ff]{1,20}$/).test(name)) {
|
|
||||||
stateError("Username must consist of 1-20 characters" +
|
|
||||||
" a-Z, A-Z, 0-9, -, or _.");
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
target.parent()
|
|
||||||
.removeClass("has-error")
|
|
||||||
.addClass("has-success");
|
|
||||||
$("#validate_username").text('');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function checkPasswords() {
|
|
||||||
function stateError(text, target, validator){
|
|
||||||
target.parent()
|
|
||||||
.addClass("has-error")
|
|
||||||
.removeClass("has-success");
|
|
||||||
$(`#${validator}`).text(text);
|
|
||||||
}
|
|
||||||
var target = $("#password");
|
|
||||||
var target2 = $("#password_confirm");
|
|
||||||
var pw = target.val();
|
|
||||||
var pwc = target2.val();
|
|
||||||
|
|
||||||
$("#validate_password").text('');
|
block content
|
||||||
$("#validate_confirm").text('');
|
if loggedIn
|
||||||
if (pw === "") {
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
stateError('Password must not be empty', target, 'validate_password')
|
.alert.alert-danger.messagebox.center
|
||||||
|
strong Already logged in
|
||||||
|
p.
|
||||||
|
You are already logged in. If you intend to register a new account, please <a href="/logout?redirect=/register">Logout</a> first.
|
||||||
|
// TODO Link to My Account page
|
||||||
|
else if !registered
|
||||||
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
|
if registerError
|
||||||
|
.alert.alert-danger.messagebox.center
|
||||||
|
strong Registration Failed
|
||||||
|
p= registerError
|
||||||
|
h2 Register
|
||||||
|
form(role="form", action="/register", method="post", onsubmit="return verify()")
|
||||||
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="username") Username
|
||||||
|
input#register-username.form-control(type="text", name="name", onkeyup="checkUsername()", maxlength="20")
|
||||||
|
p#validate_username.text-danger.pull-right
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="password") Password
|
||||||
|
input#register-password.form-control(type="password", name="password", onkeyup="checkPasswords()")
|
||||||
|
p#validate_password.text-danger.pull-right
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="password_confirm") Confirm Password
|
||||||
|
input#register-password-confirm.form-control(type="password", onkeyup="checkPasswords()")
|
||||||
|
p#validate_confirm.text-danger.pull-right
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="email") Email (optional)
|
||||||
|
input#register-email.form-control(type="email", name="email")
|
||||||
|
p#validate_email.text-danger.pull-right
|
||||||
|
p
|
||||||
|
| Providing an email address is optional and will allow you to recover your account via email if you forget your password.
|
||||||
|
strong If you do not provide an email address, you will not be able to recover a lost account!
|
||||||
|
button#registerbtn.btn.btn-success.btn-block(type="submit") Register
|
||||||
|
else
|
||||||
|
.col-lg-6.col-lg-offset-3.col-md-6.col-md-offset-3
|
||||||
|
.alert.alert-success.messagebox.center
|
||||||
|
strong Registration Successful
|
||||||
|
p Thanks for registering, #{registerName}! Now you can <a href="/login">Login</a> to use your account.
|
||||||
|
|
||||||
|
append footer
|
||||||
|
script(type="text/javascript").
|
||||||
|
function verify() {
|
||||||
|
var valid = checkUsername();
|
||||||
|
valid = checkPasswords() && valid;
|
||||||
|
valid = checkEmail() && valid;
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
function checkUsername() {
|
||||||
|
function stateError(text){
|
||||||
|
target.parent()
|
||||||
|
.addClass("has-error")
|
||||||
|
.removeClass("has-success");
|
||||||
|
$("#validate_username").text(text);
|
||||||
|
}
|
||||||
|
var target = $("#register-username");
|
||||||
|
var name = target.val();
|
||||||
|
if (name === "") {
|
||||||
|
stateError('Username must not be empty')
|
||||||
|
return false;
|
||||||
|
} else if (!(/^[-\w\u00c0-\u00ff]{1,20}$/).test(name)) {
|
||||||
|
stateError("Username must consist of 1-20 characters" +
|
||||||
|
" a-Z, A-Z, 0-9, -, or _.");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
target.parent()
|
||||||
|
.removeClass("has-error")
|
||||||
|
.addClass("has-success");
|
||||||
|
$("#validate_username").text('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function checkPasswords() {
|
||||||
|
function stateError(text, target, validator){
|
||||||
|
target.parent()
|
||||||
|
.addClass("has-error")
|
||||||
|
.removeClass("has-success");
|
||||||
|
$(`#${validator}`).text(text);
|
||||||
|
}
|
||||||
|
var target = $("#register-password");
|
||||||
|
var target2 = $("#register-password-confirm");
|
||||||
|
var pw = target.val();
|
||||||
|
var pwc = target2.val();
|
||||||
|
|
||||||
|
$("#validate_password").text('');
|
||||||
|
$("#validate_confirm").text('');
|
||||||
|
if (pw === "") {
|
||||||
|
stateError('Password must not be empty', target, 'validate_password')
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
target.parent()
|
||||||
|
.removeClass("has-error")
|
||||||
|
.addClass("has-success");
|
||||||
|
if (pw !== pwc) {
|
||||||
|
stateError('Passwords do not match', target2, 'validate_confirm')
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
target.parent()
|
target2.parent()
|
||||||
.removeClass("has-error")
|
.removeClass("has-error")
|
||||||
.addClass("has-success");
|
.addClass("has-success");
|
||||||
if (pw !== pwc) {
|
|
||||||
stateError('Passwords do not match', target2, 'validate_confirm')
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
target2.parent()
|
|
||||||
.removeClass("has-error")
|
|
||||||
.addClass("has-success");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function checkEmail() {
|
}
|
||||||
var email = $("#email").val();
|
function checkEmail() {
|
||||||
if (email.trim() === "") {
|
var email = $("#register-email").val();
|
||||||
return confirm("Are you sure you want to register without setting a recovery email address? If you lose the password, or if your account is compromised, you WILL NOT be able to recover it.");
|
if (email.trim() === "") {
|
||||||
}
|
return confirm("Are you sure you want to register without setting a recovery email address? If you lose the password, or if your account is compromised, you WILL NOT be able to recover it.");
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue