Add client drafts, add app version to template

This commit is contained in:
Yusur 2022-05-17 22:55:37 +02:00
parent e3e9d844c6
commit c53cc54d1a
3 changed files with 20 additions and 8 deletions

14
app.py
View file

@ -417,7 +417,7 @@ def remove_tags(text, convert=True, headings=True):
text = re.sub(r'\#[^\n]*', '', text) text = re.sub(r'\#[^\n]*', '', text)
if convert: if convert:
text = md(text, toc=False) text = md(text, toc=False)
return re.sub(r'<.*?>|\{\{.*?\}\}', '', text) return re.sub(r'<.*?>', '', text)
#### I18N #### #### I18N ####
@ -485,6 +485,7 @@ def _inject_variables():
'T': partial(get_string, g.lang), 'T': partial(get_string, g.lang),
'app_name': _getconf('site', 'title'), 'app_name': _getconf('site', 'title'),
'strong': lambda x:Markup('<strong>{0}</strong>').format(x), 'strong': lambda x:Markup('<strong>{0}</strong>').format(x),
'app_version': __version__
} }
@app.template_filter() @app.template_filter()
@ -522,7 +523,7 @@ def error_400(body):
return render_template('badrequest.html'), 400 return render_template('badrequest.html'), 400
# Middle point during page editing. # Middle point during page editing.
def savepoint(form, is_preview=False): def savepoint(form, is_preview=False, pageid=None):
if is_preview: if is_preview:
preview = md(form['text']) preview = md(form['text'])
else: else:
@ -531,6 +532,7 @@ def savepoint(form, is_preview=False):
pl_js_info['editing'] = dict( pl_js_info['editing'] = dict(
original_text = None, # TODO original_text = None, # TODO
preview_text = form['text'], preview_text = form['text'],
page_id = pageid
) )
return render_template('edit.html', pl_url=form['url'], pl_title=form['title'], pl_text=form['text'], pl_tags=form['tags'], preview=preview, pl_js_info=pl_js_info) return render_template('edit.html', pl_url=form['url'], pl_title=form['title'], pl_text=form['text'], pl_tags=form['tags'], preview=preview, pl_js_info=pl_js_info)
@ -579,21 +581,21 @@ def edit(id):
p = Page[id] p = Page[id]
if request.method == 'POST': if request.method == 'POST':
if request.form.get('preview'): if request.form.get('preview'):
return savepoint(request.form, is_preview=True) return savepoint(request.form, is_preview=True, pageid=id)
p_url = request.form['url'] or None p_url = request.form['url'] or None
if p_url: if p_url:
if not is_valid_url(p_url): if not is_valid_url(p_url):
flash('Invalid URL. Valid URLs contain only letters, numbers and hyphens.') flash('Invalid URL. Valid URLs contain only letters, numbers and hyphens.')
return savepoint(request.form) return savepoint(request.form, pageid=id)
elif not is_url_available(p_url) and p_url != p.url: elif not is_url_available(p_url) and p_url != p.url:
flash('This URL is not available.') flash('This URL is not available.')
return savepoint(request.form) return savepoint(request.form, pageid=id)
p_tags = [x.strip().lower().replace(' ', '-').replace('_', '-').lstrip('#') p_tags = [x.strip().lower().replace(' ', '-').replace('_', '-').lstrip('#')
for x in request.form.get('tags', '').split(',')] for x in request.form.get('tags', '').split(',')]
p_tags = [x for x in p_tags if x] p_tags = [x for x in p_tags if x]
if any(not re.fullmatch(SLUG_RE, x) for x in p_tags): if any(not re.fullmatch(SLUG_RE, x) for x in p_tags):
flash('Invalid tags text. Tags contain only letters, numbers and hyphens, and are separated by comma.') flash('Invalid tags text. Tags contain only letters, numbers and hyphens, and are separated by comma.')
return savepoint(request.form) return savepoint(request.form, pageid=id)
p.url = p_url p.url = p_url
p.title = request.form['title'] p.title = request.form['title']
p.touched = datetime.datetime.now() p.touched = datetime.datetime.now()

View file

@ -8,6 +8,9 @@
var textInput = getFirst(document.getElementsByClassName('text-input')); var textInput = getFirst(document.getElementsByClassName('text-input'));
var overTextInput = getFirst(document.getElementsByClassName('over-text-input')); var overTextInput = getFirst(document.getElementsByClassName('over-text-input'));
// TODO saving draft
var autosaveInterval = null;
overTextInput.innerHTML = [ overTextInput.innerHTML = [
'<span class="oti-modified">&nbsp;</span>', '<span class="oti-modified">&nbsp;</span>',
'<span class="oti-charcount">? chars</span>', '<span class="oti-charcount">? chars</span>',
@ -22,8 +25,9 @@
if(newText != oldText){ if(newText != oldText){
oldText = newText; oldText = newText;
overTextInput.children[0].innerHTML = newText == originalText? '&nbsp;' : '(*)'; overTextInput.children[0].innerHTML = newText === originalText? '&nbsp;' : '(*)';
overTextInput.children[1].innerHTML = newText.length + ' char' + (newText.length == 1? '' : 's'); overTextInput.children[1].innerHTML = newText.length + ' char' + (newText.length == 1? '' : 's');
if (!autosaveInterval) autosaveInterval = setInterval(autosaveText, 30000);
} }
} }
overTextInput.children[1].innerHTML = originalText.length + ' char' + (originalText.length == 1? '' : 's'); overTextInput.children[1].innerHTML = originalText.length + ' char' + (originalText.length == 1? '' : 's');
@ -53,6 +57,7 @@
var saveButton = document.getElementById('save-button'); var saveButton = document.getElementById('save-button');
saveButton.onclick = function(){ saveButton.onclick = function(){
window.onbeforeunload = null; window.onbeforeunload = null;
localStorage.removeItem('draft' + (page_info.editing.page_id || 'new'));
} }
var previewButton = document.getElementById('preview-button'); var previewButton = document.getElementById('preview-button');
previewButton.onclick = function(){ previewButton.onclick = function(){
@ -66,4 +71,8 @@
// TODO tag editor // TODO tag editor
var tagsInput = getFirst(document.getElementsByClassName('tags-input')); var tagsInput = getFirst(document.getElementsByClassName('tags-input'));
function autosaveText(){
localStorage.setItem('draft' + (page_info.editing.page_id || 'new'), textInput.value);
}
})(); })();

View file

@ -27,8 +27,9 @@
<li><a href="/create/" title="{{ T('new-note') }}" rel="nofollow"><span class="material-icons">create</span></a></li> <li><a href="/create/" title="{{ T('new-note') }}" rel="nofollow"><span class="material-icons">create</span></a></li>
</ul> </ul>
<div class="footer"> <div class="footer">
<div class="footer-copyright">&copy; 20202021 Sakuragasaki46.</div> <div class="footer-copyright">&copy; 20202022 Sakuragasaki46.</div>
<div class="footer-actions" id="page-actions">{% block actions %}{% endblock %}</div> <div class="footer-actions" id="page-actions">{% block actions %}{% endblock %}</div>
<div class="footer-versions">{{app_name}} version {{app_version}}</div>
</div> </div>
<div class="backontop"><a href="#__top" title="Back on top"><span class="material-icons">arrow_upward</span></a></div> <div class="backontop"><a href="#__top" title="Back on top"><span class="material-icons">arrow_upward</span></a></div>
{% block scripts %}{% endblock %} {% block scripts %}{% endblock %}