summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app.py41
-rw-r--r--static/smoothstate.min.js9
-rw-r--r--templates/index.html98
3 files changed, 45 insertions, 103 deletions
diff --git a/app.py b/app.py
index 9760aa2..cf427a5 100644
--- a/app.py
+++ b/app.py
@@ -290,13 +290,22 @@ def submit():
db().addJoke(text, userid())
return redirect('/page/' + page)
-@app.route('/vote', methods=['POST'])
-def vote():
+@app.route('/upvote', methods=['POST'])
+def upvote():
objectId = int(request.form['id'])
page = request.form['redirpage']
if objectId in db().getUserVotes(userid()):
db().unvoteJoke(objectId, userid())
- db().voteJoke(objectId, request.form['vote'] == 'downvote', userid())
+ db().voteJoke(objectId, False, userid())
+ return redirect('/page/' + page)
+
+@app.route('/downvote', methods=['POST'])
+def downvote():
+ objectId = int(request.form['id'])
+ page = request.form['redirpage']
+ if objectId in db().getUserVotes(userid()):
+ db().unvoteJoke(objectId, userid())
+ db().voteJoke(objectId, True, userid())
return redirect('/page/' + page)
@app.route('/report', methods=['POST'])
@@ -331,23 +340,17 @@ def login():
cookie = session['guestlogin']
name = request.form['user']
pw = request.form['password']
- skiplogin = False
- if request.form['action'] == 'register':
- if db().addUser(name, pw) == -1:
- flash('Benutzer existiert bereits.')
- skiplogin = True
- else:
- flash('Erfolgreich registriert.')
+ if db().addUser(name, pw) >= 0:
+ flash('Erfolgreich registriert.')
- if not skiplogin:
- res = db().getUser(name=name, password=pw)
- if res == -2:
- flash('Benutzer existiert nicht.')
- if res == -1:
- flash('Passwort falsch.')
- if res >= 0:
- session['userlogin'] = name
- flash('Erfolgreich eingeloggt.')
+ res = db().getUser(name=name, password=pw)
+ if res == -2:
+ flash('Benutzer existiert nicht.')
+ if res == -1:
+ flash('Passwort falsch.')
+ if res >= 0:
+ session['userlogin'] = name
+ flash('Erfolgreich eingeloggt.')
page = request.form['redirpage']
return redirect('/page/' + page)
diff --git a/static/smoothstate.min.js b/static/smoothstate.min.js
new file mode 100644
index 0000000..cfb52b8
--- /dev/null
+++ b/static/smoothstate.min.js
@@ -0,0 +1,9 @@
+/*!
+ * smoothState.js is jQuery plugin that progressively enhances
+ * page loads to behave more like a single-page application.
+ *
+ * @author Miguel Ángel Pérez reachme@miguel-perez.com
+ * @see http://smoothstate.com
+ *
+ */
+!function(t){"use strict";"object"==typeof module&&"object"==typeof module.exports?t(require("jquery"),window,document):t(jQuery,window,document)}(function(t,e,n,o){"use strict";if(!e.history.pushState)return t.fn.smoothState=function(){return this},void(t.fn.smoothState.options={});if(!t.fn.smoothState){var r=t("html, body"),a=e.console,i={debug:!1,anchors:"a",hrefRegex:"",forms:"form",allowFormCaching:!1,repeatDelay:500,blacklist:".no-smoothState",prefetch:!1,prefetchOn:"mouseover touchstart",prefetchBlacklist:".no-prefetch",cacheLength:0,loadingClass:"is-loading",scroll:!0,alterRequest:function(t){return t},alterChangeState:function(t,e,n){return t},onBefore:function(t,e){},onStart:{duration:0,render:function(t){}},onProgress:{duration:0,render:function(t){}},onReady:{duration:0,render:function(t,e){t.html(e)}},onAfter:function(t,e){}},s={isExternal:function(t){var n=t.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);return"string"==typeof n[1]&&n[1].length>0&&n[1].toLowerCase()!==e.location.protocol?!0:"string"==typeof n[2]&&n[2].length>0&&n[2].replace(new RegExp(":("+{"http:":80,"https:":443}[e.location.protocol]+")?$"),"")!==e.location.host},stripHash:function(t){return t.replace(/#.*/,"")},isHash:function(t,n){n=n||e.location.href;var o=t.indexOf("#")>-1,r=s.stripHash(t)===s.stripHash(n);return o&&r},translate:function(e){var n={dataType:"html",type:"GET"};return e="string"==typeof e?t.extend({},n,{url:e}):t.extend({},n,e)},shouldLoadAnchor:function(t,e,n){var r=t.prop("href");return!(s.isExternal(r)||s.isHash(r)||t.is(e)||t.prop("target")||typeof n!==o&&""!==n&&-1===t.prop("href").search(n))},clearIfOverCapacity:function(t,e){return Object.keys||(Object.keys=function(t){var e,n=[];for(e in t)Object.prototype.hasOwnProperty.call(t,e)&&n.push(e);return n}),Object.keys(t).length>e&&(t={}),t},storePageIn:function(e,n,o,r,a){var i=t("<html></html>").append(t(o));return e[n]={status:"loaded",title:i.find("title").first().text(),html:i.find("#"+r),doc:o,state:a},e},triggerAllAnimationEndEvent:function(e,n){n=" "+n||"";var o=0,r="animationstart webkitAnimationStart oanimationstart MSAnimationStart",a="animationend webkitAnimationEnd oanimationend MSAnimationEnd",i="allanimationend",l=function(n){t(n.delegateTarget).is(e)&&(n.stopPropagation(),o++)},u=function(n){t(n.delegateTarget).is(e)&&(n.stopPropagation(),o--,0===o&&e.trigger(i))};e.on(r,l),e.on(a,u),e.on("allanimationend"+n,function(){o=0,s.redraw(e)})},redraw:function(t){t.height()}},l=function(n){if(null!==n.state){var o=e.location.href,r=t("#"+n.state.id),a=r.data("smoothState"),i=a.href!==o&&!s.isHash(o,a.href),l=n.state!==a.cache[a.href].state;(i||l)&&(l&&a.clear(a.href),a.load(o,!1))}},u=function(i,l){var u=t(i),c=u.prop("id"),f=null,h=!1,d={},p={},g=e.location.href,m=function(t){t=t||!1,t&&d.hasOwnProperty(t)?delete d[t]:d={},u.data("smoothState").cache=d},y=function(e,n){n=n||t.noop;var o=s.translate(e);if(d=s.clearIfOverCapacity(d,l.cacheLength),!d.hasOwnProperty(o.url)||"undefined"!=typeof o.data){d[o.url]={status:"fetching"};var r=t.ajax(o);r.done(function(t){s.storePageIn(d,o.url,t,c),u.data("smoothState").cache=d}),r.fail(function(){d[o.url].status="error"}),n&&r.always(n)}},v=function(){if(f){var e=t(f,u);if(e.length){var n=e.offset().top;r.scrollTop(n)}f=null}},S=function(o){var i="#"+c,s=d[o]?t(d[o].html.html()):null;s.length?(n.title=d[o].title,u.data("smoothState").href=o,l.loadingClass&&r.removeClass(l.loadingClass),l.onReady.render(u,s),u.one("ss.onReadyEnd",function(){h=!1,l.onAfter(u,s),l.scroll&&v(),O(u)}),e.setTimeout(function(){u.trigger("ss.onReadyEnd")},l.onReady.duration)):!s&&l.debug&&a?a.warn("No element with an id of "+i+" in response from "+o+" in "+d):e.location=o},w=function(t,n,o){var i=s.translate(t);"undefined"==typeof n&&(n=!0),"undefined"==typeof o&&(o=!0);var f=!1,h=!1,g={loaded:function(){var t=f?"ss.onProgressEnd":"ss.onStartEnd";h&&f?h&&S(i.url):u.one(t,function(){S(i.url),o||m(i.url)}),n&&(p=l.alterChangeState({id:c},d[i.url].title,i.url),d[i.url].state=p,e.history.pushState(p,d[i.url].title,i.url)),h&&!o&&m(i.url)},fetching:function(){f||(f=!0,u.one("ss.onStartEnd",function(){l.loadingClass&&r.addClass(l.loadingClass),l.onProgress.render(u),e.setTimeout(function(){u.trigger("ss.onProgressEnd"),h=!0},l.onProgress.duration)})),e.setTimeout(function(){d.hasOwnProperty(i.url)&&g[d[i.url].status]()},10)},error:function(){l.debug&&a?a.log("There was an error loading: "+i.url):e.location=i.url}};d.hasOwnProperty(i.url)||y(i),l.onStart.render(u),e.setTimeout(function(){l.scroll&&r.scrollTop(0),u.trigger("ss.onStartEnd")},l.onStart.duration),g[d[i.url].status]()},E=function(e){var n,o=t(e.currentTarget);s.shouldLoadAnchor(o,l.blacklist,l.hrefRegex)&&!h&&(e.stopPropagation(),n=s.translate(o.prop("href")),n=l.alterRequest(n),y(n))},b=function(e){var n=t(e.currentTarget);if(!e.metaKey&&!e.ctrlKey&&s.shouldLoadAnchor(n,l.blacklist,l.hrefRegex)&&(e.stopPropagation(),e.preventDefault(),!T())){A();var o=s.translate(n.prop("href"));h=!0,f=n.prop("hash"),o=l.alterRequest(o),l.onBefore(n,u),w(o)}},C=function(e){var n=t(e.currentTarget);if(!n.is(l.blacklist)&&(e.preventDefault(),e.stopPropagation(),!T())){A();var r={url:n.prop("action"),data:n.serialize(),type:n.prop("method")};h=!0,r=l.alterRequest(r),"get"===r.type.toLowerCase()&&(r.url=r.url+"?"+r.data),l.onBefore(n,u),w(r,o,l.allowFormCaching)}},P=0,T=function(){var t=null===l.repeatDelay,e=parseInt(Date.now())>P;return!(t||e)},A=function(){P=parseInt(Date.now())+parseInt(l.repeatDelay)},O=function(t){l.anchors&&l.prefetch&&t.find(l.anchors).not(l.prefetchBlacklist).on(l.prefetchOn,null,E)},x=function(t){l.anchors&&(t.on("click",l.anchors,b),O(t)),l.forms&&t.on("submit",l.forms,C)},R=function(){var t=u.prop("class");u.removeClass(t),s.redraw(u),u.addClass(t)};return l=t.extend({},t.fn.smoothState.options,l),null===e.history.state?(p=l.alterChangeState({id:c},n.title,g),e.history.replaceState(p,n.title,g)):p={},s.storePageIn(d,g,n.documentElement.outerHTML,c,p),s.triggerAllAnimationEndEvent(u,"ss.onStartEnd ss.onProgressEnd ss.onEndEnd"),x(u),{href:g,cache:d,clear:m,load:w,fetch:y,restartCSSAnimations:R}},c=function(e){return this.each(function(){var n=this.tagName.toLowerCase();this.id&&"body"!==n&&"html"!==n&&!t.data(this,"smoothState")?t.data(this,"smoothState",new u(this,e)):!this.id&&a?a.warn("Every smoothState container needs an id but the following one does not have one:",this):"body"!==n&&"html"!==n||!a||a.warn("The smoothstate container cannot be the "+this.tagName+" tag")})};e.onpopstate=l,t.smoothStateUtility=s,t.fn.smoothState=c,t.fn.smoothState.options=i}}); \ No newline at end of file
diff --git a/templates/index.html b/templates/index.html
index 0da415f..78d5685 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -9,8 +9,9 @@
</head>
<body>
<script type="text/javascript" src="/static/jquery.min.js"></script>
+ <script type="text/javascript" src="/static/smoothstate.min.js"></script>
<script type="text/javascript" src="/static/materialize.min.js"></script>
- <div class="container">
+ <div class="container" id="main">
<div class="row">
<h3>Lehrersprüche</h3>
<div class="section">
@@ -22,19 +23,16 @@
{% else %}
<form action="/login" method="post">
<input type="hidden" name="redirpage" value="{{ currentpage }}">
- <div class="col s6 m4 l2 input-field">
+ <div class="col s6 m4 l3 input-field">
<label for="user">Benutzer</label>
<input type="text" name="user">
</div>
- <div class="col s6 m4 l2 input-field">
+ <div class="col s6 m4 l3 input-field">
<label for="user">Passwort</label>
<input type="password" name="password">
</div>
<div class="col s6 m4 l2">
- <button class="btn col s12" type="submit" name="action" value="login">Login</button>
- </div>
- <div class="col s6 m4 l2">
- <button class="btn col s12" type="submit" name="action" value="register">Anmelden</button>
+ <button class="btn col s12" type="submit">Anmelden</button>
</div>
</form>
{% endif %}
@@ -53,20 +51,24 @@
{% for joke in jokes %}
<li class="collection-item row valign-wrapper">
<div class="col s3 m2 valign">
- <form action="/vote" method="post">
+ <form action="/upvote" method="post">
<input type="hidden" name="id" value="{{ joke.id }}">
<input type="hidden" name="redirpage" value="{{ currentpage }}">
- <button class="col s12 upvotebtn btn{% if joke.reports>0 %}-flat{% endif %}{% if joke.upvoted %} disabled{% endif %}" type="submit" name="vote" value="upvote">
+ <button class="col s12 btn{% if joke.reports>0 %}-flat{% endif %}{% if joke.upvoted %} disabled{% endif %}" type="submit">
<i class="material-icons">thumb_up</i> <span class="btnval" data-original="{% if joke.upvoted %}{{ joke.upvotes-1 }}{% else %}{{ joke.upvotes }}{% endif %}">{{ joke.upvotes }}</span>
</button>
- <button class="col s12 downvotebtn btn{% if joke.reports>0 %}-flat{% endif %}{% if joke.downvoted %} disabled{% endif %}" type="submit" name="vote" value="downvote">
+ </form>
+ <form action="/downvote" method="post">
+ <input type="hidden" name="id" value="{{ joke.id }}">
+ <input type="hidden" name="redirpage" value="{{ currentpage }}">
+ <button class="col s12 btn{% if joke.reports>0 %}-flat{% endif %}{% if joke.downvoted %} disabled{% endif %}" type="submit">
<i class="material-icons">thumb_down</i> <span class="btnval" data-original="{% if joke.downvoted %}{{ joke.downvotes-1 }}{% else %}{{ joke.downvotes }}{% endif %}">{{ joke.downvotes }}</span>
</button>
</form>
<form action="/report" method="post">
<input type="hidden" name="id" value="{{ joke.id }}">
<input type="hidden" name="redirpage" value="{{ currentpage }}">
- <button class="reportbtn btn-flat{% if joke.reported %} disabled{% endif %}" type="submit">
+ <button class="col s12 btn-flat{% if joke.reported %} disabled{% endif %}" type="submit">
<i class="material-icons left">report_problem</i>
<span class="btnval red-text" data-original="{% if joke.reported %}{{ joke.reports-1 }}{% else %}{{ joke.reports }}{% endif %}">{{ joke.reports }}</span>
</button>
@@ -112,79 +114,7 @@
</div>
<script type="text/javascript">
$(document).ready(function() {
- $('.upvotebtn').click(function(e) { submitAjaxer.call(this, e, 'upvote'); });
- $('.downvotebtn').click(function(e) { submitAjaxer.call(this, e, 'downvote'); });
- $('.reportbtn').click(function(e) { submitAjaxer.call(this, e, 'report'); });
- $('.deletebtn').click(function(e) { submitAjaxer.call(this, e, 'delete'); });
-
- function submitAjaxer(e, type) {
- e.preventDefault();
- var form = $(this).closest('form');
- var container = $(this).closest('div');
- var data;
- if (type == 'upvote' || type == 'downvote') {
- senddata = form.serialize() + '&vote=' + type;
- } else {
- senddata = form.serialize();
- }
- $.ajax({
- url: form.attr('action'),
- type: "POST",
- data: senddata,
- success: function(data) {
- if (type == 'delete') {
- var deletebtn = $('.deletebtn', container);
- var id = deletebtn.data('id');
- var undobtn = $('<button class="btn col s12"><i class="material-icons">delete undo</i></button>');
- undobtn.click(function() {
- $.ajax({
- url: form.attr('action').replace(/\/delete$/, '/undelete'),
- type: "POST",
- data: senddata,
- success: function() {
- window.location.reload(false); // TODO rebuild DOM
- }
- })
- });
- container.html(undobtn);
- return;
- }
-
- var upvotebtn = $('.upvotebtn', container);
- var downvotebtn = $('.downvotebtn', container);
- var reportbtn = $('.reportbtn', container);
- var upvotes = parseInt($('.btnval', upvotebtn).data('original'));
- var downvotes = parseInt($('.btnval', downvotebtn).data('original'));
- var reports = parseInt($('.btnval', reportbtn).data('original'));
- $('.btnval', upvotebtn).text(upvotes);
- $('.btnval', downvotebtn).text(downvotes);
- $('.btnval', reportbtn).text(reports);
-
- upvotebtn.removeClass('disabled');
- upvotebtn.removeClass('btn-flat');
- upvotebtn.addClass('btn');
- downvotebtn.removeClass('disabled');
- downvotebtn.removeClass('btn-flat');
- downvotebtn.addClass('btn');
- reportbtn.removeClass('disabled');
-
- if (type == "upvote") {
- $('.btnval', upvotebtn).text(upvotes+1);
- upvotebtn.addClass('disabled');
- } else if (type == "downvote") {
- $('.btnval', downvotebtn).text(downvotes+1);
- downvotebtn.addClass('disabled');
- } else if (type == "report") {
- $('.btnval', reportbtn).text(reports+1);
- reportbtn.addClass('disabled');
- downvotebtn.addClass('btn-flat');
- downvotebtn.removeClass('btn');
- upvotebtn.addClass('btn-flat');
- upvotebtn.removeClass('btn');
- }
- }
- });
- }
+ $('#main').smoothState({prefetch: true, cacheLength: 2});
});
</script>
</body>