ui overhaul
This commit is contained in:
parent
1562182e33
commit
494f2f8e4a
32
routes.py
32
routes.py
|
@ -25,8 +25,7 @@ def touch_viewer(resp):
|
|||
@app.route('/')
|
||||
def index():
|
||||
if g.viewer:
|
||||
posts = Post.query.filter_by(author_id = g.viewer.account_id).order_by(db.desc(Post.created_at)).limit(30)
|
||||
return render_template('index.html', posts=posts)
|
||||
return render_template('logged_in.html', scales=lib.interval_scales)
|
||||
else:
|
||||
return render_template('index.html')
|
||||
|
||||
|
@ -66,13 +65,12 @@ def upload_tweet_archive():
|
|||
|
||||
tasks.import_twitter_archive.s(ta.id).apply_async(routing_key='high')
|
||||
|
||||
return render_template('upload_tweet_archive.html')
|
||||
return redirect(url_for('index'))
|
||||
|
||||
@app.route('/settings', methods=('GET', 'POST'))
|
||||
@app.route('/settings', methods=('POST',))
|
||||
@require_auth
|
||||
def settings():
|
||||
if request.method == 'POST':
|
||||
for attr in ('policy_enabled',
|
||||
for attr in (
|
||||
'policy_keep_favourites',
|
||||
'policy_keep_latest',
|
||||
'policy_delete_every_significand',
|
||||
|
@ -85,8 +83,28 @@ def settings():
|
|||
|
||||
db.session.commit()
|
||||
|
||||
return render_template('settings.html', scales=lib.interval_scales)
|
||||
return redirect(url_for('index', settings_saved=''))
|
||||
|
||||
@app.route('/disable', methods=('POST',))
|
||||
@require_auth
|
||||
def disable():
|
||||
g.viewer.account.policy_enabled = False
|
||||
db.session.commit()
|
||||
|
||||
return redirect(url_for('index'))
|
||||
|
||||
@app.route('/enable', methods=('POST',))
|
||||
@require_auth
|
||||
def enable():
|
||||
|
||||
# TODO require confirmation when risky
|
||||
# i.e. about to instantly delete a lot of posts,
|
||||
# or when enabling for the first time (last_delete is >1 year in the past)
|
||||
|
||||
g.viewer.account.policy_enabled = True
|
||||
db.session.commit()
|
||||
|
||||
return redirect(url_for('index'))
|
||||
|
||||
|
||||
@app.route('/logout')
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 444 KiB |
|
@ -0,0 +1,103 @@
|
|||
body {
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body > section, body > header {
|
||||
max-width: 45rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-left: 3rem;
|
||||
padding-right: 3rem;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
section > * {
|
||||
padding-left: 5rem;
|
||||
padding-right: 5rem;
|
||||
}
|
||||
|
||||
section > ul {
|
||||
padding-left: 7rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.4em;
|
||||
font-weight: normal;
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: inherit;
|
||||
font-weight: bold;
|
||||
padding-left: 5rem;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
margin-top: 0;
|
||||
text-indent:-1000vw;
|
||||
background: url('/static/logotype.png') no-repeat 2rem bottom, white;
|
||||
background-size: contain;
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
input[type=number]{
|
||||
max-width: 8ch;
|
||||
}
|
||||
|
||||
.viewer img.avatar {
|
||||
height: 1.5em;
|
||||
width: 1.5em;
|
||||
background-color: #ccc;
|
||||
border-radius:100%;
|
||||
transform:translateY(25%);
|
||||
}
|
||||
|
||||
.banner {
|
||||
border-left-width: .7rem;
|
||||
border-left-style: solid;
|
||||
padding-top: .6rem;
|
||||
padding-bottom: .6rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
body > section > .banner {
|
||||
padding-left: 4.3rem;
|
||||
}
|
||||
|
||||
.banner.enabled {
|
||||
border-left-color: transparent;
|
||||
background: #bbfbff;
|
||||
}
|
||||
|
||||
.banner.disabled {
|
||||
border-left-color: transparent;
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.banner.success {
|
||||
background: #dec;
|
||||
border-left-color: #4a2;
|
||||
}
|
||||
|
||||
.banner.error {
|
||||
border-color: #a24;
|
||||
background: #ecd;
|
||||
}
|
||||
|
||||
.banner.warning {
|
||||
border-color: #dc4;
|
||||
background: #eec;
|
||||
}
|
||||
|
||||
.banner form {
|
||||
display: inline;
|
||||
}
|
|
@ -1,20 +1,28 @@
|
|||
<h1>Forget</h1>
|
||||
{% extends 'lib/layout.html' %}
|
||||
{% block body %}
|
||||
|
||||
{% if g.viewer %}
|
||||
<p>Hello,
|
||||
<img src="{{g.viewer.account.avatar_url}}" style='height:1.5em; border-radius:100%; transform:translateY(25%);'/>
|
||||
{{g.viewer.account.display_name}}!
|
||||
<a href="{{url_for('settings')}}">Settings</a>
|
||||
<a href="{{url_for('logout')}}">Log out</a>
|
||||
</p>
|
||||
<section>
|
||||
<p>Hello, stranger! </p>
|
||||
<p>Forget is a service that automatically deletes your old posts once everyone has forgotten about them. After all, why shouldn't computers forget too?</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Features</h2>
|
||||
<ul>
|
||||
<li>Delete your stale bad posts without even having to look at them again</li>
|
||||
<li>Pick between deleting every old post or randomly deleting one old post periodically</li>
|
||||
<li>Pick between deleting posts older than a date, posts past a post count, or both</li>
|
||||
<li>Optionally mark posts that you want to preserve forever, by giving them a like</li>
|
||||
<li>Upload a tweet archive if your twitter account has more tweets than the twitter api will return</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Sign in</h2>
|
||||
<p>Sound good to you? <a href="/login/twitter">Log in with Twitter</a></p>
|
||||
</section>
|
||||
<section class='policy'>
|
||||
<h2>Policy</h2>
|
||||
<p>Forget will only start deleting posts if and when you explicitly enable it on this page. Forget will not post as you, follow any account or do anything else than delete posts.</p>
|
||||
<p>
|
||||
</section>
|
||||
|
||||
<h2>Recent posts ({{g.viewer.account.post_count()}} total posts):</h2>
|
||||
|
||||
{% for post in posts %}
|
||||
<p>{{ "♥ " if post.favourite }}{{post.body}}</p>
|
||||
{% else %}
|
||||
<p>no posts :(</p>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p>Hello, stranger! <a href="/login/twitter">Log in with Twitter</a></p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<input type=number name={{attrname}}_significand
|
||||
value={{obj[attrname + '_significand']}}
|
||||
style='max-width:8ch' min=0 step=1>
|
||||
min=0 step=1>
|
||||
<select name={{attrname}}_scale>
|
||||
{%- for scale in scales %}
|
||||
<option value="{{scale[1].total_seconds()}}"
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<head>
|
||||
<title>Forget</title>
|
||||
<link rel=stylesheet href='{{ url_for("static", filename="style.css") }}' />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Forget</h1>
|
||||
</header>
|
||||
{% block body %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,73 @@
|
|||
{% from 'lib/interval.html' import interval_input -%}
|
||||
{% extends 'lib/layout.html' %}
|
||||
{% block body -%}
|
||||
|
||||
<section class=viewer>
|
||||
<p>Hello,
|
||||
<img class=avatar src="{{g.viewer.account.avatar_url}}"/>
|
||||
{{g.viewer.account.display_name}}!
|
||||
<a href="{{url_for('logout')}}">Log out</a>
|
||||
</p>
|
||||
{% set enabled_disabled = "enabled" if g.viewer.account.policy_enabled else "disabled" %}
|
||||
<div class="banner {{enabled_disabled}}">Forget is currently {{ enabled_disabled }} on your account.
|
||||
{% if g.viewer.account.policy_enabled -%}
|
||||
<form action='{{url_for("disable")}}' method='post' enctype='multipart/form-data'>
|
||||
<input type='submit' value='Disable'>
|
||||
</form>
|
||||
{% else -%}
|
||||
<form action='{{url_for("enable")}}' method='post' enctype='multipart/form-data'>
|
||||
<input type='submit' value='Enable'>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p>Currently keeping track of {{g.viewer.account.post_count()}} posts</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Settings</h2>
|
||||
|
||||
{% if request.args.get('settings_saved') != None %}
|
||||
<div class='banner success'>Settings saved successfully</div>
|
||||
{% endif %}
|
||||
|
||||
<form action='{{url_for("settings")}}' method='post' enctype='multipart/form-data'>
|
||||
<p>Delete one post every
|
||||
{{interval_input(g.viewer.account, 'policy_delete_every', scales)}}
|
||||
</p>
|
||||
<p>Keep posts less than
|
||||
{{interval_input(g.viewer.account, 'policy_keep_younger', scales)}}
|
||||
old
|
||||
</p>
|
||||
<p>Keep my
|
||||
<input type=number name=policy_keep_latest min=0 step=1 style='max-width:8ch' value={{g.viewer.account.policy_keep_latest}}>
|
||||
latest posts
|
||||
</p>
|
||||
<p>Keep posts that I have favourited
|
||||
<label><input type=radio name=policy_keep_favourites value=true {{ "checked" if g.viewer.account.policy_keep_favourites }}> Yes</label>
|
||||
<label><input type=radio name=policy_keep_favourites value=false {{ "checked" if not g.viewer.account.policy_keep_favourites }}> No</label>
|
||||
</p>
|
||||
<input type=submit value='Save settings'>
|
||||
</form>
|
||||
|
||||
</section>
|
||||
{% if g.viewer.account.service == 'twitter' %}
|
||||
<section>
|
||||
|
||||
<h2>Tweet archive import</h2>
|
||||
<form action='{{url_for('upload_tweet_archive')}}' method='post' enctype='multipart/form-data'>
|
||||
<input type="file" name='file'><input type="submit">
|
||||
</form>
|
||||
|
||||
{% if g.viewer.account.twitter_archives %}
|
||||
<h3 >Recent tweet archive imports</h3>
|
||||
<ul>
|
||||
{% for archive in g.viewer.account.twitter_archives %}
|
||||
<li>{{archive.created_at.strftime('%Y-%m-%d %H:%M')}}<br>
|
||||
{{archive.chunks_successful}}/{{archive.chunks}} months imported, {{archive.chunks_failed}} failed</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
|
@ -1,46 +0,0 @@
|
|||
<p><a href="{{url_for('index')}}">< Back</a></p>
|
||||
|
||||
<form method='post' enctype='multipart/form-data'>
|
||||
<h2>Settings</h2>
|
||||
{% if request.method == 'POST' %}
|
||||
<h3>Settings saved successfully</h3>
|
||||
{% endif %}
|
||||
<p>Delete posts:
|
||||
<label><input type=radio name=policy_enabled value=true {{ "checked" if g.viewer.account.policy_enabled }}> Enabled</label>
|
||||
<label><input type=radio name=policy_enabled value=false {{ "checked" if not g.viewer.account.policy_enabled }}> Disabled</label>
|
||||
</p>
|
||||
{%- from 'lib/interval.html' import interval_input %}
|
||||
<p>Delete one post every
|
||||
{{interval_input(g.viewer.account, 'policy_delete_every', scales)}}
|
||||
</p>
|
||||
<p>Keep posts less than
|
||||
{{interval_input(g.viewer.account, 'policy_keep_younger', scales)}}
|
||||
old
|
||||
</p>
|
||||
<p>Keep my
|
||||
<input type=number name=policy_keep_latest min=0 step=1 style='max-width:8ch' value={{g.viewer.account.policy_keep_latest}}>
|
||||
latest posts
|
||||
</p>
|
||||
<p>Keep posts that I have favourited
|
||||
<label><input type=radio name=policy_keep_favourites value=true {{ "checked" if g.viewer.account.policy_keep_favourites }}> Yes</label>
|
||||
<label><input type=radio name=policy_keep_favourites value=false {{ "checked" if not g.viewer.account.policy_keep_favourites }}> No</label>
|
||||
</p>
|
||||
<input type=submit value='Save'>
|
||||
</form>
|
||||
|
||||
{% if g.viewer.account.service == 'twitter' %}
|
||||
|
||||
<form action='{{url_for('upload_tweet_archive')}}' method='post' enctype='multipart/form-data'>
|
||||
<h2>Tweet archive import</h2>
|
||||
Upload your tweet archive:
|
||||
<input type="file" name='file'><input type="submit">
|
||||
</form>
|
||||
|
||||
<h3>Recent tweet archive imports</h3>
|
||||
{% for archive in g.viewer.account.twitter_archives %}
|
||||
<p>{{archive.created_at}} {{archive.chunks_successful}}/{{archive.chunks}} months successfully imported, {{archive.chunks_failed}} failed</p>
|
||||
{% else %}
|
||||
<p>No recent archives found</p>
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
|
@ -1 +0,0 @@
|
|||
<p>Your archive will be processed shortly. <a href="{{url_for('settings')}}">Back</a></p>
|
Loading…
Reference in New Issue