Page MenuHomePhorge

No OneTemporary

Size
76 KB
Referenced Files
None
Subscribers
None
diff --git a/src/contents/ui/Main.qml b/src/contents/ui/Main.qml
index 2eebc07..424a5d2 100644
--- a/src/contents/ui/Main.qml
+++ b/src/contents/ui/Main.qml
@@ -1,446 +1,470 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2020-2023 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import QtQuick
import org.kde.kirigami as Kirigami
import QtQuick.Layouts
import QtQuick.Controls
import moe.kazv.mxc.kazv as MK
import '.' as Kazv
import 'shortcuts' as KazvShortcuts
import 'l10n.js' as L10n
Kirigami.ApplicationWindow {
id: root
property var kazvIOManager: MK.KazvIOManager {
cacheDirectory: kazvConfig.cacheDirectory
function jobResultL10nMsg(ec: MK.KazvIOBaseJob.ErrorCode, isUpload: bool): string {
const resultL10nId = isUpload ? 'kazv-io-upload-failure-prompt' : 'kazv-io-download-failure-prompt'
const detailL10nId = new Map([
[MK.KazvIOBaseJob.UserCancel, 'kazv-io-failure-detail-user-cancel'],
[MK.KazvIOBaseJob.OpenFileError, 'kazv-io-failure-detail-open-file-error'],
[MK.KazvIOBaseJob.WriteFileError, 'kazv-io-failure-detail-write-file-error'],
[MK.KazvIOBaseJob.NetworkError, 'kazv-io-failure-detail-network-error'],
[MK.KazvIOBaseJob.HashError, 'kazv-io-failure-detail-hash-error'],
[MK.KazvIOBaseJob.ResponseError, 'kazv-io-failure-detail-response-error'],
[MK.KazvIOBaseJob.KazvError, 'kazv-io-failure-detail-kazv-error']
]);
return l10n.get(resultL10nId, {detail: l10n.get(detailL10nId.get(ec))});
}
}
property bool loadingSession: false
property var matrixSdk: MK.MatrixSdk {
onSessionChanged: {
console.log('session changed');
reloadSdkVariables();
root.purgeTimer.start();
}
onLoadSessionFinished: (sessionName, res) => {
root.loadingSession = false;
if (res === MK.Constants.SessionLoadSuccess) {
console.log('load session successful');
switchToMainPage();
recordLastSession();
matrixSession.getSpecVersions();
} else {
showPassiveNotification(getSessionLoadError(res, sessionName));
}
}
}
property var matrixSession: matrixSdk.session()
Connections {
target: matrixSession
function onLoginSuccessful() {
console.log('Login successful');
switchToMainPage();
recordLastSession();
root.purgeTimer.start();
}
function onLoginFailed() {
console.log("Login Failed");
showPassiveNotification(l10n.get('login-page-request-failed-prompt', { errorCode, errorMsg }));
}
function onLogoutSuccessful() {
root.loggedIn = false;
pageStack.clear();
pushLoginPage();
}
function onLogoutFailed() {
console.warn('Logout failed');
showPassiveNotification(l10n.get('logout-failed-prompt', { errorCode, errorMsg }));
}
}
property var loggedIn: !!matrixSession?.token
property var sdkVars: QtObject {
property var roomList: matrixSession?.roomList()
property var userGivenNicknameMap: matrixSession?.userGivenNicknameMap()
property string currentRoomId: ''
}
property var purgeTimer: Timer {
interval: 1000 * 60 * 5
repeat: true
triggeredOnStart: true
onTriggered: () => {
matrixSession?.purgeEventsExceptRooms(
sdkVars.currentRoomId ? [sdkVars.currentRoomId] : []);
}
}
property var l10nProvider: MK.L10nProvider {
}
property var kazvConfig: MK.KazvConfig {
}
function initializeL10n () {
const availableLocales = l10nProvider.availableLocaleCodes();
console.log('available locales:', availableLocales);
const desiredLanguages = [Qt.uiLanguage];
console.log('ui language is: ', desiredLanguages);
const defaultLocale = 'en';
const wantedLocales = L10n.negotiateLanguages(desiredLanguages, availableLocales, defaultLocale);
console.log('wanted locales:', wantedLocales);
const bundles = L10n.generateBundles(wantedLocales, l10nProvider.getFtlData(wantedLocales));
const provider = new L10n.FluentProvider(bundles);
return provider;
}
property var l10n: initializeL10n();
property var confirmLogoutPopup: Kirigami.OverlaySheet {
id: confirmLogoutPopup
title: l10n.get('confirm-logout-popup-title')
ColumnLayout {
Label {
Layout.fillWidth: true
text: l10n.get('confirm-logout-popup-prompt')
}
RowLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignCenter
Button {
text: l10n.get('confirm-logout-popup-accept-button')
onClicked: {
hardLogout();
confirmLogoutPopup.close();
}
}
Button {
text: l10n.get('confirm-logout-popup-cancel-button')
onClicked: confirmLogoutPopup.close();
}
}
}
}
title: matrixSession?.userId ? l10n.get('app-title-with-user-id', { userId: matrixSession.userId }) : l10n.get('app-title-not-logged-in')
globalDrawer: Kirigami.GlobalDrawer {
title: l10n.get('global-drawer-title')
titleIcon: "applications-graphics"
property var actionGroupName: l10n.get('action-group-global-drawer-actions')
actions: [
Kirigami.Action {
objectName: 'switch-account'
text: l10n.get('global-drawer-action-switch-account')
icon.name: 'system-switch-user'
onTriggered: switchAccount()
},
Kirigami.Action {
objectName: 'hard-logout'
text: l10n.get('global-drawer-action-hard-logout')
icon.name: 'application-exit'
onTriggered: confirmLogoutPopup.open()
},
Kirigami.Action {
objectName: 'save'
text: l10n.get('global-drawer-action-save-session')
icon.name: 'document-save'
onTriggered: {
recordLastSession()
matrixSdk.serializeToFile()
}
},
Kirigami.Action {
objectName: 'configure-shortcuts'
text: l10n.get('global-drawer-action-configure-shortcuts')
icon.name: 'configure-shortcuts'
onTriggered: {
pushActionSettingsPage();
}
},
Kirigami.Action {
objectName: 'settings'
text: l10n.get('global-drawer-action-settings')
icon.name: 'configure'
onTriggered: {
pushSettingsPage();
}
},
Kirigami.Action {
objectName: 'create-room'
enabled: root.loggedIn
icon.name: 'contact-new'
text: l10n.get('global-drawer-action-create-room')
onTriggered: {
pushCreateRoomPage();
}
},
Kirigami.Action {
objectName: 'join-room'
enabled: root.loggedIn
text: l10n.get('global-drawer-action-join-room')
icon.name: 'list-add-user'
onTriggered: {
pushJoinRoomPage();
}
},
Kirigami.Action {
objectName: 'verifications'
enabled: root.loggedIn
icon.name: 'checkmark'
text: l10n.get('global-drawer-action-verifications')
onTriggered: {
pushVerificationsPage();
}
},
Kirigami.Action {
objectName: 'aboutAction'
text: l10n.get('global-drawer-action-about')
icon.name: 'help-about'
onTriggered: pageStack.pushDialogLayer(Qt.resolvedUrl('About.qml'))
}
]
}
contextDrawer: Kirigami.ContextDrawer {
id: contextDrawer
enabled: !!Kirigami.Settings.isMobile
actions: Kirigami.Settings.isMobile ? (pageStack.currentItem?.actions || []) : []
property var actionGroupName: l10n.get('action-group-context-drawer-actions')
}
property var roomPageActions: QtObject {
property var actionGroupName: l10n.get('action-group-room-page-actions')
property list<Kirigami.Action> actions: [
Kirigami.Action {
objectName: 'send-message'
icon.name: 'document-send'
text: l10n.get('send-message-box-send')
property var defaultShortcut: 'Ctrl+Return'
},
Kirigami.Action {
objectName: 'send-file'
icon.name: 'document-open-data'
text: l10n.get('send-message-box-send-file')
},
Kirigami.Action {
objectName: 'send-stickers'
icon.name: 'smiley'
text: l10n.get('send-message-box-stickers')
},
Kirigami.Action {
objectName: 'remove-related-to-event'
icon.name: 'window-close-symbolic'
text: l10n.get('action-settings-remove-related-to-event-action')
+ },
+ Kirigami.Action {
+ objectName: 'room-invite-accept-action'
+ icon.name: 'checkmark'
+ text: l10n.get('room-invite-accept-action')
+ },
+ Kirigami.Action {
+ objectName: 'room-invite-reject-action'
+ icon.name: 'im-ban-kick-user'
+ text: l10n.get('room-invite-reject-action')
+ },
+ Kirigami.Action {
+ objectName: 'pinnedEventsAction'
+ icon.name: 'pin'
+ text: l10n.get('action-settings-room-pinned-events-action')
+ },
+ Kirigami.Action {
+ objectName: 'scrollToLatestAction'
+ icon.name: "go-down"
+ text: l10n.get("room-timeline-scroll-to-latest-action")
+ },
+ Kirigami.Action {
+ objectName: 'room-settings-action'
+ icon.name: 'settings-configure'
+ text: l10n.get('room-settings-action')
}
]
}
property var actionCollection: KazvShortcuts.ActionCollection {
id: globalActionCollection
children: [
root.globalDrawer,
- root.contextDrawer,
root.roomPageActions
]
shortcutsConfig: kazvConfig
}
property var notifier: Kazv.Notifier {
}
pageStack.initialPage: Qt.resolvedUrl("LoginPage.qml")
property var emptyPage: Kirigami.Page {
title: l10n.get('empty-room-page-title')
Label {
text: l10n.get('empty-room-page-description')
}
}
signal switchToRoomRequested(string roomId)
property var pageManager: Kazv.PageManager {
pageStack: root.pageStack
sdkVars: root.sdkVars
main: root
}
function activateRoomSettingsPage(room) {
pageStack.layers.push(Qt.resolvedUrl("room-settings/RoomSettingsPage.qml"), {
room
});
}
function activateRoomPinnedEventsPage(room) {
pageStack.push(Qt.resolvedUrl('RoomPinnedEventsPage.qml'), {
room
});
}
function activateRoomInvitePage(room) {
pageStack.layers.push(Qt.resolvedUrl("room-settings/RoomInvitePage.qml"), {
room
});
}
function activateRoomStickerPacksPage(room) {
pageStack.layers.push(Qt.resolvedUrl("room-settings/RoomStickerPacksPage.qml"), {
room
});
}
function activateRoomStatePage(room) {
pageStack.layers.push(Qt.resolvedUrl("room-settings/RoomStatePage.qml"), {
room
});
}
function activateUserPage(user, room, userId) {
pageStack.layers.push(Qt.resolvedUrl("UserPage.qml"), {
userId: userId || user.userId,
user,
room
});
}
function switchToMainPage() {
pageStack.clear();
pageStack.layers.clear();
pageStack.replace([Qt.resolvedUrl('MainPage.qml')]);
pageStack.currentIndex = 0;
}
function switchToLoginPage() {
pageStack.replace([Qt.resolvedUrl("LoginPage.qml")])
pageStack.currentIndex = 0
}
function pushLoginPage() {
pageStack.layers.push(Qt.resolvedUrl("LoginPage.qml"), {
isSwitchingAccount: true,
});
}
function pushActionSettingsPage() {
pageStack.layers.push(Qt.resolvedUrl("ActionSettingsPage.qml"), {
actionsToConfigure: globalActionCollection.allActions(),
actionsGrouped: globalActionCollection.allActionsGrouped(),
});
}
function pushSettingsPage() {
pageStack.layers.push(Qt.resolvedUrl("SettingsPage.qml"));
}
function pushVerificationsPage() {
pageStack.layers.push(Qt.resolvedUrl("VerificationsPage.qml"));
}
function pushCreateRoomPage() {
pageStack.layers.push(Qt.resolvedUrl("CreateRoomPage.qml"), {});
}
function pushJoinRoomPage() {
pageStack.layers.push(Qt.resolvedUrl("JoinRoomPage.qml"), {});
}
function sessionNameFor(userId, deviceId) {
return userId + '/' + deviceId;
}
function getSessionLoadError(res, sessionName) {
switch (res) {
case MK.Constants.SessionNotFound:
return l10n.get('session-load-failure-not-found', { sessionName });
case MK.Constants.SessionFormatUnknown:
return l10n.get('session-load-failure-format-unknown', { sessionName });
case MK.Constants.SessionCannotBackup:
return l10n.get('session-load-failure-cannot-backup', { sessionName });
case MK.Constants.SessionLockFailed:
return l10n.get('session-load-failure-lock-failed', { sessionName });
case MK.Constants.SessionCannotOpenFile:
return l10n.get('session-load-failure-cannot-open-file', { sessionName });
case MK.Constants.SessionDeserializeFailed:
return l10n.get('session-load-failure-deserialize-failed', { sessionName });
default:
console.error('loadSession: Encountered an unknown error code');
}
}
function loadSession(sessionName) {
root.loadingSession = true;
matrixSdk.loadSession(sessionName);
}
function loadLastSession() {
console.log('last session is:', kazvConfig.lastSession);
return loadSession(kazvConfig.lastSession);
}
function recordLastSession() {
kazvConfig.lastSession = sessionNameFor(matrixSession?.userId, matrixSession?.deviceId);
}
function reloadSdkVariables() {
matrixSession = matrixSdk.session();
sdkVars.roomList = matrixSession?.roomList();
sdkVars.userGivenNicknameMap = matrixSession?.userGivenNicknameMap();
sdkVars.currentRoomId = '';
}
function switchAccount() {
pushLoginPage();
}
function hardLogout() {
matrixSession?.logout();
}
Component.onCompleted: {
actionCollection.setupShortcuts();
matrixSdk.startThread();
loadLastSession();
}
onClosing: {
kazvIOManager.clearJobs()
}
}
diff --git a/src/contents/ui/RoomPage.qml b/src/contents/ui/RoomPage.qml
index d9c8248..2a3c7f8 100644
--- a/src/contents/ui/RoomPage.qml
+++ b/src/contents/ui/RoomPage.qml
@@ -1,340 +1,334 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2020-2023 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import QtQuick 2.2
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import Qt.labs.platform as Platform
import org.kde.kirigami 2.13 as Kirigami
import moe.kazv.mxc.kazv 0.0 as MK
import '.' as Kazv
import 'matrix-helpers.js' as Helpers
Kazv.ScrollablePageAdapter {
id: roomPage
property string roomId: ''
property var room: sdkVars.roomList.room(roomId)
property var roomNameProvider: Kazv.RoomNameProvider {
room: roomPage.room
}
property var roomTimeline: room.timeline()
property var pinnedEvents: room.pinnedEventsTimeline()
property var lastReceiptableEventId: getLastReceiptableEventId(roomTimeline, roomTimeline.count)
property var paginationRequests: ({})
property var refreshRoomStateRequest: null
property var fileDialog: Kazv.FileDialogAdapter {
id: fileDialog
property var eventContent
property var eventId
property var jobManager: kazvIOManager
property var session: matrixSession
property var fileHandler: Kazv.FileHandler {
id: fileHandler
autoCache: false
eventContent: fileDialog.eventContent
kazvIOManager: fileDialog.jobManager
matrixSession: fileDialog.session
}
function saveAs(eventContent, eventId) {
fileDialog.eventContent = eventContent;
fileDialog.eventId = eventId;
fileDialog.open();
}
folder: Platform.StandardPaths.writableLocation(Platform.StandardPaths.DownloadLocation)
onAccepted: {
fileDialog.fileHandler.downloadFile(fileUrl);
// A newly created eventView will automatically look for its KazvIOJob.
// Here we just need to find those eventViews that have been created and notify them that the download has started.
for (const eventView of roomTimelineView.contentItem.children) {
if (eventView.event.eventId === fileDialog.eventId) {
eventView.downloadStarted();
}
}
}
Component.onCompleted: {
if (MK.KazvUtil.kfQtMajorVersion === 5) {
fileDialog.selectExisting = false;
} else {
fileDialog.fileMode = Kazv.FileDialogAdapter.SaveFile;
}
}
}
signal mentionUserRequested(string userId)
signal replaceDraftRequested(string newDraft)
signal paginateBackRequested(string eventId)
signal backfillRequested(string eventId)
signal viewEventHistoryRequested(string eventId)
title: roomNameProvider.name
padding: 0
property var isInvite: room.membership === MK.MatrixRoom.Invite
property var isJoin: room.membership === MK.MatrixRoom.Join
property var eventHistoryPopupComp: Component {
Kazv.SelfDestroyableOverlaySheet {
id: historyPopup
property var eventId
property var event: room.messageById(eventId)
shouldSelfDestroy: true
title: l10n.get('event-history-popup-title')
Kazv.EventHistoryView {
Layout.preferredWidth: Math.min(Kirigami.Units.gridUnit * 40, Window.width)
history: historyPopup.event.history()
}
}
}
actions: [
- Kirigami.Action {
+ Kazv.KazvAction {
id: acceptInviteAction
- icon.name: 'checkmark'
- text: l10n.get('room-invite-accept-action')
+ objectName: 'room-invite-accept-action'
visible: isInvite
onTriggered: joinRoomHandler.call()
},
- Kirigami.Action {
+ Kazv.KazvAction {
id: rejectInviteAction
- icon.name: 'im-ban-kick-user'
- text: l10n.get('room-invite-reject-action')
+ objectName: 'room-invite-reject-action'
visible: isInvite
onTriggered: leaveRoomHandler.call()
},
- Kirigami.Action {
+ Kazv.KazvAction {
id: pinnedEventsAction
objectName: 'pinnedEventsAction'
- icon.name: 'pin'
+ text: l10n.get('room-pinned-events-action', { count: roomPage.pinnedEvents.count })
visible: roomPage.pinnedEvents.count
enabled: roomPage.pinnedEvents.count
- text: l10n.get('room-pinned-events-action', { count: roomPage.pinnedEvents.count })
onTriggered: activateRoomPinnedEventsPage(room)
},
- Kirigami.Action {
+ Kazv.KazvAction {
id: scrollToLatestAction
objectName: 'scrollToLatestAction'
- icon.name: "go-down"
enabled: !roomTimelineView.atYEnd
- text: l10n.get("room-timeline-scroll-to-latest-action")
onTriggered: {
roomTimelineView.positionViewAtBeginning();
}
},
- Kirigami.Action {
+ Kazv.KazvAction {
id: roomSettingsAction
- icon.name: 'settings-configure'
- text: l10n.get('room-settings-action')
+ objectName: 'room-settings-action'
onTriggered: activateRoomSettingsPage(room)
}
]
property var inviteOverlay: Kirigami.OverlaySheet {
id: inviteOverlay
title: l10n.get('room-invite-popup-title')
parent: roomPage.overlay
property var self: room.member(matrixSession.userId)
property var inviteEvent: self.toEvent()
property var inviter: room.member(inviteEvent.sender)
property var inviterName: Helpers.userNameWithId(inviter, l10n)
ColumnLayout {
Label {
text: {
inviteOverlay.inviterName
? l10n.get('room-invite-popup-text-with-inviter', { inviterName: inviteOverlay.inviterName })
: l10n.get('room-invite-popup-text')
}
}
RowLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Button {
action: acceptInviteAction
}
Button {
action: rejectInviteAction
}
}
}
}
Component.onCompleted: {
if (isInvite) {
inviteOverlay.open();
}
}
RoomTimelineView {
id: roomTimelineView
objectName: 'roomTimelineView'
room: roomPage.room
timeline: roomPage.roomTimeline
}
onRoomChanged: {
kazvIOManager.deleteModelIfEmpty(roomId)
uploadList.model = kazvIOManager.getUploadJobs(roomId)
}
footer: Item {
height: childrenRect.height
width: parent.width
ListView {
id: uploadList
width: parent.width
height: contentHeight
model: kazvIOManager.getUploadJobs(roomId)
delegate: Kazv.KazvIOMenu {
width: parent.width
jobId: roomId
isUpload: true
}
}
Kazv.TypingIndicator {
id: typingIndicator
typingUsers: roomPage.room.typingUsers()
width: parent.width
anchors.top: uploadList.bottom
}
Kazv.SendMessageBox {
id: sendMessageBox
objectName: 'sendMessageBox'
width: parent.width
room: roomPage.room
anchors.top: typingIndicator.bottom
enabled: isJoin
}
}
function setDraftRelation(relType, eventId, newDraft) {
sendMessageBox.setDraftRelation(relType, eventId, newDraft);
}
property var joinRoomHandler: Kazv.AsyncHandler {
trigger: () => matrixSession.joinRoom(roomId, [])
onResolved: {
if (success) {
showPassiveNotification(l10n.get('join-room-page-success-prompt', { room: roomId }));
inviteOverlay.close();
} else {
showPassiveNotification(l10n.get('join-room-page-failed-prompt', { room: roomId, errorCode: data.errorCode, errorMsg: data.error }));
}
}
}
property var leaveRoomHandler: Kazv.AsyncHandler {
trigger: () => room.leaveRoom()
onResolved: {
if (success) {
showPassiveNotification(l10n.get('leave-room-success-prompt', { room: roomId }));
inviteOverlay.close();
} else {
showPassiveNotification(l10n.get('leave-room-failed-prompt', { room: roomId, errorCode: data.errorCode, errorMsg: data.error }));
}
}
}
onMentionUserRequested: (userId) => {
sendMessageBox.mentionUser(userId);
sendMessageBox.focusInput();
}
onReplaceDraftRequested: (newDraft) => {
sendMessageBox.replaceDraft(newDraft);
}
function getLastReceiptableEventId(timeline, timelineCount) {
for (let i = 0; i < timelineCount; ++i) {
const event = timeline.at(i);
if (!event.isLocalEcho && event.sender !== matrixSession.userId) {
return event.eventId;
}
}
}
onLastReceiptableEventIdChanged: maybePostReadReceipt()
Window.onActiveChanged: maybePostReadReceipt()
onVisibleChanged: maybePostReadReceipt()
function maybePostReadReceipt() {
if (!Window.active || !roomPage.visible) {
return;
}
const eventId = roomPage.lastReceiptableEventId;
if (!eventId) {
return;
}
const event = roomPage.room.messageById(eventId);
const readByMe = Helpers.isEventReadBy(event, matrixSession.userId);
if (!readByMe) {
roomPage.room.postReadReceipt(eventId);
}
}
onPaginateBackRequested: (eventId) => {
if (!paginationRequests[eventId]) {
console.debug('paginating back from', eventId);
paginationRequests[eventId] = room.paginateBackFrom(eventId);
paginationRequests[eventId].resolved.connect(() => {
console.debug('finished paginating back from', eventId);
delete paginationRequests[eventId];
});
} else {
console.debug('pagination request of', eventId, 'is already under way');
}
}
onBackfillRequested: (eventId) => {
if (!paginationRequests[eventId]) {
paginationRequests[eventId] = matrixSession.backfillRoomFromEvent(roomId, eventId);
paginationRequests[eventId].resolved.connect((isSuccess, data) => {
console.debug(
'finished backfill from', eventId,
'success=', isSuccess, JSON.stringify(data));
delete paginationRequests[eventId];
});
}
}
onViewEventHistoryRequested: (eventId) => {
eventHistoryPopupComp.createObject(applicationWindow().overlay, { eventId }).open();
}
Timer {
id: goToEventTimer
property var eventId
onTriggered: {
console.log('goto event');
roomTimelineView.goToEvent(eventId);
}
}
function delayGoToEvent(eventId, time) {
goToEventTimer.interval = time;
goToEventTimer.eventId = eventId
goToEventTimer.start();
}
}
diff --git a/src/l10n/cmn-Hans/100-ui.ftl b/src/l10n/cmn-Hans/100-ui.ftl
index 03cbc29..b981c88 100644
--- a/src/l10n/cmn-Hans/100-ui.ftl
+++ b/src/l10n/cmn-Hans/100-ui.ftl
@@ -1,485 +1,486 @@
### This file is part of kazv.
### SPDX-FileCopyrightText: 2020-2023 tusooa <tusooa@kazv.moe>
### SPDX-License-Identifier: AGPL-3.0-or-later
app-title-with-user-id = { -kt-app-name } - { $userId }
app-title-not-logged-in = { -kt-app-name } - 未登录
about-page-title = 关于 { -kt-app-name }
about-copyright = (c) 2020- the Kazv Project
about-display-name = { -kt-app-name } { $version }
about-short-description = 各平台同一的 Matrix 客户端和即时通讯软件
about-license = 以 AGPL 3 或以后版本授权
about-used-libraries = 使用了的库
about-authors = 作者
about-author-email-action = 写电邮
about-author-website-action = 访问网站
about-author-task-maintainer = 维护者
about-author-task-developer = 开发者
action-group-global-drawer-actions = 全局操作
action-group-context-drawer-actions = 页面操作
action-group-room-page-actions = 房间页面操作
user-name-with-id = { $name } ({ $userId })
user-name-overrided = { $overridedName } ({ $globalName })
global-drawer-title = { -kt-app-name }
global-drawer-action-switch-account = 切换账号
global-drawer-action-hard-logout = 登出
global-drawer-action-save-session = 保存当前会话
global-drawer-action-configure-shortcuts = 配置快捷键
global-drawer-action-settings = 设置
global-drawer-action-create-room = 创建房间
global-drawer-action-join-room = 加入房间
global-drawer-action-verifications = 设备验证
global-drawer-action-about = 关于 { -kt-app-name }
action-settings-page-title = 配置快捷键
action-settings-shortcut-prompt = 快捷键:{ $shortcut }
action-settings-shortcut-none = (无)
action-settings-shortcut-edit-action = 编辑
action-settings-shortcut-remove-action = 清除
action-settings-shortcut-conflict-modal-title = 冲突的快捷键
action-settings-shortcut-conflict = 快捷键 { $shortcut } 跟别的指令有冲突。<br>若要继续,别的指令的快捷键会被清除。<br><br>冲突的指令有:<br>{ $conflictingAction }
action-settings-shortcut-conflict-continue = 继续
action-settings-shortcut-conflict-cancel = 取消
action-settings-remove-related-to-event-action = 取消回复或编辑
+action-settings-room-pinned-events-action = 查看置顶消息
empty-room-page-title = 没有选中房间
empty-room-page-description = 当前没有选中的房间。
login-page-title = 登录
login-page-userid-prompt = 用户 id:
login-page-userid-input-placeholder = 例如: @foo:example.org
login-page-password-prompt = 密码:
login-page-login-button = 登录
login-page-close-button = 关闭
login-page-existing-sessions-prompt = 从已有会话中选一个:
login-page-alternative-password-login-prompt = 或者用用户 id 和密码启动新会话:
login-page-restore-session-button = 恢复会话
login-page-request-failed-prompt = 登录失败。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
login-page-discover-failed-enter-prompt = 不能检测此用户所在的服务器,或者服务器不可用。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。请手动输入服务器链接。
login-page-server-url-placeholder = 例如: https://example.org
login-page-server-url-prompt = 服务器链接(可选):
login-page-next-action = 下一步
login-page-server-label = 连接到 { $serverUrl }
login-page-login-flow-choice = 选择一种登录方式:
login-page-login-flow-password = 密码
login-page-login-flow-sso = 单点登录
login-page-login-with-sso-button = 进行单点登录
login-page-login-sso-redirect-url-label = 你应该看到浏览器打开了一个网页。遵从那个页面上的指示。如果没看到,那就手动打开下面的 URL:
login-page-change-server-button = 切换服务器
login-page-no-flow-supported = 这个服务器并不提供任何 { -kt-app-name } 支持的登录流程。
session-load-failure-not-found = 找不到会话 { $sessionName }。
session-load-failure-format-unknown = 会话 { $sessionName } 包含不支持的格式。是由未来版本的 { -kt-app-name } 保存的吗?
session-load-failure-cannot-backup = 无法备份会话 { $sessionName }。
session-load-failure-lock-failed = 会话 { $sessionName } 正在被别的程序使用。
session-load-failure-cannot-open-file = 无法打开会话 { $sessionName } 的存档文件。
session-load-failure-deserialize-failed = 无法打开会话 { $sessionName }。是被损坏了或者是由未来版本的 { -kt-app-name } 保存的吗?
main-page-title = { -kt-app-name } - { $userId }
main-page-recent-tab-title = 最近
main-page-favourites-tab-title = 最爱
main-page-people-tab-title = 人们
main-page-rooms-tab-title = 房间
main-page-room-filter-prompt = 过滤房间...
room-list-view-room-item-title-name = { $name }
room-list-view-room-item-title-heroes = { $hero } { $otherNum ->
[0] { "" }
[1] 和 { $secondHero }
*[other] 和别的 { $otherNum } 个人
}
room-list-view-room-item-title-id = 未命名房间({ $roomId })
room-list-view-room-item-fav-action = 设为最爱
room-list-view-room-item-unread-indicator = 未读
room-list-view-room-item-unread-notification-count = { $count }
room-list-view-room-item-unread-notification-count-text = { $count } 条未读通知
room-tags-fav-action-notification = 把 { $name } 设为了最爱
room-tags-fav-action-notification-failed = 不能把 { $name } 设为最爱。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
room-tags-unfav-action-notification = 把 { $name } 从最爱中移除了
room-tags-unfav-action-notification-failed = 不能把 { $name } 从最爱中移除。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
room-tags-add-tag-action-notification = 把标签 { $tag } 添加到了 { $name }
room-tags-add-tag-action-notification-failed = 不能把标签 { $tag } 添加到 { $name }。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
room-tags-remove-tag-action-notification = 把标签 { $tag } 从 { $name } 移除了
room-tags-remove-tag-action-notification-failed = 不能把标签 { $tag } 从 { $name } 移除。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
room-list-view-room-item-more-action = 更多...
room-list-view-room-item-invited = (邀请)
room-list-view-room-item-left = (已离开)
room-list-view-room-item-tombstone = (已废弃)
room-settings-action = 房间设置...
room-settings-page-title = { $room } 的房间设置
room-settings-tags = 房间标签
room-settings-favourited = 设为最爱
room-settings-remove-tag = 移除标签
room-settings-add-tag = 添加标签
room-settings-members-action = 房间成员...
room-settings-banned-members-action = 被封禁的成员...
room-settings-enable-encryption-prompt-dialog-title = 启用加密
room-settings-enable-encryption-prompt-dialog-prompt = 一旦在本房间中启用了加密,就不能再禁用了。确定吗?
room-settings-enable-encryption-action = 启用加密
room-settings-encrypted = 本房间中的消息是端对端加密了的。
room-settings-not-encrypted = 本房间中的消息没有端对端加密。
room-settings-encryption-enabled-notification = 本房间中的加密已经启用。
room-settings-encryption-failed-to-enable-notification = 不能在本房间中启用加密。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
room-settings-name-missing = 这个房间没有名字。
room-settings-topic-missing = 这个房间没有话题。
room-settings-edit-name-action = 编辑房间名字
room-settings-edit-topic-action = 编辑话题
room-settings-save-name-action = 保存房间名字
room-settings-save-topic-action = 保存话题
room-settings-discard-name-action = 放弃房间名字
room-settings-discard-topic-action = 放弃话题
room-settings-set-name-failed-prompt = 不能设置房间名字。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
room-settings-set-topic-failed-prompt = 不能设置话题。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
room-sticker-packs-action = 贴纸包...
room-sticker-packs-page-title = { $room } 中的贴纸包
room-sticker-packs-use-action = 使用贴纸包
room-sticker-packs-use-failed = 设置使用的贴纸包失败。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
room-sticker-packs-page-add-action = 添加贴纸包
room-sticker-packs-page-add-popup-title = 添加贴纸包
room-sticker-packs-page-add-success = 已添加贴纸包。
room-sticker-packs-page-add-failed = 无法添加贴纸包。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
room-sticker-packs-page-add-popup-name-prompt = 贴纸包名称:
room-sticker-packs-page-add-popup-state-key-prompt = 状态键:
room-member-list-page-title = { $room } 的成员
room-leave-action = 离开房间
room-leave-confirm-popup-title = 离开房间
room-leave-confirm-popup-message = 你确定要离开这个房间吗?
room-leave-confirm-popup-confirm-action = 离开
room-leave-confirm-popup-cancel-action = 留下
room-forget-action = 忘记房间
room-forget-confirm-popup-title = 忘记房间
room-forget-confirm-popup-message = 你确定要忘记这个房间吗?
room-forget-confirm-popup-confirm-action = 忘记
room-forget-confirm-popup-cancel-action = 取消
send-message-box-input-placeholder = 在此输入您的讯息...
send-message-box-send = 发送
send-message-box-send-file = 发送文件
send-message-box-reply-to = 回复给
send-message-box-edit = 编辑
send-message-box-remove-reply-to-action = 移除回复关系
send-message-box-remove-replace-action = 取消编辑
send-message-box-stickers = 发送贴纸...
send-message-box-stickers-popup-title = 发送贴纸
save-draft-confirmation-title = 保存草稿
save-draft-confirmation = 你有一个未发送的草稿,需要保存草稿以便在稍后恢复它吗?
save-draft-confirm-action = 保存
save-draft-discard-action = 丢弃
save-draft-cancel-action = 维持现状
discard-draft-confirmation-title = 丢弃草稿
discard-draft-confirmation = 你有一个未发送的草稿,你的操作将会丢弃它。
discard-draft-confirm-action = 丢弃
discard-draft-keep-action = 保留
discard-draft-cancel-action = 维持现状
sticker-picker-user-stickers = 我的贴纸
sticker-picker-room-sticker-pack-name = {$room} 中的 {$stateKey}
sticker-picker-room-default-sticker-pack-name = {$room} 中的默认包
room-timeline-load-more-action = 加载更多
room-timeline-scroll-to-latest-action = 滚动到最新的消息
room-invite-accept-action = 接受邀请
room-invite-reject-action = 拒绝邀请
room-invite-popup-title = 被邀请了
room-invite-popup-text = 你被邀请到这个房间了。
room-invite-popup-text-with-inviter = 你被 { $inviterName } 邀请到这个房间了。
room-pinned-events-action = { $count } 条置顶消息...
room-pinned-events-page-title = { $room } 的置顶消息
## 状态事件
## 通用参数:
## gender = 发送者的性别(male/female/neutral)
## stateKeyUser = state key 用户的名字
## stateKeyUserGender = state key 用户的性别
member-state-joined-room = 加入了房间。
member-state-changed-name-and-avatar = 修改了名字和头像。
member-state-changed-name = 修改了名字。
member-state-changed-avatar = 修改了头像。
member-state-invited = 把 { $stateKeyUser } 邀请到了本房间。
member-state-left = 离开了房间。
member-state-kicked = 踢出了 { $stateKeyUser }。
member-state-banned = 封禁了 { $stateKeyUser }。
member-state-unbanned = 解封了 { $stateKeyUser }。
state-room-created = 创建了房间。
state-room-name-changed = 把房间名字改成了 { $newName }。
state-room-topic-changed = 把房间话题改成了 { $newTopic }。
state-room-avatar-changed = 修改了房间头像。
state-room-pinned-events-changed = 修改了房间的置顶讯息。
state-room-alias-changed = 修改了房间的别名。
state-room-join-rules-changed = 修改了房间的加入规则。
state-room-power-levels-changed = 修改了房间的权限。
state-room-encryption-activated = 对本房间启用了加密。
event-message-image-sent = 发送了图片「{ $body }」。
event-message-sticker-sent = 发送了贴纸「{ $body }」。
event-summary-image-sent = 发送了图片「{ $body }」。
event-summary-sticker-sent = 发送了贴纸「{ $body }」。
event-message-file-sent = 发送了文件「{ $body }」。
event-message-video-sent = 发送了视频「{ $body }」。
event-summary-video-sent = 发送了视频「{ $body }」。
event-message-audio-sent = 发送了音频「{ $body }」。
event-message-audio-play-audio = 播放音频
event-sending = 发送中...
event-send-failed = 发送失败
event-resend = 重试发送这个事件
event-deleted = (已删除)
event-delete = 删除
event-delete-failed = 删除事件出错。错误码:{ $errorCode }。错误讯息:{ $errorMsg }。
event-view-source = 查看源码...
event-view-history = 查看编辑历史...
event-source-popup-title = 事件源码
event-source-decrypted = 解密的事件源码
event-source-original = 原始的事件源码
event-history-popup-title = 事件编辑历史
event-reply-action = 回复
event-popup-action = 更多关于这个事件...
event-reacted-with = 回应了「{ $key }」
event-react-action = 回应...
event-react-popup-title = 回应一条消息
event-react-accept-action = 回应
event-react-cancel-action = 取消
event-react-with-prompt = 回应以:
event-react-button-description = 回应以 { $key }
event-edit-action = 编辑
event-encrypted = 这条消息已加密
event-msgtype-fallback-text = 未知的消息类型:{ $msgtype }
event-fallback-text = 未知事件:{ $type }
event-cannot-decrypt-text = (加密内容)
event-read-indicator-more = +{ $rest }
event-read-indicator-list-title = { $numUsers } 个用户已读
event-edited-indicator = (编辑过了)
event-pin-action = 在房间置顶
event-unpin-action = 从房间取消置顶
event-pin-confirmation-title = 在房间置顶
event-pin-confirmation = 确定要置顶这条消息吗?
event-pin-confirm-action = 置顶
event-pin-cancel-action = 不置顶
event-pin-success-prompt = 消息在房间置顶了。
event-pin-failed-prompt = 无法置顶消息。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
event-unpin-confirmation-title = 从房间取消置顶
event-unpin-confirmation = 确定要取消置顶这条消息吗?
event-unpin-confirm-action = 取消置顶
event-unpin-cancel-action = 不取消置顶
event-unpin-success-prompt = 消息从房间取消置顶了。
event-unpin-failed-prompt = 无法取消置顶消息。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
event-request-key-action = 请求加密密钥
media-file-menu-option-view = 查看
media-file-menu-option-save-as = 保存为
media-file-menu-add-sticker-action = 添加到贴纸...
add-sticker-popup-title = 添加到贴纸
add-sticker-popup-pack-prompt = 添加到:
add-sticker-popup-short-code-prompt = 短代码:
add-sticker-popup-short-code-exists-warning = 贴纸包里已经有这个短代码了。上面的贴纸会覆盖已有的。
add-sticker-popup-add-sticker-button = 添加
add-sticker-popup-cancel-button = 取消
add-sticker-popup-failed-prompt = 无法添加贴纸。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
sticker-remove-action = 移除贴纸...
sticker-remove-confirmation-title = 移除贴纸
sticker-remove-confirmation-message = 确定要移除贴纸「{ $shortCode }」吗?
sticker-remove-confirm-action = 移除
sticker-remove-cancel-action = 不移除
sticker-remove-failed-prompt = 无法移除贴纸。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
kazv-io-download-success-prompt = 下载成功
kazv-io-download-failure-prompt = 下载失败:{ $detail }
kazv-io-failure-detail-user-cancel = 用户已取消
kazv-io-failure-detail-network-error = 网络错误
kazv-io-failure-detail-open-file-error = 打开文件错误
kazv-io-failure-detail-write-file-error = 写入文件错误
kazv-io-failure-detail-hash-error = 哈息值校验失败
kazv-io-failure-detail-response-error = 接收到无效的响应
kazv-io-failure-detail-kazv-error = 未知错误,请将此报告为漏洞
kazv-io-upload-failure-prompt = 上传失败:{ $detail }
kazv-io-downloading-prompt = 正在下载:{ $fileName }
kazv-io-uploading-prompt = 正在上传:{ $fileName }
kazv-io-prompt-close = 好的
kazv-io-pause = 暂停
kazv-io-resume = 继续
kazv-io-cancel = 取消
kazv-io-progress = { $progress }/100
create-room-page-title = 创建房间
create-room-page-type-prompt = 房间类型:
create-room-page-type-public = 公开(每个人都可加入)
create-room-page-type-private = 私有(仅受邀请用户可加入)
create-room-page-type-direct = 私聊(与私有一样,但初始受邀请用户具有管理权限)
create-room-page-name-prompt = 房间名称(可选):
create-room-page-name-placeholder = 无名
create-room-page-alias-prompt = 房间别名(可选):
create-room-page-alias-placeholder = #foo:example.org
create-room-page-topic-prompt = 房间主题(可选):
create-room-page-topic-placeholder = 无题
create-room-page-allow-federate-prompt = 允许别的服务器上的用户加入
create-room-page-action-create-room = 创建房间
create-room-page-success-prompt = 房间已创建。
create-room-page-failed-prompt = 无法创建房间。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
create-room-invite-userids-prompt = 受邀请的用户的 Matrix id:
create-room-page-add-invite-prompt = 添加一个新的受邀请用户:
create-room-page-add-invite-placeholder = Matrix id,例如 @foo:example.org
create-room-page-action-add-invite = 添加
create-room-page-encrypted-prompt = 启用端对端加密
join-room-page-title = 加入房间
join-room-page-id-or-alias-prompt = 房间 id 或别名:
join-room-page-id-or-alias-placeholder = #foo:example.org 或 !abcdef:example.org
join-room-page-servers-prompt = 经由服务器(可选,用换行分割):
join-room-page-servers-placeholder =
example.org
example.com
join-room-page-action-join-room = 加入房间
join-room-page-success-prompt = 成功加入房间 { $room }。
join-room-page-failed-prompt = 无法加入房间 { $room }。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
leave-room-success-prompt = 成功离开房间 { $room }。
leave-room-failed-prompt = 无法离开房间 { $room }。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
forget-room-success-prompt = 成功忘记房间 { $room }。
forget-room-failed-prompt = 无法忘记房间 { $room }。错误代码: { $errorCode }。错误讯息: { $errorMsg }。
user-devices = 设备
device-trust-level-unseen = 未曾见过
device-trust-level-seen = 见过
device-trust-level-verified = 已验证
device-trust-level-blocked = 已屏蔽
device-set-trust-level = 设置信任等级...
device-set-trust-level-dialog-title = 设置信任等级
device-set-trust-level-dialog-name-label = 设备名:{ $name }
device-set-trust-level-dialog-id-label = 设备id:{ $id }
device-set-trust-level-dialog-ed25519-key-label = Ed25519公钥:{ $key }
device-set-trust-level-dialog-curve25519-key-label = Curve25519公钥:{ $key }
device-set-trust-level-dialog-save = 保存
device-set-trust-level-dialog-cancel = 取消
device-verify-action = 验证设备...
device-verification-request-failed = 无法发送验证请求。错误码:{ $errorCode }。错误讯息:{ $errorMsg }。
device-item-title-deleted = (已删除) { $deviceId }
settings-page-title = 设置
settings-save = 保存设置
settings-profile-load-failed-prompt = 无法加载用户资料。错误码:{ $errorCode }。错误讯息:{ $errorMsg }。
settings-profile-change-avatar = 改变头像...
settings-profile-display-name = 显示名:
settings-profile-save-failed-prompt = 无法保存用户资料。错误码:{ $errorCode }。错误讯息:{ $errorMsg }。
settings-cache-directory = 缓存目录:
settings-select-cache-directory = 选择缓存目录...
settings-security-import-keys-action = 从备份文件导入密钥...
settings-security-import-keys-password-input-title = 输入密码
settings-security-import-keys-password-input-label = 当你创建备份时,提示了你要设置一个用来加密备份文件的密码。输入你当时设置的那个密码:
settings-security-import-keys-confirm-action = 导入
settings-security-import-keys-cancel-action = 不导入
settings-security-import-keys-success-notification = 导入了 { $imported } 个密钥。
settings-security-import-keys-failure-notification = 无法加载密钥备份文件。错误码:{ $errorCode }。错误讯息:{ $errorMsg }。
typing-indicator = { $typingUser } { $otherNum ->
[0] 正在输入...
[1] 和 { $secondTypingUser } 正在输入...
*[other] 和另外 { $otherNum } 人正在输入...
}
notification-message = <b>{ $user }:</b> { $message }
notification-message-no-content = <b>{ $user }</b> 给你发了一条讯息。
notification-open = 打开
user-page-power-level = 权限等级:{ $powerLevel }
user-page-edit-power-level-action = 编辑
user-page-save-power-level-action = 保存
user-page-discard-power-level-action = 丢弃
user-page-set-power-level-failed-prompt = 无法设置权限等级。错误码:{ $errorCode }。错误讯息:{ $errorMsg }。
user-page-kick-user-action = 踢出
user-page-kick-user-confirm-dialog-title = 踢出用户
user-page-kick-user-confirm-dialog-content = 确定要把 { $name }({ $userId })踢出 { $roomName } 吗?
user-page-kick-user-reason-prompt = 原因(可选):
user-page-kick-user-failed-prompt = 无法踢出用户。错误码:{ $errorCode }。错误讯息:{ $errorMsg }。
user-page-ban-user-action = 封禁
user-page-ban-user-confirm-dialog-title = 封禁用户
user-page-ban-user-confirm-dialog-content = 确定要在 { $roomName } 中封禁 { $name }({ $userId })吗?
user-page-ban-user-reason-prompt = 原因(可选):
user-page-ban-user-failed-prompt = 无法封禁用户。错误码:{ $error }。错误讯息:{ $errorMsg }。
user-page-unban-user-action = 解禁
user-page-unban-user-failed-prompt = 无法解禁用户。错误码:{ $error }。错误讯息:{ $errorMsg }。
user-page-overrided-name-placeholder = 自定义显示名...
user-page-save-name-override-action = 保存
user-page-update-name-override-failed-prompt = 无法设置自定义显示名。错误码:{ $error }。错误讯息:{ $errorMsg }。
user-page-self-name-prompt = 自己在房间里的显示名:
user-page-self-name-placeholder = 自己在房间里的显示名...
user-page-save-self-name-action = 保存
user-page-update-self-name-failed-prompt = 无法设置自己在房间里的显示名。错误码:{ $error }。错误讯息:{ $errorMsg }。
room-invite-page-title = 邀请用户到 { $room }
room-invite-page-invite-failed-prompt = 无法邀请用户。错误码:{ $errorCode }。错误讯息:{ $errorMsg }。
room-invite-invitee-matrix-id-placeholder = 用户的 Matrix id,比如 @foo:example.org
room-invite-invitee-matrix-id-prompt = 要邀请的用户:
room-invite-page-invite-button = 邀请
room-invite-action = 邀请到房间...
room-explore-state-action = 查看完整房间状态...
room-state-page-title = { $room } 的状态
room-state-page-state-key = 状态键:「<code>{ $stateKey }</code>」
confirm-upload-popup-title = 确认上传
confirm-upload-popup-prompt = 即将上传「{ $file }」({ $current } / { $total })。
confirm-upload-popup-prompt-single-file = 即将上传「{ $file }」。
confirm-upload-popup-accept-button = 上传
confirm-upload-popup-cancel-button = 取消
action-cut = 剪切
action-copy = 复制
action-paste = 粘贴
action-undo = 撤销
action-redo = 重做
action-delete = 删除
action-select-all = 全选
logout-failed-prompt = 登出失败,请检查您的网络后重试。错误码:{ $errorCode }。错误讯息:{ $errorMsg }。
confirm-logout-popup-title = 确认登出
confirm-logout-popup-prompt = 你确定要登出吗?
confirm-logout-popup-accept-button = 是
confirm-logout-popup-cancel-button = 取消
emoji-smileys-and-emotion = 笑容与情绪
emoji-people-and-body = 人与身体
emoji-animals-and-nature = 动物与自然
emoji-food-and-drink = 食物与饮料
emoji-travel-and-places = 旅行与地点
emoji-activities = 活动
emoji-objects = 物体
emoji-symbols = 符号
emoji-flags = 旗帜
confirm-deletion-popup-title = 删除事件
confirm-deletion-popup-message = 你确定要删除这个事件吗?
confirm-deletion-popup-confirm-action = 删除
confirm-deletion-popup-cancel-action = 取消
get-room-id-by-alias-failed-prompt = 无法通过房间别名获取房间 id。错误码:{ $errorCode }。错误讯息:{ $errorMsg }。
verifications-page-title = 设备验证
verification-state-they-requested = 请求验证了此设备。
verification-state-waiting = 正在等待另一方。
verification-state-waiting-after-verified = 正在等待另一方。
verification-state-confirm-code = 请确认这些代码是否和另一个设备上一致。
verification-state-done = 过程已经完成。
verification-state-cancelled = 过程被取消了。
verification-action-ready = 继续
verification-action-cancel = 取消
verification-action-confirm-sas-match = 是一致的
verification-action-deny-sas-match = 并不一致
verification-show-numbers = 转而显示数字
verification-show-emojis = 转而显示表情文字
diff --git a/src/l10n/en/100-ui.ftl b/src/l10n/en/100-ui.ftl
index 4cda789..10555f2 100644
--- a/src/l10n/en/100-ui.ftl
+++ b/src/l10n/en/100-ui.ftl
@@ -1,507 +1,508 @@
### This file is part of kazv.
### SPDX-FileCopyrightText: 2020-2023 tusooa <tusooa@kazv.moe>
### SPDX-License-Identifier: AGPL-3.0-or-later
app-title-with-user-id = { -kt-app-name } - { $userId }
app-title-not-logged-in = { -kt-app-name } - Not Logged In
about-page-title = About { -kt-app-name }
about-copyright = (c) 2020- the Kazv Project
about-display-name = { -kt-app-name } { $version }
about-short-description = Convergent Matrix client and instant messaging app
about-license = licensed under AGPL 3 or later
about-used-libraries = Used libraries
about-authors = Authors
about-author-email-action = Write an email
about-author-website-action = Access website
about-author-task-maintainer = Maintainer
about-author-task-developer = Developer
action-group-global-drawer-actions = Global Actions
action-group-context-drawer-actions = Page Actions
action-group-room-page-actions = Room Page Actions
user-name-with-id = { $name } ({ $userId })
user-name-overrided = { $overridedName } ({ $globalName })
global-drawer-title = { -kt-app-name }
global-drawer-action-switch-account = Switch account
global-drawer-action-hard-logout = Logout
global-drawer-action-save-session = Save current session
global-drawer-action-configure-shortcuts = Configure shortcuts
global-drawer-action-settings = Settings
global-drawer-action-create-room = Create room
global-drawer-action-join-room = Join room
global-drawer-action-verifications = Device Verification
global-drawer-action-about = About { -kt-app-name }
action-settings-page-title = Configure shortcuts
action-settings-shortcut-prompt = Shortcut: { $shortcut }
action-settings-shortcut-none = (none)
action-settings-shortcut-edit-action = Edit
action-settings-shortcut-remove-action = Clear
action-settings-shortcut-conflict-modal-title = Conflicting shortcuts
action-settings-shortcut-conflict = The shortcut { $shortcut } has conflicts with other actions. <br>If you continue, the shortcuts for other actions will be cleared. <br><br>Conflicting actions: <br>{ $conflictingAction }
action-settings-shortcut-conflict-continue = Continue
action-settings-shortcut-conflict-cancel = Cancel
action-settings-remove-related-to-event-action = Cancel reply or edit
+action-settings-room-pinned-events-action = View pinned messages
empty-room-page-title = No rooms selected
empty-room-page-description = There is no room selected now.
login-page-title = Log in
login-page-userid-prompt = User id:
login-page-userid-input-placeholder = E.g.: @foo:example.org
login-page-password-prompt = Password:
login-page-login-button = Log in
login-page-close-button = Close
login-page-existing-sessions-prompt = Choose from one of the existing sessions:
login-page-alternative-password-login-prompt = Or start a new session with user id and password:
login-page-restore-session-button = Restore session
login-page-request-failed-prompt = Login failed. Error code: { $errorCode }. Error message: { $errorMsg }.
login-page-discover-failed-enter-prompt = Unable to detect the server this user is on, or the server is unavailable. Error code: { $errorCode }. Error message: { $errorMsg }. Please enter the server url manually.
login-page-server-url-placeholder = E.g.: https://example.org
login-page-server-url-prompt = Server url (optional):
login-page-next-action = Next
login-page-server-label = Connecting to { $serverUrl }
login-page-login-flow-choice = Choose a way to log in:
login-page-login-flow-password = Password
login-page-login-flow-sso = Single Sign On
login-page-login-with-sso-button = Log in using Single Sign On
login-page-login-sso-redirect-url-label = You should see a web page open in your browser. Follow the instructions on that page. If not, manually open the following URL:
login-page-change-server-button = Change server
login-page-no-flow-supported = This server does not have any login flow that { -kt-app-name } supports.
session-load-failure-not-found = The session { $sessionName } is not found.
session-load-failure-format-unknown = The session { $sessionName } contains an unsupported format. Is it saved using a future version of { -kt-app-name }?
session-load-failure-cannot-backup = Cannot make a backup of the session { $sessionName }.
session-load-failure-lock-failed = The session { $sessionName } is being used by another program.
session-load-failure-cannot-open-file = Unable to open the store file for the session { $sessionName }.
session-load-failure-deserialize-failed = The session { $sessionName } cannot be opened. Is it corrupted or saved using a future version of { -kt-app-name }?
main-page-title = { -kt-app-name } - { $userId }
main-page-recent-tab-title = Recent
main-page-favourites-tab-title = Favourites
main-page-people-tab-title = People
main-page-rooms-tab-title = Rooms
main-page-room-filter-prompt = Filter rooms by...
room-list-view-room-item-title-name = { $name }
room-list-view-room-item-title-heroes = { $hero } { $otherNum ->
[0] { "" }
[1] and { $secondHero }
*[other] and { $otherNum } others
}
room-list-view-room-item-title-id = Unnamed room ({ $roomId })
room-list-view-room-item-fav-action = Set as favourite
room-list-view-room-item-unread-indicator = Unread
room-list-view-room-item-unread-notification-count = { $count }
room-list-view-room-item-unread-notification-count-text = { $count } unread {
$count ->
[1] message
*[other] messages
}
room-tags-fav-action-notification = Set { $name } as favourite
room-tags-fav-action-notification-failed = Cannot set { $name } as favourite. Error code: { $errorCode }. Error message: { $errorMsg }.
room-tags-unfav-action-notification = Removed { $name } from favourites
room-tags-unfav-action-notification-failed = Cannot remove { $name } from favourites. Error code: { $errorCode }. Error message: { $errorMsg }.
room-tags-add-tag-action-notification = Added tag { $tag } to { $name }
room-tags-add-tag-action-notification-failed = Cannot add tag { $tag } to { $name }. Error code: { $errorCode }. Error message: { $errorMsg }.
room-tags-remove-tag-action-notification = Removed tag { $tag } from { $name }
room-tags-remove-tag-action-notification-failed = Cannot remove tag { $tag } from { $name }. Error code: { $errorCode }. Error message: { $errorMsg }.
room-list-view-room-item-more-action = More...
room-list-view-room-item-invited = (Invited)
room-list-view-room-item-left = (Left)
room-list-view-room-item-tombstone = (Deprecated)
room-settings-action = Room settings...
room-settings-page-title = Room settings for { $room }
room-settings-tags = Room tags
room-settings-favourited = Set as favourite
room-settings-remove-tag = Remove tag
room-settings-add-tag = Add tag
room-settings-members-action = Room members...
room-settings-banned-members-action = Banned members...
room-settings-enable-encryption-prompt-dialog-title = Enabling encryption
room-settings-enable-encryption-prompt-dialog-prompt = Once you enable encryption in this room, you cannot disable it again. Are you sure?
room-settings-enable-encryption-action = Enable encryption
room-settings-encrypted = Messages in this room are end-to-end encrypted.
room-settings-not-encrypted = Messages in this room are not end-to-end-encrypted.
room-settings-encryption-enabled-notification = Encryption is now enabled in this room.
room-settings-encryption-failed-to-enable-notification = Cannot enable encryption in this room. Error code: { $errorCode }. Error message: { $errorMsg }.
room-settings-name-missing = This room dose not have a name.
room-settings-topic-missing = This room does not have a topic.
room-settings-edit-name-action = Edit name
room-settings-edit-topic-action = Edit topic
room-settings-save-name-action = Save name
room-settings-save-topic-action = Save topic
room-settings-discard-name-action = Discard name
room-settings-discard-topic-action = Discard topic
room-settings-set-name-failed-prompt = Cannot set name. Error code: { $errorCode }. Error message: { $errorMsg }.
room-settings-set-topic-failed-prompt = Cannot set topic. Error code: { $errorCode }. Error message: { $errorMsg }.
room-sticker-packs-action = Sticker packs...
room-sticker-packs-page-title = Sticker packs in { $room }
room-sticker-packs-use-action = Use sticker pack
room-sticker-packs-use-failed = Failed to set sticker packs in use. Error code: { $errorCode }. Error message: { $errorMsg }.
room-sticker-packs-page-add-action = Add sticker pack
room-sticker-packs-page-add-popup-title = Add sticker pack
room-sticker-packs-page-add-success = Sticker pack added.
room-sticker-packs-page-add-failed = Cannot add sticker pack. Error code: { $errorCode }. Error message: { $errorMsg }.
room-sticker-packs-page-add-popup-name-prompt = Sticker pack name:
room-sticker-packs-page-add-popup-state-key-prompt = State key:
room-member-list-page-title = Members of { $room }
room-leave-action = Leave room
room-leave-confirm-popup-title = Leaving room
room-leave-confirm-popup-message = Are you sure you want to leave this room?
room-leave-confirm-popup-confirm-action = Leave
room-leave-confirm-popup-cancel-action = Stay
room-forget-action = Forget room
room-forget-confirm-popup-title = Forgetting room
room-forget-confirm-popup-message = Are you sure you want to forget this room?
room-forget-confirm-popup-confirm-action = Forget
room-forget-confirm-popup-cancel-action = Cancel
send-message-box-input-placeholder = Type your message here...
send-message-box-send = Send
send-message-box-send-file = Send file
send-message-box-reply-to = Replying to
send-message-box-edit = Editing
send-message-box-remove-reply-to-action = Remove reply-to relationship
send-message-box-remove-replace-action = Cancel editing
send-message-box-stickers = Send a sticker...
send-message-box-stickers-popup-title = Send a sticker
save-draft-confirmation-title = Save draft
save-draft-confirmation = You have an unsent draft, do you want to save it to restore it later?
save-draft-confirm-action = Save it
save-draft-discard-action = Discard it
save-draft-cancel-action = Do nothing
discard-draft-confirmation-title = Discard draft
discard-draft-confirmation = You have an unsent draft, your operation will dicard it.
discard-draft-confirm-action = Discard it
discard-draft-keep-action = Keep it
discard-draft-cancel-action = Do nothing
sticker-picker-user-stickers = My stickers
sticker-picker-room-sticker-pack-name = {$stateKey} in {$room}
sticker-picker-room-default-sticker-pack-name = Default pack in {$room}
room-timeline-load-more-action = Load more
room-timeline-scroll-to-latest-action = Scroll to latest message
room-invite-accept-action = Accept invite
room-invite-reject-action = Reject invite
room-invite-popup-title = Invited
room-invite-popup-text = You are invited to join this room.
room-invite-popup-text-with-inviter = You are invited to join this room by { $inviterName }.
room-pinned-events-action = { $count } pinned { $count ->
[1] message
*[other] messages
}...
room-pinned-events-page-title = Pinned messages of { $room }
## State events
## Common parameters:
## gender = gender of the sender (male/female/neutral)
## stateKeyUser = name of the state key user
## stateKeyUserGender = gender of the state key user
member-state-joined-room = joined the room.
member-state-changed-name-and-avatar = changed { $gender ->
[male] his
[female] her
*[neutral] their
} name and avatar.
member-state-changed-name = changed { $gender ->
[male] his
[female] her
*[neutral] their
} name.
member-state-changed-avatar = changed { $gender ->
[male] his
[female] her
*[neutral] their
} avatar.
member-state-invited = invited { $stateKeyUser } to the room.
member-state-left = left the room.
member-state-kicked = kicked { $stateKeyUser }.
member-state-banned = banned { $stateKeyUser }.
member-state-unbanned = unbanned { $stateKeyUser }.
state-room-created = created the room.
state-room-name-changed = changed the name of the room to { $newName }.
state-room-topic-changed = changed the topic of the room to { $newTopic }.
state-room-avatar-changed = changed the avatar of the room.
state-room-pinned-events-changed = changed the pinned events of the room.
state-room-alias-changed = changed the aliases of the room.
state-room-join-rules-changed = changed join rules of the room.
state-room-power-levels-changed = changed power levels of the room.
state-room-encryption-activated = enabled encryption for this room.
event-message-image-sent = sent an image "{ $body }".
event-message-sticker-sent = sent a sticker "{ $body }".
event-summary-image-sent = sent an image "{ $body }".
event-summary-sticker-sent = sent a sticker "{ $body }".
event-message-file-sent = sent a file "{ $body }".
event-message-video-sent = sent a video "{ $body }".
event-summary-video-sent = sent a video "{ $body }".
event-message-audio-sent = sent an audio "{ $body }".
event-message-audio-play-audio = Play audio
event-sending = Sending...
event-send-failed = Failed to send
event-resend = Retry sending this event
event-deleted = (Deleted)
event-delete = Delete
event-delete-failed = Error deleting event. Error code: { $errorCode }. Error message: { $errorMsg }.
event-view-source = View source...
event-view-history = View edit history...
event-source-popup-title = Event source
event-source-decrypted = Decrypted event source
event-source-original = Original event source
event-history-popup-title = Event edit history
event-reply-action = Reply
event-popup-action = More about this event...
event-reacted-with = Reacted with "{ $key }"
event-react-action = React...
event-react-popup-title = React to a message
event-react-accept-action = React
event-react-cancel-action = Cancel
event-react-with-prompt = React with:
event-react-button-description = React with { $key }
event-edit-action = Edit
event-encrypted = This message is encrypteed
event-msgtype-fallback-text = Unknown message type: { $msgtype }
event-fallback-text = Unknown event: { $type }
event-cannot-decrypt-text = (Encrypted content)
event-read-indicator-more = +{ $rest }
event-read-indicator-list-title = Read by { $numUsers ->
[1] 1 user
*[other] { $numUsers } users
}
event-edited-indicator = (edited)
event-pin-action = Pin to room
event-unpin-action = Unpin from room
event-pin-confirmation-title = Pin to room
event-pin-confirmation = Are you sure you want to pin this message?
event-pin-confirm-action = Pin
event-pin-cancel-action = Do not pin
event-pin-success-prompt = Message pinned to room.
event-pin-failed-prompt = Unable to pin message. Error code: { $errorCode }. Error message: { $errorMsg }.
event-unpin-confirmation-title = Unpin from room
event-unpin-confirmation = Are you sure you want to unpin this message?
event-unpin-confirm-action = Unpin
event-unpin-cancel-action = Do not unpin
event-unpin-success-prompt = Message unpinned from room.
event-unpin-failed-prompt = Unable to unpin message. Error code: { $errorCode }. Error message: { $errorMsg }.
event-request-key-action = Request encryption key
media-file-menu-option-view = View
media-file-menu-option-save-as = Save as
media-file-menu-add-sticker-action = Add to sticker...
add-sticker-popup-title = Add to sticker
add-sticker-popup-pack-prompt = Add to pack:
add-sticker-popup-short-code-prompt = Short code:
add-sticker-popup-short-code-exists-warning = The short code already exists in this pack. The sticker above will override the existing one.
add-sticker-popup-add-sticker-button = Add
add-sticker-popup-cancel-button = Cancel
add-sticker-popup-failed-prompt = Unable to add sticker. Error code: { $errorCode }. Error message: { $errorMsg }.
sticker-remove-action = Remove sticker...
sticker-remove-confirmation-title = Remove sticker
sticker-remove-confirmation-message = Are you sure you want to remove the sticker "{ $shortCode }"?
sticker-remove-confirm-action = Remove
sticker-remove-cancel-action = Do not remove
sticker-remove-failed-prompt = Unable to remove sticker. Error code: { $errorCode }. Error message: { $errorMsg }.
kazv-io-download-success-prompt = Download successful
kazv-io-download-failure-prompt = Download failure: { $detail }
kazv-io-failure-detail-user-cancel = User canceled
kazv-io-failure-detail-network-error = Network error
kazv-io-failure-detail-open-file-error = Open file error
kazv-io-failure-detail-write-file-error = Write file error
kazv-io-failure-detail-hash-error = Hash check error
kazv-io-failure-detail-response-error = Get an invalid response
kazv-io-failure-detail-kazv-error = Unknow Error, please report this as bug.
kazv-io-upload-failure-prompt = Upload failure: { $detail }
kazv-io-downloading-prompt = Downloading: { $fileName }
kazv-io-uploading-prompt = Uploading: { $fileName }
kazv-io-prompt-close = Got it
kazv-io-pause = Pause
kazv-io-resume = Resume
kazv-io-cancel = Cancel
kazv-io-progress = { $progress }/100
create-room-page-title = Create room
create-room-page-type-prompt = Room type:
create-room-page-type-public = Public (everyone can join)
create-room-page-type-private = Private (only invited users can join)
create-room-page-type-direct = Direct message (same as private, but those initially invited get admin permissions)
create-room-page-name-prompt = Room name (optional):
create-room-page-name-placeholder = No name
create-room-page-alias-prompt = Room alias (optional):
create-room-page-alias-placeholder = #foo:example.org
create-room-page-topic-prompt = Room topic (optional):
create-room-page-topic-placeholder = No topic
create-room-page-allow-federate-prompt = Allow users from other servers to join
create-room-page-action-create-room = Create room
create-room-page-success-prompt = Room created.
create-room-page-failed-prompt = Unable to create room. Error code: { $errorCode }. Error message: { $errorMsg }.
create-room-invite-userids-prompt = Matrix ids of users to invite:
create-room-page-add-invite-prompt = Add a new user to invite:
create-room-page-add-invite-placeholder = Matrix id, e.g. @foo:example.org
create-room-page-action-add-invite = Add
create-room-page-encrypted-prompt = Enable end-to-end encryption
join-room-page-title = Join room
join-room-page-id-or-alias-prompt = Room id or alias:
join-room-page-id-or-alias-placeholder = #foo:example.org or !abcdef:example.org
join-room-page-servers-prompt = Via servers (optional, separated by newlines):
join-room-page-servers-placeholder =
example.org
example.com
join-room-page-action-join-room = Join room
join-room-page-success-prompt = Successfully joined room { $room }.
join-room-page-failed-prompt = Unable to join room { $room }. Error code: { $errorCode }. Error message: { $errorMsg }.
leave-room-success-prompt = Successfully left room { $room }.
leave-room-failed-prompt = Unable to leave room { $room }. Error code: { $errorCode }. Error message: { $errorMsg }.
forget-room-success-prompt = Successfully forgot room { $room }.
forget-room-failed-prompt = Unable to forget room { $room }. Error code: { $errorCode }. Error message: { $errorMsg }.
user-devices = Devices
device-trust-level-unseen = Unseen
device-trust-level-seen = Seen
device-trust-level-verified = Verified
device-trust-level-blocked = Blocked
device-set-trust-level = Set trust level...
device-set-trust-level-dialog-title = Set trust level
device-set-trust-level-dialog-name-label = Device name: { $name }
device-set-trust-level-dialog-id-label = Device id: { $id }
device-set-trust-level-dialog-ed25519-key-label = Ed25519 public key: { $key }
device-set-trust-level-dialog-curve25519-key-label = Curve25519 public key: { $key }
device-set-trust-level-dialog-save = Save
device-set-trust-level-dialog-cancel = Cancel
device-verify-action = Verify device...
device-verification-request-failed = Unable to send verification request. Error code: { $errorCode }. Error message: { $errorMsg }.
device-item-title-deleted = (Deleted) { $deviceId }
settings-page-title = Settings
settings-save = Save settings
settings-profile-load-failed-prompt = Unable to load profile. Error code: { $errorCode }. Error message: { $errorMsg }.
settings-profile-change-avatar = Change avatar...
settings-profile-display-name = Display name:
settings-profile-save-failed-prompt = Unable to save profile. Error code: { $errorCode }. Error message: { $errorMsg }.
settings-cache-directory = Cache directory:
settings-select-cache-directory = Select cache directory...
settings-security-import-keys-action = Import keys from a backup file...
settings-security-import-keys-password-input-title = Enter password
settings-security-import-keys-password-input-label = When you created the backup, you were prompted to set a password to encrypt the backup file. Enter the password you set at that time:
settings-security-import-keys-confirm-action = Import
settings-security-import-keys-cancel-action = Do not import
settings-security-import-keys-success-notification = Imported { $imported } keys.
settings-security-import-keys-failure-notification = Unable to load key backup file. Error code: { $errorCode }. Error message: { $errorMsg }.
typing-indicator = { $typingUser } { $otherNum ->
[0] is typing...
[1] and { $secondTypingUser } are typing...
*[other] and { $otherNum } others are typing...
}
notification-message = <b>{ $user }:</b> { $message }
notification-message-no-content = <b>{ $user }</b> sent you a message.
notification-open = Open
user-page-power-level = Power level: { $powerLevel }
user-page-edit-power-level-action = Edit
user-page-save-power-level-action = Save
user-page-discard-power-level-action = Discard
user-page-set-power-level-failed-prompt = Unable to set power level. Error code: { $errorCode }. Error message: { $errorMsg }.
user-page-kick-user-action = Kick
user-page-kick-user-confirm-dialog-title = Kicking user
user-page-kick-user-confirm-dialog-content = Are you sure you want to kick { $name } ({ $userId }) out of { $roomName }?
user-page-kick-user-reason-prompt = Reason (optional):
user-page-kick-user-failed-prompt = Unable to kick user. Error code: { $errorCode }. Error message: { $errorMsg }.
user-page-ban-user-action = Ban
user-page-ban-user-confirm-dialog-title = Banning user
user-page-ban-user-confirm-dialog-content = Are you sure you want to ban { $name } ({ $userId }) in { $roomName }?
user-page-ban-user-reason-prompt = Reason (optional):
user-page-ban-user-failed-prompt = Unable to ban user. Error code: { $errorCode }. Error message: { $errorMsg }.
user-page-unban-user-action = Unban
user-page-unban-user-failed-prompt = Unable to unban user. Error code: { $errorCode }. Error message: { $errorMsg }.
user-page-overrided-name-placeholder = Custom display name...
user-page-save-name-override-action = Save
user-page-update-name-override-failed-prompt = Unable to set custom display name. Error code: { $errorCode }. Error message: { $errorMsg }.
user-page-self-name-prompt = Own display name in room:
user-page-self-name-placeholder = Own display name in room...
user-page-save-self-name-action = Save
user-page-update-self-name-failed-prompt = Unable to set own display name in room. Error code: { $errorCode }. Error message: { $errorMsg }.
room-invite-page-title = Inviting user to { $room }
room-invite-page-invite-failed-prompt = Unable to invite user. Error code: { $errorCode }. Error message: { $errorMsg }.
room-invite-invitee-matrix-id-placeholder = Matrix id of the user, e.g. @foo:example.org
room-invite-invitee-matrix-id-prompt = User to invite:
room-invite-page-invite-button = Invite
room-invite-action = Invite to room...
room-explore-state-action = View full room state...
room-state-page-title = Room state of { $room }
room-state-page-state-key = State key: "<code>{ $stateKey }</code>"
confirm-upload-popup-title = Confirm upload
confirm-upload-popup-prompt = You are about to upload "{ $file }" ({ $current } / { $total }).
confirm-upload-popup-prompt-single-file = You are about to upload "{ $file }".
confirm-upload-popup-accept-button = Upload
confirm-upload-popup-cancel-button = Cancel
action-cut = Cut
action-copy = Copy
action-paste = Paste
action-undo = Undo
action-redo = Redo
action-delete = Delete
action-select-all = Select All
logout-failed-prompt = Logout failed. Please check your network and try again. Error code: { $errorCode }, error message: { $errorMsg }.
confirm-logout-popup-title = Confirm logout
confirm-logout-popup-prompt = Are you sure to logout?
confirm-logout-popup-accept-button = Yes
confirm-logout-popup-cancel-button = Cancel
emoji-smileys-and-emotion = Smiley && Emotion
emoji-people-and-body = People && Body
emoji-animals-and-nature = Animals && Nature
emoji-food-and-drink = Food && Drink
emoji-travel-and-places = Travel && Places
emoji-activities = Activities
emoji-objects = Objects
emoji-symbols = Symbols
emoji-flags = Flags
confirm-deletion-popup-title = Delete event
confirm-deletion-popup-message = Are you sure you want to delete this event?
confirm-deletion-popup-confirm-action = Delete
confirm-deletion-popup-cancel-action = Cancel
get-room-id-by-alias-failed-prompt = Unable to get room id by alias. Error code: { $errorCode }. Error message: { $errorMsg }.
verifications-page-title = Device Verification
verification-state-they-requested = requested to verify this device.
verification-state-waiting = Waiting for the other party.
verification-state-waiting-after-verified = Waiting for the other party.
verification-state-confirm-code = Please confirm whether the codes match the other device.
verification-state-done = The process is done.
verification-state-cancelled = The process is cancelled.
verification-action-ready = Continue
verification-action-cancel = Cancel
verification-action-confirm-sas-match = They match
verification-action-deny-sas-match = They do not match
verification-show-numbers = Show numbers instead
verification-show-emojis = Show emojis instead

File Metadata

Mime Type
text/x-diff
Expires
Thu, Oct 8, 7:25 PM (8 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1784235
Default Alt Text
(76 KB)

Event Timeline