bluesky login
This commit is contained in:
parent
43e9db72b7
commit
bf92528331
20 changed files with 549 additions and 240 deletions
|
@ -104,7 +104,8 @@ env = environ.FileAwareEnv(
|
||||||
SLACK_API_TOKEN=(str, ""),
|
SLACK_API_TOKEN=(str, ""),
|
||||||
THREADS_APP_ID=(str, ""),
|
THREADS_APP_ID=(str, ""),
|
||||||
THREADS_APP_SECRET=(str, ""),
|
THREADS_APP_SECRET=(str, ""),
|
||||||
BLUESKY_LOGIN_ENABLED=(bool, False),
|
NEODB_ENABLE_LOGIN_BLUESKY=(bool, False),
|
||||||
|
NEODB_ENABLE_LOGIN_THREADS=(bool, False),
|
||||||
# SSL only, better be True for production security
|
# SSL only, better be True for production security
|
||||||
SSL_ONLY=(bool, False),
|
SSL_ONLY=(bool, False),
|
||||||
NEODB_SENTRY_DSN=(str, ""),
|
NEODB_SENTRY_DSN=(str, ""),
|
||||||
|
@ -181,7 +182,8 @@ else:
|
||||||
THREADS_APP_ID = env("THREADS_APP_ID")
|
THREADS_APP_ID = env("THREADS_APP_ID")
|
||||||
THREADS_APP_SECRET = env("THREADS_APP_SECRET")
|
THREADS_APP_SECRET = env("THREADS_APP_SECRET")
|
||||||
|
|
||||||
BLUESKY_LOGIN_ENABLED = env("BLUESKY_LOGIN_ENABLED")
|
ENABLE_LOGIN_BLUESKY = env("NEODB_ENABLE_LOGIN_BLUESKY")
|
||||||
|
ENABLE_LOGIN_THREADS = env("NEODB_ENABLE_LOGIN_THREADS")
|
||||||
|
|
||||||
SITE_DOMAIN = env("NEODB_SITE_DOMAIN").lower()
|
SITE_DOMAIN = env("NEODB_SITE_DOMAIN").lower()
|
||||||
SITE_INFO = {
|
SITE_INFO = {
|
||||||
|
|
|
@ -54,26 +54,7 @@
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if identity.user.mastodon %}
|
{% include "users/_profile_social_icons.html" %}
|
||||||
<span>
|
|
||||||
<a href="{{ identity.user.mastodon.url }}"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
title="@{{ identity.user.mastodon.handle }}">
|
|
||||||
<i class="fa-brands fa-mastodon"></i>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
{% if identity.user.threads %}
|
|
||||||
<span>
|
|
||||||
<a href="{{ identity.user.threads.url }}"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
title="@{{ identity.user.threads.handle }}">
|
|
||||||
<i class="fa-brands fa-threads"></i>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
{% elif request.user.is_authenticated %}
|
{% elif request.user.is_authenticated %}
|
||||||
{% include 'users/profile_actions.html' %}
|
{% include 'users/profile_actions.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.http import JsonResponse
|
from django.http import HttpRequest, JsonResponse
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ from takahe.utils import Takahe
|
||||||
from .api import api
|
from .api import api
|
||||||
|
|
||||||
|
|
||||||
def render_error(request, title, message=""):
|
def render_error(request: HttpRequest, title, message=""):
|
||||||
return render(
|
return render(
|
||||||
request, "common/error.html", {"msg": title, "secondary_msg": message}
|
request, "common/error.html", {"msg": title, "secondary_msg": message}
|
||||||
)
|
)
|
||||||
|
|
|
@ -43,6 +43,8 @@ x-shared:
|
||||||
NEODB_EMAIL_URL:
|
NEODB_EMAIL_URL:
|
||||||
NEODB_EMAIL_FROM: no-reply@${NEODB_SITE_DOMAIN}
|
NEODB_EMAIL_FROM: no-reply@${NEODB_SITE_DOMAIN}
|
||||||
NEODB_ENABLE_LOCAL_ONLY:
|
NEODB_ENABLE_LOCAL_ONLY:
|
||||||
|
NEODB_ENABLE_LOGIN_BLUESKY:
|
||||||
|
NEODB_ENABLE_LOGIN_THREADS:
|
||||||
NEODB_EXTRA_APPS:
|
NEODB_EXTRA_APPS:
|
||||||
NEODB_FANOUT_LIMIT_DAYS:
|
NEODB_FANOUT_LIMIT_DAYS:
|
||||||
TAKAHE_FANOUT_LIMIT_DAYS:
|
TAKAHE_FANOUT_LIMIT_DAYS:
|
||||||
|
@ -69,7 +71,6 @@ x-shared:
|
||||||
TAKAHE_VENV: /takahe-venv
|
TAKAHE_VENV: /takahe-venv
|
||||||
THREADS_APP_ID:
|
THREADS_APP_ID:
|
||||||
THREADS_APP_SECRET:
|
THREADS_APP_SECRET:
|
||||||
BLUESKY_LOGIN_ENABLED:
|
|
||||||
SPOTIFY_API_KEY:
|
SPOTIFY_API_KEY:
|
||||||
TMDB_API_V3_KEY:
|
TMDB_API_V3_KEY:
|
||||||
GOOGLE_API_KEY:
|
GOOGLE_API_KEY:
|
||||||
|
|
|
@ -9,7 +9,7 @@ import django_rq
|
||||||
|
|
||||||
# from deepmerge import always_merger
|
# from deepmerge import always_merger
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied, RequestAborted
|
||||||
from django.core.signing import b62_decode, b62_encode
|
from django.core.signing import b62_decode, b62_encode
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import CharField, Q
|
from django.db.models import CharField, Q
|
||||||
|
@ -309,7 +309,7 @@ class Piece(PolymorphicModel, UserOwnedObjectMixin):
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
r = threads.post(**params)
|
r = threads.post(**params)
|
||||||
except Exception:
|
except RequestAborted:
|
||||||
logger.warning(f"{self} post to {threads} failed")
|
logger.warning(f"{self} post to {threads} failed")
|
||||||
messages.error(threads.user, _("A recent post was not posted to Threads."))
|
messages.error(threads.user, _("A recent post was not posted to Threads."))
|
||||||
return False
|
return False
|
||||||
|
@ -338,9 +338,8 @@ class Piece(PolymorphicModel, UserOwnedObjectMixin):
|
||||||
mastodon = self.owner.user.mastodon
|
mastodon = self.owner.user.mastodon
|
||||||
if not mastodon:
|
if not mastodon:
|
||||||
return False
|
return False
|
||||||
r = mastodon.post(**params)
|
|
||||||
try:
|
try:
|
||||||
pass
|
r = mastodon.post(**params)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
messages.error(
|
messages.error(
|
||||||
mastodon.user,
|
mastodon.user,
|
||||||
|
@ -348,7 +347,7 @@ class Piece(PolymorphicModel, UserOwnedObjectMixin):
|
||||||
meta={"url": mastodon.get_reauthorize_url()},
|
meta={"url": mastodon.get_reauthorize_url()},
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
except Exception:
|
except RequestAborted:
|
||||||
logger.warning(f"{self} post to {mastodon} failed")
|
logger.warning(f"{self} post to {mastodon} failed")
|
||||||
messages.error(
|
messages.error(
|
||||||
mastodon.user, _("A recent post was not posted to Mastodon.")
|
mastodon.user, _("A recent post was not posted to Mastodon.")
|
||||||
|
|
|
@ -6,7 +6,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-07-03 16:40-0400\n"
|
"POT-Creation-Date: 2024-07-04 00:13-0400\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -15,15 +15,15 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: boofilsic/settings.py:406
|
#: boofilsic/settings.py:408
|
||||||
msgid "English"
|
msgid "English"
|
||||||
msgstr "英语"
|
msgstr "英语"
|
||||||
|
|
||||||
#: boofilsic/settings.py:407
|
#: boofilsic/settings.py:409
|
||||||
msgid "Simplified Chinese"
|
msgid "Simplified Chinese"
|
||||||
msgstr "简体中文"
|
msgstr "简体中文"
|
||||||
|
|
||||||
#: boofilsic/settings.py:408
|
#: boofilsic/settings.py:410
|
||||||
msgid "Traditional Chinese"
|
msgid "Traditional Chinese"
|
||||||
msgstr "繁体中文"
|
msgstr "繁体中文"
|
||||||
|
|
||||||
|
@ -1108,8 +1108,7 @@ msgstr "热门标签"
|
||||||
|
|
||||||
#: catalog/templates/discover.html:177 catalog/templates/item_base.html:236
|
#: catalog/templates/discover.html:177 catalog/templates/item_base.html:236
|
||||||
#: catalog/templates/item_mark_list.html:54
|
#: catalog/templates/item_mark_list.html:54
|
||||||
#: catalog/templates/item_review_list.html:50
|
#: catalog/templates/item_review_list.html:50 common/templates/_sidebar.html:90
|
||||||
#: common/templates/_sidebar.html:109
|
|
||||||
#: common/templates/_sidebar_anonymous.html:43
|
#: common/templates/_sidebar_anonymous.html:43
|
||||||
#: common/templates/_sidebar_anonymous.html:58
|
#: common/templates/_sidebar_anonymous.html:58
|
||||||
#: journal/templates/collection_items.html:8 journal/templates/posts.html:49
|
#: journal/templates/collection_items.html:8 journal/templates/posts.html:49
|
||||||
|
@ -1472,7 +1471,7 @@ msgstr "开发者"
|
||||||
msgid "Source Code"
|
msgid "Source Code"
|
||||||
msgstr "源代码"
|
msgstr "源代码"
|
||||||
|
|
||||||
#: common/templates/_footer.html:16 users/templates/users/login.html:173
|
#: common/templates/_footer.html:16 users/templates/users/login.html:191
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "You are visiting an alternative domain for %(site_name)s, please always use <a href=\"%(site_url)s%(request.get_full_path)s\">original version</a> if possible."
|
msgid "You are visiting an alternative domain for %(site_name)s, please always use <a href=\"%(site_url)s%(request.get_full_path)s\">original version</a> if possible."
|
||||||
msgstr "这是%(site_name)s的临时镜像,请尽可能使用<a href=\"%(site_url)s%(request.get_full_path)s\">原始站点</a>。"
|
msgstr "这是%(site_name)s的临时镜像,请尽可能使用<a href=\"%(site_url)s%(request.get_full_path)s\">原始站点</a>。"
|
||||||
|
@ -1545,50 +1544,50 @@ msgstr "打开"
|
||||||
msgid "approving followers manually"
|
msgid "approving followers manually"
|
||||||
msgstr "已开启关注审核"
|
msgstr "已开启关注审核"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:94
|
#: common/templates/_sidebar.html:75
|
||||||
msgid "Current Targets"
|
msgid "Current Targets"
|
||||||
msgstr "当前目标"
|
msgstr "当前目标"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:107
|
#: common/templates/_sidebar.html:88
|
||||||
msgid "Set a collection as target, its progress will show up here."
|
msgid "Set a collection as target, its progress will show up here."
|
||||||
msgstr "将自己或他人的收藏单设为目标,这里就会显示进度"
|
msgstr "将自己或他人的收藏单设为目标,这里就会显示进度"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:120
|
#: common/templates/_sidebar.html:101
|
||||||
msgid "Recent podcast episodes"
|
msgid "Recent podcast episodes"
|
||||||
msgstr "近期播客节目"
|
msgstr "近期播客节目"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:155
|
#: common/templates/_sidebar.html:136
|
||||||
msgid "Currently reading"
|
msgid "Currently reading"
|
||||||
msgstr "正在阅读"
|
msgstr "正在阅读"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:178
|
#: common/templates/_sidebar.html:159
|
||||||
msgid "Currently watching"
|
msgid "Currently watching"
|
||||||
msgstr "正在追看"
|
msgstr "正在追看"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:201 journal/templates/user_tag_list.html:12
|
#: common/templates/_sidebar.html:182 journal/templates/user_tag_list.html:12
|
||||||
#: journal/templates/user_tagmember_list.html:4
|
#: journal/templates/user_tagmember_list.html:4
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "标签"
|
msgstr "标签"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:207 journal/templates/user_tag_list.html:26
|
#: common/templates/_sidebar.html:188 journal/templates/user_tag_list.html:26
|
||||||
#: journal/templates/user_tagmember_list.html:10
|
#: journal/templates/user_tagmember_list.html:10
|
||||||
msgid "featured tag"
|
msgid "featured tag"
|
||||||
msgstr "置顶标签"
|
msgstr "置顶标签"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:210 journal/templates/user_tag_list.html:29
|
#: common/templates/_sidebar.html:191 journal/templates/user_tag_list.html:29
|
||||||
#: journal/templates/user_tagmember_list.html:15
|
#: journal/templates/user_tagmember_list.html:15
|
||||||
msgid "personal tag"
|
msgid "personal tag"
|
||||||
msgstr "个人标签"
|
msgstr "个人标签"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:217 journal/templates/user_tag_list.html:37
|
#: common/templates/_sidebar.html:198 journal/templates/user_tag_list.html:37
|
||||||
msgid "no tags so far."
|
msgid "no tags so far."
|
||||||
msgstr "暂无标签。"
|
msgstr "暂无标签。"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:221
|
#: common/templates/_sidebar.html:202
|
||||||
msgid "show all"
|
msgid "show all"
|
||||||
msgstr "显示全部"
|
msgstr "显示全部"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:231
|
#: common/templates/_sidebar.html:212
|
||||||
msgid "Recent Posts"
|
msgid "Recent Posts"
|
||||||
msgstr "近期帖文"
|
msgstr "近期帖文"
|
||||||
|
|
||||||
|
@ -1746,11 +1745,11 @@ msgstr "自己和提到的人"
|
||||||
msgid "A recent post was not posted to Threads."
|
msgid "A recent post was not posted to Threads."
|
||||||
msgstr "帖文未能发布到Threads。"
|
msgstr "帖文未能发布到Threads。"
|
||||||
|
|
||||||
#: journal/models/common.py:347
|
#: journal/models/common.py:346
|
||||||
msgid "A recent post was not posted to Mastodon, please re-authorize."
|
msgid "A recent post was not posted to Mastodon, please re-authorize."
|
||||||
msgstr "帖文未能发布到联邦实例,请重新验证登录。"
|
msgstr "帖文未能发布到联邦实例,请重新验证登录。"
|
||||||
|
|
||||||
#: journal/models/common.py:354
|
#: journal/models/common.py:353
|
||||||
msgid "A recent post was not posted to Mastodon."
|
msgid "A recent post was not posted to Mastodon."
|
||||||
msgstr "帖文未能发布到联邦实例。"
|
msgstr "帖文未能发布到联邦实例。"
|
||||||
|
|
||||||
|
@ -2781,7 +2780,7 @@ msgstr "Mastodon"
|
||||||
msgid "Threads"
|
msgid "Threads"
|
||||||
msgstr "Threads"
|
msgstr "Threads"
|
||||||
|
|
||||||
#: mastodon/models/common.py:14 users/templates/users/login.html:83
|
#: mastodon/models/common.py:14
|
||||||
msgid "Bluesky"
|
msgid "Bluesky"
|
||||||
msgstr "Bluesky"
|
msgstr "Bluesky"
|
||||||
|
|
||||||
|
@ -2879,47 +2878,63 @@ msgstr "转播"
|
||||||
msgid "New Post"
|
msgid "New Post"
|
||||||
msgstr "新帖文"
|
msgstr "新帖文"
|
||||||
|
|
||||||
|
#: mastodon/views/bluesky.py:22 mastodon/views/bluesky.py:28
|
||||||
#: mastodon/views/common.py:29 mastodon/views/mastodon.py:37
|
#: mastodon/views/common.py:29 mastodon/views/mastodon.py:37
|
||||||
#: mastodon/views/mastodon.py:44 mastodon/views/mastodon.py:54
|
#: mastodon/views/mastodon.py:44 mastodon/views/mastodon.py:54
|
||||||
#: mastodon/views/mastodon.py:61 mastodon/views/threads.py:40
|
#: mastodon/views/mastodon.py:61 mastodon/views/threads.py:41
|
||||||
#: mastodon/views/threads.py:45 users/views/account.py:104
|
#: mastodon/views/threads.py:47 users/views/account.py:104
|
||||||
msgid "Authentication failed"
|
msgid "Authentication failed"
|
||||||
msgstr "认证失败"
|
msgstr "认证失败"
|
||||||
|
|
||||||
#: mastodon/views/common.py:29 mastodon/views/common.py:79
|
#: mastodon/views/bluesky.py:23
|
||||||
|
msgid "Username and app password is required."
|
||||||
|
msgstr "请输入用户名和密码。"
|
||||||
|
|
||||||
|
#: mastodon/views/bluesky.py:28
|
||||||
|
msgid "Invalid account data from Bluesky."
|
||||||
|
msgstr "Bluesky返回了无效的账号数据。"
|
||||||
|
|
||||||
|
#: mastodon/views/common.py:29 mastodon/views/common.py:94
|
||||||
msgid "Invalid user."
|
msgid "Invalid user."
|
||||||
msgstr "无效用户。"
|
msgstr "无效用户。"
|
||||||
|
|
||||||
#: mastodon/views/common.py:44
|
#: mastodon/views/common.py:45
|
||||||
msgid "Registration failed"
|
msgid "Registration failed"
|
||||||
msgstr "注册失败"
|
msgstr "注册失败"
|
||||||
|
|
||||||
#: mastodon/views/common.py:44
|
#: mastodon/views/common.py:45
|
||||||
msgid "User already logged in."
|
msgid "User already logged in."
|
||||||
msgstr "用户已经登录了。"
|
msgstr "用户已经登录了。"
|
||||||
|
|
||||||
#: mastodon/views/common.py:52
|
#: mastodon/views/common.py:57
|
||||||
msgid "Unable to update login information: identical identity."
|
#, python-brace-format
|
||||||
msgstr "无法更新登录信息:该身份与当前账号相同。"
|
msgid "Continue login as {handle}."
|
||||||
|
msgstr "继续以 {handle} 登录。"
|
||||||
|
|
||||||
#: mastodon/views/common.py:56
|
#: mastodon/views/common.py:63
|
||||||
msgid "Unable to update login information: identity in use."
|
msgid "Unable to update login information"
|
||||||
msgstr "无法更新登录信息:该身份已被其它账号使用。"
|
msgstr "无法更新登录信息"
|
||||||
|
|
||||||
#: mastodon/views/common.py:70
|
#: mastodon/views/common.py:64
|
||||||
msgid "Login information updated."
|
#, python-brace-format
|
||||||
msgstr "登录信息已更新"
|
msgid "Identity {handle} in use by a different user."
|
||||||
|
msgstr "身份 {handle} 已被其它账号使用。"
|
||||||
|
|
||||||
#: mastodon/views/common.py:77 mastodon/views/common.py:79
|
#: mastodon/views/common.py:80
|
||||||
#: mastodon/views/common.py:83
|
#, python-brace-format
|
||||||
|
msgid "Login information updated as {handle}."
|
||||||
|
msgstr "登录信息已更新为{handle}。"
|
||||||
|
|
||||||
|
#: mastodon/views/common.py:90 mastodon/views/common.py:94
|
||||||
|
#: mastodon/views/common.py:100
|
||||||
msgid "Disconnect identity failed"
|
msgid "Disconnect identity failed"
|
||||||
msgstr "未能取消身份关联"
|
msgstr "未能取消身份关联"
|
||||||
|
|
||||||
#: mastodon/views/common.py:77
|
#: mastodon/views/common.py:90
|
||||||
msgid "Identity not found."
|
msgid "Identity not found."
|
||||||
msgstr "身份未找到"
|
msgstr "身份未找到"
|
||||||
|
|
||||||
#: mastodon/views/common.py:84
|
#: mastodon/views/common.py:101
|
||||||
msgid "You cannot disconnect last login identity."
|
msgid "You cannot disconnect last login identity."
|
||||||
msgstr "无法取消唯一的登录用身份。"
|
msgstr "无法取消唯一的登录用身份。"
|
||||||
|
|
||||||
|
@ -2967,7 +2982,7 @@ msgstr "联邦实例返回了无效的认证令牌。"
|
||||||
msgid "Invalid account data from Fediverse instance."
|
msgid "Invalid account data from Fediverse instance."
|
||||||
msgstr "联邦实例返回了无效的账号数据。"
|
msgstr "联邦实例返回了无效的账号数据。"
|
||||||
|
|
||||||
#: mastodon/views/threads.py:45
|
#: mastodon/views/threads.py:47
|
||||||
msgid "Invalid account data from Threads."
|
msgid "Invalid account data from Threads."
|
||||||
msgstr "Threads返回了无效的账号数据。"
|
msgstr "Threads返回了无效的账号数据。"
|
||||||
|
|
||||||
|
@ -3305,7 +3320,8 @@ msgid "Verified Identity"
|
||||||
msgstr "已验证的身份"
|
msgstr "已验证的身份"
|
||||||
|
|
||||||
#: users/templates/users/account.html:86 users/templates/users/account.html:147
|
#: users/templates/users/account.html:86 users/templates/users/account.html:147
|
||||||
#: users/templates/users/account.html:209
|
#: users/templates/users/account.html:183
|
||||||
|
#: users/templates/users/account.html:263
|
||||||
msgid "Last updated"
|
msgid "Last updated"
|
||||||
msgstr "最近更新"
|
msgstr "最近更新"
|
||||||
|
|
||||||
|
@ -3335,6 +3351,7 @@ msgstr "关联联邦宇宙身份后可发现更多用户,并使用本站完整
|
||||||
|
|
||||||
#: users/templates/users/account.html:123
|
#: users/templates/users/account.html:123
|
||||||
#: users/templates/users/account.html:159
|
#: users/templates/users/account.html:159
|
||||||
|
#: users/templates/users/account.html:213
|
||||||
msgid "Once disconnected, you will no longer be able login with this identity. Are you sure to continue?"
|
msgid "Once disconnected, you will no longer be able login with this identity. Are you sure to continue?"
|
||||||
msgstr "取消关联后将无法使用这个身份登录本站,确认继续吗?"
|
msgstr "取消关联后将无法使用这个身份登录本站,确认继续吗?"
|
||||||
|
|
||||||
|
@ -3362,75 +3379,107 @@ msgstr "关联一个threads.net账号"
|
||||||
msgid "Disconnect with Threads"
|
msgid "Disconnect with Threads"
|
||||||
msgstr "取消关联"
|
msgstr "取消关联"
|
||||||
|
|
||||||
#: users/templates/users/account.html:171
|
#: users/templates/users/account.html:170 users/templates/users/login.html:83
|
||||||
|
msgid "Bluesky (ATProto)"
|
||||||
|
msgstr "Bluesky (ATProto)"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:176
|
||||||
|
msgid "Verified ATProto identity"
|
||||||
|
msgstr "已验证的ATProto身份"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:192 users/templates/users/login.html:151
|
||||||
|
msgid "Bluesky Login ID"
|
||||||
|
msgstr "Bluesky 登录名"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:200 users/templates/users/login.html:159
|
||||||
|
msgid "Bluesky app password"
|
||||||
|
msgstr "Bluesky 应用密码"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:206
|
||||||
|
msgid "Link with a different ATProto identity"
|
||||||
|
msgstr "关联另一个ATProto身份"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:206
|
||||||
|
msgid "Link with an ATProto identity"
|
||||||
|
msgstr "关联ATProto身份"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:207 users/templates/users/login.html:164
|
||||||
|
msgid "App password can be created on <a href=\"https://bsky.app/settings/app-passwords\" target=\"_blank\">bsky.app</a>."
|
||||||
|
msgstr "应用密码可在 <a href=\"https://bsky.app/settings/app-passwords\" target=\"_blank\">bsky.app</a> 创建管理。"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:216
|
||||||
|
msgid "Disconnect with ATProto identity"
|
||||||
|
msgstr "取消关联"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:225
|
||||||
msgid "Sync and import social account"
|
msgid "Sync and import social account"
|
||||||
msgstr "同步第三方社交网络上的个人信息和社交数据"
|
msgstr "同步第三方社交网络上的个人信息和社交数据"
|
||||||
|
|
||||||
#: users/templates/users/account.html:181
|
#: users/templates/users/account.html:235
|
||||||
msgid "Sync display name, bio and avatar"
|
msgid "Sync display name, bio and avatar"
|
||||||
msgstr "自动同步用户昵称等基本信息"
|
msgstr "自动同步用户昵称等基本信息"
|
||||||
|
|
||||||
#: users/templates/users/account.html:189
|
#: users/templates/users/account.html:243
|
||||||
msgid "Sync follow, mute and block"
|
msgid "Sync follow, mute and block"
|
||||||
msgstr "自动导入新增的关注、屏蔽和隐藏列表"
|
msgstr "自动导入新增的关注、屏蔽和隐藏列表"
|
||||||
|
|
||||||
#: users/templates/users/account.html:193
|
#: users/templates/users/account.html:247
|
||||||
msgid "Save sync settings"
|
msgid "Save sync settings"
|
||||||
msgstr "保存同步设置"
|
msgstr "保存同步设置"
|
||||||
|
|
||||||
#: users/templates/users/account.html:196
|
#: users/templates/users/account.html:250
|
||||||
msgid "New follow, mute and blocks in the associated identity may be automatically imported; removal has to be done manually."
|
msgid "New follow, mute and blocks in the associated identity may be automatically imported; removal has to be done manually."
|
||||||
msgstr "本站会按照以上设置每天自动导入你在联邦宇宙实例等社交网络中新增的关注、屏蔽和隐藏列表;如果你在联邦宇宙实例中关注的用户加入了本站,你会自动关注她;如果你在联邦宇宙实例中取消了关注、屏蔽或隐藏,本站不会自动取消,但你可以手动移除。"
|
msgstr "本站会按照以上设置每天自动导入你在联邦宇宙实例等社交网络中新增的关注、屏蔽和隐藏列表;如果你在联邦宇宙实例中关注的用户加入了本站,你会自动关注她;如果你在联邦宇宙实例中取消了关注、屏蔽或隐藏,本站不会自动取消,但你可以手动移除。"
|
||||||
|
|
||||||
#: users/templates/users/account.html:203
|
#: users/templates/users/account.html:257
|
||||||
msgid "Click button below to start sync now."
|
msgid "Click button below to start sync now."
|
||||||
msgstr "如果希望立即开始同步,可以点击下方按钮。"
|
msgstr "如果希望立即开始同步,可以点击下方按钮。"
|
||||||
|
|
||||||
#: users/templates/users/account.html:205
|
#: users/templates/users/account.html:259
|
||||||
msgid "Sync now"
|
msgid "Sync now"
|
||||||
msgstr "立即同步"
|
msgstr "立即同步"
|
||||||
|
|
||||||
#: users/templates/users/account.html:217
|
#: users/templates/users/account.html:271
|
||||||
msgid "Users you are following"
|
msgid "Users you are following"
|
||||||
msgstr "正在关注的用户"
|
msgstr "正在关注的用户"
|
||||||
|
|
||||||
#: users/templates/users/account.html:223
|
#: users/templates/users/account.html:277
|
||||||
msgid "Users who follow you"
|
msgid "Users who follow you"
|
||||||
msgstr "关注了你的用户"
|
msgstr "关注了你的用户"
|
||||||
|
|
||||||
#: users/templates/users/account.html:229
|
#: users/templates/users/account.html:283
|
||||||
msgid "Users who request to follow you"
|
msgid "Users who request to follow you"
|
||||||
msgstr "请求关注你的用户"
|
msgstr "请求关注你的用户"
|
||||||
|
|
||||||
#: users/templates/users/account.html:235
|
#: users/templates/users/account.html:289
|
||||||
msgid "Users you are muting"
|
msgid "Users you are muting"
|
||||||
msgstr "已隐藏的用户"
|
msgstr "已隐藏的用户"
|
||||||
|
|
||||||
#: users/templates/users/account.html:241
|
#: users/templates/users/account.html:295
|
||||||
msgid "Users you are blocking"
|
msgid "Users you are blocking"
|
||||||
msgstr "已屏蔽的用户"
|
msgstr "已屏蔽的用户"
|
||||||
|
|
||||||
#: users/templates/users/account.html:248
|
#: users/templates/users/account.html:302
|
||||||
msgid "Delete Account"
|
msgid "Delete Account"
|
||||||
msgstr "删除账号"
|
msgstr "删除账号"
|
||||||
|
|
||||||
#: users/templates/users/account.html:251
|
#: users/templates/users/account.html:305
|
||||||
msgid "Once deleted, account data cannot be recovered. Sure to proceed?"
|
msgid "Once deleted, account data cannot be recovered. Sure to proceed?"
|
||||||
msgstr "账号数据一旦删除后将无法恢复,确定继续吗?"
|
msgstr "账号数据一旦删除后将无法恢复,确定继续吗?"
|
||||||
|
|
||||||
#: users/templates/users/account.html:254
|
#: users/templates/users/account.html:308
|
||||||
msgid "Enter full <code>username@instance.social</code> or <code>email@domain.com</code> to confirm deletion."
|
msgid "Enter full <code>username@instance.social</code> or <code>email@domain.com</code> to confirm deletion."
|
||||||
msgstr "输入完整的登录用 <code>用户名@实例名</code> 或 <code>电子邮件地址</code> 以确认删除"
|
msgstr "输入完整的登录用 <code>用户名@实例名</code> 或 <code>电子邮件地址</code> 以确认删除"
|
||||||
|
|
||||||
#: users/templates/users/account.html:264
|
#: users/templates/users/account.html:318
|
||||||
msgid "Once deleted, account data cannot be recovered."
|
msgid "Once deleted, account data cannot be recovered."
|
||||||
msgstr "账号数据一旦删除后将无法恢复"
|
msgstr "账号数据一旦删除后将无法恢复"
|
||||||
|
|
||||||
#: users/templates/users/account.html:266
|
#: users/templates/users/account.html:320
|
||||||
msgid "Importing in progress, can't delete now."
|
msgid "Importing in progress, can't delete now."
|
||||||
msgstr "暂时无法删除,因为有导入任务正在进行"
|
msgstr "暂时无法删除,因为有导入任务正在进行"
|
||||||
|
|
||||||
#: users/templates/users/account.html:269
|
#: users/templates/users/account.html:323
|
||||||
msgid "Permanently Delete"
|
msgid "Permanently Delete"
|
||||||
msgstr "永久删除"
|
msgstr "永久删除"
|
||||||
|
|
||||||
|
@ -3586,7 +3635,7 @@ msgstr "实例域名(不含@和@之前的部分),如mastodon.social"
|
||||||
msgid "Please enter domain of your instance; e.g. if your id is <i>@neodb@mastodon.social</i>, only enter <i>mastodon.social</i>."
|
msgid "Please enter domain of your instance; e.g. if your id is <i>@neodb@mastodon.social</i>, only enter <i>mastodon.social</i>."
|
||||||
msgstr "请输入你的实例域名(不含@和@之前的部分);如果你的联邦账号是<i>@neodb@mastodon.social</i>,只需要在此输入<i>mastodon.social</i>。"
|
msgstr "请输入你的实例域名(不含@和@之前的部分);如果你的联邦账号是<i>@neodb@mastodon.social</i>,只需要在此输入<i>mastodon.social</i>。"
|
||||||
|
|
||||||
#: users/templates/users/login.html:125 users/templates/users/login.html:156
|
#: users/templates/users/login.html:125 users/templates/users/login.html:174
|
||||||
msgid "Authorize via Fediverse instance"
|
msgid "Authorize via Fediverse instance"
|
||||||
msgstr "去联邦实例授权注册或登录"
|
msgstr "去联邦实例授权注册或登录"
|
||||||
|
|
||||||
|
@ -3602,35 +3651,35 @@ msgstr "去Threads授权注册或登录"
|
||||||
msgid "If you have already account here registered via a different way, you may login through there and link with your Threads account in account settings."
|
msgid "If you have already account here registered via a different way, you may login through there and link with your Threads account in account settings."
|
||||||
msgstr "如果你已通过其它方式注册过本站帐号,请用该方式登录后再关联Threads。"
|
msgstr "如果你已通过其它方式注册过本站帐号,请用该方式登录后再关联Threads。"
|
||||||
|
|
||||||
#: users/templates/users/login.html:147
|
#: users/templates/users/login.html:165
|
||||||
msgid "Authorize via Bluesky"
|
msgid "Authorize via bsky.app"
|
||||||
msgstr "去Bluesky授权注册或登录"
|
msgstr "使用Bluesky账号信息注册或登录"
|
||||||
|
|
||||||
#: users/templates/users/login.html:148
|
#: users/templates/users/login.html:166
|
||||||
msgid "If you have already account here registered via a different way, you may login through there and link with your Bluesky account in account settings."
|
msgid "If you have already account here registered via a different way, you may login through there and link with your Bluesky account in account settings."
|
||||||
msgstr "如果你已通过其它方式注册过本站帐号,请用该方式登录后再关联Bluesky。"
|
msgstr "如果你已通过其它方式注册过本站帐号,请用该方式登录后再关联Bluesky。"
|
||||||
|
|
||||||
#: users/templates/users/login.html:163
|
#: users/templates/users/login.html:181
|
||||||
msgid "Valid invitation code, please login or register."
|
msgid "Valid invitation code, please login or register."
|
||||||
msgstr "邀请链接有效,可注册新用户"
|
msgstr "邀请链接有效,可注册新用户"
|
||||||
|
|
||||||
#: users/templates/users/login.html:165
|
#: users/templates/users/login.html:183
|
||||||
msgid "Please use invitation link to register a new account; existing user may login."
|
msgid "Please use invitation link to register a new account; existing user may login."
|
||||||
msgstr "本站目前为邀请注册,已有账户可直接登入,新用户请使用有效邀请链接注册"
|
msgstr "本站目前为邀请注册,已有账户可直接登入,新用户请使用有效邀请链接注册"
|
||||||
|
|
||||||
#: users/templates/users/login.html:167
|
#: users/templates/users/login.html:185
|
||||||
msgid "Invitation code invalid or expired."
|
msgid "Invitation code invalid or expired."
|
||||||
msgstr "邀请链接无效,已有账户可直接登入,新用户请使用有效邀请链接注册"
|
msgstr "邀请链接无效,已有账户可直接登入,新用户请使用有效邀请链接注册"
|
||||||
|
|
||||||
#: users/templates/users/login.html:175
|
#: users/templates/users/login.html:193
|
||||||
msgid "Loading timed out, please check your network (VPN) settings."
|
msgid "Loading timed out, please check your network (VPN) settings."
|
||||||
msgstr "部分模块加载超时,请检查网络(翻墙)设置。"
|
msgstr "部分模块加载超时,请检查网络(翻墙)设置。"
|
||||||
|
|
||||||
#: users/templates/users/login.html:181
|
#: users/templates/users/login.html:199
|
||||||
msgid "Continue using this site implies consent to our <a href=\"/pages/rules/\">rules</a> and <a href=\"/pages/terms/\">terms</a>, including using cookies to provide necessary functionality."
|
msgid "Continue using this site implies consent to our <a href=\"/pages/rules/\">rules</a> and <a href=\"/pages/terms/\">terms</a>, including using cookies to provide necessary functionality."
|
||||||
msgstr "继续访问或注册视为同意<a href=\"/pages/rules/\">站规</a>与<a href=\"/pages/terms/\">协议</a>,及使用cookie提供必要功能"
|
msgstr "继续访问或注册视为同意<a href=\"/pages/rules/\">站规</a>与<a href=\"/pages/terms/\">协议</a>,及使用cookie提供必要功能"
|
||||||
|
|
||||||
#: users/templates/users/login.html:187
|
#: users/templates/users/login.html:205
|
||||||
msgid "Domain of your instance (excl. @)"
|
msgid "Domain of your instance (excl. @)"
|
||||||
msgstr "实例域名(不含@和@之前的部分)"
|
msgstr "实例域名(不含@和@之前的部分)"
|
||||||
|
|
||||||
|
@ -3786,59 +3835,59 @@ msgstr "用户资料"
|
||||||
msgid "original home"
|
msgid "original home"
|
||||||
msgstr "原始主页"
|
msgstr "原始主页"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:82
|
#: users/templates/users/profile_actions.html:63
|
||||||
msgid "accept follow request"
|
msgid "accept follow request"
|
||||||
msgstr "接受关注请求"
|
msgstr "接受关注请求"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:84
|
#: users/templates/users/profile_actions.html:65
|
||||||
msgid "sure to accept follow request?"
|
msgid "sure to accept follow request?"
|
||||||
msgstr "确定接受关注请求吗?"
|
msgstr "确定接受关注请求吗?"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:92
|
#: users/templates/users/profile_actions.html:73
|
||||||
msgid "reject follow request"
|
msgid "reject follow request"
|
||||||
msgstr "拒绝关注请求"
|
msgstr "拒绝关注请求"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:94
|
#: users/templates/users/profile_actions.html:75
|
||||||
msgid "sure to reject follow request?"
|
msgid "sure to reject follow request?"
|
||||||
msgstr "确定拒绝关注请求吗?"
|
msgstr "确定拒绝关注请求吗?"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:104
|
#: users/templates/users/profile_actions.html:85
|
||||||
msgid "click to unfollow"
|
msgid "click to unfollow"
|
||||||
msgstr "点击可取消关注"
|
msgstr "点击可取消关注"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:106
|
#: users/templates/users/profile_actions.html:87
|
||||||
msgid "sure to unfollow?"
|
msgid "sure to unfollow?"
|
||||||
msgstr "确定取消关注该用户吗?"
|
msgstr "确定取消关注该用户吗?"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:115
|
#: users/templates/users/profile_actions.html:96
|
||||||
msgid "click to cancel follow request"
|
msgid "click to cancel follow request"
|
||||||
msgstr "点击可取消关注请求"
|
msgstr "点击可取消关注请求"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:117
|
#: users/templates/users/profile_actions.html:98
|
||||||
msgid "sure to cancel follow request?"
|
msgid "sure to cancel follow request?"
|
||||||
msgstr "确定取消关注请求吗?"
|
msgstr "确定取消关注请求吗?"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:126
|
#: users/templates/users/profile_actions.html:107
|
||||||
msgid "click to follow"
|
msgid "click to follow"
|
||||||
msgstr "点击可关注"
|
msgstr "点击可关注"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:127
|
#: users/templates/users/profile_actions.html:108
|
||||||
msgid "sure to follow?"
|
msgid "sure to follow?"
|
||||||
msgstr "确定关注该用户吗?"
|
msgstr "确定关注该用户吗?"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:137
|
#: users/templates/users/profile_actions.html:118
|
||||||
msgid "click to mute"
|
msgid "click to mute"
|
||||||
msgstr "点击可静音"
|
msgstr "点击可静音"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:146
|
#: users/templates/users/profile_actions.html:127
|
||||||
msgid "click to unmute"
|
msgid "click to unmute"
|
||||||
msgstr "点击可取消静音"
|
msgstr "点击可取消静音"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:156
|
#: users/templates/users/profile_actions.html:137
|
||||||
msgid "click to block"
|
msgid "click to block"
|
||||||
msgstr "点击可屏蔽"
|
msgstr "点击可屏蔽"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:157
|
#: users/templates/users/profile_actions.html:138
|
||||||
msgid "sure to block?"
|
msgid "sure to block?"
|
||||||
msgstr "确定屏蔽该用户吗?"
|
msgstr "确定屏蔽该用户吗?"
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-07-03 16:40-0400\n"
|
"POT-Creation-Date: 2024-07-04 00:13-0400\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -15,15 +15,15 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: boofilsic/settings.py:406
|
#: boofilsic/settings.py:408
|
||||||
msgid "English"
|
msgid "English"
|
||||||
msgstr "英語"
|
msgstr "英語"
|
||||||
|
|
||||||
#: boofilsic/settings.py:407
|
#: boofilsic/settings.py:409
|
||||||
msgid "Simplified Chinese"
|
msgid "Simplified Chinese"
|
||||||
msgstr "簡體中文"
|
msgstr "簡體中文"
|
||||||
|
|
||||||
#: boofilsic/settings.py:408
|
#: boofilsic/settings.py:410
|
||||||
msgid "Traditional Chinese"
|
msgid "Traditional Chinese"
|
||||||
msgstr "繁體中文"
|
msgstr "繁體中文"
|
||||||
|
|
||||||
|
@ -1108,8 +1108,7 @@ msgstr "熱門標籤"
|
||||||
|
|
||||||
#: catalog/templates/discover.html:177 catalog/templates/item_base.html:236
|
#: catalog/templates/discover.html:177 catalog/templates/item_base.html:236
|
||||||
#: catalog/templates/item_mark_list.html:54
|
#: catalog/templates/item_mark_list.html:54
|
||||||
#: catalog/templates/item_review_list.html:50
|
#: catalog/templates/item_review_list.html:50 common/templates/_sidebar.html:90
|
||||||
#: common/templates/_sidebar.html:109
|
|
||||||
#: common/templates/_sidebar_anonymous.html:43
|
#: common/templates/_sidebar_anonymous.html:43
|
||||||
#: common/templates/_sidebar_anonymous.html:58
|
#: common/templates/_sidebar_anonymous.html:58
|
||||||
#: journal/templates/collection_items.html:8 journal/templates/posts.html:49
|
#: journal/templates/collection_items.html:8 journal/templates/posts.html:49
|
||||||
|
@ -1472,7 +1471,7 @@ msgstr "開發者"
|
||||||
msgid "Source Code"
|
msgid "Source Code"
|
||||||
msgstr "源代碼"
|
msgstr "源代碼"
|
||||||
|
|
||||||
#: common/templates/_footer.html:16 users/templates/users/login.html:173
|
#: common/templates/_footer.html:16 users/templates/users/login.html:191
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "You are visiting an alternative domain for %(site_name)s, please always use <a href=\"%(site_url)s%(request.get_full_path)s\">original version</a> if possible."
|
msgid "You are visiting an alternative domain for %(site_name)s, please always use <a href=\"%(site_url)s%(request.get_full_path)s\">original version</a> if possible."
|
||||||
msgstr "這是%(site_name)s的臨時鏡像,請儘可能使用<a href=\"%(site_url)s%(request.get_full_path)s\">原始站點</a>。"
|
msgstr "這是%(site_name)s的臨時鏡像,請儘可能使用<a href=\"%(site_url)s%(request.get_full_path)s\">原始站點</a>。"
|
||||||
|
@ -1545,50 +1544,50 @@ msgstr "打開"
|
||||||
msgid "approving followers manually"
|
msgid "approving followers manually"
|
||||||
msgstr "已開啓關注審覈"
|
msgstr "已開啓關注審覈"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:94
|
#: common/templates/_sidebar.html:75
|
||||||
msgid "Current Targets"
|
msgid "Current Targets"
|
||||||
msgstr "當前目標"
|
msgstr "當前目標"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:107
|
#: common/templates/_sidebar.html:88
|
||||||
msgid "Set a collection as target, its progress will show up here."
|
msgid "Set a collection as target, its progress will show up here."
|
||||||
msgstr "將自己或他人的收藏單設爲目標,這裏就會顯示進度"
|
msgstr "將自己或他人的收藏單設爲目標,這裏就會顯示進度"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:120
|
#: common/templates/_sidebar.html:101
|
||||||
msgid "Recent podcast episodes"
|
msgid "Recent podcast episodes"
|
||||||
msgstr "近期播客節目"
|
msgstr "近期播客節目"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:155
|
#: common/templates/_sidebar.html:136
|
||||||
msgid "Currently reading"
|
msgid "Currently reading"
|
||||||
msgstr "正在閱讀"
|
msgstr "正在閱讀"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:178
|
#: common/templates/_sidebar.html:159
|
||||||
msgid "Currently watching"
|
msgid "Currently watching"
|
||||||
msgstr "正在追看"
|
msgstr "正在追看"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:201 journal/templates/user_tag_list.html:12
|
#: common/templates/_sidebar.html:182 journal/templates/user_tag_list.html:12
|
||||||
#: journal/templates/user_tagmember_list.html:4
|
#: journal/templates/user_tagmember_list.html:4
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "標籤"
|
msgstr "標籤"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:207 journal/templates/user_tag_list.html:26
|
#: common/templates/_sidebar.html:188 journal/templates/user_tag_list.html:26
|
||||||
#: journal/templates/user_tagmember_list.html:10
|
#: journal/templates/user_tagmember_list.html:10
|
||||||
msgid "featured tag"
|
msgid "featured tag"
|
||||||
msgstr "置頂標籤"
|
msgstr "置頂標籤"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:210 journal/templates/user_tag_list.html:29
|
#: common/templates/_sidebar.html:191 journal/templates/user_tag_list.html:29
|
||||||
#: journal/templates/user_tagmember_list.html:15
|
#: journal/templates/user_tagmember_list.html:15
|
||||||
msgid "personal tag"
|
msgid "personal tag"
|
||||||
msgstr "個人標籤"
|
msgstr "個人標籤"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:217 journal/templates/user_tag_list.html:37
|
#: common/templates/_sidebar.html:198 journal/templates/user_tag_list.html:37
|
||||||
msgid "no tags so far."
|
msgid "no tags so far."
|
||||||
msgstr "暫無標籤。"
|
msgstr "暫無標籤。"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:221
|
#: common/templates/_sidebar.html:202
|
||||||
msgid "show all"
|
msgid "show all"
|
||||||
msgstr "顯示全部"
|
msgstr "顯示全部"
|
||||||
|
|
||||||
#: common/templates/_sidebar.html:231
|
#: common/templates/_sidebar.html:212
|
||||||
msgid "Recent Posts"
|
msgid "Recent Posts"
|
||||||
msgstr "近期帖文"
|
msgstr "近期帖文"
|
||||||
|
|
||||||
|
@ -1746,11 +1745,11 @@ msgstr "自己和提到的人"
|
||||||
msgid "A recent post was not posted to Threads."
|
msgid "A recent post was not posted to Threads."
|
||||||
msgstr "帖文未能發佈到Threads。"
|
msgstr "帖文未能發佈到Threads。"
|
||||||
|
|
||||||
#: journal/models/common.py:347
|
#: journal/models/common.py:346
|
||||||
msgid "A recent post was not posted to Mastodon, please re-authorize."
|
msgid "A recent post was not posted to Mastodon, please re-authorize."
|
||||||
msgstr "帖文未能發佈到聯邦實例,請重新驗證登錄。"
|
msgstr "帖文未能發佈到聯邦實例,請重新驗證登錄。"
|
||||||
|
|
||||||
#: journal/models/common.py:354
|
#: journal/models/common.py:353
|
||||||
msgid "A recent post was not posted to Mastodon."
|
msgid "A recent post was not posted to Mastodon."
|
||||||
msgstr "帖文未能發佈到聯邦實例。"
|
msgstr "帖文未能發佈到聯邦實例。"
|
||||||
|
|
||||||
|
@ -2781,7 +2780,7 @@ msgstr "Mastodon"
|
||||||
msgid "Threads"
|
msgid "Threads"
|
||||||
msgstr "Threads"
|
msgstr "Threads"
|
||||||
|
|
||||||
#: mastodon/models/common.py:14 users/templates/users/login.html:83
|
#: mastodon/models/common.py:14
|
||||||
msgid "Bluesky"
|
msgid "Bluesky"
|
||||||
msgstr "Bluesky"
|
msgstr "Bluesky"
|
||||||
|
|
||||||
|
@ -2879,47 +2878,63 @@ msgstr "轉播"
|
||||||
msgid "New Post"
|
msgid "New Post"
|
||||||
msgstr "新帖文"
|
msgstr "新帖文"
|
||||||
|
|
||||||
|
#: mastodon/views/bluesky.py:22 mastodon/views/bluesky.py:28
|
||||||
#: mastodon/views/common.py:29 mastodon/views/mastodon.py:37
|
#: mastodon/views/common.py:29 mastodon/views/mastodon.py:37
|
||||||
#: mastodon/views/mastodon.py:44 mastodon/views/mastodon.py:54
|
#: mastodon/views/mastodon.py:44 mastodon/views/mastodon.py:54
|
||||||
#: mastodon/views/mastodon.py:61 mastodon/views/threads.py:40
|
#: mastodon/views/mastodon.py:61 mastodon/views/threads.py:41
|
||||||
#: mastodon/views/threads.py:45 users/views/account.py:104
|
#: mastodon/views/threads.py:47 users/views/account.py:104
|
||||||
msgid "Authentication failed"
|
msgid "Authentication failed"
|
||||||
msgstr "認證失敗"
|
msgstr "認證失敗"
|
||||||
|
|
||||||
#: mastodon/views/common.py:29 mastodon/views/common.py:79
|
#: mastodon/views/bluesky.py:23
|
||||||
|
msgid "Username and app password is required."
|
||||||
|
msgstr "請輸入用戶名和密碼。"
|
||||||
|
|
||||||
|
#: mastodon/views/bluesky.py:28
|
||||||
|
msgid "Invalid account data from Bluesky."
|
||||||
|
msgstr "Bluesky返回了無效的賬號數據。"
|
||||||
|
|
||||||
|
#: mastodon/views/common.py:29 mastodon/views/common.py:94
|
||||||
msgid "Invalid user."
|
msgid "Invalid user."
|
||||||
msgstr "無效用戶。"
|
msgstr "無效用戶。"
|
||||||
|
|
||||||
#: mastodon/views/common.py:44
|
#: mastodon/views/common.py:45
|
||||||
msgid "Registration failed"
|
msgid "Registration failed"
|
||||||
msgstr "註冊失敗"
|
msgstr "註冊失敗"
|
||||||
|
|
||||||
#: mastodon/views/common.py:44
|
#: mastodon/views/common.py:45
|
||||||
msgid "User already logged in."
|
msgid "User already logged in."
|
||||||
msgstr "用戶已經登錄了。"
|
msgstr "用戶已經登錄了。"
|
||||||
|
|
||||||
#: mastodon/views/common.py:52
|
#: mastodon/views/common.py:57
|
||||||
msgid "Unable to update login information: identical identity."
|
#, python-brace-format
|
||||||
msgstr "無法更新登錄信息:該身份與當前賬號相同。"
|
msgid "Continue login as {handle}."
|
||||||
|
msgstr "繼續以 {handle} 登錄。"
|
||||||
|
|
||||||
#: mastodon/views/common.py:56
|
#: mastodon/views/common.py:63
|
||||||
msgid "Unable to update login information: identity in use."
|
msgid "Unable to update login information"
|
||||||
msgstr "無法更新登錄信息:該身份已被其它賬號使用。"
|
msgstr "無法更新登錄信息"
|
||||||
|
|
||||||
#: mastodon/views/common.py:70
|
#: mastodon/views/common.py:64
|
||||||
msgid "Login information updated."
|
#, python-brace-format
|
||||||
msgstr "登錄信息已更新"
|
msgid "Identity {handle} in use by a different user."
|
||||||
|
msgstr "身份 {handle} 已被其它賬號使用。"
|
||||||
|
|
||||||
#: mastodon/views/common.py:77 mastodon/views/common.py:79
|
#: mastodon/views/common.py:80
|
||||||
#: mastodon/views/common.py:83
|
#, python-brace-format
|
||||||
|
msgid "Login information updated as {handle}."
|
||||||
|
msgstr "登錄信息已更新爲{handle}。"
|
||||||
|
|
||||||
|
#: mastodon/views/common.py:90 mastodon/views/common.py:94
|
||||||
|
#: mastodon/views/common.py:100
|
||||||
msgid "Disconnect identity failed"
|
msgid "Disconnect identity failed"
|
||||||
msgstr "未能取消身份關聯"
|
msgstr "未能取消身份關聯"
|
||||||
|
|
||||||
#: mastodon/views/common.py:77
|
#: mastodon/views/common.py:90
|
||||||
msgid "Identity not found."
|
msgid "Identity not found."
|
||||||
msgstr "身份未找到"
|
msgstr "身份未找到"
|
||||||
|
|
||||||
#: mastodon/views/common.py:84
|
#: mastodon/views/common.py:101
|
||||||
msgid "You cannot disconnect last login identity."
|
msgid "You cannot disconnect last login identity."
|
||||||
msgstr "無法取消唯一的登錄用身份。"
|
msgstr "無法取消唯一的登錄用身份。"
|
||||||
|
|
||||||
|
@ -2967,7 +2982,7 @@ msgstr "聯邦實例返回了無效的認證令牌。"
|
||||||
msgid "Invalid account data from Fediverse instance."
|
msgid "Invalid account data from Fediverse instance."
|
||||||
msgstr "聯邦實例返回了無效的賬號數據。"
|
msgstr "聯邦實例返回了無效的賬號數據。"
|
||||||
|
|
||||||
#: mastodon/views/threads.py:45
|
#: mastodon/views/threads.py:47
|
||||||
msgid "Invalid account data from Threads."
|
msgid "Invalid account data from Threads."
|
||||||
msgstr "Threads返回了無效的賬號數據。"
|
msgstr "Threads返回了無效的賬號數據。"
|
||||||
|
|
||||||
|
@ -3305,7 +3320,8 @@ msgid "Verified Identity"
|
||||||
msgstr "已驗證的身份"
|
msgstr "已驗證的身份"
|
||||||
|
|
||||||
#: users/templates/users/account.html:86 users/templates/users/account.html:147
|
#: users/templates/users/account.html:86 users/templates/users/account.html:147
|
||||||
#: users/templates/users/account.html:209
|
#: users/templates/users/account.html:183
|
||||||
|
#: users/templates/users/account.html:263
|
||||||
msgid "Last updated"
|
msgid "Last updated"
|
||||||
msgstr "最近更新"
|
msgstr "最近更新"
|
||||||
|
|
||||||
|
@ -3335,6 +3351,7 @@ msgstr "關聯聯邦宇宙身份後可發現更多用戶,並使用本站完整
|
||||||
|
|
||||||
#: users/templates/users/account.html:123
|
#: users/templates/users/account.html:123
|
||||||
#: users/templates/users/account.html:159
|
#: users/templates/users/account.html:159
|
||||||
|
#: users/templates/users/account.html:213
|
||||||
msgid "Once disconnected, you will no longer be able login with this identity. Are you sure to continue?"
|
msgid "Once disconnected, you will no longer be able login with this identity. Are you sure to continue?"
|
||||||
msgstr "取消關聯後將無法使用這個身份登錄本站,確認繼續嗎?"
|
msgstr "取消關聯後將無法使用這個身份登錄本站,確認繼續嗎?"
|
||||||
|
|
||||||
|
@ -3362,75 +3379,107 @@ msgstr "關聯一個threads.net賬號"
|
||||||
msgid "Disconnect with Threads"
|
msgid "Disconnect with Threads"
|
||||||
msgstr "取消關聯"
|
msgstr "取消關聯"
|
||||||
|
|
||||||
#: users/templates/users/account.html:171
|
#: users/templates/users/account.html:170 users/templates/users/login.html:83
|
||||||
|
msgid "Bluesky (ATProto)"
|
||||||
|
msgstr "Bluesky (ATProto)"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:176
|
||||||
|
msgid "Verified ATProto identity"
|
||||||
|
msgstr "已驗證的ATProto身份"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:192 users/templates/users/login.html:151
|
||||||
|
msgid "Bluesky Login ID"
|
||||||
|
msgstr "Bluesky 登錄名"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:200 users/templates/users/login.html:159
|
||||||
|
msgid "Bluesky app password"
|
||||||
|
msgstr "Bluesky 應用密碼"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:206
|
||||||
|
msgid "Link with a different ATProto identity"
|
||||||
|
msgstr "關聯另一個ATProto身份"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:206
|
||||||
|
msgid "Link with an ATProto identity"
|
||||||
|
msgstr "關聯ATProto身份"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:207 users/templates/users/login.html:164
|
||||||
|
msgid "App password can be created on <a href=\"https://bsky.app/settings/app-passwords\" target=\"_blank\">bsky.app</a>."
|
||||||
|
msgstr "應用密碼可在 <a href=\"https://bsky.app/settings/app-passwords\" target=\"_blank\">bsky.app</a> 創建管理。"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:216
|
||||||
|
msgid "Disconnect with ATProto identity"
|
||||||
|
msgstr "取消關聯"
|
||||||
|
|
||||||
|
#: users/templates/users/account.html:225
|
||||||
msgid "Sync and import social account"
|
msgid "Sync and import social account"
|
||||||
msgstr "同步第三方社交網絡上的個人信息和社交數據"
|
msgstr "同步第三方社交網絡上的個人信息和社交數據"
|
||||||
|
|
||||||
#: users/templates/users/account.html:181
|
#: users/templates/users/account.html:235
|
||||||
msgid "Sync display name, bio and avatar"
|
msgid "Sync display name, bio and avatar"
|
||||||
msgstr "自動同步用戶暱稱等基本信息"
|
msgstr "自動同步用戶暱稱等基本信息"
|
||||||
|
|
||||||
#: users/templates/users/account.html:189
|
#: users/templates/users/account.html:243
|
||||||
msgid "Sync follow, mute and block"
|
msgid "Sync follow, mute and block"
|
||||||
msgstr "自動導入新增的關注、屏蔽和隱藏列表"
|
msgstr "自動導入新增的關注、屏蔽和隱藏列表"
|
||||||
|
|
||||||
#: users/templates/users/account.html:193
|
#: users/templates/users/account.html:247
|
||||||
msgid "Save sync settings"
|
msgid "Save sync settings"
|
||||||
msgstr "保存同步設置"
|
msgstr "保存同步設置"
|
||||||
|
|
||||||
#: users/templates/users/account.html:196
|
#: users/templates/users/account.html:250
|
||||||
msgid "New follow, mute and blocks in the associated identity may be automatically imported; removal has to be done manually."
|
msgid "New follow, mute and blocks in the associated identity may be automatically imported; removal has to be done manually."
|
||||||
msgstr "本站會按照以上設置每天自動導入你在聯邦宇宙實例等社交網絡中新增的關注、屏蔽和隱藏列表;如果你在聯邦宇宙實例中關注的用戶加入了本站,你會自動關注她;如果你在聯邦宇宙實例中取消了關注、屏蔽或隱藏,本站不會自動取消,但你可以手動移除。"
|
msgstr "本站會按照以上設置每天自動導入你在聯邦宇宙實例等社交網絡中新增的關注、屏蔽和隱藏列表;如果你在聯邦宇宙實例中關注的用戶加入了本站,你會自動關注她;如果你在聯邦宇宙實例中取消了關注、屏蔽或隱藏,本站不會自動取消,但你可以手動移除。"
|
||||||
|
|
||||||
#: users/templates/users/account.html:203
|
#: users/templates/users/account.html:257
|
||||||
msgid "Click button below to start sync now."
|
msgid "Click button below to start sync now."
|
||||||
msgstr "如果希望立即開始同步,可以點擊下方按鈕。"
|
msgstr "如果希望立即開始同步,可以點擊下方按鈕。"
|
||||||
|
|
||||||
#: users/templates/users/account.html:205
|
#: users/templates/users/account.html:259
|
||||||
msgid "Sync now"
|
msgid "Sync now"
|
||||||
msgstr "立即同步"
|
msgstr "立即同步"
|
||||||
|
|
||||||
#: users/templates/users/account.html:217
|
#: users/templates/users/account.html:271
|
||||||
msgid "Users you are following"
|
msgid "Users you are following"
|
||||||
msgstr "正在關注的用戶"
|
msgstr "正在關注的用戶"
|
||||||
|
|
||||||
#: users/templates/users/account.html:223
|
#: users/templates/users/account.html:277
|
||||||
msgid "Users who follow you"
|
msgid "Users who follow you"
|
||||||
msgstr "關注了你的用戶"
|
msgstr "關注了你的用戶"
|
||||||
|
|
||||||
#: users/templates/users/account.html:229
|
#: users/templates/users/account.html:283
|
||||||
msgid "Users who request to follow you"
|
msgid "Users who request to follow you"
|
||||||
msgstr "請求關注你的用戶"
|
msgstr "請求關注你的用戶"
|
||||||
|
|
||||||
#: users/templates/users/account.html:235
|
#: users/templates/users/account.html:289
|
||||||
msgid "Users you are muting"
|
msgid "Users you are muting"
|
||||||
msgstr "已隱藏的用戶"
|
msgstr "已隱藏的用戶"
|
||||||
|
|
||||||
#: users/templates/users/account.html:241
|
#: users/templates/users/account.html:295
|
||||||
msgid "Users you are blocking"
|
msgid "Users you are blocking"
|
||||||
msgstr "已屏蔽的用戶"
|
msgstr "已屏蔽的用戶"
|
||||||
|
|
||||||
#: users/templates/users/account.html:248
|
#: users/templates/users/account.html:302
|
||||||
msgid "Delete Account"
|
msgid "Delete Account"
|
||||||
msgstr "刪除賬號"
|
msgstr "刪除賬號"
|
||||||
|
|
||||||
#: users/templates/users/account.html:251
|
#: users/templates/users/account.html:305
|
||||||
msgid "Once deleted, account data cannot be recovered. Sure to proceed?"
|
msgid "Once deleted, account data cannot be recovered. Sure to proceed?"
|
||||||
msgstr "賬號數據一旦刪除後將無法恢復,確定繼續嗎?"
|
msgstr "賬號數據一旦刪除後將無法恢復,確定繼續嗎?"
|
||||||
|
|
||||||
#: users/templates/users/account.html:254
|
#: users/templates/users/account.html:308
|
||||||
msgid "Enter full <code>username@instance.social</code> or <code>email@domain.com</code> to confirm deletion."
|
msgid "Enter full <code>username@instance.social</code> or <code>email@domain.com</code> to confirm deletion."
|
||||||
msgstr "輸入完整的登錄用 <code>用戶名@實例名</code> 或 <code>電子郵件地址</code> 以確認刪除"
|
msgstr "輸入完整的登錄用 <code>用戶名@實例名</code> 或 <code>電子郵件地址</code> 以確認刪除"
|
||||||
|
|
||||||
#: users/templates/users/account.html:264
|
#: users/templates/users/account.html:318
|
||||||
msgid "Once deleted, account data cannot be recovered."
|
msgid "Once deleted, account data cannot be recovered."
|
||||||
msgstr "賬號數據一旦刪除後將無法恢復"
|
msgstr "賬號數據一旦刪除後將無法恢復"
|
||||||
|
|
||||||
#: users/templates/users/account.html:266
|
#: users/templates/users/account.html:320
|
||||||
msgid "Importing in progress, can't delete now."
|
msgid "Importing in progress, can't delete now."
|
||||||
msgstr "暫時無法刪除,因爲有導入任務正在進行"
|
msgstr "暫時無法刪除,因爲有導入任務正在進行"
|
||||||
|
|
||||||
#: users/templates/users/account.html:269
|
#: users/templates/users/account.html:323
|
||||||
msgid "Permanently Delete"
|
msgid "Permanently Delete"
|
||||||
msgstr "永久刪除"
|
msgstr "永久刪除"
|
||||||
|
|
||||||
|
@ -3586,7 +3635,7 @@ msgstr "實例域名(不含@和@之前的部分),如mastodon.social"
|
||||||
msgid "Please enter domain of your instance; e.g. if your id is <i>@neodb@mastodon.social</i>, only enter <i>mastodon.social</i>."
|
msgid "Please enter domain of your instance; e.g. if your id is <i>@neodb@mastodon.social</i>, only enter <i>mastodon.social</i>."
|
||||||
msgstr "請輸入你的實例域名(不含@和@之前的部分);如果你的聯邦賬號是<i>@neodb@mastodon.social</i>,只需要在此輸入<i>mastodon.social</i>。"
|
msgstr "請輸入你的實例域名(不含@和@之前的部分);如果你的聯邦賬號是<i>@neodb@mastodon.social</i>,只需要在此輸入<i>mastodon.social</i>。"
|
||||||
|
|
||||||
#: users/templates/users/login.html:125 users/templates/users/login.html:156
|
#: users/templates/users/login.html:125 users/templates/users/login.html:174
|
||||||
msgid "Authorize via Fediverse instance"
|
msgid "Authorize via Fediverse instance"
|
||||||
msgstr "去聯邦實例授權註冊或登錄"
|
msgstr "去聯邦實例授權註冊或登錄"
|
||||||
|
|
||||||
|
@ -3602,35 +3651,35 @@ msgstr "去Threads授權註冊或登錄"
|
||||||
msgid "If you have already account here registered via a different way, you may login through there and link with your Threads account in account settings."
|
msgid "If you have already account here registered via a different way, you may login through there and link with your Threads account in account settings."
|
||||||
msgstr "如果你已通過其它方式註冊過本站帳號,請用該方式登錄後再關聯Threads。"
|
msgstr "如果你已通過其它方式註冊過本站帳號,請用該方式登錄後再關聯Threads。"
|
||||||
|
|
||||||
#: users/templates/users/login.html:147
|
#: users/templates/users/login.html:165
|
||||||
msgid "Authorize via Bluesky"
|
msgid "Authorize via bsky.app"
|
||||||
msgstr "去Bluesky授權註冊或登錄"
|
msgstr "使用Bluesky賬號信息註冊或登錄"
|
||||||
|
|
||||||
#: users/templates/users/login.html:148
|
#: users/templates/users/login.html:166
|
||||||
msgid "If you have already account here registered via a different way, you may login through there and link with your Bluesky account in account settings."
|
msgid "If you have already account here registered via a different way, you may login through there and link with your Bluesky account in account settings."
|
||||||
msgstr "如果你已通過其它方式註冊過本站帳號,請用該方式登錄後再關聯Bluesky。"
|
msgstr "如果你已通過其它方式註冊過本站帳號,請用該方式登錄後再關聯Bluesky。"
|
||||||
|
|
||||||
#: users/templates/users/login.html:163
|
#: users/templates/users/login.html:181
|
||||||
msgid "Valid invitation code, please login or register."
|
msgid "Valid invitation code, please login or register."
|
||||||
msgstr "邀請鏈接有效,可註冊新用戶"
|
msgstr "邀請鏈接有效,可註冊新用戶"
|
||||||
|
|
||||||
#: users/templates/users/login.html:165
|
#: users/templates/users/login.html:183
|
||||||
msgid "Please use invitation link to register a new account; existing user may login."
|
msgid "Please use invitation link to register a new account; existing user may login."
|
||||||
msgstr "本站目前爲邀請註冊,已有賬戶可直接登入,新用戶請使用有效邀請鏈接註冊"
|
msgstr "本站目前爲邀請註冊,已有賬戶可直接登入,新用戶請使用有效邀請鏈接註冊"
|
||||||
|
|
||||||
#: users/templates/users/login.html:167
|
#: users/templates/users/login.html:185
|
||||||
msgid "Invitation code invalid or expired."
|
msgid "Invitation code invalid or expired."
|
||||||
msgstr "邀請鏈接無效,已有賬戶可直接登入,新用戶請使用有效邀請鏈接註冊"
|
msgstr "邀請鏈接無效,已有賬戶可直接登入,新用戶請使用有效邀請鏈接註冊"
|
||||||
|
|
||||||
#: users/templates/users/login.html:175
|
#: users/templates/users/login.html:193
|
||||||
msgid "Loading timed out, please check your network (VPN) settings."
|
msgid "Loading timed out, please check your network (VPN) settings."
|
||||||
msgstr "部分模塊加載超時,請檢查網絡(翻牆)設置。"
|
msgstr "部分模塊加載超時,請檢查網絡(翻牆)設置。"
|
||||||
|
|
||||||
#: users/templates/users/login.html:181
|
#: users/templates/users/login.html:199
|
||||||
msgid "Continue using this site implies consent to our <a href=\"/pages/rules/\">rules</a> and <a href=\"/pages/terms/\">terms</a>, including using cookies to provide necessary functionality."
|
msgid "Continue using this site implies consent to our <a href=\"/pages/rules/\">rules</a> and <a href=\"/pages/terms/\">terms</a>, including using cookies to provide necessary functionality."
|
||||||
msgstr "繼續訪問或註冊視爲同意<a href=\"/pages/rules/\">站規</a>與<a href=\"/pages/terms/\">協議</a>,及使用cookie提供必要功能"
|
msgstr "繼續訪問或註冊視爲同意<a href=\"/pages/rules/\">站規</a>與<a href=\"/pages/terms/\">協議</a>,及使用cookie提供必要功能"
|
||||||
|
|
||||||
#: users/templates/users/login.html:187
|
#: users/templates/users/login.html:205
|
||||||
msgid "Domain of your instance (excl. @)"
|
msgid "Domain of your instance (excl. @)"
|
||||||
msgstr "實例域名(不含@和@之前的部分)"
|
msgstr "實例域名(不含@和@之前的部分)"
|
||||||
|
|
||||||
|
@ -3786,59 +3835,59 @@ msgstr "用戶資料"
|
||||||
msgid "original home"
|
msgid "original home"
|
||||||
msgstr "原始主頁"
|
msgstr "原始主頁"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:82
|
#: users/templates/users/profile_actions.html:63
|
||||||
msgid "accept follow request"
|
msgid "accept follow request"
|
||||||
msgstr "接受關注請求"
|
msgstr "接受關注請求"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:84
|
#: users/templates/users/profile_actions.html:65
|
||||||
msgid "sure to accept follow request?"
|
msgid "sure to accept follow request?"
|
||||||
msgstr "確定接受關注請求嗎?"
|
msgstr "確定接受關注請求嗎?"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:92
|
#: users/templates/users/profile_actions.html:73
|
||||||
msgid "reject follow request"
|
msgid "reject follow request"
|
||||||
msgstr "拒絕關注請求"
|
msgstr "拒絕關注請求"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:94
|
#: users/templates/users/profile_actions.html:75
|
||||||
msgid "sure to reject follow request?"
|
msgid "sure to reject follow request?"
|
||||||
msgstr "確定拒絕關注請求嗎?"
|
msgstr "確定拒絕關注請求嗎?"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:104
|
#: users/templates/users/profile_actions.html:85
|
||||||
msgid "click to unfollow"
|
msgid "click to unfollow"
|
||||||
msgstr "點擊可取消關注"
|
msgstr "點擊可取消關注"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:106
|
#: users/templates/users/profile_actions.html:87
|
||||||
msgid "sure to unfollow?"
|
msgid "sure to unfollow?"
|
||||||
msgstr "確定取消關注該用戶嗎?"
|
msgstr "確定取消關注該用戶嗎?"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:115
|
#: users/templates/users/profile_actions.html:96
|
||||||
msgid "click to cancel follow request"
|
msgid "click to cancel follow request"
|
||||||
msgstr "點擊可取消關注請求"
|
msgstr "點擊可取消關注請求"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:117
|
#: users/templates/users/profile_actions.html:98
|
||||||
msgid "sure to cancel follow request?"
|
msgid "sure to cancel follow request?"
|
||||||
msgstr "確定取消關注請求嗎?"
|
msgstr "確定取消關注請求嗎?"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:126
|
#: users/templates/users/profile_actions.html:107
|
||||||
msgid "click to follow"
|
msgid "click to follow"
|
||||||
msgstr "點擊可關注"
|
msgstr "點擊可關注"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:127
|
#: users/templates/users/profile_actions.html:108
|
||||||
msgid "sure to follow?"
|
msgid "sure to follow?"
|
||||||
msgstr "確定關注該用戶嗎?"
|
msgstr "確定關注該用戶嗎?"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:137
|
#: users/templates/users/profile_actions.html:118
|
||||||
msgid "click to mute"
|
msgid "click to mute"
|
||||||
msgstr "點擊可靜音"
|
msgstr "點擊可靜音"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:146
|
#: users/templates/users/profile_actions.html:127
|
||||||
msgid "click to unmute"
|
msgid "click to unmute"
|
||||||
msgstr "點擊可取消靜音"
|
msgstr "點擊可取消靜音"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:156
|
#: users/templates/users/profile_actions.html:137
|
||||||
msgid "click to block"
|
msgid "click to block"
|
||||||
msgstr "點擊可屏蔽"
|
msgstr "點擊可屏蔽"
|
||||||
|
|
||||||
#: users/templates/users/profile_actions.html:157
|
#: users/templates/users/profile_actions.html:138
|
||||||
msgid "sure to block?"
|
msgid "sure to block?"
|
||||||
msgstr "確定屏蔽該用戶嗎?"
|
msgstr "確定屏蔽該用戶嗎?"
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,91 @@
|
||||||
|
from functools import cached_property
|
||||||
|
|
||||||
|
from atproto import Client, SessionEvent, client_utils
|
||||||
|
from django.utils import timezone
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
from catalog.common import jsondata
|
from catalog.common import jsondata
|
||||||
|
|
||||||
from .common import SocialAccount
|
from .common import SocialAccount
|
||||||
|
|
||||||
|
|
||||||
class Bluesky:
|
class Bluesky:
|
||||||
pass
|
BASE_DOMAIN = "bsky.app" # TODO support alternative servers
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def authenticate(username: str, password: str) -> "BlueskyAccount | None":
|
||||||
|
try:
|
||||||
|
client = Client()
|
||||||
|
profile = client.login(username, password)
|
||||||
|
session_string = client.export_session_string()
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Bluesky login {username} exception {e}")
|
||||||
|
return None
|
||||||
|
existing_account = BlueskyAccount.objects.filter(
|
||||||
|
uid=profile.did, domain=Bluesky.BASE_DOMAIN
|
||||||
|
).first()
|
||||||
|
if existing_account:
|
||||||
|
existing_account.session_string = session_string
|
||||||
|
existing_account.save(update_fields=["access_data"])
|
||||||
|
existing_account.refresh(save=True, profile=profile)
|
||||||
|
return existing_account
|
||||||
|
account = BlueskyAccount(uid=profile.did, domain=Bluesky.BASE_DOMAIN)
|
||||||
|
account.session_string = session_string
|
||||||
|
account.refresh(save=False, profile=profile)
|
||||||
|
return account
|
||||||
|
|
||||||
|
|
||||||
class BlueskyAccount(SocialAccount):
|
class BlueskyAccount(SocialAccount):
|
||||||
app_username = jsondata.CharField(json_field_name="access_data", default="")
|
# app_username = jsondata.CharField(json_field_name="access_data", default="")
|
||||||
app_password = jsondata.EncryptedTextField(
|
# app_password = jsondata.EncryptedTextField(
|
||||||
|
# json_field_name="access_data", default=""
|
||||||
|
# )
|
||||||
|
session_string = jsondata.EncryptedTextField(
|
||||||
json_field_name="access_data", default=""
|
json_field_name="access_data", default=""
|
||||||
)
|
)
|
||||||
pass
|
|
||||||
|
def on_session_change(self, event, session) -> None:
|
||||||
|
logger.debug("Bluesky session changed:", event, repr(session))
|
||||||
|
if event in (SessionEvent.CREATE, SessionEvent.REFRESH):
|
||||||
|
session_string = session.export()
|
||||||
|
if session_string != self.session_string:
|
||||||
|
self.session_string = session_string
|
||||||
|
if self.pk:
|
||||||
|
self.save(update_fields=["access_data"])
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def _client(self):
|
||||||
|
client = Client()
|
||||||
|
client.on_session_change(self.on_session_change)
|
||||||
|
self._profile = client.login(session_string=self.session_string)
|
||||||
|
return client
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url(self):
|
||||||
|
return f"https://bsky.app/profile/{self.handle}"
|
||||||
|
|
||||||
|
def refresh(self, save=True, profile=None):
|
||||||
|
if not profile:
|
||||||
|
_ = self._client
|
||||||
|
profile = self._profile
|
||||||
|
self.handle = profile.handle
|
||||||
|
self.account_data = {
|
||||||
|
k: v for k, v in profile.__dict__.items() if isinstance(v, (int, str))
|
||||||
|
}
|
||||||
|
self.last_refresh = timezone.now()
|
||||||
|
self.last_reachable = self.last_refresh
|
||||||
|
if save:
|
||||||
|
self.save(
|
||||||
|
update_fields=[
|
||||||
|
"account_data",
|
||||||
|
"handle",
|
||||||
|
"last_refresh",
|
||||||
|
"last_reachable",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def post(self, content):
|
||||||
|
text = client_utils.TextBuilder().text(content)
|
||||||
|
# .link("Python SDK", "https://atproto.blue")
|
||||||
|
post = self._client.send_post(text)
|
||||||
|
return {"id": post.cid, "url": post.uri}
|
||||||
|
|
|
@ -83,6 +83,8 @@ class SocialAccount(TypedModel):
|
||||||
if k
|
if k
|
||||||
not in [
|
not in [
|
||||||
"_state",
|
"_state",
|
||||||
|
"_client",
|
||||||
|
"_profile",
|
||||||
"api_domain",
|
"api_domain",
|
||||||
"created",
|
"created",
|
||||||
"modified",
|
"modified",
|
||||||
|
|
|
@ -851,7 +851,7 @@ class MastodonAccount(SocialAccount):
|
||||||
spoiler_text,
|
spoiler_text,
|
||||||
attachments,
|
attachments,
|
||||||
)
|
)
|
||||||
if response:
|
if response is not None:
|
||||||
if response.status_code in [200, 201]:
|
if response.status_code in [200, 201]:
|
||||||
j = response.json()
|
j = response.json()
|
||||||
return {"id": j["id"], "url": j["url"]}
|
return {"id": j["id"], "url": j["url"]}
|
||||||
|
@ -864,4 +864,4 @@ class MastodonAccount(SocialAccount):
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
def get_reauthorize_url(self):
|
def get_reauthorize_url(self):
|
||||||
return reverse("mastodon:connect") + "?domain=" + self.domain
|
return reverse("mastodon:login") + "?domain=" + self.domain
|
||||||
|
|
|
@ -20,4 +20,7 @@ urlpatterns = [
|
||||||
path("threads/uninstall", threads_uninstall, name="threads_uninstall"),
|
path("threads/uninstall", threads_uninstall, name="threads_uninstall"),
|
||||||
path("threads/delete", threads_delete, name="threads_delete"),
|
path("threads/delete", threads_delete, name="threads_delete"),
|
||||||
# Bluesky
|
# Bluesky
|
||||||
|
path("bluesky/login", bluesky_login, name="bluesky_login"),
|
||||||
|
path("bluesky/reconnect", bluesky_reconnect, name="bluesky_reconnect"),
|
||||||
|
path("bluesky/disconnect", bluesky_disconnect, name="bluesky_disconnect"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from .bluesky import *
|
||||||
from .email import *
|
from .email import *
|
||||||
from .mastodon import *
|
from .mastodon import *
|
||||||
from .threads import *
|
from .threads import *
|
||||||
|
|
44
mastodon/views/bluesky.py
Normal file
44
mastodon/views/bluesky.py
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.http import HttpRequest
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
from django.views.decorators.http import require_http_methods
|
||||||
|
|
||||||
|
from common.views import render_error
|
||||||
|
from mastodon.models import bluesky
|
||||||
|
|
||||||
|
from ..models import Bluesky
|
||||||
|
from .common import disconnect_identity, process_verified_account
|
||||||
|
|
||||||
|
|
||||||
|
@require_http_methods(["POST"])
|
||||||
|
def bluesky_login(request: HttpRequest):
|
||||||
|
username = request.POST.get("username", "").strip()
|
||||||
|
password = request.POST.get("password", "").strip()
|
||||||
|
if not username or not password:
|
||||||
|
return render_error(
|
||||||
|
request,
|
||||||
|
_("Authentication failed"),
|
||||||
|
_("Username and app password is required."),
|
||||||
|
)
|
||||||
|
account = Bluesky.authenticate(username, password)
|
||||||
|
if not account:
|
||||||
|
return render_error(
|
||||||
|
request, _("Authentication failed"), _("Invalid account data from Bluesky.")
|
||||||
|
)
|
||||||
|
return process_verified_account(request, account)
|
||||||
|
|
||||||
|
|
||||||
|
@require_http_methods(["POST"])
|
||||||
|
@login_required
|
||||||
|
def bluesky_reconnect(request: HttpRequest):
|
||||||
|
"""link another bluesky to an existing logged-in user"""
|
||||||
|
return bluesky_login(request)
|
||||||
|
|
||||||
|
|
||||||
|
@require_http_methods(["POST"])
|
||||||
|
@login_required
|
||||||
|
def bluesky_disconnect(request):
|
||||||
|
"""unlink bluesky from an existing logged-in user"""
|
||||||
|
return disconnect_identity(request, request.user.bluesky)
|
|
@ -26,7 +26,7 @@ def process_verified_account(request: HttpRequest, account: SocialAccount):
|
||||||
def login_existing_user(request: HttpRequest, account: SocialAccount):
|
def login_existing_user(request: HttpRequest, account: SocialAccount):
|
||||||
user = authenticate(request, social_account=account)
|
user = authenticate(request, social_account=account)
|
||||||
if not user:
|
if not user:
|
||||||
return render_error(_("Authentication failed"), _("Invalid user."))
|
return render_error(request, _("Authentication failed"), _("Invalid user."))
|
||||||
existing_user = account.user
|
existing_user = account.user
|
||||||
auth_login(request, existing_user)
|
auth_login(request, existing_user)
|
||||||
account.sync_later()
|
account.sync_later()
|
||||||
|
@ -41,19 +41,29 @@ def login_existing_user(request: HttpRequest, account: SocialAccount):
|
||||||
|
|
||||||
def register_new_user(request: HttpRequest, account: SocialAccount):
|
def register_new_user(request: HttpRequest, account: SocialAccount):
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
return render_error(_("Registration failed"), _("User already logged in."))
|
return render_error(
|
||||||
|
request, _("Registration failed"), _("User already logged in.")
|
||||||
|
)
|
||||||
request.session["verified_account"] = account.to_dict()
|
request.session["verified_account"] = account.to_dict()
|
||||||
return redirect(reverse("users:register"))
|
return redirect(reverse("users:register"))
|
||||||
|
|
||||||
|
|
||||||
def reconnect_account(request, account: SocialAccount):
|
def reconnect_account(request, account: SocialAccount):
|
||||||
if account.user == request.user:
|
if account.user == request.user:
|
||||||
return render_error(
|
account.sync_later()
|
||||||
request, _("Unable to update login information: identical identity.")
|
messages.add_message(
|
||||||
|
request,
|
||||||
|
messages.INFO,
|
||||||
|
_("Continue login as {handle}.").format(handle=account.handle),
|
||||||
)
|
)
|
||||||
|
return redirect(reverse("users:info"))
|
||||||
elif account.user:
|
elif account.user:
|
||||||
return render_error(
|
return render_error(
|
||||||
request, _("Unable to update login information: identity in use.")
|
request,
|
||||||
|
_("Unable to update login information"),
|
||||||
|
_("Identity {handle} in use by a different user.").format(
|
||||||
|
handle=account.handle
|
||||||
|
),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# TODO add confirmation screen
|
# TODO add confirmation screen
|
||||||
|
@ -67,19 +77,26 @@ def reconnect_account(request, account: SocialAccount):
|
||||||
messages.add_message(
|
messages.add_message(
|
||||||
request,
|
request,
|
||||||
messages.INFO,
|
messages.INFO,
|
||||||
_("Login information updated.") + account.handle,
|
_("Login information updated as {handle}.").format(
|
||||||
|
handle=account.handle
|
||||||
|
),
|
||||||
)
|
)
|
||||||
return redirect(reverse("users:info"))
|
return redirect(reverse("users:info"))
|
||||||
|
|
||||||
|
|
||||||
def disconnect_identity(request, account):
|
def disconnect_identity(request, account):
|
||||||
if not account:
|
if not account:
|
||||||
return render_error(_("Disconnect identity failed"), _("Identity not found."))
|
return render_error(
|
||||||
|
request, _("Disconnect identity failed"), _("Identity not found.")
|
||||||
|
)
|
||||||
if request.user != account.user:
|
if request.user != account.user:
|
||||||
return render_error(_("Disconnect identity failed"), _("Invalid user."))
|
return render_error(
|
||||||
|
request, _("Disconnect identity failed"), _("Invalid user.")
|
||||||
|
)
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
if request.user.social_accounts.all().count() <= 1:
|
if request.user.social_accounts.all().count() <= 1:
|
||||||
return render_error(
|
return render_error(
|
||||||
|
request,
|
||||||
_("Disconnect identity failed"),
|
_("Disconnect identity failed"),
|
||||||
_("You cannot disconnect last login identity."),
|
_("You cannot disconnect last login identity."),
|
||||||
)
|
)
|
||||||
|
|
|
@ -37,12 +37,14 @@ def threads_oauth(request: HttpRequest):
|
||||||
code = request.GET.get("code")
|
code = request.GET.get("code")
|
||||||
if not code:
|
if not code:
|
||||||
return render_error(
|
return render_error(
|
||||||
_("Authentication failed"), request.GET.get("error_description", "")
|
request,
|
||||||
|
_("Authentication failed"),
|
||||||
|
request.GET.get("error_description", ""),
|
||||||
)
|
)
|
||||||
account = Threads.authenticate(request, code)
|
account = Threads.authenticate(request, code)
|
||||||
if not account:
|
if not account:
|
||||||
return render_error(
|
return render_error(
|
||||||
_("Authentication failed"), _("Invalid account data from Threads.")
|
request, _("Authentication failed"), _("Invalid account data from Threads.")
|
||||||
)
|
)
|
||||||
return process_verified_account(request, account)
|
return process_verified_account(request, account)
|
||||||
|
|
||||||
|
|
30
users/templates/users/_profile_social_icons.html
Normal file
30
users/templates/users/_profile_social_icons.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{% if identity.user.mastodon %}
|
||||||
|
<span>
|
||||||
|
<a href="{{ identity.user.mastodon.url }}"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
title="@{{ identity.user.mastodon.handle }}">
|
||||||
|
<i class="fa-brands fa-mastodon"></i>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
{% if identity.user.threads %}
|
||||||
|
<span>
|
||||||
|
<a href="{{ identity.user.threads.url }}"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
title="@{{ identity.user.threads.handle }}">
|
||||||
|
<i class="fa-brands fa-threads"></i>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
{% if identity.user.bluesky %}
|
||||||
|
<span>
|
||||||
|
<a href="{{ identity.user.bluesky.url }}"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
title="@{{ identity.user.bluesky.handle }}">
|
||||||
|
<i class="fa-brands fa-bluesky"></i>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
|
@ -154,7 +154,7 @@
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
{% if request.user.threads %}
|
{% if request.user.threads %}
|
||||||
<form action="{% url 'mastodon:threads_login' %}"
|
<form action="{% url 'mastodon:threads_disconnect' %}"
|
||||||
method="post"
|
method="post"
|
||||||
onsubmit="return confirm('{% trans "Once disconnected, you will no longer be able login with this identity. Are you sure to continue?" %}')">
|
onsubmit="return confirm('{% trans "Once disconnected, you will no longer be able login with this identity. Are you sure to continue?" %}')">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
@ -165,6 +165,60 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</details>
|
</details>
|
||||||
</article>
|
</article>
|
||||||
|
<article>
|
||||||
|
<details>
|
||||||
|
<summary>{% trans "Bluesky (ATProto)" %}</summary>
|
||||||
|
<form action="{% url 'mastodon:bluesky_reconnect' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<fieldset>
|
||||||
|
{% if request.user.bluesky %}
|
||||||
|
<label>
|
||||||
|
<i class="fa-brands fa-bluesky"></i> {% trans "Verified ATProto identity" %}
|
||||||
|
<input type="input"
|
||||||
|
aria-invalid="false"
|
||||||
|
value="@{{ request.user.bluesky.handle }} {{ request.user.bluesky.uid }}"
|
||||||
|
readonly>
|
||||||
|
<small>
|
||||||
|
{% if request.user.bluesky.last_refresh %}
|
||||||
|
{% trans "Last updated" %} {{ request.user.bluesky.last_refresh }}
|
||||||
|
{% endif %}
|
||||||
|
</small>
|
||||||
|
</label>
|
||||||
|
{% endif %}
|
||||||
|
<input required
|
||||||
|
type="email"
|
||||||
|
name="username"
|
||||||
|
autofocus
|
||||||
|
placeholder="{% trans 'Bluesky Login ID' %}"
|
||||||
|
autocorrect="off"
|
||||||
|
autocapitalize="off"
|
||||||
|
autocomplete="off"
|
||||||
|
spellcheck="false" />
|
||||||
|
<input required
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
placeholder="{% trans 'Bluesky app password' %}"
|
||||||
|
autocorrect="off"
|
||||||
|
autocapitalize="off"
|
||||||
|
autocomplete="off"
|
||||||
|
spellcheck="false" />
|
||||||
|
<input type="submit"
|
||||||
|
value="{% if request.user.bluesky %} {% trans 'Link with a different ATProto identity' %} {% else %} {% trans "Link with an ATProto identity" %} {% endif %} " />
|
||||||
|
<small>{% blocktrans %}App password can be created on <a href="https://bsky.app/settings/app-passwords" target="_blank">bsky.app</a>.{% endblocktrans %}</small>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
{% if request.user.bluesky %}
|
||||||
|
<form action="{% url 'mastodon:bluesky_disconnect' %}"
|
||||||
|
method="post"
|
||||||
|
onsubmit="return confirm('{% trans "Once disconnected, you will no longer be able login with this identity. Are you sure to continue?" %}')">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="submit"
|
||||||
|
value="{% trans 'Disconnect with ATProto identity' %}"
|
||||||
|
class="secondary" />
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
</details>
|
||||||
|
</article>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<article>
|
<article>
|
||||||
<details>
|
<details>
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
{% if enable_bluesky %}
|
{% if enable_bluesky %}
|
||||||
<button class="platform outline" _="on click add .outline to .platform then remove .outline from me then hide
|
<button class="platform outline" _="on click add .outline to .platform then remove .outline from me then hide
|
||||||
<form/>
|
<form/>
|
||||||
then show #login-bluesky" id="platform-bluesky" title="{% trans "Bluesky" %}">
|
then show #login-bluesky" id="platform-bluesky" title="{% trans "Bluesky (ATProto)" %}">
|
||||||
<i class="fa-brands fa-bluesky" style="font-size:85%"></i>
|
<i class="fa-brands fa-bluesky" style="font-size:85%"></i>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -139,12 +139,30 @@
|
||||||
</form>
|
</form>
|
||||||
<form id="login-bluesky"
|
<form id="login-bluesky"
|
||||||
style="display:none"
|
style="display:none"
|
||||||
action="{% url 'mastodon:login' %}"
|
action="{% url 'mastodon:bluesky_login' %}"
|
||||||
method="post"
|
method="post"
|
||||||
onsubmit="return login(this);">
|
onsubmit="return login(this);">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input name="method" value="bluesky" type="hidden" />
|
<input name="method" value="bluesky" type="hidden" />
|
||||||
<input type='submit' value="{% trans 'Authorize via Bluesky' %}" />
|
<input required
|
||||||
|
type="email"
|
||||||
|
name="username"
|
||||||
|
autofocus
|
||||||
|
placeholder="{% trans 'Bluesky Login ID' %}"
|
||||||
|
autocorrect="off"
|
||||||
|
autocapitalize="off"
|
||||||
|
autocomplete="off"
|
||||||
|
spellcheck="false" />
|
||||||
|
<input required
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
placeholder="{% trans 'Bluesky app password' %}"
|
||||||
|
autocorrect="off"
|
||||||
|
autocapitalize="off"
|
||||||
|
autocomplete="off"
|
||||||
|
spellcheck="false" />
|
||||||
|
<small>{% blocktrans %}App password can be created on <a href="https://bsky.app/settings/app-passwords" target="_blank">bsky.app</a>.{% endblocktrans %}</small>
|
||||||
|
<input type='submit' value="{% trans 'Authorize via bsky.app' %}" />
|
||||||
<small>{% trans "If you have already account here registered via a different way, you may login through there and link with your Bluesky account in account settings." %}</small>
|
<small>{% trans "If you have already account here registered via a different way, you may login through there and link with your Bluesky account in account settings." %}</small>
|
||||||
</form>
|
</form>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -55,26 +55,7 @@
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not identity.locked or request.user.is_superuser or relationship.requested or relationship.status %}
|
{% if not identity.locked or request.user.is_superuser or relationship.requested or relationship.status %}
|
||||||
{% if identity.user.mastodon %}
|
{% include "users/_profile_social_icons.html" %}
|
||||||
<span>
|
|
||||||
<a href="{{ identity.user.mastodon.url }}"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
title="@{{ identity.user.mastodon.handle }}">
|
|
||||||
<i class="fa-brands fa-mastodon"></i>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
{% if identity.user.threads %}
|
|
||||||
<span>
|
|
||||||
<a href="{{ identity.user.threads.url }}"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
title="@{{ identity.user.threads.handle }}">
|
|
||||||
<i class="fa-brands fa-threads"></i>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if relationship.requested %}
|
{% if relationship.requested %}
|
||||||
|
|
|
@ -46,8 +46,8 @@ def login(request):
|
||||||
"selected_domain": selected_domain,
|
"selected_domain": selected_domain,
|
||||||
"allow_any_site": settings.MASTODON_ALLOW_ANY_SITE,
|
"allow_any_site": settings.MASTODON_ALLOW_ANY_SITE,
|
||||||
"enable_email": settings.ENABLE_LOGIN_EMAIL,
|
"enable_email": settings.ENABLE_LOGIN_EMAIL,
|
||||||
"enable_threads": bool(settings.THREADS_APP_ID),
|
"enable_threads": settings.ENABLE_LOGIN_THREADS,
|
||||||
"enable_bluesky": settings.BLUESKY_LOGIN_ENABLED,
|
"enable_bluesky": settings.ENABLE_LOGIN_BLUESKY,
|
||||||
"invite_status": invite_status,
|
"invite_status": invite_status,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue