You've already forked snikket-web-portal
Compare commits
2 Commits
feature/mu
...
feature/wt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad229d6700 | ||
|
|
b822000f2e |
@@ -19,12 +19,11 @@ from quart import (
|
||||
abort,
|
||||
flash,
|
||||
)
|
||||
import flask_wtf
|
||||
|
||||
from flask_babel import lazy_gettext as _l, _
|
||||
|
||||
from . import prosodyclient
|
||||
from .infra import client, circle_name
|
||||
from .infra import client, circle_name, BaseForm
|
||||
|
||||
bp = Blueprint("admin", __name__, url_prefix="/admin")
|
||||
|
||||
@@ -35,7 +34,7 @@ async def index() -> str:
|
||||
return await render_template("admin_home.html")
|
||||
|
||||
|
||||
class PasswordResetLinkPost(flask_wtf.FlaskForm): # type: ignore
|
||||
class PasswordResetLinkPost(BaseForm):
|
||||
action_create = wtforms.StringField()
|
||||
action_revoke = wtforms.StringField()
|
||||
|
||||
@@ -55,7 +54,7 @@ async def users() -> str:
|
||||
)
|
||||
|
||||
|
||||
class DeleteUserForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class DeleteUserForm(BaseForm):
|
||||
action_delete = wtforms.SubmitField(
|
||||
_l("Delete user permanently")
|
||||
)
|
||||
@@ -132,11 +131,11 @@ async def create_password_reset_link() -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
class InvitesListForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class InvitesListForm(BaseForm):
|
||||
action_revoke = wtforms.StringField()
|
||||
|
||||
|
||||
class InvitePost(flask_wtf.FlaskForm): # type:ignore
|
||||
class InvitePost(BaseForm):
|
||||
circles = wtforms.SelectMultipleField(
|
||||
_l("Invite to circle"),
|
||||
# NOTE: This is for when/if we ever support multi-group invites.
|
||||
@@ -230,7 +229,7 @@ async def invitations() -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
class InviteForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class InviteForm(BaseForm):
|
||||
action_revoke = wtforms.SubmitField(
|
||||
_l("Revoke")
|
||||
)
|
||||
@@ -302,7 +301,7 @@ async def edit_invite(id_: str) -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
class CirclePost(flask_wtf.FlaskForm): # type:ignore
|
||||
class CirclePost(BaseForm):
|
||||
name = wtforms.StringField(
|
||||
_l("Name"),
|
||||
validators=[wtforms.validators.InputRequired()],
|
||||
@@ -350,7 +349,7 @@ async def create_circle() -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
class EditCircleForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class EditCircleForm(BaseForm):
|
||||
name = wtforms.StringField(
|
||||
_l("Name"),
|
||||
validators=[wtforms.validators.InputRequired()],
|
||||
|
||||
@@ -10,6 +10,7 @@ from quart import (
|
||||
)
|
||||
|
||||
import flask_babel
|
||||
import flask_wtf
|
||||
from flask_babel import _
|
||||
|
||||
from . import prosodyclient
|
||||
@@ -55,3 +56,14 @@ def generate_error_id() -> str:
|
||||
return base64.b32encode(secrets.token_bytes(8)).decode(
|
||||
"ascii"
|
||||
).rstrip("=")
|
||||
|
||||
|
||||
class BaseForm(flask_wtf.FlaskForm): # type:ignore
|
||||
def __init__(self, *args: typing.Any, **kwargs: typing.Any):
|
||||
meta = kwargs["meta"] = dict(kwargs.get("meta", {}))
|
||||
if "locales" not in meta:
|
||||
locale = flask_babel.get_locale()
|
||||
if locale:
|
||||
meta["locales"] = [str(locale)]
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -16,10 +16,9 @@ from quart import (
|
||||
|
||||
import wtforms
|
||||
|
||||
import flask_wtf
|
||||
from flask_babel import lazy_gettext as _l
|
||||
|
||||
from .infra import client, selected_locale
|
||||
from .infra import client, selected_locale, BaseForm
|
||||
|
||||
|
||||
bp = Blueprint("invite", __name__)
|
||||
@@ -102,7 +101,7 @@ async def view(id_: str) -> typing.Union[quart.Response,
|
||||
)
|
||||
|
||||
|
||||
class RegisterForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class RegisterForm(BaseForm):
|
||||
localpart = wtforms.StringField(
|
||||
_l("Username"),
|
||||
)
|
||||
@@ -148,15 +147,15 @@ async def register(id_: str) -> typing.Union[str, quart.Response]:
|
||||
except aiohttp.ClientResponseError as exc:
|
||||
if exc.status == 409:
|
||||
form.localpart.errors.append(
|
||||
_l("That username is already taken")
|
||||
_l("That username is already taken.")
|
||||
)
|
||||
elif exc.status == 403:
|
||||
form.localpart.errors.append(
|
||||
_l("Registration was declined for unknown reasons")
|
||||
_l("Registration was declined for unknown reasons.")
|
||||
)
|
||||
elif exc.status == 400:
|
||||
form.localpart.errors.append(
|
||||
_l("The username is not valid")
|
||||
_l("The username is not valid.")
|
||||
)
|
||||
elif exc.status == 404:
|
||||
return redirect(url_for(".view", id_=id_))
|
||||
@@ -173,7 +172,7 @@ async def register(id_: str) -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
class ResetForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class ResetForm(BaseForm):
|
||||
password = wtforms.PasswordField(
|
||||
_l("Password"),
|
||||
)
|
||||
@@ -216,7 +215,7 @@ async def reset(id_: str) -> typing.Union[str, quart.Response]:
|
||||
except aiohttp.ClientResponseError as exc:
|
||||
if exc.status == 403:
|
||||
form.localpart.errors.append(
|
||||
_l("Registration was declined for unknown reasons")
|
||||
_l("Registration was declined for unknown reasons.")
|
||||
)
|
||||
elif exc.status == 404:
|
||||
return redirect(url_for(".view", id_=id_))
|
||||
|
||||
@@ -22,17 +22,16 @@ import babel
|
||||
import wtforms
|
||||
|
||||
import flask_wtf
|
||||
|
||||
from flask_babel import lazy_gettext as _l, _
|
||||
|
||||
from . import xmpputil, _version
|
||||
from .infra import client
|
||||
from .infra import client, BaseForm
|
||||
|
||||
|
||||
bp = quart.Blueprint("main", __name__)
|
||||
|
||||
|
||||
class LoginForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class LoginForm(BaseForm):
|
||||
address = wtforms.TextField(
|
||||
_l("Address"),
|
||||
validators=[wtforms.validators.InputRequired()],
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
<div class="box warning">{#- -#}
|
||||
<header>{% trans %}Invalid input{% endtrans %}</header>
|
||||
{%- if error_list | length == 1 -%}
|
||||
<p>{{ error_list[0] }}.</p>
|
||||
<p>{{ error_list[0] }}</p>
|
||||
{%- else -%}
|
||||
<ul>
|
||||
{%- for error in error_list -%}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "library.j2" import box, form_button %}
|
||||
{% from "library.j2" import box, form_button, render_errors %}
|
||||
{% set body_id = "login" %}
|
||||
{% block head_lead %}
|
||||
<title>{{ _("Snikket Login") }}</title>
|
||||
@@ -14,11 +14,7 @@
|
||||
<p class="form-desc">{{ _("Enter your Snikket address and password to manage your account.") }}</p>
|
||||
<form method="POST" action="{{ url_for('.login') }}" name="login" id="login-form" onsubmit="return domainCheck();" data-addressid="{{ form.address.id }}" data-domain="{{ config["SNIKKET_DOMAIN"] }}">
|
||||
{{ form.csrf_token }}
|
||||
{% if form.errors %}
|
||||
{% call box("alert", _("Login failed")) %}
|
||||
<p>{{ form.errors.values() | flatten | join(", ")}}</p>
|
||||
{% endcall %}
|
||||
{% endif %}
|
||||
{% call render_errors(form) %}{% endcall %}
|
||||
<div class="box alert" role="alert" style="display: none;" id="id-warning">
|
||||
<header>{% trans %}Incorrect address{% endtrans %}</header>
|
||||
<p>{% trans snikket_domain=config["SNIKKET_DOMAIN"] %}This Snikket service only hosts addresses ending in <em>@{{ snikket_domain }}</em>. Your password was not sent.{% endtrans %}</p>
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2021-03-20 16:15+0100\n"
|
||||
"POT-Creation-Date: 2021-03-20 16:27+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -17,135 +17,135 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.9.0\n"
|
||||
|
||||
#: snikket_web/admin.py:60
|
||||
#: snikket_web/admin.py:59
|
||||
msgid "Delete user permanently"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:73
|
||||
#: snikket_web/admin.py:72
|
||||
msgid "User deleted"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:116
|
||||
#: snikket_web/admin.py:115
|
||||
msgid "Password reset link created"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:122
|
||||
#: snikket_web/admin.py:121
|
||||
msgid "Password reset link deleted"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:141
|
||||
#: snikket_web/admin.py:140
|
||||
msgid "Invite to circle"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:147
|
||||
#: snikket_web/admin.py:146
|
||||
msgid "At least one circle must be selected"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:152
|
||||
#: snikket_web/admin.py:151
|
||||
msgid "Valid for"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:154
|
||||
#: snikket_web/admin.py:153
|
||||
msgid "One hour"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:155
|
||||
#: snikket_web/admin.py:154
|
||||
msgid "Twelve hours"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:156
|
||||
#: snikket_web/admin.py:155
|
||||
msgid "One day"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:157
|
||||
#: snikket_web/admin.py:156
|
||||
msgid "One week"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:158
|
||||
#: snikket_web/admin.py:157
|
||||
msgid "Four weeks"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:164 snikket_web/templates/admin_edit_invite.html:17
|
||||
#: snikket_web/admin.py:163 snikket_web/templates/admin_edit_invite.html:17
|
||||
msgid "Invitation type"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:166 snikket_web/templates/library.j2:116
|
||||
#: snikket_web/admin.py:165 snikket_web/templates/library.j2:116
|
||||
msgid "Individual"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:167 snikket_web/templates/library.j2:114
|
||||
#: snikket_web/admin.py:166 snikket_web/templates/library.j2:114
|
||||
msgid "Group"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:173
|
||||
#: snikket_web/admin.py:172
|
||||
msgid "New invitation link"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:235
|
||||
#: snikket_web/admin.py:234
|
||||
msgid "Revoke"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:259
|
||||
#: snikket_web/admin.py:258
|
||||
msgid "Invitation created"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:275
|
||||
#: snikket_web/admin.py:274
|
||||
msgid "No such invitation exists"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:290
|
||||
#: snikket_web/admin.py:289
|
||||
msgid "Invitation revoked"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:307 snikket_web/admin.py:355
|
||||
#: snikket_web/admin.py:306 snikket_web/admin.py:354
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:312 snikket_web/templates/admin_circles.html:47
|
||||
#: snikket_web/admin.py:311 snikket_web/templates/admin_circles.html:47
|
||||
msgid "Create circle"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:342
|
||||
#: snikket_web/admin.py:341
|
||||
msgid "Circle created"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:360
|
||||
#: snikket_web/admin.py:359
|
||||
msgid "Select user"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:365
|
||||
#: snikket_web/admin.py:364
|
||||
msgid "Update circle"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:369
|
||||
#: snikket_web/admin.py:368
|
||||
msgid "Delete circle permanently"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:375
|
||||
#: snikket_web/admin.py:374
|
||||
msgid "Add user"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:391
|
||||
#: snikket_web/admin.py:390
|
||||
msgid "No such circle exists"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:428
|
||||
#: snikket_web/admin.py:427
|
||||
msgid "Circle data updated"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:434
|
||||
#: snikket_web/admin.py:433
|
||||
msgid "Circle deleted"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:445
|
||||
#: snikket_web/admin.py:444
|
||||
msgid "User added to circle"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:454
|
||||
#: snikket_web/admin.py:453
|
||||
msgid "User removed from circle"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/infra.py:40
|
||||
#: snikket_web/infra.py:41
|
||||
msgid "Main"
|
||||
msgstr ""
|
||||
|
||||
@@ -153,7 +153,7 @@ msgstr ""
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:110 snikket_web/invite.py:177 snikket_web/main.py:42
|
||||
#: snikket_web/invite.py:110 snikket_web/invite.py:177 snikket_web/main.py:41
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
@@ -170,15 +170,15 @@ msgid "Create account"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:150
|
||||
msgid "That username is already taken"
|
||||
msgid "That username is already taken."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:154 snikket_web/invite.py:218
|
||||
msgid "Registration was declined for unknown reasons"
|
||||
msgid "Registration was declined for unknown reasons."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:158
|
||||
msgid "The username is not valid"
|
||||
msgid "The username is not valid."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:190 snikket_web/templates/user_home.html:32
|
||||
@@ -186,90 +186,90 @@ msgstr ""
|
||||
msgid "Change password"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/main.py:37
|
||||
#: snikket_web/main.py:36
|
||||
msgid "Address"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/main.py:47
|
||||
#: snikket_web/main.py:46
|
||||
msgid "Sign in"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/main.py:56
|
||||
#: snikket_web/main.py:55
|
||||
msgid "Invalid username or password."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/main.py:84
|
||||
#: snikket_web/main.py:83
|
||||
msgid "Login successful!"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:29
|
||||
#: snikket_web/user.py:27
|
||||
msgid "Current password"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:34
|
||||
#: snikket_web/user.py:32
|
||||
msgid "New password"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:39
|
||||
#: snikket_web/user.py:37
|
||||
msgid "Confirm new password"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:43
|
||||
#: snikket_web/user.py:41
|
||||
msgid "The new passwords must match"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:50
|
||||
#: snikket_web/user.py:48
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:55
|
||||
#: snikket_web/user.py:53
|
||||
msgid "Nobody"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:56
|
||||
#: snikket_web/user.py:54
|
||||
msgid "Friends only"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:57
|
||||
#: snikket_web/user.py:55
|
||||
msgid "Everyone"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:12
|
||||
#: snikket_web/templates/admin_users.html:11 snikket_web/user.py:63
|
||||
#: snikket_web/templates/admin_users.html:11 snikket_web/user.py:61
|
||||
msgid "Display name"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:67
|
||||
#: snikket_web/user.py:65
|
||||
msgid "Avatar"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:71
|
||||
#: snikket_web/user.py:69
|
||||
msgid "Profile visibility"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:76
|
||||
#: snikket_web/user.py:74
|
||||
msgid "Update profile"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:101
|
||||
msgid "Incorrect password"
|
||||
#: snikket_web/user.py:99
|
||||
msgid "Incorrect password."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:105
|
||||
#: snikket_web/user.py:103
|
||||
msgid "Password changed"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:113
|
||||
#: snikket_web/user.py:111
|
||||
msgid ""
|
||||
"The chosen avatar is too big. To be able to upload larger avatars, please"
|
||||
" use the app"
|
||||
" use the app."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:161
|
||||
#: snikket_web/user.py:159
|
||||
msgid "Profile updated"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/unauth.html:18 snikket_web/user.py:169
|
||||
#: snikket_web/templates/unauth.html:18 snikket_web/user.py:167
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
@@ -789,19 +789,20 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:14
|
||||
#: snikket_web/templates/invite_view.html:38
|
||||
#: snikket_web/templates/invite_view.html:39
|
||||
msgid "App already installed?"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:16
|
||||
#: snikket_web/templates/invite_reset_view.html:21
|
||||
#: snikket_web/templates/invite_view.html:40
|
||||
#: snikket_web/templates/invite_view.html:105
|
||||
#: snikket_web/templates/invite_view.html:41
|
||||
#: snikket_web/templates/invite_view.html:106
|
||||
#: snikket_web/templates/invite_view.html:134
|
||||
msgid "Open the app"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:18
|
||||
#: snikket_web/templates/invite_view.html:42
|
||||
#: snikket_web/templates/invite_view.html:43
|
||||
msgid "This button works only if you have the app installed already!"
|
||||
msgstr ""
|
||||
|
||||
@@ -887,7 +888,7 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:26
|
||||
#: snikket_web/templates/invite_view.html:76
|
||||
#: snikket_web/templates/invite_view.html:77
|
||||
msgid ""
|
||||
"Your camera will turn on. Point it at the square code below until it is "
|
||||
"within the highlighted square on your screen, and wait until the app "
|
||||
@@ -899,7 +900,7 @@ msgid "You will then be prompted to enter a new password for your account."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:29
|
||||
#: snikket_web/templates/invite_view.html:44
|
||||
#: snikket_web/templates/invite_view.html:45
|
||||
msgid "Alternatives"
|
||||
msgstr ""
|
||||
|
||||
@@ -975,21 +976,25 @@ msgid "Get it on Google Play"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:30
|
||||
#: snikket_web/templates/invite_view.html:101
|
||||
#: snikket_web/templates/invite_view.html:102
|
||||
msgid "Download on the App Store"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:34
|
||||
#: snikket_web/templates/invite_view.html:32
|
||||
msgid "Get it on F-Droid"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:35
|
||||
msgid "Send to mobile device"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:37
|
||||
#: snikket_web/templates/invite_view.html:38
|
||||
msgid ""
|
||||
"After installation the app should automatically open and prompt you to "
|
||||
"create an account. If not, simply click the button below."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:45
|
||||
#: snikket_web/templates/invite_view.html:46
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You can connect to Snikket using any XMPP-compatible software. If the "
|
||||
@@ -997,64 +1002,82 @@ msgid ""
|
||||
"href=\"%(register_url)s\">register an account manually</a>."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:51
|
||||
#: snikket_web/templates/invite_view.html:52
|
||||
msgid "Scan invite code"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:54
|
||||
#: snikket_web/templates/invite_view.html:83
|
||||
#: snikket_web/templates/invite_view.html:95
|
||||
#: snikket_web/templates/invite_view.html:111
|
||||
#: snikket_web/templates/invite_view.html:55
|
||||
#: snikket_web/templates/invite_view.html:84
|
||||
#: snikket_web/templates/invite_view.html:96
|
||||
#: snikket_web/templates/invite_view.html:112
|
||||
#: snikket_web/templates/invite_view.html:124
|
||||
#: snikket_web/templates/invite_view.html:140
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:57
|
||||
#: snikket_web/templates/invite_view.html:58
|
||||
msgid ""
|
||||
"You can transfer this invite to your mobile device by scanning a code "
|
||||
"with your camera. You can use either a QR scanner app or the Snikket app "
|
||||
"itself."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:62
|
||||
#: snikket_web/templates/invite_view.html:63
|
||||
msgid "Using a QR code scanner"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:64
|
||||
#: snikket_web/templates/invite_view.html:65
|
||||
msgid "Using the Snikket app"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:69
|
||||
#: snikket_web/templates/invite_view.html:70
|
||||
msgid ""
|
||||
"Use a <em>QR code</em> scanner on your mobile device to scan the code "
|
||||
"below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:75
|
||||
#: snikket_web/templates/invite_view.html:76
|
||||
msgid ""
|
||||
"Install the Snikket app on your mobile device, open it, and tap the "
|
||||
"'Scan' button at the top."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:92
|
||||
#: snikket_web/templates/invite_view.html:93
|
||||
msgid "Install on iOS"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:98
|
||||
#: snikket_web/templates/invite_view.html:99
|
||||
msgid ""
|
||||
"After downloading Snikket from the app store, you have to return to this "
|
||||
"invite link and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:100
|
||||
#: snikket_web/templates/invite_view.html:101
|
||||
msgid "First download Snikket from the app store using the button below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:102
|
||||
#: snikket_web/templates/invite_view.html:103
|
||||
#: snikket_web/templates/invite_view.html:131
|
||||
msgid ""
|
||||
"After the installation is complete, you can return to this page and tap "
|
||||
"the \"Open the app\" button to continue with the setup:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:121
|
||||
#: snikket_web/templates/invite_view.html:130
|
||||
msgid "Install via F-Droid"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:127
|
||||
msgid ""
|
||||
"After installing Snikket via F-Droid, you have to return to this invite "
|
||||
"link and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:129
|
||||
msgid "First install Snikket from F-Droid using the button below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/library.j2:18
|
||||
msgid "Copy link"
|
||||
msgstr ""
|
||||
@@ -1083,15 +1106,11 @@ msgstr ""
|
||||
msgid "Enter your Snikket address and password to manage your account."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/login.html:18
|
||||
msgid "Login failed"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/login.html:23
|
||||
#: snikket_web/templates/login.html:19
|
||||
msgid "Incorrect address"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/login.html:24
|
||||
#: snikket_web/templates/login.html:20
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This Snikket service only hosts addresses ending in "
|
||||
|
||||
@@ -15,16 +15,14 @@ import quart.exceptions
|
||||
|
||||
import wtforms
|
||||
|
||||
import flask_wtf
|
||||
|
||||
from flask_babel import lazy_gettext as _l, _
|
||||
|
||||
from .infra import client
|
||||
from .infra import client, BaseForm
|
||||
|
||||
bp = Blueprint('user', __name__)
|
||||
|
||||
|
||||
class ChangePasswordForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class ChangePasswordForm(BaseForm):
|
||||
current_password = wtforms.PasswordField(
|
||||
_l("Current password"),
|
||||
validators=[wtforms.validators.InputRequired()]
|
||||
@@ -45,7 +43,7 @@ class ChangePasswordForm(flask_wtf.FlaskForm): # type:ignore
|
||||
)
|
||||
|
||||
|
||||
class LogoutForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class LogoutForm(BaseForm):
|
||||
action_signout = wtforms.SubmitField(
|
||||
_l("Sign out"),
|
||||
)
|
||||
@@ -58,7 +56,7 @@ _ACCESS_MODEL_CHOICES = [
|
||||
]
|
||||
|
||||
|
||||
class ProfileForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class ProfileForm(BaseForm):
|
||||
nickname = wtforms.TextField(
|
||||
_l("Display name"),
|
||||
)
|
||||
@@ -98,7 +96,7 @@ async def change_pw() -> typing.Union[str, quart.Response]:
|
||||
quart.exceptions.Forbidden):
|
||||
# server refused current password, set an appropriate error
|
||||
form.current_password.errors.append(
|
||||
_("Incorrect password"),
|
||||
_("Incorrect password."),
|
||||
)
|
||||
else:
|
||||
await flash(
|
||||
@@ -112,7 +110,7 @@ async def change_pw() -> typing.Union[str, quart.Response]:
|
||||
|
||||
EAVATARTOOBIG = _l(
|
||||
"The chosen avatar is too big. To be able to upload larger "
|
||||
"avatars, please use the app"
|
||||
"avatars, please use the app."
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user